Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Docs/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
href: ui.md
- name: MLEM.Ui Gallery
href: ui_gallery.md
- name: MLEM.Ui FAQ
href: ui_faq.md

- name: MLEM.Extended
- name: Tiled Extensions
Expand Down
2 changes: 1 addition & 1 deletion Docs/articles/ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**MLEM.Ui** is a Ui framework for MonoGame, FNA and KNI that features elements with automatic positioning and sizing. It contains various ready-made element types like buttons, paragraphs, text fields and more, along with the ability to easily create custom controls. It supports **mouse**, **keyboard**, **gamepad** and **touch** input with little to no additional setup work required.

To see some of what MLEM.Ui can do, you can check out [the demo](https://github.com/Ellpeck/MLEM/blob/main/Demos/UiDemo.cs) as well.
To see some of what MLEM.Ui can do, you can check out [the demo](https://github.com/Ellpeck/MLEM/blob/main/Demos/UiDemo.cs) as well. If you have additional questions about MLEM.Ui after reading this article, be sure to check the [MLEM.Ui FAQ](ui_faq.md) as well!

## About Ui Systems

Expand Down
49 changes: 49 additions & 0 deletions Docs/articles/ui_faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Frequently Asked Questions About MLEM.Ui

This article compiles some frequently asked questions about MLEM.Ui and tries to answer them succinctly. If you haven't checked out the [introductory article](ui.md) to MLEM.Ui yet, it's recommended you do that first!

## How Do I Structure My UI Code?

Of course, you can structure your UI code any way you like, but here are two suggestions: the way that MLEM.Ui was designed for, and the way that many users have chosen to do it instead!

### "Intended" Way
MLEM.Ui was initially developed with the goal of not requiring users to create custom classes that extend any preexisting UI elements or even the `Element` class itself. The original idea was that users would write their UI code "on the fly", largely using [object initializers](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers) to configure elements, and any frequently used constructs would be put into static methods that returned a group, panel or other element with a set of children, similarly to the [ElementHelper class](xref:MLEM.Ui.Elements.ElementHelper).

```cs
private void InitializeMyUi() {
var box = InfoBox("This is some example text!");
this.UiSystem.Add("InfoBox", box);
}

private static Element InfoBox(string text) {
var box = new Panel(Anchor.Center, new Vector2(100, 1), Vector2.Zero, setHeightBasedOnChildren: true);
box.AddChild(new Paragraph(Anchor.AutoLeft, 1, text));
box.AddChild(new Button(Anchor.AutoCenter, new Vector2(0.5F, 20), "Okay") {
OnPressed = element => element.System.Remove("InfoBox"),
PositionOffset = new Vector2(0, 1)
});
return box;
}
```

### "Custom Classes" Way
I've since noticed many users opting for a custom class structure instead, where they will extend `Panel` or `Group` and add all the required child elements in their constructor. This is, of course, also a great way of structuring your UI, but with the way that the MLEM.Ui API works, it [poses some issues](https://github.com/Ellpeck/MLEM/issues/43) for the virtual methods and properties frequently used for element configuration. To get around this issue, you can always make your custom classes `sealed` or call the `base` versions of the properties and methods that configure your elements instead.

```cs
private void InitializeMyUi() {
var box = new InfoBox("This is some example text!");
this.UiSystem.Add("InfoBox", box);
}

private sealed class InfoBox : Panel {

public InfoBox(string text) : base(Anchor.Center, new Vector2(100, 1), Vector2.Zero, setHeightBasedOnChildren: true) {
this.AddChild(new Paragraph(Anchor.AutoLeft, 1, text));
this.AddChild(new Button(Anchor.AutoCenter, new Vector2(0.5F, 20), "Okay") {
OnPressed = element => element.System.Remove("InfoBox"),
PositionOffset = new Vector2(0, 1)
});
}

}
```
Loading