Table of Contents

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(), перекрывает интерфейс.

См. также