Iguina is a framework-agnostic, cross platform, modern UI system for C#. Its a spiritual successor to the GeonBit.UI library, but takes a more flexible and modern approach, and can be used with any framework, and not just MonoGame.
$ dotnet add package Iguina
Iguina is a framework-agnostic, cross platform, modern UI system for C#.
Its a spiritual successor to the GeonBit.UI library, but takes a more flexible and modern approach, and can be used with any framework, and not just MonoGame.
Understanding Iguina and quick examples:
Writing drivers and a UI theme (only required if you don't use the built-in drivers and UI theme from the demo projects):
Using Iguina in your application:
Miscs:
Iguina provides the following key features:

If you have a MonoGame project and you're already using GeonBit.UI, it will probably won't worth the effort to switch to Iguina. Also keep in mind that currently not all GeonBit.UI features are supported in Iguina.
However, you should pick Iguina over GeonBit.UI for the following cases:
Iguina is going to be maintained for longer, it has leaner and modern APIs, and its not dependant on MonoGame and its content manager.Iguina is completely framework-agnostic and can be used with RayLib, SFML, SDL or any other alternative.Iguina introduces some new features, including animations, cursor stylesheet, non-monospace fonts support, and much more.Iguina is built with a more flexible design and can be ported more easily to any framework or device.To make Iguina framework-agnostic, the host application need to provide 'drivers' layer to the UI system. There are two types of drivers to implement:
This is all Iguina needs to work. You can use whatever framework you want for rendering and whatever method you want for input, and just provide this functionality to Iguina via the drivers.
Note that for gamepad and other input methods that are not mouse / keyboard based, you can emulate mouse move and clicks and the UI would work normally. For example, gamepad sticks can emulate mouse movement, and triggers can emulate mouse clicks.
Iguina includes a generic demo project located in the Iguina.Demo/ folder. This project takes drivers as input to create an example UI, without depending on specific rendering and input layers. There you can also find the built-in free UI theme (under Assets).
In addition to the generic demo project (which is a DLL), Iguina also provides two executable demo projects that uses it: one for MonoGame and another for RayLib.
You can take the Renderer and Input Provider implementations from these demos and use in your own projects, as they offer a solid starting point. Or you can implement your own, which is quite easy to do.
Note: if you take the demo projects implementations, know that rendering text outline is done in a lacky, quick and dirty way. You might want to replace that part with a proper shader (not mandatory).
Before we learn about Iguina and how to use it, lets see a quick example with MonoGame and RayLib.
Note: the corresponding drivers are not shown here. They can be found in the provided demo projects, along with many other Iguina examples. Check them out.
/// <summary>
/// Basic monogame example.
/// </summary>
public class IguinaMonoGameExample : Game
{
private GraphicsDeviceManager _graphics = null!;
private SpriteBatch _spriteBatch = null!;
UISystem _uiSystem = null!;
public IguinaMonoGameExample()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
Window.Title = "Iguina Demo - MonoGame";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
// start demo project and provide our renderer and input provider.
var uiThemeFolder = "../../../../Iguina.Demo/Assets/DefaultTheme";
// create ui system
var renderer = new MonoGameRenderer(Content, GraphicsDevice, _spriteBatch, uiThemeFolder);
var input = new MonoGameInput();
_uiSystem = new UISystem(Path.Combine(uiThemeFolder, "system_style.json"), renderer, input);
// create panel with hello message
{
var panel = new Panel(_uiSystem);
panel.Anchor = Defs.Anchor.Center;
panel.Size.SetPixels(400, 400);
_uiSystem.Root.AddChild(panel);
var paragraph = new Paragraph(_uiSystem);
paragraph.Text = "Hello World!";
panel.AddChild(paragraph);
}
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// update input and ui system
var input = (_uiSystem.Input as MonoGameInput)!;
input.StartFrame(gameTime);
_uiSystem.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
input.EndFrame();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.CornflowerBlue);
// render ui
var renderer = (_uiSystem.Renderer as MonoGameRenderer)!;
renderer.StartFrame();
_uiSystem.Draw();
renderer.EndFrame();
base.Draw(gameTime);
}
}
Result should look like this (provided you got the MonoGame drivers from the demo project first):

// get screen resolution for demo size
int screenWidth = 800;
int screenHeight = 600;
// init window
Raylib.SetConfigFlags(ConfigFlags.Msaa4xHint | ConfigFlags.ResizableWindow);
InitWindow(screenWidth, screenHeight, "Iguina.Demo.RayLib");
// start demo project and provide our renderer and input provider.
var uiThemeFolder = "../../../../Iguina.Demo/Assets/DefaultTheme";
var renderer = new RayLibRenderer(uiThemeFolder);
var input = new RayLibInput();
var uiSystem = new Iguina.UISystem(Path.Combine(uiThemeFolder, "system_style.json"), renderer, input);
// create panel with hello message
{
var panel = new Panel(uiSystem);
panel.Anchor = Anchor.Center;
panel.Size.SetPixels(400, 400);
uiSystem.Root.AddChild(panel);
var paragraph = new Paragraph(uiSystem);
paragraph.Text = "Hello World!";
panel.AddChild(paragraph);
}
// Main game loop
while (!WindowShouldClose())
{
// begin drawing
BeginDrawing();
ClearBackground(Raylib_cs.Color.DarkBlue);
// update and draw ui
BeginMode2D(new Camera2D() { Zoom = 1f });
renderer.StartFrame();
uiSystem.Update(GetFrameTime());
uiSystem.Draw();
renderer.EndFrame();
EndMode2D();
// end drawing
EndDrawing();
}
CloseWindow();
Environment.Exit(0);
Result should look like this (provided you got the RayLib drivers from the demo project first):

Before we dive into code, lets go over some basic concepts of Iguina.
UISystem is the main object that manage and runs an instance of UI. This include the UI style, all its entities, events, etc.
You can run multiple UISystems at the same time, but usually that won't be necessary.
The UISystem contains a Root entity, which is the UI tree top element you can add entities to.
Every UI element type is an Entity, and you can add any entity type as a child of another entity.
Iguina positions entities based on Anchors. An Anchor basically means to which side the entity should stick to inside its parent entity.
We have the following constant anchors to position entities by:

In addition, we have 'Auto Anchors', which will position entities automatically based on other entities in the parent:
Entities also have an offset from the anchor they are aligned to. For example, an offset of {x:10, y:0} and anchor of TopRight, means that the entity will stick to the parent top-right internal corner, and move 10 pixels to the left from that position.
Entities offset can be in pixels, or as percent of parent entity size.
Similar to offsets, entities size can be in pixels, or as percent of parent entity size.
Every entity type has its own default size, and in addition default sizes can be defined in the stylesheets, which we will cover next.
A stylesheet is an object that defines how to render, size, and position a UI entity. The stylesheets define the entire appearance of your UI system, and you can create them via code or load them from JSON files.
To learn more, you can check out the stylesheets of the demo project UI Theme. We will cover stylesheets and explain how to write them in details later in this doc, in this section.
Every UI Entity has a 'state' indicating its current interaction with the user. Stylesheets can define different graphics to use per state, and transition between states can be immediate, or smooth (animated).
Every entity can have the following states:
Note that you don't have to define graphics for every state. States will fallback to another states when properties are not defined, and eventually will go all the way back to Default.
The following list show the fallback order of states when properties are missing in stylesheet:
As mentioned before, to use Iguina your host application need to provide the UI system with drivers.
There are two types of drivers to implement:
If you need a shelf implementation for MonoGame or RayLib, you can find them here:
Just copy them into your project and you're good to go. For MonoGame be sure to copy content assets as well.
If you want to implement your own drivers or use a framework not covered here, continue reading.
The Renderer class (Iguina.Drivers.IRenderer) is responsible to render textures and texts, and is what gives Iguina the ability to present itself on screen.
When implementing the Renderer, you need to implement the following methods:
Rectangle GetScreenBounds();Return a rectangle representing the visible region we can render on. By default should return Rectangle(0, 0, WindowWidth, WindowHeight), but if you want the GUI to only cover a part of the screen and not all of it, you can provide offset or smaller width / height.
void DrawTexture(string? effectIdentifier, string textureId, Rectangle destRect, Rectangle sourceRect, Color color);Render a 2D texture on screen. This is one the main methods Iguina uses to render itself.
Parameters:
texelColor * color.Point MeasureText(string text, string? fontId, int fontSize, float spacing);Measure the actual size of a string, given font, size and spacing factor.
int GetTextLineHeight(string? fontId, int fontSize);Measure the line height, in pixels, of a given font id and size. In most cases, this can be implemented as something like this:
return MeasureText("A", fontId, fontSize, 0f).Y;
void DrawText(string? effectIdentifier, string text, string? fontId, int fontSize, Point position, Color fillColor, Color outlineColor, int outlineWidth, float spacing);Render 2D text on screen. This is one the main methods Iguina uses to render itself.
Parameters:
Note: in the default drivers implementation for both RayLib and MonoGame, outline is implemented in a quick-and-dirty way by simply rendering the string multiple times with offset for outline, and then on top of it render the fill without offset.
This is less efficient and doesn't look that good with opacity. It's recommended to replace this implementation with something that uses a shader to draw outline. But not mandatory, it will work either way.
void DrawRectangle(Rectangle rectangle, Color color);Render a colored rectangle on screen. This method is mostly used for debug draw mode, and is not that critical to implement efficiently.
void SetScissorRegion(Rectangle region);Set a region on screen, in pixels, on which we can render pixels. Anything rendered outside this region, should not appear. We use this method to implement hidden overflow mode for panels with scrollbars.
If you don't implement this method properly (ie leave it empty inside), everything would work pretty much the same, but entities that exceed parent panels will be visible instead of hidden.
Rectangle? GetScissorRegion();Get the currently set scissor region, or null if no limit is set.
void ClearScissorRegion();Clear previously set scissor region, allowing us to render on the entire visible screen.
Color GetPixelFromTexture(string textureId, Point sourcePosition);Return pixel color from a texture id and source offset in texture. This method is used by color picker entities. If you don't use them, you can just return a constant value from this method.
Point? FindPixelOffsetInTexture(string textureId, Rectangle sourceRect, Color color, bool returnNearestColor)Return pixel offset from a texture id and source rectangle that matches the given color. This method is used by color picker entities to set value from Color. If you don't need it, you can just return null from this method.
The Input Provider class (Iguina.Drivers.IInputProvider) is responsible to pass user input to the UI system. This includes mouse, keyboard, and text typing input.
While the input provider interface is designed around mainly keyboard and mouse, you can implement it internally for any kind of input device. For example, you can emulate gamepad movement as mouse movement, to control the UI via gamepad.
When implementing the Input Provider, you need to implement the following methods:
Point GetMousePosition();Return mouse current position, in pixels, as offset from your window's top-left corner.
bool IsMouseButtonDown(MouseButton btn);Return if one of the mouse buttons is currently being pressed down.
int GetMouseWheelChange();Return if the mouse wheel was scrolled in this frame.
int[] GetTextInput();Return the unicode values of all the characters that are being typed by the user during this update call. This method is a bit tricky, as you also need to handle repeat delay and repeating rate.
If you try to play with any text editor, you would notice these delays are not the same. Without proper delay and rate limit, characters will be typed too fast.
Note:
This method is perheps the most complicated thing to implement for Iguina.
TextInputCommands[] GetTextInputCommands();Similar to GetTextInput, but handle special typing command, such as line break, delete, backspace, home, end, etc.
KeyboardInteractions? GetKeyboardInteraction();Return keyboard-based interactions, like arrow keys pressing and toggling with space / enter.
As mentioned before, Stylesheets define how to render, size and position different entities. We have one main stylesheet for the entire UI System, plus a default stylesheet per entity type.
When you create any UI entity, you can either provide its stylesheets in the constructor, or use the default stylesheets currently assigned for that entity type in the parent UI system.
All default stylesheets are defined under uiSystem.DefaultStylesheets.
Stylesheets can be created either by code at runtime, or loaded from JSON files. In this doc, we will focus more on loading them from JSON files, since its a cleaner and more flexible approach.
Before we discuss the format of stylesheet files, it’s important to review the different types supported in a stylesheet, as we will reference them while exploring these files.
Represent a 2D point with X and Y.
For example:
{
"X": 0,
"Y": 0
}
Represent offset from rectangle sides with Left, Right, Top and Bottom.
For example:
{
"Left": 0,
"Right": 0,
"Top": 0,
"Bottom": 0
}
A measurement value that can be either in pixels, or in percents of parent entity. Used to define things like size and positions.
Example of pixels value (150 pixels size):
{
"Value": 150,
"Units": "Pixels"
}
Example of percents value (50% of parent size value):
{
"Value": 50,
"Units": "PercentOfParent"
}
A rectangle value.
For example:
{
"X": 0,
"Y": 0,
"Width": 32,
"Height": 32
}
A framed texture is a texture to render that has an internal part and a frame. The internal part will cover the entire region of the entity with repeating mode, while the frame will be rendered around it (also repeating).
This type of texture to draw is best used for things like panels and boxes, that have middle part and a frame and can adjust to any size without stretching.
The Framed Texture has the following fields:
ExternalSourceRect and InternalSourceRect, you can set just ExternalSourceRect + FrameWidth, and Iguina will calculate InternalSourceRect automatically based on this property.For example:
{
"TextureId": "Textures/UI.png",
"InternalSourceRect": {"X": 20, "Y": 4, "Width": 88, "Height": 88},
"ExternalSourceRect": {"X": 16, "Y": 0, "Width": 96, "Height": 96},
"TextureScale": 3,
"Offset": {"X": 0, "Y": 0}
}
A simple texture to render at the entity destination rectangle, stretching it to cover the entire region.
The Stretched Texture has the following fields:
For example:
{
"TextureId": "Textures/UI.png",
"SourceRect": {"X": 32, "Y": 32, "Width": 64, "Height": 64},
"ExtraSize": {"Left": 0, "Right": 0, "Top": 0, "Bottom": 0}
}
A texture to render with constant size on the entity region. The size of the icon will be source rect size multiplied by the scale factor.
The Icon Texture has the following fields:
For example:
{
"TextureId": "Textures/UI.png",
"SourceRect": {"X": 0, "Y": 0, "Width": 32, "Height": 32},
"TextureScale": 1
}
A color value, with R, G, B and A as bytes.
For example:
{
"R": 255,
"G": 255,
"B": 255,
"A": 255
}
The global system stylesheet primarily defines cursor appearance and other visual factors, while also providing a mapping of stylesheets to entity types.
Using this default stylesheet map, you can create a comprehensive UI theme that covers all entity types and load it as a single, unified package.
Lets explore the sections of the System Level Stylesheet:
You can define how to render the cursor, per UI state. Cursor properties have the following fields:
For example, the following json define the default cursor in the built-in UI theme:
"CursorDefault": {
"TextureId": "Textures/UI.png",
"Scale": 3,
"SourceRect": {"X": 0, "Y": 0, "Width": 16, "Height": 16}
}
In the global system stylesheet, you can define cursor properties for the following states:
The map of default stylesheets to load is a simple dictionary of <string, string>, where key is entity type identifier, and value is path to load stylesheet for this entity from. For example, these are all the default stylesheets we load in our built-in theme:
"LoadDefaultStylesheets": {
"Panels": "Styles/panel.json",
"Paragraphs": "Styles/paragraph.json",
"Titles": "Styles/title.json",
"Buttons": "Styles/button.json",
"HorizontalLines": "Styles/horizontal_line.json",
"VerticalLines": "Styles/vertical_line.json",
"CheckBoxes": "Styles/checkbox.json",
"RadioButtons": "Styles/radio_button.json",
"HorizontalSliders": "Styles/slider_horizontal.json",
"VerticalSliders": "Styles/slider_vertical.json",
"HorizontalSlidersHandle": "Styles/slider_handle.json",
"VerticalSlidersHandle": "Styles/slider_handle.json",
"ListPanels": "Styles/list_panel.json",
"ListItems": "Styles/list_item.json",
"DropDownPanels": "Styles/list_panel.json",
"DropDownItems": "Styles/list_item.json",
"DropDownIcon": "Styles/dropdown_icon.json",
"VerticalScrollbars": "Styles/scrollbar_vertical.json",
"VerticalScrollbarsHandle": "Styles/scrollbar_vertical_handle.json",
"TextInput": "Styles/text_input.json",
"HorizontalProgressBars": "Styles/progress_bar_horizontal.json",
"HorizontalProgressBarsFill": "Styles/progress_bar_horizontal_fill.json"
}
In addition to the cursor styles and the default stylesheets to load, the global ui system stylesheet also have the following properties:
RowsSpacer row.Per-entity stylesheet define how every entity type renders and behaves. Entities stylesheet have general properties, and per-state properties.
Lets begin with the general properties:
The following are stylesheet properties we have per entity state.
If you recall from this section, entity states fallback to 'lesser' states all the way back to default.
This means that in stylesheet files you can define most of the properties under the Default state, and only add changed properties to the other states.
The following states properties can be defined: Default, Targeted, Interacted, Checked, TargetedChecked, Disabled, DisabledChecked.
For each state, we can define the following properties:
If you got here it means you have a UI theme ready (ie textures + stylesheets) and drivers to use with your host application framework of choice.
Now its time to setup and start using Iguina.
First step to using Iguina is to create your UISystem. This object manage your entire UI instance, loaded theme, and entities:
// uiThemeFolder assumed to be the path of the folder containing your UI theme files.
// system_style.json is the system-level stylesheet to initialize from.
var uiSystem = new Iguina.UISystem(Path.Combine(uiThemeFolder, "system_style.json"), renderer, input);
Note that you can also create a UI system without providing a stylesheet file:
var uiSystem = new Iguina.UISystem(renderer, input);
Use this option if you want to build your stylesheets from code, or provide stylesheets individually per entity type.
Once your UI system is created, there are two methods your host application need to call to run the UI:
Note: if your application don't have separated Update() and Draw() calls, just call Update() and Draw() one after another.
As we saw in the setup section, first step of using Iguina is to create a UI System.
Once the UI System is initialized, and we call its Update() and Draw() methods, the UI is operational and we can start add UI entities to it. But first, lets see what else we can do with the UI System:
RootThe UI System root entity. This is the container we add UI entities to when we build our UI scene.
Its an empty Entity instance. We'll learn more about entities later in this section.
CurrentInputStateuiSystem.CurrentInputState provides the last frame input, provided by the Input Provider.
It has some useful getters to indicate if a mouse key was just pressed, released, etc.
DebugRenderEntitiesIf true, will debug-draw entities layout data and anchors. This option is useful to debug your layout, if you encounter unexpected behavior.
DefaultStylesheetsThis class contains all the default Stylesheets to use for new entities, when we don't provide any specific Stylesheet for them. The default Stylesheets are either populated when loading the system-level stylesheet, if the default Stylesheets map is defined, or you can build it manually via code.
You can also call LoadDefaultStylesheets() and provide a dictionary to load stylesheets from.
SystemStyleSheetThe currently loaded system-level system-level stylesheet.
TargetedEntityWill contain the UI entity the user is currently pointing on or interacts with.
EventsEvents you can register callbacks to, which will be called for any entity and not just a specific entity instance.
ShowCursorIf true (default) will render the UI cursor. Does not affect the default operation system cursor, its up to you to hide / show it.
AutoFocusEntitiesIf true (default) will focus on entities the user interacts with. If false there will be no focused entities unless you set them explicitly via code.
MessageBoxesA utility to generate message boxes.
This is just an instance of the MessageBoxUtils utility for this UI system instance.
InvokeOnUIThreadIguina is not thread safe, which means if you work with multiple threads / async calls and try to change entities from a different thread, unexpected behavior may occur.
To solve this, you can use InvokeOnUIThread and provide a callback to trigger on the next update call of the UI system, which will execute from the same thread that manage the UI.
When you use InvokeOnUIThread you are guaranteed that nothing will break due to multi threading.
Now its time to add UI Entities and actually start building your UI!
All entities inherit from a base type, Entity. Lets begin by covering the Entity class.
Every UI entity shares the following key properties from the Entity base class.
There are other less important properties not covered in this doc.
AddChild(entity)Add a child entity to this entity.
RemoveChild(entity)Remove a child entity from this entity.
RemoveSelf()Remove this entity from its parent.
EventsDifferent events this entity can emit. This is the main method you use to interact with the UI. For example, you can register to buttons click event to do something when the button is clicked.
AnchorEntity anchor.
AutoWidth / AutoHeightIf true, will set entity size based on its children.
For example, a panel with AutoHeight will grow in height to fit all the entities inside of it.
IdentifierOptional string identifier we can attach to this entity.
EnabledIf false, the entity and all its children will be in Disabled state, and will not be interactable.
LockedIf true, this entity and all its children will not be interactable, but won't be in Disabled state.
IgnoreInteractionsIf true, this entity will ignore all user interactions as if it doesn't exist.
It will not have the Disabled state, and will not block mouse events like with locked mode. It will be click-through.
DraggableModeSet if this entity is draggable by mouse, and if to confine the entity to its parent region or not.
VisibleIf false, this entity and all its children will not be visible.
UserDataOptional user-defined objects you can attach to this entity.
StyleSheetEntity stylesheet.
OverrideStylesOptional stylesheet properties to override for this specific entity only, without changing the original stylesheet which is most likely shared with other entities.
OverflowModeDefine if to show or hide child entities that exceed this entity bounds.
ParentParent entity, or null if have no parent.
CheckedEntity is an entity type that introduce a toggle functionality.
Its the base class for checkboxes, radio buttons, and buttons.
CheckedEntity adds the following additional properties:
CheckedIs this entity currently in Checked state?
ToggleCheckOnClickIf true, will toggle Checked mode when clicking on this entity.
ExclusiveSelectionIf true, only one entity can be in Checked state under the same parent (radio button behavior).
CanClickToUncheckIf true, clicking on this entity while its in Checked state will uncheck it.
If false, the user can only check this entity but not uncheck it.

Clickable buttons.
Buttons inherit from the CheckedEntity base class, which means you can make buttons toggleable and behave like a checkbox or a radio button, by enabling the ToggleCheckOnClick and ExclusiveSelection flags.

A toggleable checkbox, with a box to indicate state and a label.
Checkbox inherits from the CheckedEntity base class.
A toggleable radio button, with a box to indicate state and a label.
This entity is like a Checkbox, but it uses different default stylesheets, and by default it has ExclusiveSelection = true, and CanClickToUncheck = false.
RadioButton inherits from the CheckedEntity base class.

A list of string items that users can select items from.
ListBox adds the following additional properties:
ItemsCountHow many items are in list.
SelectedIndexCurrently selected list index, or -1 if no item is selected.
SelectedValueCurrently selected item value, or null if no item is selected.
SelectedTextReturn selected value label, or value itself if it has no label. Will return null if no value is selected.
AllowDeselectIf true, users can click on selected item again to deselect it.
AddItem(value, label?, index?)Adds an item to the list.
ReplaceItem(index, value, label?)Replace an existing item in the list.
RemoveItem(value) / RemoveItem(index)Removes a value from the list.
Clear()Remove all values from list.

DropDown entity is a derived class of ListBox, that collapses into a single line when not interacted with.
Its a way to take less space for lists.

