Если иерархия экранов проекта панели имеет большую глубину, то для упрощения навигации между ними хочется иметь возможность возвращаться на предыдущие экраны.
Для этого можно использовать стандартную функциональную кнопку с выбранной функцией перехода на предыдущий экран при нажатии:
![]() |
Создание стандартной кнопки 'Назад' |
Однако эта кнопка оказывается способна обеспечить переключение только между двумя экранами - текущим и предыдущим.
При переходе на предыдущий экран, текущий экран становится предыдущим и при повторном нажатии кнопки мы возвращаемся туда откуда только что пришли.
Это немного не то, чего обычно ожидаешь от кнопки 'Назад'. Ожидаемое поведение - это воспроизведение последовательности переходов между экранами в обратном порядке. Такую функциональность мы и реализуем с помощью макросов C.Для того, чтобы хранить историю переходов нам понадобится буфер. Создадим его в Глобальном макросе добавив объявление глобального массива с именем _back_stack:
WORD _back_stack[20];
Количество сохранённых экранов будет определяться количеством элементов массива - будет на единицу меньше его.
Этим буфером мы будем пользоваться как стеком. При переходе на новый экран будем дописывать в него идентификатор этого экрана. А при возврате на предыдущий экран удалять последний дописанный идентификатор.
Нам понадобятся два макроса. Первый, назовём его PushScreenId, будет вызываться при переходе на новый экран и сохранять его идентификатор:
В этом макросе мы учли наличие скринсейвера. Если идентификатор нового экрана (переменная current_screen) совпадает с идентификатором экрана скринсейвера (константа SCREEN_SAVER), то мы этот идентификатор в историю переходов не заносим (прерываем выполнение функции).
Этот макрос также будет выполняться при возврате на предыдущий экран. В этом случае на вершине стека окажется идентификатор экрана, на который мы перешли, поэтому его в стек заносить не нужно и мы также прерываем выполнение функции.
Двумя последними строчками мы сдвигаем содержимое стека на одну позицию и кладём на вершину стека идентификатор текущего экрана.
Для вызова этого макроса мы используем функциональную область с выбранной функцией 'Вызов макроса' и условием запуска 'Переход на экран элемента':
Эту функциональную область нужно сделать глобальной, так как она должна присутствовать на всех экранах.
Второй макрос, который мы назовём JumpBack, будет вызываться при нажатии кнопки 'Назад':
В этом макросе мы учли случай, когда в стеке находится только один элемент - значит возвращаться некуда и мы прерываем выполнение функции.
Этот макрос мы привяжем к функции 'Вызов макроса' функциональной кнопки, которую также нужно сделать глобальной.
Добавив для тестирования несколько экранов и кнопок перехода мы получаем демонстрационный проект, который можно скачать по ссылке:
Этим буфером мы будем пользоваться как стеком. При переходе на новый экран будем дописывать в него идентификатор этого экрана. А при возврате на предыдущий экран удалять последний дописанный идентификатор.
Нам понадобятся два макроса. Первый, назовём его PushScreenId, будет вызываться при переходе на новый экран и сохранять его идентификатор:
const WORD SCREEN_SAVER = 8; WORD current_screen = PSW[1]; if (current_screen == _back_stack[0] || current_screen == SCREEN_SAVER) return; memmove(_back_stack + 1, _back_stack, sizeof(_back_stack) - sizeof(_back_stack[0])); _back_stack[0] = current_screen;
В этом макросе мы учли наличие скринсейвера. Если идентификатор нового экрана (переменная current_screen) совпадает с идентификатором экрана скринсейвера (константа SCREEN_SAVER), то мы этот идентификатор в историю переходов не заносим (прерываем выполнение функции).
Этот макрос также будет выполняться при возврате на предыдущий экран. В этом случае на вершине стека окажется идентификатор экрана, на который мы перешли, поэтому его в стек заносить не нужно и мы также прерываем выполнение функции.
Двумя последними строчками мы сдвигаем содержимое стека на одну позицию и кладём на вершину стека идентификатор текущего экрана.
Для вызова этого макроса мы используем функциональную область с выбранной функцией 'Вызов макроса' и условием запуска 'Переход на экран элемента':
![]() |
Создание функциональной области для вызова PushScreenId |
Эту функциональную область нужно сделать глобальной, так как она должна присутствовать на всех экранах.
Второй макрос, который мы назовём JumpBack, будет вызываться при нажатии кнопки 'Назад':
if (_back_stack[1] == 0) return; memmove(_back_stack, _back_stack + 1, sizeof(_back_stack) - sizeof(_back_stack[0])); ScreenJump(_back_stack[0]);
В этом макросе мы учли случай, когда в стеке находится только один элемент - значит возвращаться некуда и мы прерываем выполнение функции.
Этот макрос мы привяжем к функции 'Вызов макроса' функциональной кнопки, которую также нужно сделать глобальной.
![]() |
Создание функциональной кнопки для вызова JumpBack |
Добавив для тестирования несколько экранов и кнопок перехода мы получаем демонстрационный проект, который можно скачать по ссылке:
![]() |
Скриншот демонстрационного проекта |
Комментариев нет:
Отправить комментарий