You are viewing a potentially older version of this package. View all versions.
Sparroh-SparrohUILib-2.1.0 icon

SparrohUILib

Shared UI library for Sparroh Mycopunk mods. Provides themed widgets, HUD builders, windows, and resolution-aware layout.

Date uploaded a day ago
Version 2.1.0
Download link Sparroh-SparrohUILib-2.1.0.zip
Downloads 29
Dependency string Sparroh-SparrohUILib-2.1.0

This mod requires the following mods to function

BepInEx-BepInExPack_Mycopunk-5.4.2403 icon
BepInEx-BepInExPack_Mycopunk

BepInEx pack for Mycopunk. Preconfigured and ready to use.

Preferred version: 5.4.2403

README

SparrohUILib

Shared UI library for Sparroh Mycopunk mods. One theme, one set of widgets, resolution-aware layout.

Features

  • Theme system — Mycopunk-inspired teal/slate surfaces with bioluminescent accents

  • Resolution scaling — Reference 1920×1080; scales cleanly across aspect ratios via CanvasScaler + UITheme.Scale

  • HUD builder — Single- and multi-line HUD text under the player reticle (normalized anchors); respects vanilla Hide HUD

  • HUD reposition — Soft-dependency helpers for ModSettingsMenu drag-reposition (HudAnchors, HudRepositionClient, HudHandle.EnableReposition)

  • Gear action bar — Shared top toolbar on the gear/menu canvas for cross-mod action buttons

  • Widgets — Text, Button, Toggle, InputField, Panel, ScrollView, Separator, Dropdown, Slider, ProgressBar, Tabs, Tooltip, DragList

  • Windows & dialogs — Overlay windows (per-window canvas), confirm/alert dialogs

  • Rich text helpersLabel: value unit formatting with colored values

  • Config colors — Bind hex color config entries with cached Color values

Install

Thunderstore / r2modman: install Sparroh-SparrohUILib as a dependency of your mod.

Manual: place SparrohUILib.dll in BepInEx/plugins/.

Consumer setup

csproj

<Reference Include="SparrohUILib">
  <HintPath>..\SparrohUILib\bin\Release\netstandard2.1\SparrohUILib.dll</HintPath>
</Reference>

Plugin

[BepInDependency("sparroh.uilibrary")]
[BepInPlugin(...)]
public class MyPlugin : BaseUnityPlugin { }

thunderstore.toml

[package.dependencies]
BepInEx-BepInExPack_Mycopunk = "5.4.2403"
Sparroh-SparrohUILib = "1.2.0"

Quick examples

using Sparroh.UI;

// HUD anchors (config) + rebuild when the handle dies after quit-to-menu
var anchors = HudAnchors.Bind(Config, "Altimeter", 0.15f, 0.84f);

if (!HudHandle.IsValid(hud))
{
    hud = HudBuilder.Create("AltimeterHUD")
        .ParentToReticle()
        .Anchor(anchors.XValue, anchors.YValue)
        .Size(300, 25)
        .AddText("AltitudeText")
        .Build();

    // Soft-dep ModSettingsMenu: drag in F9 mode, SettingChanged → SetAnchor, auto-unregister on destroy
    if (HudHandle.IsValid(hud))
        hud.EnableReposition("my.mod.guid", "Altimeter", anchors);
}

if (HudHandle.IsValid(hud))
    hud.Primary.SetRich("Altitude", 12.3f, UIColors.Shamrock, "m");


// Multi-line HUD
var meter = HudBuilder.Create("Carnometer")
    .ParentToReticle()
    .Anchor(0.15f, 0.95f)
    .Size(320, 100)
    .AddLines(4)
    .Build();

meter.Lines[0].SetRichWithRate("Total Damage", total, dps, UIColors.Rose);

// Overlay window
var window = UIWindow.Create("Settings", new Vector2(800, 600), "Mod Settings", scrollable: true);
UIWindow.CreateSectionHeader(window.Content, "General");
UIToggle.Create(window.Content, "Enable HUD", true, on => { /* ... */ });
UISlider.Create(window.Content, "Opacity", 0f, 1f, 0.8f, v => { /* ... */ });
UIButton.Create(window.Content, "Save", () => { /* ... */ }, UIButtonStyle.Primary);

// Dialogs
UIDialog.Confirm("Scrap upgrades?", "This cannot be undone.", onConfirm: DoScrap);
UIDialog.Alert("Done", "Upgrades scrapped.");

// Tooltip
UITooltip.Attach(someButton.GameObject, "Does the thing");

// Gear menu action bar (library hosts/ticks the bar)
GearActionBar.Register("mymod.scrap", "Scrap", GearActionBar.OrderScrapMarked, DoScrap, UIButtonStyle.Danger);

Theme & scaling

API Purpose
UIColors.* Palette (Sky, Rose, Shamrock, PanelBg, ButtonPrimary, …)
UIColors.TryParseHex / ParseHex Parse RRGGBB / #RRGGBB / RRGGBBAA / #RRGGBBAA
UIColors.ToHex / WithAlpha Convert Color ↔ hex; adjust alpha
ConfigColor.Bind(...) Bind a hex color config entry with cached Color
UITheme.S(px) / UITheme.Scale Scale reference pixels to current resolution
UITheme.ScaledSize(w, h) Scaled Vector2
UITheme.ClampToScreen(size) Keep windows on-screen
RichText.Labeled(...) Colored label/value strings

Configurable HUD colors

// In your mod constructor:
valueColor = ConfigColor.Bind(Config, "Colors", "ValueColor", UIColors.Sky,
    "Rich-text value color (hex RRGGBB or #RRGGBB).");

// When drawing:
hud.Primary.SetRich("Speed", speed, valueColor.Value, "m/s");

HUD positions use normalized anchors (0–1) so they stay consistent across resolutions. Window canvases use CanvasScaler with reference 1920×1080 and match width/height 0.5.

Vanilla Hide HUD

Gameplay HUDs created with HudBuilder automatically hide when the player enables the vanilla Hide HUD option (PlayerLook.DisablePlayerHUD). Call hud.SetActive(yourConfigEnabled) as usual — the library combines your desired state with the vanilla toggle.

// Optional: read the vanilla toggle yourself (e.g. custom non-HudHandle UI)
if (HudVisibility.IsHidden) { /* skip drawing */ }

Menu overlays (UIWindow, GearActionBar) are not affected.

Scene transitions (quit to menu / lobby)

Reticle-parented HUD is destroyed with the player when you quit to menu. The C# HudHandle wrapper is not a MonoBehaviour, so you must treat a dead handle as missing and rebuild:

// Every frame (or whenever you would create/update HUD):
if (!HudHandle.IsValid(hud))
{
    hud = null;
    hud = HudBuilder.Create("MyHUD")
        .ParentToReticle()
        .Anchor(anchors.XValue, anchors.YValue)
        .Size(300, 25)
        .AddText()
        .Build();

    // EnableReposition auto-unregisters when the old handle dies; call again after rebuild
    if (HudHandle.IsValid(hud))
        hud.EnableReposition("my.mod.guid", "My HUD", anchors);
}

if (!HudHandle.IsValid(hud))
    return; // player/reticle not ready yet

hud.Primary.SetRich("Speed", speed, UIColors.Sky, "m/s");
  • hud.IsAlive / HudHandle.IsValid(hud) become false after scene unload
  • Do not use if (hud != null) return alone in your create helper — a destroyed handle is still a non-null C# object
  • Reposition bindings detach automatically on destroy / scene unload; re-call EnableReposition after a successful rebuild
  • GearActionBar rebuilds its host under the live Menu canvas automatically (library ticks it each frame)

Gear action bar

Shared button row for the gear details menu. Hosted on the game Menu canvas (camera/blit UI space) so hitboxes match vanilla menu chrome. The library builds, re-parents, and ticks the bar — consumers only register slots.

GearActionBar.Register(
    id: "mymod.clear",
    label: "Clear",
    order: GearActionBar.OrderClearGrid,
    onClick: OnClear,
    style: UIButtonStyle.Default);

GearActionBar.SetText("mymod.clear", "Clear All");
GearActionBar.SetInteractable("mymod.clear", canClear);
GearActionBar.SetSlotVisible("mymod.clear", showClear);
GearActionBar.Unregister("mymod.clear");

Use the shared GearActionBar.Order* constants so buttons from different mods sort consistently. Call GearActionBar.SetContextVisible(true/false) when your gear UI opens/closes if you drive visibility yourself.

HUD repositioning

Drag mode (default F9) lives in ModSettingsMenu. SparrohUILib provides the consumer-side helpers so each mod does not need a copied reflection client.

// 1) Bind anchor config (writes [HUD Positioning] / "Altimeter X" + "Altimeter Y")
var anchors = HudAnchors.Bind(Config, "Altimeter", defaultX: 0.15f, defaultY: 0.84f);

// 2) After a successful HudBuilder.Build():
hud.EnableReposition("your.mod.guid", "Altimeter", anchors);

What EnableReposition does:

  • Soft-calls ModSettingsMenu HudRepositionAPI via reflection (no hard dependency)
  • Applies SetAnchor when the config entries change (including after a drag-save)
  • Unregisters and drops listeners when the handle is destroyed or DisableReposition() is called

Lower-level APIs (same soft dependency):

API Purpose
HudRepositionClient.Register / Unregister Direct register with rect + ConfigEntrys
HudRepositionClient.IsAvailable Whether ModSettingsMenu API was found
HudReposition.Bind / Unbind Same as EnableReposition / DisableReposition
HudAnchors.BindKeys Custom key names (e.g. FooAnchorX / FooAnchorY)

Convention for auto-detect in ModSettingsMenu: section [HUD Positioning], float keys ending in AnchorX / AnchorY, or the {Name} X / {Name} Y keys used by HudAnchors.Bind. Parent HUD under the player reticle.

License

MIT — see LICENSE

CHANGELOG

Changelog

1.2.3

Fixes

  • Input caret — runtime-created UIInputField now toggles enabled after wiring so TMP builds caret/selection graphics (focus alone was not enough)

1.2.2

Fixes

  • UIDragList — drop targeting uses padded slot bands (floor into row+spacing) so reordering needs less precise pointer placement

1.2.1

Fixes

  • UIDragList — dragged row now follows the pointer (grab-offset preserved) instead of only jumping on index change
  • Drop index accounts for content padding/spacing and live row centers; scrolling disabled while dragging
  • OnReordered fires once on drop (from start index → final index)

1.2.0

Added

  • HUD reposition helpers — soft-dependency client for ModSettingsMenu's drag-reposition API (no hard reference required)
    • HudRepositionClient.Register / Unregister / IsAvailable
    • HudAnchors.Bind — bind {Name} X / {Name} Y under [HUD Positioning]
    • HudAnchors.BindKeys — bind custom key names
    • HudReposition.Bind / HudHandle.EnableReposition — register, sync anchors on SettingChanged, auto-unregister on destroy
    • HudHandle.DisableReposition / HasReposition

Notes

  • Drag mode (F9), overlay, and auto-detect remain in ModSettingsMenu
  • Consumer mods can delete their copied HudRepositionClient.cs and use the library API instead
  • UISlider / UIProgressBar were already present; no changes in this release

1.1.6

Fixes

  • Input caretUIInputField now enables customCaretColor, sets a readable caret width, and uses a standard blink rate so focused fields show a clear blinking insertion line

1.1.5

Fixes

  • Dropdown layering — open option lists reparent to the root canvas and use override sorting (UITheme.DropdownSortingOrder) so they paint above later siblings and are not clipped by scroll masks
  • Dropdowns flip above the trigger when there is not enough room below

API

  • Added UIDropdown.IsOpen for consumers that track open state after reparent

1.1.4

Fixes

  • Quit-to-menu / lobby reload — HUD handles parented to the player reticle no longer stay "alive" as stale C# wrappers after scene unload. HudHandle.IsAlive / HudHandle.IsValid let consumers detect teardown and rebuild
  • HudHandleLife marks handles dead immediately when Unity destroys the root (player despawn / scene unload)
  • HudVisibility prunes dead handles every tick and resets hide-state cache on scene unload
  • GearActionBar host is invalidated on scene unload and ticked from the library plugin (no longer depends on a single consumer calling Tick)
  • UITheme font cache cleared on scene unload so destroyed in-scene TMP fonts are not reused
  • UIText accessors no-op safely when the underlying TMP was destroyed

API

  • HudHandle.IsAlive — true while the Unity GameObject still exists
  • HudHandle.IsValid(handle) — null-safe validity check
  • HudVisibility.PruneDead / ResetSessionState
  • UITheme.ClearFontCache

1.1.3

Added

  • HUD elements built via HudBuilder / HudHandle now respect the vanilla Hide HUD option (PlayerLook.DisablePlayerHUD)
  • Added HudVisibility helper; HudHandle.SetActive stores desired visibility and applies it only when the vanilla HUD is shown

Notes

  • Menu/overlay UI (windows, gear action bar) is unaffected

1.1.2

Fixes

  • Fixed gear action bar buttons requiring clicks slightly above the visible control
  • GearActionBar now parents under the game Menu canvas (camera/blit UI space) instead of a separate overlay canvas
  • Bar sizing uses menu reference pixels to avoid double-scaling with the menu CanvasScaler
  • Bar re-attaches if the menu is destroyed/recreated; stays on top while gear details is open
  • Nudged bar down/right so it sits cleanly in the curved menu chrome
  • Gear action buttons are centered and grow outward as more mods register slots

1.1.1

Fixes

  • Fixed gear-bar / button hover being wiped when SetInteractable or SetStyle ran every frame
  • UIButton now tracks hover/press state and reapplies the correct color after style/interactable changes
  • GearActionBar.Register / SetText / SetInteractable only apply when values actually change
  • Stronger, style-specific button hover/pressed colors for Default, Primary, Danger, and Active

1.1.0

Added

  • Hex color parsing helpers: UIColors.TryParseHex, UIColors.ParseHex
  • ConfigColor helper for binding hex color config entries with cached Color values

1.0.0

Added

  • Initial release of SparrohUILib
  • Theme system with Mycopunk-inspired palette and resolution-aware scaling
  • Core UI factory and layout helpers
  • HUD builders (single-line and multi-line panels)
  • Gear action bar for shared gear-menu buttons
  • Widgets: text, button, toggle, input field, panel, scroll view, separator, dropdown, slider, progress bar, tabs, tooltip, drag list
  • Overlay windows and confirmation/alert dialogs (per-window canvases)
  • Rich text helpers for labeled values and rates