Лекция #23. GUI [Лектор - Sark7]
Автор: Арсений Капулкин
Disclaimer: некоторые опечатки поправлены, некоторые реплики передвинуты. полный лог
[13:42] <Sark7> значецо, хотим мы гуи
[13:43] <Sark7> и чтобы ексендабельный был
[13:43] <Sark7> и чтобы по возможности как можно более кроссплатформенный/апи
[13:43] <Sark7> не в смысле работать на всех платформах, а уменьшить зависимость от апи/системы
[13:43] <Sark7> первое что приходит в голову
[13:44] <Sark7> это html
[13:44] <Sark7> ну и xml в той же степени
[13:44] <Sark7> на самом деле, это единственно реальный вариант
[13:44] <Sark7> и адобе, и мозилла, и мс это понимают, поэтому предложили свои варианты gui markup langs
[13:45] <Sark7> причина этого
[13:45] <Sark7> что абсолютный (ручной) лайоут контролов - зло
[13:45] <Sark7> абсолютное
[13:45] <Sark7> слишком многое надо учесть чтобы такой лайоут нормально работал на всех разрешениях, dpi, шрифтах итд
[13:46] <Sark7> мне вот лично очень понравился SWT
[13:46] <Sark7> это такая gui библиотека для явы в eclipse
[13:46] <Sark7> я брал ее за основу
[13:46] <Sark7> итак
[13:46] <Sark7> есть контрол
[13:47] <Sark7> у него есть методы Layout() и Draw(UIRenderer& renderer)
[13:47] <Sark7> события рассмотрим позже
[13:47] <Sark7> в контроле Layout() ничего не делает
[13:47] <Sark7> как и Draw
[13:48] <Sark7> есть контейнер
[13:48] <Sark7> наследуется от контрола, и их хранит
[13:48] <Sark7> у него Layout() выполняет работу по расстановке контролов
[13:49] <Sark7> это так сказать база
[13:49] <Sark7> что такое UIRenderer
[13:50] <Sark7> у него есть методы по отрисовке основных виджетов и графических примитивов
[13:50] <Sark7> чтобы когда мы захотели поменять стиль контролов, нам пришлось бы только сменить рендерер
[13:50] <Sark7> есть Window который наследуется от контейнера
[13:51] <Sark7> он как раз и выполняет основную работу
[13:51] <Sark7> и посылает нужным контролам сообщения
[13:52] <Sark7> идеальная модель для сообщений - это event sinking/bubbling
[13:52] <Sark7> т.е. сначала событие как бы тонет
[13:52] <Sark7> т.е. идет от парента к чайлду
[13:53] <Sark7> на этом этапе парент может обработать его и далее оно тонуть не будет
[13:53] <Sark7> после того как событие достигло дна
[13:53] <Sark7> т.е. собственно таргет контрола для которого событие предназначалось
[13:53] <Sark7> оно начинает всплывать
[13:54] <Sark7> и идет от чайлда к паренту
[13:54] <Sark7> на этом этапе, если событие пришло к паренту, он знает, что никакой из чайлдов его не обработал
[13:55] <Sark7> и может действовать соответственно
[13:55] <Sark7> сообщения я лично разделил на три категории
[13:56] <Sark7> MouseEvent, KeyEvent и CommandEvent
[13:56] <Sark7> ну из названий понятно что они делают )
[13:56] <Sark7> соотв. в контроле имеется три методы on(MouseEvent&), on(KeyEvent)&, on(CommandEvent&)
[13:56] <Sark7> это базисные
[13:57] <Sark7> ладно, может кто чо спросить хочет )
[13:58] <Anubis|tea> про евенты понятно... не понял самое начало правда
[13:58] <Anubis|tea> про маркап
[13:58] <Anubis|tea> чем он помогает от ручного лэйаута... и какой он тогда, если не ручной
[13:59] <Sark7> он автоматический
[13:58] <Sark7> такая модель гуи легко переносится на data-driven
[13:59] <Sark7> в этом пойнт
[13:59] <cppg> да, кто контролы двигает?
[13:59] <Sark7> у контролов есть стиль
[13:59] <Sark7> это как css стиль у элемента в html
[13:59] <Sark7> он определяет как контрол будет позиционироваться в контейнере
[14:00] <Sark7> и вообще его внешний вид
[14:00] <Sark7> т.е. его align, font-size, overflow... практически весь css
[14:00] <Anubis|tea> а, то есть есть набор контролов, и аффтаматам, как в броузере, определяеццо как он рисоваццо будет?
[14:01] <Anubis|tea> гм... а речь о гуи для игр? там ведь дизайнер хочет контролировать все на свете, как, где, что и зачем, каким цветом рисуецца
[14:01] <Sark7> что именно ненравицо?
[14:01] <Anubis|tea> с точностью до пикселей как будет нарисовано.. или нет?
[14:01] <Sark7> веб-дизайнеры все прекрасно контролируют с помощью html/css
[14:02] <Zeux> у веб дизайнеров есть опции алигнмента по позиции
[14:02] <Zeux> в том самом html/css
[14:03] <Sark7> что еще за алигнмент по позиции? )
[14:03] <Zeux> ну, хочу текст в позиции 100, 100
[14:03] <Sark7> ну, есть абсолютное позиционирование конечно
[14:03] <Zeux> то что ты называешь абсолютным лейаутом
[14:03] <Sark7> и у меня )
[14:03] <Sark7> будет тоже, да
[14:04] <Zeux> вопрос в том
[14:04] <Zeux> как будет авто лейаут
[14:04] <Zeux> сочетаться с абсолютным лейаутом
[14:04] <Zeux> и не съедет ли все
[14:04] <Sark7> замечательно
[14:04] <Sark7> как он в html сочетается
[14:05] <Sark7> на самом деле абсолютное позиционирование контрола нужно в очень редких случаях
[14:05] <Sark7> лого там нарисовать чтобы висело на месте итд
[14:05] <Zeux> в html он сочетается так
[14:05] <Zeux> что страницы во всех браузерах выглядят по-разному
[14:04] <_Anubis_> ну ладно, проехали :) надо обдумать.. просто я не вижу, почему дизайнерам самим все не расставить на экране. и дать им возможность подрисовать для разных разрешений если где что некрасиво смотрицца.
[14:04] <cppg> патамушта разные разрешения надо
[14:04] <cppg> любые размеры окна, скажем
[14:05] <cppg> имхо надо всё указывать в координатах float 0.0...1.0 и не париться с размерами окон и пикселями
[14:05] <_Anubis_> цппг - разрешения вполней фиксированые ведь.. их не много и чаще фсего с фиксированым аспектом
[14:05] <Sark7> _Anubis_, размеры окон
[14:06] <cppg> _Anubis_, их много во-первых, во-вторых незачем делать десять раз то, что можно сделать один раз
[14:06] <_Anubis_> цппг - так я так и имел ввиду, блин
[14:06] <_Anubis_> просто при некоторых может там ченить съехать
[14:07] <cppg> АА вруби и не сьедет
[14:07] <Sark7> как бы оно не сьехало, оно нормально будет выглядеть
[14:07] <Sark7> в отличие от ручного лайоута
[14:06] <_Anubis_> я имел ввиду дать возможность подправить руками там где не нравицца
[14:07] <Zeux> координаты от 0 до 1 - это здорово
[14:07] <Zeux> но шрифты масштабировать не стоит
[14:07] <Zeux> так что все равно делать кучу шрифтов
[14:07] <Zeux> под разные разрешения
[14:07] <cppg> текстурные шрифты отлично ложаццо на это
[14:07] <Zeux> cppg, если рисовать крупные надписи - ложатся
[14:07] <Zeux> если мелкие - нет
[14:07] <cppg> ну вруби trilinear?
[14:08] <Zeux> ага, и будет все размыто
[14:08] <Zeux> т.е. если есть фиксированный размер шрифта
[14:08] <Zeux> то можно аккуратно попадать тексель в пиксель
[14:08] <Zeux> и делать чтобы можно было читать
[14:08] <cppg> ну вапще да
[14:08] <cppg> ну для мелких надо отдельный фонт делать, да
[14:08] <Sark7> шрифтами управляет UIRenderer... он и выбирает нужный шрифт в зависимости от
[14:08] <Sark7> или масштабирует какой есть если нету нужного
[14:08] <_Anubis_> не зря же консольный шрифт в кваке той же меняецца по размеру на экране в зависимости от разрешения
[14:08] <Zeux> но вообще конечно для каждого разрешения делать раскладку контролов по экрану - это об стену
[14:08] <Zeux> правда (!)
[14:08] <Zeux> об стену дизайнерам, а не программистам :)
[14:09] <Sark7> так
[14:09] <Sark7> как происходит собственно отправка событий в Window
[14:09] <Sark7> Window приходит сообщение (от WindowManager, я про него позже расскажу)
[14:10] <Sark7> для MouseEvent
[14:10] <Sark7> Window находит контрол в котором находится мышь
[14:11] <Sark7> и отправляет сначала parent2child затем child2parent
[14:11] <Sark7> на самом деле немного сложнее, потому что есть еще leave/enter события, но в принципе одинаково
[14:11] <Sark7> для KeyEvent
[14:12] <Sark7> Window держит фокусный контрол
[14:12] <Sark7> которому и шлет событие от клавиатуры
[14:12] <Sark7> Command вообще тривиально и зависит от
[14:12] <Sark7> так, расскажу про UIRenderer
[14:13] <Sark7> он и обеспечивает некий промежуточный слой между рендер-апи и собственно гуи
[14:13] <Sark7> у него есть методы для отрисовки основных виджетов
[14:13] <Sark7> типа DrawSlider, DrawCheckbox итд
[14:13] <Sark7> на самом деле это необязательно, но нужно если мы хотим total theming
[14:14] <Sark7> и методы для отрисовки примитивов - квады, треугольники, текст
[14:14] <Sark7> контрол передает в эти методы _желаемые_ параметры вывода
[14:14] <Sark7> UIRenderer выбирает актуальные
[14:14] <Sark7> и рисует
[14:15] <Sark7> например
[14:15] <Sark7> текстуры тоже абстрагированы
[14:16] <Sark7> контрол передает в методы UIRenderer имя текстуры/хендл
[14:16] <Sark7> это нужно например, если у нас атласинг для гуи
[14:16] <Sark7> и текстуры виртуализированы )
[14:17] <Sark7> про WindowManager
[14:17] <Sark7> он управляет собственно окнами
[14:17] <Sark7> есть список окон
[14:17] <Sark7> наверху этого списка - модальное окно
[14:17] <Sark7> т.е. сообщения посылаются лишь одному окну, первому в списке
[14:18] <Sark7> мультиоконность реализуется через MultiWindow
[14:18] <Sark7> которое собственно наследуется он окна, но управляет несколькими окнами в себе
26 апреля 2006