From 9162a4212f1eaa3b26844157fc6ffa68a08b62b6 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Tue, 6 Jan 2026 15:07:55 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0/=D1=8D=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/ncui/engine/action.d | 28 +++++++++++++++++++++++----- source/ncui/engine/ncui.d | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/source/ncui/engine/action.d b/source/ncui/engine/action.d index 4343ed5..7362228 100644 --- a/source/ncui/engine/action.d +++ b/source/ncui/engine/action.d @@ -66,6 +66,9 @@ struct ScreenAction IScreen next; // Результат (используется для `Pop`, `Quit`). ScreenResult result; + // Количество извлекаемых экранов. + int popScreenCount; + /** * Ничего не делать. * @@ -73,8 +76,9 @@ struct ScreenAction */ 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) { // 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) { - 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) { - 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-цикл и вернуть финальный результат наружу. * @@ -114,6 +132,6 @@ struct ScreenAction */ static ScreenAction quit(ScreenResult result) { - return ScreenAction(ActionKind.Quit, null, result); + return ScreenAction(ActionKind.Quit, null, result, 0); } } diff --git a/source/ncui/engine/ncui.d b/source/ncui/engine/ncui.d index 5bf4ac4..c31073b 100644 --- a/source/ncui/engine/ncui.d +++ b/source/ncui/engine/ncui.d @@ -25,6 +25,19 @@ private: // Конечный результат выполнения. 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) { while (_running && action.kind != ActionKind.None) @@ -49,6 +62,28 @@ private: break; 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; case ActionKind.Quit: