Canvas, хост и дерево элементов
Всё, что рисует IcyUI, находится на Canvas: поверхности размером с окно игры, которая выполняет компоновку
своих элементов, рисует их каждый кадр и направляет им ввод с мыши, клавиатуры, геймпада и сенсорного экрана.
UseIcyUI() создаёт хост, который связывает Canvas с движком, и даёт вам первый Canvas.
Хост
UseIcyUI() возвращает хост движка: MonoGameIcyHost или StrideIcyHost. Оба реализуют IIcyHost:
- Configuration: настройки, с которыми создаётся каждый элемент (см. Конфигурация);
- MainCanvas: Canvas, созданный
UseIcyUI(), с включённым вводом; - Canvases: все Canvas, которые хост рисует каждый кадр, по порядку.
Каждый кадр хост обрабатывает ввод и следит за масштабом дисплея. В MonoGame это игровой компонент, который рисует во
время base.Draw(), после вашей собственной отрисовки; в Stride он рисует через графический компоновщик, после сцены.
Другой код получает тот же хост через GetIcyHost() (или GetIcyCanvas() для главного Canvas) у игры.
Более поздний Canvas в Canvases рисуется поверх более раннего. Второй Canvas пригодится для HUD, который остаётся над меню, или для отладочного слоя:
// A second canvas for a HUD, drawn above the main one; a background canvas at index 0 would draw below.
public static Canvas AddHudCanvas(IIcyHost ui)
{
var hud = new Canvas(ui.Configuration);
ui.Canvases.Add(hud);
return hud;
}
Дерево элементов
Canvas содержит корневые элементы (Add(UIElement) или LoadMarkup для файла разметки).
Панели и элементы управления содержат дочерние элементы, поэтому весь интерфейс — это дерево. Каждый элемент знает свой
Parent; у корневого элемента он равен null, а сам элемент принадлежит Canvas.
- Порядок отрисовки: дочерние элементы рисуются после родителя, по порядку; ZIndex поднимает элемент над соседними или опускает под них.
- Оверлеи: всплывающие окна, выпадающие списки, подсказки и диалоги попадают в Overlays Canvas: они рисуются поверх всех корневых элементов и получают ввод первыми.
- Видимость: IsVisible скрывает элемент вместе с дочерними и отключает их ввод, но место в
компоновке за ними остаётся; Opacity делает их прозрачнее (при 0 они не рисуются и не
реагируют на нажатия); IsHitTestVisible, равный
false, пропускает нажатия насквозь.
Ввод интерфейса и ввод игры
Canvas забирает ввод, предназначенный интерфейсу. Игра должна игнорировать щелчок, попавший на кнопку: проверьте IsMouseOverGUI, прежде чем реагировать на мышь.
// In your game's update: don't fire when the player clicks a button.
public static bool ShouldFire(IIcyHost ui, bool mousePressed) => mousePressed && !ui.MainCanvas.IsMouseOverGUI;
Элемент, у которого фокус клавиатуры и геймпада, — это FocusedElement; см. Ввод, фокус и навигация.
Типичные ошибки
- У элемента один родитель. Добавление элемента, который всё ещё находится в панели, рамке, содержимом элемента
управления или на Canvas, бросает
InvalidOperationException. Сначала уберите его оттуда (Children.Remove,Content = null,Canvas.Remove), потом добавляйте в другое место. - У элементов, созданных в коде, нет темы, пока их не добавили на Canvas. Стили темы применяются, когда элемент
попадает на Canvas, поэтому читайте
Templateили цвета темы послеAdd, а не до. - Скрытый элемент всё равно занимает место. Чтобы убрать элемент из компоновки, удалите его из панели; используйте IsVisible, когда элемент должен лишь снова появиться на том же месте.
- Рисуйте своё содержимое до интерфейса. В MonoGame всё, что вы рисуете после
base.Draw(), перекрывает интерфейс.
См. также
- Конфигурация: что настраивает
UseIcyUI(). - Компоновка: как элементы на Canvas получают размер и положение.
- Начало работы со Stride и с MonoGame.