Oct 2023

  • Reorganized the theming and skinning system:
    • In August, I added special fields that described how to reach theme objects. For example, skin["*tex_side"] = "textures/side" would eventually lead to the assignment skin.tex_side = resources.textures.side. This was wanted because when changing themes, a texture object might be overwritten with a new object (making the skin’s reference outdated). This month, I went all-in on special prefixed keys, and removed all direct access to the theme resources table when SkinDefs are created. The initialization of a SkinDef is now handled through the theme object’s refreshSkinDef() method, which can be called multiple times throughout the application session.
    • I also added a prefix to automatically scale and floor numbers.
    • Moved most widget measurement and alignment variables to the skin tables. This reduces some memory usage across widget instances, but does make widgets less flexible (since every widget with a given skin must have the same alignment properties and measurements). To work around that, I also added SkinDef patching. By creating a new table with an index__ lookup to an existing SkinDef, one can make short-lived customized skins for one or a handful of widgets. If you follow the API, your temporary SkinDef patches will be managed by the theming system, and they will also be deleted by the garbage collector when no other references exist to them (via weak tables).
  • Added “barebones” versions of some basic controls. These are unskinned, and are intended to help when troubleshooting skinned widgets.
  • Added override behavior for scroll bar styles. The order is:
    1. Widget instance
    2. SkinDef, if it has one
    3. The default style
  • I ported the border and margin measurements from the ListBox widget to most of the other WIMP controls.
  • Merged the widget text label code for buttons, checkboxes, etc., into lgc_label.lua.
    • Three modes are supported:
      • single: A single line of text.
      • single-ul: A single line of text with one optional underlined section (for denoting shortcut keys).
      • multi: Multi-line text.
    • Label formatting is provided by the widget’s skin table: font, text alignment, underline colour and thickness, etc.
  • Cleaned up the code for Slider Bars, moving the internal logic to lgc_slider.lua so that multiple widgets can make use of it.
  • Increased the number of optional widget internal viewports from 2 to 8, and wrote some parameterized functions to operate on any of them. Viewports are useful for representing simple embedded buttons within a widget.
  • Reorganized logic for buttons. Now, button, button_repeat, radio_button and checkbox use methods from a shared lgc_button.lua module.
  • Added button_double_click, button_instant and button_sticky.
  • Added some auxiliary action callbacks to buttons and other WIMP controls. Generally:
    • Action 1: Single-click; return, kpenter or space
    • Action 2: Right-click; application or shift+f10
    • Action 3: Middle-click
  • Adjusted control widgets to take keyboard focus if the user clicks on them with buttons 1, 2 or 3. Previously, it was only buttons 1 and 2.
  • The main WIMP demo file is bloated, so I have been migrating some test widget setup code to separate plan / factory files. Eventually, I want something like the SLAB or Love Frames demos where widgets are presented by category.
  • Investigated mkdocs as a solution for documenting ProdUI.
  • Fixed up the Progress Bar widget, which was in a half-finished state.
  • Implemented a LUIGI-style Stepper widget.
  • Worked on ListBox, fixing measurement and alignment code and adding callbacks for actions.
  • WIMP root widget cleanup:
    • I simplified the thimble stepping code (how you get from widget to widget with the keyboard). Before, you could link up widgets in any order, and use the arrow keys in addition to tabbing through. Now, only tab and shift+tab work, and they move through widgets in the order that they are stored internally. I’ve kept the other handlers because they might be useful with other UI styles, and so that I can walk this back if it turns out to be a problem. From my current vantage point, though, the flexibility isn’t worth the cost of linking up every widget manually.
    • Added selectTopFrame() to the WIMP root so that applications can quickly select a window frame at startup.
    • Added a uiCall_destroy() check in the WIMP root to select a window frame when the current frame is in the process of being destroyed (called only when that frame is currently selected).
    • Added the shortcut ctrl+f4 to close the current window frame.
  • Inspector Key: fixed a bad scancode (was menu, should have been application).


Various window frames with test content.