Добавлена возможность удаления экрана по тегу.
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,
|
Replace,
|
||||||
// Удалить один или несколько экранов с вершины стека.
|
// Удалить один или несколько экранов с вершины стека.
|
||||||
Pop,
|
Pop,
|
||||||
|
// Удалить один или несколько экранов с вершины стека до указанного тега.
|
||||||
|
PopTo,
|
||||||
// Завершить выполнение UI-цикла.
|
// Завершить выполнение UI-цикла.
|
||||||
Quit
|
Quit
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +68,10 @@ struct ScreenAction
|
||||||
IScreen next;
|
IScreen next;
|
||||||
// Результат (используется для `Pop`, `Quit`).
|
// Результат (используется для `Pop`, `Quit`).
|
||||||
ScreenResult result;
|
ScreenResult result;
|
||||||
// Количество извлекаемых экранов.
|
// Количество удаляемых экранов.
|
||||||
int popScreenCount;
|
int popScreenCount;
|
||||||
|
// Целевой тег экрана, до которого необходимо удалить экраны из стека.
|
||||||
|
int targetTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ничего не делать.
|
* Ничего не делать.
|
||||||
|
|
@ -76,7 +80,7 @@ struct ScreenAction
|
||||||
*/
|
*/
|
||||||
static ScreenAction none()
|
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)
|
static ScreenAction push(IScreen screen)
|
||||||
{
|
{
|
||||||
// assert(isPointer!(typeof(result)), "ncuiNotNull expects a function that returns a pointer.");
|
// 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)
|
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)
|
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)
|
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)
|
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)
|
void apply(ScreenAction action)
|
||||||
{
|
{
|
||||||
while (_running && action.kind != ActionKind.None)
|
while (_running && action.kind != ActionKind.None)
|
||||||
|
|
@ -86,6 +104,30 @@ private:
|
||||||
action = parent.onShow(_context);
|
action = parent.onShow(_context);
|
||||||
break;
|
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:
|
case ActionKind.Quit:
|
||||||
_result = action.result;
|
_result = action.result;
|
||||||
_running = false;
|
_running = false;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,12 @@ interface IScreen
|
||||||
void close();
|
void close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Интерфейс тега экрана.
|
||||||
|
interface ITaggedScreen
|
||||||
|
{
|
||||||
|
int tag();
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ScreenBase : IScreen
|
abstract class ScreenBase : IScreen
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue