diff --git a/Documentation/GUI.md b/Documentation/GUI.md index a64295ef..4364f1ea 100644 --- a/Documentation/GUI.md +++ b/Documentation/GUI.md @@ -104,14 +104,14 @@ GUI.**container**( x, y, width, height ): *table* container ----------------------------------------------------------- | Тип | Аргумент | Описание | | ------ | ------ | ------ | -| *int* | x | Координата объекта по оси x | -| *int* | y | Координата объекта по оси y | -| *int* | width | Ширина объекта | -| *int* | height | Высота объекта | +| *int* | x | Координата контейнера по оси x | +| *int* | y | Координата контейнера по оси y | +| *int* | width | Ширина контейнера | +| *int* | height | Высота контейнера | -Каждый контейнер - это объект-группировщик для других объектов, его поведение очень похоже на папку, содержащую файлы. При изменении позиции контейнера на экране все его дочерние элементы будут также смещены на соответствующие координаты. Контейнер также имеет методы по добавлению дочерних элементов и работе с ними. +Каждый контейнер - это группировщик для других объектов, его поведение очень похоже на папку, содержащую множество вложенных файлов и других папок. -Все дочерние элементы контейнера имеют свою *localPosition* в контейнере (к примеру, *{x = 4, y = 2}*). После добавления дочернего элемента в контейнер для дальнейших рассчетов используется именно локальная позиция. Для получения глобальных (экранных) координат дочернего элемента необходимо обращаться к *element.x* и *element.y*. Глобальная (экранная) позиция дочерних элементов рассчитывается при каждой отрисовке содержимого контейнера. Таким образом, изменяя глобальные координаты дочернего элемента вручную, вы, в сущности, ничего не добьётесь. +Все дочерние элементы контейнера имеют свою *localPosition* в контейнере (к примеру, *{x = 4, y = 2}*). После добавления дочернего элемента в контейнер для дальнейших рассчетов используется именно его локальная позиция. Для получения глобальных (экранных) координат дочернего элемента необходимо обращаться к *element.x* и *element.y*. Глобальная (экранная) позиция дочерних элементов рассчитывается при каждой отрисовке содержимого контейнера. Таким образом, изменяя глобальные координаты дочернего элемента вручную, вы, в сущности, ничего не добьётесь. Наглядно система иерархии и позиционирования контейнеров и дочерних элементов представлена на следущем изображении: @@ -123,12 +123,34 @@ GUI.**container**( x, y, width, height ): *table* container Для добавления в контейнер дочернего элемента используйте синтаксическую конструкцию :**addChild**(**<Объект>**). При этом глобальные координаты объекта становятся локальными. К примеру, для добавления кнопки на локальную позицию *x = 5, y = 10* используйте :**addChild**(GUI.**button**(5, 10, ...)). В контейнер можно добавлять другие контейнеры, а в добавленные - еще одни, создавая сложные иерархические цепочки и группируя дочерние объекты по своему усмотрению. -Наконец, самая важная особенность контейнеров - это автоматизированная обработка системных событий. Для запуска обработчика событий необходимо вызвать метод :**startEventHandling**. После его запуска при каждом событии текущий контейнер и всего его вложенные объекты будут рекурсивно проанализированы на наличие метода-обработчика .**eventHandler**. Если необходимо прекратить обработку событий, то необходимо вызывать метод :**stopEventHandling**. +Наконец, самая важная особенность контейнеров - это автоматизированная обработка системных событий. Для запуска обработки событий необходимо вызвать метод :**startEventHandling**. После этого при каждом событии текущий контейнер и всего его вложенные объекты будут рекурсивно проанализированы на наличие метода-обработчика .**eventHandler**. -Если метод-обработчик имеется, то он будет вызван со следующими аргументами: *container* mainContainer, *object* object, *table* eventData, где первым аргументом является контейнер с вызванным обработчиком событий, вторым является текущий рассматриваемый объект обработчика событий, а третьим - таблица с данными события. Все объекты, перечисленные ниже, уже имеются собственный .**eventHandler** - к примеру, кнопка автоматически нажимается, слайдер перемещается влево-вправо, а селектор цвета открывает палитру для выбора желаемого оттенка. Все это реализовано именно на методе-обработчике. +Если метод-обработчик имеется, то он будет вызван со следующими аргументами: *container* mainContainer, *object* object, *table* eventData, где первым аргументом является контейнер, обрабатывающий события, вторым является текущий рассматриваемый объект обработчика событий, а третьим - таблица с данными события. Все объекты, перечисленные ниже, уже имеются собственный .**eventHandler** - к примеру, кнопка автоматически нажимается, слайдер перемещается влево-вправо, а селектор цвета открывает палитру для выбора желаемого оттенка. Все это реализовано именно на методе-обработчике. + +В качестве примера ниже приведен исходный код обработчика событий GUI.**button**. Как видите, в начале событие анализируется на соответствие "touch", затем кнопка визуально "нажимается", а в конце вызывается метод кнопки .*onTouch*, если он вообще имеется. +```lua +button.eventHandler = function(mainContainer, button, eventData) + if eventData[1] == "touch" then + button.pressed = true + mainContainer:draw() + buffer.draw() + + os.sleep(0.2) + + button.pressed = false + mainContainer:draw() + buffer.draw() + + if button.onTouch then + button.onTouch(mainContainer, object, eventData) + end + end +``` Ключевая деталь обработчика событий в том, что если событие "экранное", то есть относящееся к клику пользователя на монитор (touch, drag, drop, scroll), то метод-обработчик объекта будет вызван только в том случае, если пользователь "кликнул" на него, после чего обработка событий для оставшихся необработанных дочерних элементов завершится. Если событие не относится к экрану (key_down, clipboard и т.д.), или же объект не имеет метода-обработчика, то обработка оставшихся дочерних элементов продолжится в прежнем виде. +Если необходимо прекратить обработку событий, то необходимо вызвать метод :**stopEventHandling**. + | Тип свойства | Свойство |Описание | | ------ | ------ | ------ | | *function* | :**addChild**( *table* child ): *table* child| Добавить произвольный объект в контейнер в качестве дочернего - таким образом вы способны создавать собственные виджеты с индивидуальными особенностями. Уточняю, что у добавляемого объекта **обязательно** должен иметься метод *:draw* (подробнее см. ниже). При добавлении объекта его глобальные координаты становятся локальными |