Mega UI

Look and feel

Themes, accents and per-widget colours - and how to take the whole window when the library gets in your way.

Your app looks how you want

Every colour in the API is optional and every one of them is yours. Pass nothing and you get a sensible default; pass something and it wins, for that one widget or for the whole app.

A library helps, it does not restrict

An earlier version of this page said you did not pick colours, and that the uniformity was the feature. That was wrong, and it is worth being clear about why. A mod with an API - Mega Tree, say - may impose its look, because it is its tree that you are adding to. A library is the opposite: it is your app, and the library is there to save you the work of positioning, not to make your choices for you.

Two starting points

csharp
MegaUiApi.Register(Plugin.Guid, new AppDefinition
{
    Title = "Stock Report",
    Theme = UiTheme.Dark,      // or UiTheme.Light, the default
});
PresetWhat it is for
UiTheme.LightThe default. The store desktop is light and minty, so a light window sits on it like part of the system.
UiTheme.DarkA slate window with an emerald accent. The same values Mega Tree uses, so the two read as one product side by side.

Changing one thing

Both presets are starting points, not fixed objects. WithAccent gives you a copy with a different highlight; With gives you a copy you can edit freely.

csharp
// Just the accent
Theme = UiTheme.Light.WithAccent(new Color32(0xE6, 0x7E, 0x22, 0xFF)),

// Anything at all
Theme = UiTheme.Dark.With(t =>
{
    t.Window   = new Color32(0x12, 0x12, 0x18, 0xFF);
    t.Accent   = new Color32(0xFF, 0x6B, 0x6B, 0xFF);
    t.TextMain = Color.white;
}),

// Or start from nothing and fill it in yourself
Theme = new UiTheme { /* ... */ },

What is in a theme

FieldWhere you see it
WindowBehind everything
HeaderThe title bar, and the tooltip card
ContentThe scrolling area behind your widgets
Card / CardHoverCards, and the face of a button at rest and under the pointer
ChipSunken things — the box of a toggle, the disc behind a node
LineSeparators, borders, unlit links
AccentThe tick in a toggle, the active tab, a lit node
TextMain / TextDim / TextMutedHeaders and values / labels / hints

Overriding a single widget

The theme is the default, never the rule. Anything you colour explicitly stays that colour.

csharp
ui.Header("Danger zone", color: new Color32(0xF8, 0x71, 0x71, 0xFF));

ui.Button("Delete everything", Wipe,
          face: new Color32(0x7F, 0x1D, 0x1D, 0xFF),
          textColor: Color.white);

ui.Toggle("Night mode", () => _night, v => _night = v,
          tick: new Color32(0x38, 0xBD, 0xF8, 0xFF));

Taking the whole window

If your app has its own header, its own tabs or its own toolbar, the library's title bar is a second bar stacked on top of yours. UiChrome.None removes it and hands you the entire window.

csharp
MegaUiApi.Register(Plugin.Guid, new AppDefinition
{
    Title  = "Mega Tree",
    Chrome = UiChrome.None,
    Theme  = UiTheme.Dark,
});
You then own closing it

There is no close button of ours left to click. Draw your own and call app.Close() and app.Minimize() — both are on the handle you got back from Register.

Combine it with a full-bleed diagram and ui.Area.y to draw the window edge to edge:

csharp
ui.Diagram(ui.Area.y, d => DrawMyWholeWindow(d), bleed: true);

The font comes from the game

Mega UI borrows the TextMeshPro font asset off the desktop itself rather than loading its own. Two reasons, and the second is the one that bites:

You never configure this, and it means your labels are safe in any language. If you need the asset itself — for something you are drawing through Raw — it is on ui.Font.

Translating your own text

Mega UI does not translate for you: every string you pass is drawn as given. If your mod supports several languages, resolve the string before handing it over.

csharp
ui.Header(MyStrings.Get("warehouse_title"));

// A Value re-reads on every open, so a language change is picked up
// the next time the window opens - no extra work.
ui.Value(() => MyStrings.Get("boxes_stored"));
Long translations fit by themselves

A button label shrinks until it fits rather than spilling over the edge, so the tab that reads "Store" in English survives "Loja · EM BREVE" in Portuguese. Pass shrink: false if you would rather the size were honoured exactly.