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
BepInEx pack for Mycopunk. Preconfigured and ready to use.
Preferred version: 5.4.2403README
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 helpers —
Label: value unitformatting with colored values -
Config colors — Bind hex color config entries with cached
Colorvalues
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) returnalone in your create helper — a destroyed handle is still a non-null C# object - Reposition bindings detach automatically on destroy / scene unload; re-call
EnableRepositionafter a successful rebuild GearActionBarrebuilds 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
HudRepositionAPIvia reflection (no hard dependency) - Applies
SetAnchorwhen 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
UIInputFieldnow togglesenabledafter wiring so TMP builds caret/selection graphics (focus alone was not enough)
1.2.2
Fixes
- UIDragList — drop targeting uses padded slot bands (
floorinto 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
OnReorderedfires 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/IsAvailableHudAnchors.Bind— bind{Name} X/{Name} Yunder[HUD Positioning]HudAnchors.BindKeys— bind custom key namesHudReposition.Bind/HudHandle.EnableReposition— register, sync anchors onSettingChanged, auto-unregister on destroyHudHandle.DisableReposition/HasReposition
Notes
- Drag mode (F9), overlay, and auto-detect remain in ModSettingsMenu
- Consumer mods can delete their copied
HudRepositionClient.csand use the library API instead UISlider/UIProgressBarwere already present; no changes in this release
1.1.6
Fixes
- Input caret —
UIInputFieldnow enablescustomCaretColor, 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.IsOpenfor 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.IsValidlet consumers detect teardown and rebuild HudHandleLifemarks handles dead immediately when Unity destroys the root (player despawn / scene unload)HudVisibilityprunes dead handles every tick and resets hide-state cache on scene unloadGearActionBarhost is invalidated on scene unload and ticked from the library plugin (no longer depends on a single consumer callingTick)UIThemefont cache cleared on scene unload so destroyed in-scene TMP fonts are not reusedUITextaccessors no-op safely when the underlying TMP was destroyed
API
HudHandle.IsAlive— true while the Unity GameObject still existsHudHandle.IsValid(handle)— null-safe validity checkHudVisibility.PruneDead/ResetSessionStateUITheme.ClearFontCache
1.1.3
Added
- HUD elements built via
HudBuilder/HudHandlenow respect the vanilla Hide HUD option (PlayerLook.DisablePlayerHUD) - Added
HudVisibilityhelper;HudHandle.SetActivestores 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
GearActionBarnow parents under the gameMenucanvas (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
SetInteractableorSetStyleran every frame UIButtonnow tracks hover/press state and reapplies the correct color after style/interactable changesGearActionBar.Register/SetText/SetInteractableonly 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 ConfigColorhelper for binding hex color config entries with cachedColorvalues
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