This entity is just a graphical horizontal line to separate between sections.

This entity is just a graphical vertical line to separate between sections.

Panels are graphical containers of entities, like a windows form or a group box.

An entity used to render text.
Paragraph adds the following additional properties:
TextString to render.
EnableStyleCommandsIf true, will enable paragraph style commands.
Style commands are special flags you can set inside the text to change paragraph colors and outline mid-sentence.
A style command is defined between ${}. The following commands are supported:
For example, the following code:
paragraph.Text = "Hello, ${FC:00FF00}Hero${RESET}! Welcome to my ${OC:FF00FF,OW:2}cave${RESET}."
Will render a Paragraph with the word 'Hero' marked in green fill color, and the word 'cave' will have outline of 2 pixels with purple color.
ShrinkWidthToMinimalSize / ShrinkHeightToMinimalSizeIf true (default) it will minimize the Paragraph entity size to match the actual rendered text size.
TextOverflowModeDetermine how to handle a text that overflows the parent entity width:
Title entity is a derived class of Paragraph, but it uses different default stylesheets and used for texts that are titles for sections or panels.
Label entity is a derived class of Paragraph, but it uses different default stylesheets and used for smaller texts above input entities.

A slider to pick numeric integer values, using a draggable handle confined to a track it drags on. It can be Vertical or Horizontal (determined in constructor).
Slider adds the following additional properties:
HandleThe internal handle entity.
OrientationSlider Orientation (vertical / horizontal).
MouseWheelStepHow much to change the slider value when the mouse scrolls on it.
MinValueSlider min value.
MaxValueSlider max value.
ValueSlider current value.
ValueSafeSlider current value, that you can set without exceptions (value will be clamped to min/max).
StepsCountHow many steps there are on the slider.
ValuePercentGet current value as percent between 0.0 to 1.0.
FlippedDirectionIf true, will flip slider direction.
ValueRangeValue range (max - min).

ProgressBar entity is a derived class of Slider, but instead of dragging an handle it 'fills' an internal entity based on value.

An entity to get free text input from users.
TextInput adds the following additional properties:
PlaceholderTextOptional text to show when there's no value in the text input.
ValueCurrent text value.
MultilineIf true, text input will support line breaks.
MaxLinesOptional lines limit.
MaxLengthOptional max length limit.
CaretOffsetCaret offset.
CaretCharacterCharacter to use to show caret.
MaskingCharacterIf provided, will replace all characters with this character when presenting the input text. Useful for stuff like passwords input field, where you want the password hidden.

NumericInput entity is a derived class of TextInput, but it only accept numbers as input.
NumericValueGet / set value as a float.
DefaultValueDefault numeric value, when no value is set.
CultureInfoCulture info to use, will determine the character to use as decimal separator.
AcceptsDecimalIf true, it will accept decimal point and float values.
MinValueIf defined, will add a min value limit to the Numeric Input.
MaxValueIf defined, will add a max value limit to the Numeric Input.
ButtonsStepSizeHow much to increase / decrease value when clicking on the plus / minus buttons of the numeric input field.
An empty entity that creates an extra space between rows of entities, with constant space unit that can be defined by the UI system stylesheet RowSpaceHeight property.

ColorSlider entity is a derived class of Slider, but used to pick a color value from a range.
The returned color is based on the source texture and source rectangle used to render the slider itself.
With Colors slider you don't need to set Min, Max, or Step Counts properties. They are set automatically.
ColorValueReturn the color value, as extracted from the source texture.

