Элементы интерфейса: поле, переключатель и список
Рабочая галерея C# с вводом имени, идентификаторами вариантов, ползунком и индикатором.
Выберите элемент по данным
| Нужно | Тип и событие |
|---|---|
| Показать короткий текст | Label |
| Форматированный текст, выделение, метаданные ссылок | RichTextLabel; для ссылок обработчик MetaClicked |
| Выполнить действие | Button.Pressed |
| Хранить да/нет | CheckButton или CheckBox, Toggled |
| Ввести одну строку | LineEdit, TextChanged / TextSubmitted |
| Редактировать несколько строк | TextEdit; для кода есть CodeEdit |
| Выбрать один вариант | OptionButton.ItemSelected |
| Список с выбором элементов | ItemList |
| Изменить число | HSlider/VSlider или SpinBox |
| Показать число без редактирования | ProgressBar / TextureProgressBar |
| Картинка без собственного действия | TextureRect; для кнопки с текстурами — TextureButton |
| Диалог отдельного окна | AcceptDialog/ConfirmationDialog: это Window, а не Container |
Не имитируйте поле ввода через Label и глобальные нажатия клавиш: готовые редакторы текста уже решают выбор, курсор и ввод символов. Не открывайте произвольные адреса из RichTextLabel без проверки назначения; MetaClicked даёт метаданные, а не обязанность их выполнять.
Запустить галерею
Добавьте UiSampleStyle.cs, прикрепите WidgetGalleryDemo к корню Control, соберите и запустите F6. Введите имя и Enter: статус покажет имя. Переключатель скрывает/показывает индикатор. Ползунок меняет его значение; варианты качества имеют стабильные ID 100/200/300. Многострочное поле можно редактировать отдельно.
WidgetGalleryDemo.cs
using Reckfell;
public partial class WidgetGalleryDemo : Control
{
public LineEdit NameInput { get; private set; } = null!;
public CheckButton EnabledSwitch { get; private set; } = null!;
public OptionButton Quality { get; private set; } = null!;
public HSlider Slider { get; private set; } = null!;
public ProgressBar Progress { get; private set; } = null!;
public Label Status { get; private set; } = null!;
public int SubmittedCount { get; private set; }
public override void _Ready()
{
UiSampleStyle.Prepare(this);
var margin = new MarginContainer(); AddChild(margin); margin.SetAnchorsAndOffsetsPreset(LayoutPreset.FullRect, margin: 16);
var scroll = new ScrollContainer { HorizontalScrollMode = ScrollContainer.ScrollMode.Disabled }; margin.AddChild(scroll);
var column = new VBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill }; scroll.AddChild(column);
column.AddChild(new Label { Text = UiSampleStyle.Text("Элементы интерфейса", "Interface controls") });
NameInput = new LineEdit { Name = "NameInput", PlaceholderText = UiSampleStyle.Text("Имя игрока", "Player name") }; column.AddChild(NameInput);
EnabledSwitch = new CheckButton { Text = UiSampleStyle.Text("Показывать прогресс", "Show progress"), ButtonPressed = true }; column.AddChild(EnabledSwitch);
Quality = new OptionButton(); column.AddChild(Quality);
Quality.AddItem(UiSampleStyle.Text("Низкое", "Low"), 100);
Quality.AddItem(UiSampleStyle.Text("Среднее", "Medium"), 200);
Quality.AddItem(UiSampleStyle.Text("Высокое", "High"), 300); Quality.Select(1);
Slider = new HSlider { MinValue = 0, MaxValue = 100, Step = 1, Value = 25 }; column.AddChild(Slider);
Progress = new ProgressBar { MinValue = 0, MaxValue = 100, Value = Slider.Value, ShowPercentage = true }; column.AddChild(Progress);
column.AddChild(new TextEdit { Text = UiSampleStyle.Text("Многострочный текст", "Multiple lines of text"), CustomMinimumSize = new Vector2(0, 90) });
Status = new Label { Text = UiSampleStyle.Text("Готово", "Ready"), AutowrapMode = TextServer.AutowrapMode.WordSmart }; column.AddChild(Status);
Slider.ValueChanged += value => Progress.Value = value;
EnabledSwitch.Toggled += enabled => Progress.Visible = enabled;
Quality.ItemSelected += index => Status.Text = "Quality ID: " + Quality.GetSelectedId();
NameInput.TextSubmitted += text => { SubmittedCount++; Status.Text = UiSampleStyle.Text("Имя: ", "Name: ") + text; };
}
}Значение, индекс и событие
OptionButton.Selected — индекс в текущем списке; GetSelectedId() — ID варианта. Для сохранения выбора удобен стабильный ID, а не номер строки, который меняется при перестановке. Если ID не задавать, не рассчитывайте на свою внешнюю систему идентификаторов автоматически.
Присвойте вариантам уникальные стабильные ID в своей схеме сохранений. OptionButton.Select(index) меняет выбор программно и не отправляет ItemSelected: после восстановления настроек обновите модель/подпись явно. Для CheckButton/CheckBox аналогичная загрузка без Toggled выполняется через SetPressedNoSignal; связанные элементы тоже нужно синхронизировать отдельно. Не используйте отсутствие сигнала как признак того, что значение не изменилось.
Range-элементы используют MinValue, MaxValue и Step. У ScrollBar есть также Page: он влияет на допустимую верхнюю границу; не переносите его смысл на процент ProgressBar. Для начальной загрузки ползунка используйте SetValueNoSignal, если изменение не должно вызывать бизнес-логику. После такого вызова связанный индикатор нужно обновить явно: его обработчик ValueChanged не запускался.
Не путайте текст, принятый из UI, с проверенными данными игры. Ограничьте допустимую длину и правила имени в своём коде; галерея демонстрирует связь событий, а не политику аккаунта. Программная установка значения, пользовательский ввод и отправка строки — отдельные операции с разными сигналами.
Для изменяемой длины текста включайте перенос там, где он нужен, и проверяйте перевод. Галерея помещена в ScrollContainer: длинное содержимое прокручивается вместо требования увеличивать всё окно.