Добавлена обработка удаления экрана/экранов.

This commit is contained in:
Alexander Zhirov 2026-01-06 15:07:55 +03:00
parent c43ef1e908
commit 9162a4212f
Signed by: alexander
GPG key ID: C8D8BE544A27C511
2 changed files with 58 additions and 5 deletions

View file

@ -66,6 +66,9 @@ struct ScreenAction
IScreen next; IScreen next;
// Результат (используется для `Pop`, `Quit`). // Результат (используется для `Pop`, `Quit`).
ScreenResult result; ScreenResult result;
// Количество извлекаемых экранов.
int popScreenCount;
/** /**
* Ничего не делать. * Ничего не делать.
* *
@ -73,8 +76,9 @@ struct ScreenAction
*/ */
static ScreenAction none() static ScreenAction none()
{ {
return ScreenAction(ActionKind.None, null, ScreenResult.none()); return ScreenAction(ActionKind.None, null, ScreenResult.none(), 0);
} }
/** /**
* Добавить новый экран поверх текущего. * Добавить новый экран поверх текущего.
* *
@ -84,8 +88,9 @@ 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()); return ScreenAction(ActionKind.Push, screen, ScreenResult.none(), 0);
} }
/** /**
* Заменить верхний экран стека новым. * Заменить верхний экран стека новым.
* *
@ -94,8 +99,9 @@ struct ScreenAction
*/ */
static ScreenAction replace(IScreen screen) static ScreenAction replace(IScreen screen)
{ {
return ScreenAction(ActionKind.Replace, screen, ScreenResult.none()); return ScreenAction(ActionKind.Replace, screen, ScreenResult.none(), 0);
} }
/** /**
* Закрыть верхний экран и передать результат родителю. * Закрыть верхний экран и передать результат родителю.
* *
@ -104,8 +110,20 @@ struct ScreenAction
*/ */
static ScreenAction pop(ScreenResult result) static ScreenAction pop(ScreenResult result)
{ {
return ScreenAction(ActionKind.Pop, null, result); return ScreenAction(ActionKind.Pop, null, result, 1);
} }
/**
* Закрыть верхний экран и передать результат родителю.
*
* Params:
* - result: результат закрываемого экрана.
*/
static ScreenAction popN(int count, ScreenResult result)
{
return ScreenAction(ActionKind.Pop, null, result, count < 1 ? 1 : count);
}
/** /**
* Завершить UI-цикл и вернуть финальный результат наружу. * Завершить UI-цикл и вернуть финальный результат наружу.
* *
@ -114,6 +132,6 @@ struct ScreenAction
*/ */
static ScreenAction quit(ScreenResult result) static ScreenAction quit(ScreenResult result)
{ {
return ScreenAction(ActionKind.Quit, null, result); return ScreenAction(ActionKind.Quit, null, result, 0);
} }
} }

View file

@ -25,6 +25,19 @@ private:
// Конечный результат выполнения. // Конечный результат выполнения.
ScreenResult _result; ScreenResult _result;
// Извлечение из стека указанное количество экранов.
void popMany(int screenCount)
{
if (screenCount < 1)
screenCount = 1;
for (int i = 0; i < screenCount && _stack.length != 0; ++i)
{
_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)
@ -49,6 +62,28 @@ private:
break; break;
case ActionKind.Pop: case ActionKind.Pop:
// Результат работы удаляемого экрана (дочерний экран).
// Позже он будет передан родительскому экрану.
auto childResult = action.result;
// Количество удаляемых экранов.
int screenCount = (action.popScreenCount <= 0) ? 1 : action.popScreenCount;
popMany(screenCount);
_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; break;
case ActionKind.Quit: case ActionKind.Quit: