Добавлена возможность удаления экрана по тегу.
This commit is contained in:
parent
1a3c144e80
commit
42744c6b16
3 changed files with 71 additions and 7 deletions
|
|
@ -21,6 +21,8 @@ enum ActionKind
|
|||
Replace,
|
||||
// Удалить один или несколько экранов с вершины стека.
|
||||
Pop,
|
||||
// Удалить один или несколько экранов с вершины стека до указанного тега.
|
||||
PopTo,
|
||||
// Завершить выполнение UI-цикла.
|
||||
Quit
|
||||
}
|
||||
|
|
@ -66,8 +68,10 @@ struct ScreenAction
|
|||
IScreen next;
|
||||
// Результат (используется для `Pop`, `Quit`).
|
||||
ScreenResult result;
|
||||
// Количество извлекаемых экранов.
|
||||
// Количество удаляемых экранов.
|
||||
int popScreenCount;
|
||||
// Целевой тег экрана, до которого необходимо удалить экраны из стека.
|
||||
int targetTag;
|
||||
|
||||
/**
|
||||
* Ничего не делать.
|
||||
|
|
@ -76,7 +80,7 @@ struct ScreenAction
|
|||
*/
|
||||
static ScreenAction none()
|
||||
{
|
||||
return ScreenAction(ActionKind.None, null, ScreenResult.none(), 0);
|
||||
return ScreenAction(ActionKind.None, null, ScreenResult.none(), 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,7 +92,7 @@ struct ScreenAction
|
|||
static ScreenAction push(IScreen screen)
|
||||
{
|
||||
// assert(isPointer!(typeof(result)), "ncuiNotNull expects a function that returns a pointer.");
|
||||
return ScreenAction(ActionKind.Push, screen, ScreenResult.none(), 0);
|
||||
return ScreenAction(ActionKind.Push, screen, ScreenResult.none(), 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,7 +103,7 @@ struct ScreenAction
|
|||
*/
|
||||
static ScreenAction replace(IScreen screen)
|
||||
{
|
||||
return ScreenAction(ActionKind.Replace, screen, ScreenResult.none(), 0);
|
||||
return ScreenAction(ActionKind.Replace, screen, ScreenResult.none(), 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,7 +114,7 @@ struct ScreenAction
|
|||
*/
|
||||
static ScreenAction pop(ScreenResult result)
|
||||
{
|
||||
return ScreenAction(ActionKind.Pop, null, result, 1);
|
||||
return ScreenAction(ActionKind.Pop, null, result, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,7 +125,19 @@ struct ScreenAction
|
|||
*/
|
||||
static ScreenAction popN(int count, ScreenResult result)
|
||||
{
|
||||
return ScreenAction(ActionKind.Pop, null, result, count < 1 ? 1 : count);
|
||||
return ScreenAction(ActionKind.Pop, null, result, count < 1 ? 1 : count, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрыть экраны до экрана с указанным тегом и передать ему результат.
|
||||
*
|
||||
* Params:
|
||||
* - tag: целевой тег.
|
||||
* - result: результат закрываемого экрана.
|
||||
*/
|
||||
static ScreenAction popTo(int targetTag, ScreenResult result)
|
||||
{
|
||||
return ScreenAction(ActionKind.PopTo, null, result, 0, targetTag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,6 +148,6 @@ struct ScreenAction
|
|||
*/
|
||||
static ScreenAction quit(ScreenResult result)
|
||||
{
|
||||
return ScreenAction(ActionKind.Quit, null, result, 0);
|
||||
return ScreenAction(ActionKind.Quit, null, result, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,24 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Проверить наличие тега у экрана.
|
||||
int hasScreenTag(IScreen screen)
|
||||
{
|
||||
auto taggetScreen = cast(ITaggedScreen) screen;
|
||||
// Пользовательский тег не должен быть равен int.min!
|
||||
return (taggetScreen is null) ? int.min : taggetScreen.tag();
|
||||
}
|
||||
|
||||
// Извлечение из стека экраны до указанного тега.
|
||||
void popToTag(int targetTag)
|
||||
{
|
||||
while (_stack.length != 0 && hasScreenTag(_stack[$ - 1]) != targetTag)
|
||||
{
|
||||
_stack[$ - 1].close();
|
||||
_stack.popBack();
|
||||
}
|
||||
}
|
||||
|
||||
void apply(ScreenAction action)
|
||||
{
|
||||
while (_running && action.kind != ActionKind.None)
|
||||
|
|
@ -86,6 +104,30 @@ private:
|
|||
action = parent.onShow(_context);
|
||||
break;
|
||||
|
||||
case ActionKind.PopTo:
|
||||
// Результат работы удаляемого экрана (дочерний экран).
|
||||
// Позже он будет передан родительскому экрану.
|
||||
auto childResult = action.result;
|
||||
// Удалить экраны до указанного тега.
|
||||
popToTag(action.targetTag);
|
||||
_session.clear();
|
||||
if (_stack.length == 0)
|
||||
{
|
||||
_result = childResult;
|
||||
_running = false;
|
||||
return;
|
||||
}
|
||||
auto parent = _stack[$ - 1];
|
||||
// Передача результата дочернего экрана первому экрану в стеке (родительскому экрану).
|
||||
auto actionResult = parent.onChildResult(_context, childResult);
|
||||
if (actionResult.kind != ActionKind.None)
|
||||
{
|
||||
action = actionResult;
|
||||
break;
|
||||
}
|
||||
action = parent.onShow(_context);
|
||||
break;
|
||||
|
||||
case ActionKind.Quit:
|
||||
_result = action.result;
|
||||
_running = false;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ interface IScreen
|
|||
void close();
|
||||
}
|
||||
|
||||
// Интерфейс тега экрана.
|
||||
interface ITaggedScreen
|
||||
{
|
||||
int tag();
|
||||
}
|
||||
|
||||
abstract class ScreenBase : IScreen
|
||||
{
|
||||
protected:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue