Feb 2025

A ProdUI workspace test. The snowy background is tied to a workspace render callback, so it only appears when its associated workspace is active.

A ProdUI workspace test. The snowy background is tied to a workspace render callback, so it only appears when its associated workspace is active.

ProdUI Development

Changed how widgets are initialized. Previously, the addChild() method accepted a table argument that could be used as the basis for the new instance. This allowed the library user to supply some important resources early, like fonts, before the widget’s creation callback was triggered. There was always a danger, though, that the library user might use the same initial table multiple times, causing multiple instances to use the same table (ie point to the same instance memory, which is really bad). Now, you create the widget with addChild(), make your adjustments, and then invoke widget:initialize() explicitly.

Merged menu structures with the widgets that they belong to. Basically, this means that self.menu.items is now self.items.

Settled on MkDocs for the documentation. I experimented with writing the reference material as Lua source and then exporting it to HTML, but I had to acknowledge that this is not a good use of my time.

Window Frame enhancements:

  • Increased the default size of window frame resize sensors, and added a setting to further increase the clickable area of the diagonal parts of those sensors.
  • Flag to toggle resizing of Window Frames (by the user; program code can still make changes).
  • The header buttons (maximize, close) are now hard-coded sensors, rather than full-blown button widgets.
  • Toggle visibility of the header bar.
  • Toggle visibility of the maximize and close buttons. Enable/disable the actions to maximize or close (by the user’s hand).
  • Merged Window Frames and containers. Whereas Window Frames used to have a few hard-coded children—the header bar (until last month), an optional menu bar, the content container, a status bar (which was never completed)—they now serve the function of content container.
  • Added support for unselectable, hidden, and “always on top” Window Frames.

Restructured the widget tree. Before, there were multiple “top-level” instances which could be swapped in as the root widget. These instances would have served as discrete states for the program. All of that has been gutted and replaced with Workspaces, which are direct children of the program’s one WIMP root. There can be zero or one Workspaces active at a time, and Window Frames can be associated with Workspaces such that they only appear when their Workspace is active. Workspaces and Window Frames are categorized as UI Frames, and they can be selected by the WIMP Root for focus and input.

Added ‘awake’ flag for widgets. Sleeping widgets do not tick (meaning they don’t run uiCall_update() and userUpdate() on every frame). To take the thimble (keyboard focus), a widget and all of its ancestors must be awake.

Prevented the WIMP demo from opening multiple copies of the same plan-generated Window Frame. Some of these frames expect to have exclusive access to debug features, like drawing viewports. This is a demo constraint, not a limitation of the library itself. I plan to rewrite the WIMP demo in March to use fewer Window Frames.

Added a context flag to direct love.wheelmoved events to current thimble, rather than current_hover.