Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.6.3-unofficial-mushymato.1
Added
- New
IMenuControllerpropertyOpenSound, set the sound which plays when menu becomes active for the first time. - New
IMenuControllerpropertyNavigateSound, set the sound which plays when menu scrolling or moving around with gamepad. - New
IMenuControllerpropertyHideHUD, controls whether menu should hide the HUD. - New
ButtonpropertyPadding, set the inner frame's padding. - New
ButtonpropertyHorizontalContentAlignmentandVerticalContentAlignment, set the button frame's alignment.
Fixed
ReflectionPropertyDescriptorshould useMethodInfoExtensions.SafeCreateDelegateto correctly handle property getters on value types.buttonscreen-read should use delegate method of updating.checkboxscreen-read should include label-text.drop-downoverlay screen-read inherit them from labels.
0.6.3-unofficial-mushymato.0 - WIP
Added
- New
scrollableattributesprogressfor controlling scroll progress, andscroll-stepfor how much to scroll each turn of mouse wheel. - New view attribute
hovered-subjectwhich takes in aItemor aNPCand passes it to Lookup Anything. issue#81 - New view attribute
screen-readwhich takes a string or aIScreenReadableand passes it to Stardew Access.
Fixed
0.6.2-unofficial-mushymato.2 - 2026-03-18
Changed
- Try to account for usage of 'field' keyword in actual methods when analyzing auto properties
- The
wasHudDisplayedcheck now only setsGame1.displayHUDback to true, never to back to false
0.6.2-unofficial-mushymato.1 - 2026-01-12
Added
- Keybind editor view now supports mouse buttons (left/right/middle/x1/x2).
Fixed
Changed
- Empty text label is now also in a frame.
0.6.2-unofficial-mushymato - 2025-11-16
Changed
- Unofficial release, forked from this commit
- Includes PR#96 (property binding Turkish fix)
Notice
The unofficial StardewUI release began here.
0.6.1 - 2025-02-12
Changed
- Drop-down lists with many items are now scrollable, either with a fixed maximum height or implicitly at the bottom of the viewport.
- Most image components include some additional safety checks for invalid sprites, i.e. those whose
Texture2Dis eithernulldue to inconsistent type checking, or Disposed due to incorrect lifetime management.
Fixed
- Focus search lands on correct target when navigating up from below a grid to the last row of that grid.
CustomButtonSpriteMapprovides the actual mouse button sprites instead of error sprites.- Preloaded assets are now cached by localized name instead of base name, resolving the failure to load nested assets (sprite textures) from SMAPI when the game is configured to a non-English language.
- Keybind editors configured to only accept a single-button will actually accept only a single button, instead of displaying only one button in the UI but potentially storing a button combination.
0.6.0 - 2025-01-31
Added
- All views now have a layout-typed
ClipSizeproperty for limiting overflow or cropping content, which allows for animated slides and wipes. - Segmented Controls are an improved alternative to dropdowns when selecting from a very small number of choices.
- Color Pickers provide color selection using either RGBA (sliders) or HSVA (wheel), as well as customizable presets.
- All views now have a
ButtonRepeatevent, which has the same signature asButtonPressbut fires at a repeating interval while the button is held. - Built-in behavior attributes now include
+state:<name>and+state:<name>:<arg>behaviors which create a custom named state bound to a boolean value and any number of properties modified by that state. - This allows for transitions that work like
+hoverand support animated transitions, but are controlled by data; for example, setting adisabledstate to control bothopacityandpointer-events-enabled, or aselectedstate to control a frame'sbackground-tintor a label'sboldproperty. Framenow supports aBorderTintin addition to the already-existingBackgroundTint.Buttonnow has tint properties for both backgrounds (default and hover).- Several built-in conversions between SMAPI's keybind types; all combinations of
string,SButton,KeybindandKeybindListshould be supported. - Mods can now register a Custom Data path, which is a new centralized location for certain bespoke asset types that are neither views nor sprites.
- The current use case is for custom sprite maps, for use in keybind-related widgets instead of the default ("Xelu") sprites.
Changed
- Setting
PointerEventsEnabled = falsewill also exclude the view from hover events and focus searches, and block children/descendants of the disabled view. TextInputincludes new properties:Placeholdertext which will show when the input is (a) empty and (b) not currently being edited.Disabledproperty which prevents clicks/capturing and dims the content.DropDownListincludes new properties:MaxLinesallows options in the dropdown menu to span multiple lines if set to a value other than1(default)SelectionFrameLayoutreplacesOptionMinWidthand allows dropdowns to be given any layout, e.g. stretched instead of fixed-width.KeybindListEditorwill display an empty frame when it has no keybinds and noEmptyText.KeybindListEditornow has aBackgroundColorproperty that can be used e.g. to indicate that it is disabled/read-only.LayoutParameterssupports transitions as long as eachLengthTyperemains the same.- This is primarily intended for
ClipSize, which only takes effect at draw time, and is not recommended forLayout, which forces new layout (i.e. slows performance). IMenuControllerAPI includes new properties and methods:Close()allows the menu to be closed programmatically.CloseOnOutsideClickcauses the menu to be automatically closed when clicking outside its border, i.e. the same way Overlays work.CloseSoundcustomizes what sound will be played when the menu is closed.PointerStylechanges the mouse cursor when hovering inside the view. All vanilla cursors such as the hand, harvest and dialogue cursors are supported.SetCursorAttachment(...)andClearCursorAttachmentwill add/remove a sprite to be drawn next to the cursor, e.g. to indicate moving an item to/from inventory as is done in the vanillaInventoryMenu.IViewEngineAPI now includes aPreload()method that will start preloading all mod assets in the background, which can help reduce latency when showing complex menus or drawables for the first time.- When a
ButtonPresshandler returnsfalse, it will short-circuit focus searches, i.e. making it possible to trap controller focus within some view. - When a
Clickhandler returnsfalse, it will preempt anyLeftClickorRightClickhandlers on the same view. - Duck-type conversions will fail gracefully when there are multiple, case-insensitive matches such as both
descriptionandDescription. - Ambiguous matches will prefer the case-sensitive match when one exists, otherwise choose an arbitrary match.
ViewMenutype is no longer generic.- The generic (view type) parameter was removed because nothing important depended on it, and generic types interfere with .NET hot reload.
Fixed
TransformandTransitiontypes now support duck type conversion.- Behaviors now retain view state properties on view recreation, avoiding most cases of "stuck" hover states and other inconsistencies.
- Transitions should behave correctly with zero state, i.e. when only the underlying property value is changed.
*repeatnodes will correctly rebuild when bound observable collections areClear()ed.*repeatnodes no longer crash when encountering a negative index in theCollectionChangedevent arguments.- Keybind editor now correctly renders empty text when initialized without a keybind.
KeybindandKeybindListproperties now use value-equality comparisons, preventing thrashing between aKeybindListEditorand its boundKeybindListin specific cases.- Overlays, such as those used in keybind editors and color pickers, will no longer pick up the mouse button used to open them as a new click.
- Menus no longer draw tooltips when they have a child menu open.
- Floating elements whose owners have non-zero margins will now receive correct coordinates for their pointer events.
- Output bindings such as
{>OuterSize}force an update on initial bind - This fixes the issue that properties might never receive the correct value if the view never changes or if a new context is bound to an old view.
- Common UI sprites should stretch correctly with both vanilla rendering and SpriteMaster/Clear Glasses.
- Notepad++ syntax highlighting no longer highlights elements inside comment tags.
0.5.0 - 2024-12-23
Added
- Floating Elements are now supported in StarML via the
*floatstructural attribute. - Transforms have been added and can be used on all views, including layout views.
- Views also have a
transform-originproperty which is layout-wide, e.g. an entire menu can be scaled or rotated around its center. - Behaviors enable self-contained functionality to be attached to views. Built-in behaviors include:
- State modifiers that change a view's property when the view enters certain states (currently
hover:for hovered andshow:for visible) - Transitions that animate property changes according to some timing and easing settings, à la CSS transitions.
Gridviews usinglength-based item layout can append a+to the end (e.g.item-layout="length: 64+") in order to fill the available layout size and eliminate leading/trailing whitespace.- Structural attributes that apply conditional behavior, such as
*ifand*case, can now be negated using the negation operator, e.g.*!if={Condition}. Imageviews can now specifySpriteEffects, i.e. to flip horizontally or vertically.
Changed
- Menus will automatically watch for loss of focus—i.e. when the gamepad cursor is no longer on a valid target—and attempt to restore focus to either the previous target or to the default element, which is important for "in-place" pagination or multi-step flows.
- Menus now support focus restore for vanilla child menus (via
IClickableMenu.SetChildMenu) as well as the Overlay focus support that already existed. - Images no longer require a layout pass when their
Spritechanges to a value with the same dimensions; this typically eliminates the entire recursive layout operation and makes sprite animation more efficient. - Most
Scrollbarbehavior and appearance can now be customized through theScrollableView(<scrollable>element). Visibilityproperties can be bound toboolproperties.- Minor optimization of the
Opacityproperty to reduce render target requirements in simple views such asLabelandImage.
Fixed
- Menus with custom close actions should no longer close prematurely when the controller B button is pressed to dismiss an overlay.
Frameviews will use the correct boundaries for focus searches, and will not fail or land the cursor in the wrong place when moving a large distance to/from a much smaller element.Laneviews now handle innerScrollableViews correctly and will not break focus searching when scrolling with the right thumbstick.- Value-typed
<dropdown>views can be set back to their default values again. - Keybind and nine-grid editors no longer lose their hover states when their overlays are closed.
- Hot reload will no longer spam reloads and SMAPI console messages when updated via source sync.
0.4.2 - 2024-12-07
Changed
Labelcan now break single words that are too long to fit in a single line, instead of overflowing. Non-CJK languages will hyphenate.ScrollableContaineradjusts for its own margins (including negative margins) and allows content to draw inside its padding.TextInputscrolls the current text instead of truncating/eliding it.- Clicking to position the caret in a
TextInputis slightly more accurate.
Fixed
- Pointer enter/leave events (e.g. hover effects) fire correctly when menus are opened with a view already under the cursor.
- Text no longer wiggles inside
TextInputwhen moving the caret.
0.4.1 - 2024-12-03
Added
- HTML-style comments can be used (
<!-- comment -->) in StarML views.
Changed
- Minor adjustment to
MenuSlotInsetsprites for proper display with Clear Glasses mod. - Custom close actions via
IMenuController.CloseActionnow also override the title-submenu behavior.
Fixed
- 6- and 8-digit hex colors, such as
#112233, now parse to the correct colors. - Structural attributes such as
*ifpropagate correctly from inside<template>elements.
0.4.0 - 2024-11-22
Added
- Templates are a lightweight alternative to Included Views, which support attribute substitution and require no extra assets.
- Menu Controllers, available via the new
CreateMenuControllerAPIs, enable additional customization of the menu shell. Customize a menu's position, screen dimming, whether it is allowed to close, and more. - Menus can now display a top-right close button (red "X") similar to the game's main menu.
- All views now have a
pointer-moveevent. - All views now have an
opacityproperty that controls transparency of the entire view/layout. - Specific item sprites can now be referenced as asset bindings, e.g.
<image sprite={@Item/(O)152} />. - Several additional common sprites added to
UiSprites, including the uncolored menu tiles, and a white pixel for background shading.
Changed
- Performance improvements, leading to initial load times reduced by 60-70%.
- All
tooltipattributes are nowTooltipDataand support all extended vanilla tooltip features: item images, recovery stats, cost/currency, etc. - Includes implicit conversion from
string, so views already using string-based tooltips will continue to function as before. - Implicit z-ordering now works the same as explicit
z-index; whichever view draws on top will receive pointer events first. - Hot-reload system is now also aware of .NET Hot Reload ("Edit and Continue"), and it is now possible for hot-reloaded assets (i.e. changed
.sml) to access hot-reloaded fields, properties and other members. - Test mod rewritten as a full example gallery/demo.
Fixed
- Drop-down lists respect the
option-min-widthattribute again. - No more error log spam when the game is using a language other than English.
- Named colors, e.g. as in
color="Blue", are parsed correctly. - Cursor location snaps back to original position after exiting on-screen keyboard (via gamepad).
- Empty attributes such as
text=""are correctly interpreted as empty strings instead of breaking the parser. - Exponential backoff error-handling behavior, which was implemented in 0.2.0 and regressed in 0.3.0, is working again.
0.3.0 - 2024-11-10
Added
- Duck typing conversions for bound properties: internal types like
Spritecan now be bound without an assembly reference by creating an equivalent type on the caller's side. - Add-on system, AKA framework extensions: Create and register custom widgets and type converters that can be included in StarML.
- Translation ("i18n") bindings using the syntax:
attr={#TranslationKey}for keys in the same mod orattr={#authorname.ModName:TranslationKey}for keys in a different mod. - Tab widget to use for top or side navigation.
Changed
- Improved hot reloading: files can now be edited in the source directory instead of deployed mod directory using the source sync feature.
- Layout strings (i.e. in the
layoutattribute) can now specify min and max values using a range similar to C# syntax. - For example
layout="50%[600..1200] content[800..]"specifies a width of 50% constrained between 600px and 1200px and a height that grows with content but has a minimum of 800px. - View bindings can now dispatch update ticks to bound context (models).
- Label widget now supports text shadows.
- Text Input widget now only captures on left-click, to allow right-clicks to be used for other behavior such as clearing the text.
- Expanded and improved warnings emitted to SMAPI console for bindings that can't receive updates. Warnings were already shown for types not implementing
INotifyPropertyChangedbut will now also be shown for fields and auto-properties regardless of the declaring type. - Renamed
Framedebug class toTraceFrameto avoid ambiguity withFrameview.
Fixed
- Button, Wheel and Focus Search events now properly respect the UI scale when set to a value other than 100% or when running in split-screen mode.
- Final row of a
Gridwill no longer be misaligned under specific layout conditions. - Input events now trigger a forced "re-hover" on menus so that tooltips update and pointer events (e.g.
pointer-enterandpointer-leave) fire when content is scrolled but the actual mouse position has not changed. - Improved bounds-detection when overlays are combined with floating elements; should avoid premature closure in most cases.
0.2.5 - 2024-10-30
Added
- General button-press event for all views, able to handle any
SButtonas opposed to just mouse-click equivalents. Mainly intended for tabbing/paging implementations built using StarML instead ofIPageable/ITabbable, which will probably be deprecated in a future version. - View outlets and the
*outletattribute for widgets such as the Expander with multiple distinct content areas. - Value converters for nullable types; support all combinations of nullable and non-nullable for the source and destination.
- Filled out most remaining documentation pages. There are still a few stubs, mostly having to do with as-yet unimplemented features assigned to Milestone 3.
- Added XML-to-Markdown doc generator, and generated reference docs for entire API.
Changed
- Refactored
WrapperView<T>intoComponentView<T>and base classDecoratorView<T>to promote reuse for other wrapper types, including the StarMLDocumentView. DecoratorView<T>now exposes the inner/root view as a child view, instead of passing through it, so that the inner view can be found byViewMenuand other hierarchy-sensitive areas needing the exact view for tooltips, scrolling, event dispatch, etc.Laneno longer returns early when it runs out of space for child layout; this is done to prevent any child views from continuing to remain dirty and repeatedly re-triggering layout on every frame.TextInputchooses useful default sprites, colors and dimensions so that it can be used from StarML without having to specify every attribute explicitly.- Updated all Core namespaces to reflect the actual path structure. This is a one-time change but will likely break any users that were previously using a source dependency (shared project).
Fixed
- Use a constant caret size and correct rotation in Expander widget.
- Keybind-related views propagate
SpriteMapupdates immediately; required to see any sprites when created from StarML.
0.2.0 - 2024-10-19
Added
- More predefined sprites, such as left/right navigation arrows.
- Scale setting for
Labelcontrol, to simulate font sizes. - Enable binding to fields, as opposed to properties only.
- One-time bindings, which prevent update checks and also suppress the
INotifyPropertyChangedwarning. - Speedscope-compatible performance tracing (default hotkey: Ctrl+Shift+F6).
- Several more complete documentation pages, including full examples.
Changed
- Failed asset loading, parsing, binding and other UI-pipeline operations now use throttled retries with exponential backoff to avoid stealing all frames and spamming the error log in the case of malformed or invalid markup.
- Event bindings now support
boolreturn values, and set theHandledproperty of a bubbled event accordingly. - Log warnings when binding to properties of an object that does not implement
INotifyPropertyChanged. <dropdown>element now uses a new type,DynamicDropDownList, which silently adapts the realDropDownList<T>to whichever option typeTthe view model appears to be using.- Moved constructor arguments (e.g. sprites, or sprite maps) on all standard views to regular properties, so they can be set from StarML. Default sprites will still be used if properties are not set.
Fixed
- Cached event bindings are no longer (incorrectly) reused across separate view instances; also eliminates a possible memory leak.
- Individual attribute bindings should handle
nullcontext safely.
0.1.0 - 2024-10-12
Added
- Initial release of framework.
- StarML grammar, asset loader and menu view.
- Initial documentation site based on material-mkdocs; many pages are stubs.
- Syntax highlighting for Visual Studio, VSCode and Notepad++.