ColorPicker is used to pick a source color from a texture, by dragging a handle over it.
The default UI theme comes with a texture that covers all basic colors, effectively creating a color picker similar to painting software. However, you can replace this picker with a palette of your choice.
Color picker must have a stretched texture in its stylesheet, which is used as its source texture.
ColorValueReturn the color value, as extracted from the source texture.
SetHandleOffset()Set handle offset, in pixels, from top-left corner of the entity.

ColorButtons is used to pick a color from a set of predefined colors, using simple buttons.
Unlike the other color pickers, this type is not purely by stylesheet and you will have to feed the color choices by code.
AddColorAdd a color choice button to the color picker.
ColorValueReturn the color value, as extracted from the source texture.
ColorIndexGet / set the selected color index.

A utility to show message boxes and file dialogs.
ShowConfirmMessageBox()Show a prompt with Confirm vs Cancel buttons.
ShowInfoMessageBox()Show info message box with just text and OK button.
ShowSaveFileDialog()Show save file dialog, that returns selected file path (or null if user cancelled).
ShowOpenFileDialog()Show open file dialog, that returns selected file path (or null if user cancelled).
This is very similar to ShowSaveFileDialog() but with different default flags and designed to select an existing files rather than creating a new file or overriding old one.
To use Iguina on Android with MonoGame, you can see general instructions here.
SelectedText property to ListBox and DropDown.DropDown to properly show the selected item label (if set) and not just the item value.ListBox and DropDown to change selection value if the selected item value is replaced.OverrideSelectedText property to DropDown.Label entity.ListBox and DropDown.DropDown to Auto Height by default.DropDown to always show selected value and look more like a 'classic' dropdown.BoxOutlineWidth, BoxOutlineOffset and BoxOutlineColor property to entities.DropDown collision rectangle slightly larger to make it more convenient.SetVisibleItemsCount() method to ListBox and DropDown.DropDown to open, close and toggle list.HorizontalLine ignore interactions by default.MarginAfter property into calculation.BackgroundColor stylesheet property.FillColor stylesheet property.NumericInput entity.MaskingCharacter to TextInput.TextInput less "sticky" to be kept focused.VerticalLine entity.MarginBefore and MarginAfter properties for positioning.DropDown entities.8.0.ColorSlider entity.ColorPicker entity.MonoGame renderer.ColorPicker and ColorSlider works internally, now its possible to set their starting value without waiting for an update first.ColorSlider and ColorPicker values from a given color.IColorPicker interface.NumericInput having wrong value during the OnChange event call.NumericInput not being able to accept values that start with '0.'.NumericInput input normalization.MeasureVector.FromPixels and MeasureVector.FromPercents methods.ShowInfoMessageBox to message box utility.Breaking Changes
SelectedText.All changes:
InvokeOnUIThread to handle concurrency properly.Focused entity style.SelectedTextWithIcon to ListBox and changed SelectedText to not include icons data.Offset, CenterVertically and CenterHorizontally properties to icons.ClearChildren().InteractableTargetedEntity to get TargetedEntity, but only if its interactable.AutoWidthMaxSize and AutoHeightMaxSize to limit auto size values.FrameWidth graphic property to FillTextureFramed as a simpler way to set InternalSourceRect out of ExternalSourceRect.9.0.ColorButtons entity.Color struct.BackgroundColorPadding.Iguina is distributed with the permissive MIT license.
You can use it for any purpose.
The UI theme in the demo project is made by me and its public domain.