Rand Stats

Terminal::Widgets

zef:japhb
Revision history for Terminal-Widgets

0.2.5  2025-12-13T17:26:57-08:00
  [Bug Fixes]
  - Work around an Emacs source code highlighting bug

  [Docs]
  - Rewrite adding-new-widgets doc for clarity and to conform to current
    self-registering widget class API
  - Fix some comment markers that should have been WHY markers

  [Functionality]
  - Add a WidgetRegistry that every widget class self-registers into, with
    caches and accessors to make registry looks fast
  - Add WIP WrappableBuffer abstraction (not ready for full use this release)

  [Performance]
  - Switch to using `nano` to get nanosecond counts as fast as possible for all
    performance stopwatches; `now` is now only used for getting Instant stamps

  [Refactoring]
  - Refactor layout tree and widget building using the WidgetRegistry API
  - Move layout class definitions out to widget implementation modules
  - Move `DEBUG` and `gist-name` to a new Common role
  - Move DirtyAreas role to its own module file
  - Factor `gist-dirty-areas` out to DirtyAreas role
  - Rebase Viewer::Log on top of WIP WrappableBuffer


0.2.4  2025-12-03T23:14:40-08:00
  [Bug Fixes]
  - Fix a thinko bug with InterpolantSpans that had previously been silent
  - Fix off-by-one error in set-x/y-scroll that would scroll all content
    offscreen
  - Fix Viewer::Tree node _UN_highlighting bug
  - Fix Viewer::Tree refresh handling bug that delayed refresh when expanding
    an empty parent node
  - Fix some copy/pasted comments

  [Debugging]
  - Rename TERMINAL_WIDGETS_DEBUG to TW_DEBUG so that all T-W env vars have
    the same prefix
  - Add debug notes for status of the Terminal event reactor
  - More concise and clear gists for Events
  - Save $*DEBUG into Terminal!debug
  - Give all Widgets a $.debug attribute (based on $*DEBUG as with Terminal),
    and use instead of custom debug handling
  - Hook TopLevel.process-event to add debugging/timing for all events

  [Docs]
  - Add doc detailing T-W configuration methods, including env vars, Terminal
    instance attributes, and `%ui-prefs`

  [Examples]
  - Simplify styles example using centering layout builder
  - Add faint attribute to styles example
  - Add tree-viewer example, based on tree-view with new widgets/APIs
  - Add color-sets example, showing effect of different theme variants and
    the input-activation-flash preference

  [Functionality]
  - Misc
    + Add center/hcenter/vcenter convenience layout builders
    + Give every Event a unique ID (since process start)
    + Allow forcing Scrollable.refresh-for-scroll
  - Tree viewing
    + Make Viewer::Tree sorting optional
    + Default Viewer::DirTree sort to *.short-name
    + Add Volatile::Tree support for static trees
    + Remember expanded descendents of collapsed parents, automatically
      re-expanding them when the parent makes them visible again
  - Themes and colors
    + Improve default theme variants: better consistency, readability, and
      respect for the user's external preferences where possible
    + Support NO_COLOR standard env var and theme variant autodetection
    + Allow setting a Widget's colorset after instantiation
    + Allow Input!active to be set at instantiation
    + Allow Themables to set extra theme states (beyond those auto-computed,
      and allowing overrides if desired)
    + Merge PlainText color on top of current-color
  - UX
    + Separate current and selected concepts for better Input::Menu KB UX
    + Add mouse wheel handling for ScrollBar/Scrollable; note that some
      terminals do not send mouse wheel left/right events
    + Support scroll speed/inversion preferences, and pick them up dynamically

  [Performance]
  - Micro-optimize several heavily used methods and critical paths
  - Add timing/debugging of events and expensive operations
  - Improve SpanTree performance
  - Improve Event handling performance
  - Improve Viewer::Log performance, especially with large logs
  - Improve performance of dir-tree example log handling


0.2.3  2025-11-26T00:19:56-08:00
  [Debugging]
  - Support TERMINAL_WIDGETS_DEBUG env var to set debug verbosity (default 0)
  - Provide a RenderSpan.Str method to get an SGR-escaped string

  [Docs]
  - Add a document explaining the basics of the TextContent model

  [Functionality]
  - Add node highlighting to Viewer::Tree (and thus Viewer::DirTree)
  - Add helper subs for building TextContent instances
  - Support mixed Str and span children in span-tree helper
  - Add pad-span() convenience sub to TextContent
  - Provide ContentRenderer methods that stop at caching points
  - Support ContentRenderer.flat-spans/flat-string-spans in I18N::Locale
  - Add RenderSpan.string-span for path to access attributes
  - Add lines methods to RenderSpan, StringSpan, and SpanTree
  - Support both old (SpanStyle) and new (TextContent) models in Viewer::Log
  - Properly merge color attributes in TextContent trees
  - Labeled inputs now support colored/styled labels

  [Packaging]
  - Bump T::MU dependency for much faster duospace-width() implementation
  - Bump C::DC dependency for perf tweaks

  [Performance]
  - Above dependency bumps, picking up faster implementations
  - Make use of duospace-width-core() in a few cases
  - Show Widget.full-refresh timing info when debug > 0
  - Show timing info for Viewer::Tree cache fills when debug > 0
  - Optimize several key Viewer::Tree routines
  - Remove redundant full-refresh in SpanWrappingAndHighlighting!my-refresh

  [Refactoring]
  - Switch Input modules to TextContent
  - Switch Tree and DirTree Viewers to RenderSpans
  - Switch debugger-mockup, dir-tree, and form examples over to TextContent
  - Simplify flatten methods in StringSpan and InterpolantSpan
  - Get rid of remaining bogus $.grid.set-span* calls outside where they belong
  - Remove unneeded 'use' statements in several modules
  - Prefer locale.width over manual duospace-width where feasible

  [Tests]
  - Prevent export conflicts in 00-use while changing content model


0.2.2  2025-11-22T16:00:27-08:00
  [Bug Fixes]
  - Don't apply minimize-w layout style in with-scrollbars
  - Fix thinko that had broken scrollbar keypresses
  - Switch to the full-refresh protocol for TopLevel.focus-on,
    fixing visual behavior of focus moves

  [Docs]
  - Add per-directory READMEs explaining intent of lib/ subdirs

  [Examples]
  - Extend tree-view example to expose some bugs
  - Add dir-tree example demonstrating Viewer::DirTree

  [Functionality]
  - Support (and switch to) content-area-relative mouse events
  - Introduce the volatile data structures tree, Volatile/
  - Add Volatile::Tree, providing base roles for volatile tree structures
  - Add Volatile::DirTree data structure, representing a live filesystem
  - Add Viewer::Tree, base class for viewers of volatile trees
  - Add Viewer::DirTree, specialized to Volatile::DirTree
  - Fade scrollbars when not in use (everything visible and scroll = 0)
  - Make scrollbars Themable and Focusable (and participate in tab ring)

  [Packaging]
  - Bump T::C and C::DC dependencies to get new SGR attr support, and thus
    more complete support for GNU dircolors in Viewer::DirTree


0.2.1  2025-11-15T13:19:52-08:00
  [Bug Fixes]
  - Remove a duplicated check in draw-line-spans due to merging reorded code

  [Examples]
  - Add rich-text and tree-view examples
  - Make use of with-scrollbars to clean up several examples
  - Use add-top-level to instantiate Form2UI in two-forms example

  [Functionality]
  - Add Focusable role (Patrick Böker)++
  - Add focus tabbing support to more widget types (Patrick Böker)++
  - Make focus tabbing wrap around at start and end (Patrick Böker)++
  - Add SpanWrappingAndHighlighting role (Patrick Böker)++
  - Add RichText and TreeView widgets (Patrick Böker)++
  - Add Themable role and make Widget Themable
  - Add with-scrollbars layout method to associate a Scrollable child
    with matching scrollbars
  - Continued work on new TextContent model and TranslatableStrings

  [Refactoring]
  - Push 'is Widget' from roles to consuming classes, to allow multiple
    inheritance without forming diamond relationships (Patrick Böker)++
  - Refactor Widget.draw-frame for more correct painting order and to
    separate draw-content from draw-framing
  - Move the common full-refresh method implementation down to Widget
  - Cleanup/refactor gist-flags handling
  - Refactor widget coloring around Themable role


0.2.0  2025-11-06T15:15:38-08:00
  [Bug Fixes]
  - Fix duospaced text printing bug due to reused variable (Patrick Böker)++
  - Fix draw-line-spans bugs found by (Patrick Böker)++

  [Cleanups]
  - Reduce overuse of double quotes to make security sweeps less noisy
    + Single quote things that don't require any double-quotishness
    + Convert interpolations to concatenations
    + Replace "\n" with $?NL

  [Docs]
  - Greatly expand and clarify comments in Widget.draw-line-spans, one of the
    most complex algorithms in T-W

  [Examples]
  - Add a debugger-mockup example inspired by issue #11

  [Functionality]
  - Add ToggleButton widget: looks like Button, acts like Checkbox
  - Create new TextContent/ContentRenderer model based on RenderSpans
  - Realign I18N::Locale and Translation around new content model
  - Ask locale for (possibly translated) plain-text when Str desired
  - Add Widget.content-rect to get XYWH rect of content area
  - Support capabilities autodetection on controlling terminal

  [Packaging]
  - Bump deps to pick up numerous bug fixes and functional improvements:
    + Terminal::Capabilities to 0.0.12+
    + Terminal::LineEditor to 0.0.23+
    + Terminal::Print to 0.977+

  [Portability]
  - Unlock Windows support! (Patrick Böker)++
  - Work around change in object hash semantics in Rakudo 2025.03-27
    with a fix that works both before and after

  [Refactoring]
  - Refactor refresh handling for Checkbox/RadioButton/Boolean
    + Move identical full-refresh methods up to base class
    + Drop unneeded refresh-value methods
    + Refactor draw-frame method in Boolean
  - Factor group management out of RadioButton into GroupedBoolean
  - Refactor lots of basic input pieces into SimpleClickable
  - Factor draw-line-spans out of SpanBuffer.draw-frame into the Widget core
  - Refactor SpanBuffer.draw-frame in terms of Widget.content-rect
  - Rebase PlainText on top of SpanBuffer

  [Security]
  - Sanitize text in a few insecure places found during double-quote sweep

  [Testing]
  - Fix order of use tests to match dependency order of modules


0.1.5  2024-04-01T00:35:56-07:00
  [Bug Fixes]
  - Ignore Input events that change state when the Input is disabled, but
    continue to allow navigation events regardless

  [Cleanup]
  - Fix and clarify a few comments
  - Remove unused imports in several files

  [Debugging]
  - Show widget dirty state in Widget.gist

  [Examples]
  - Add a heat-ping example based on the new SmokeChart widget
  - Add proper log scrolling to the basic form example

  [Functionality]
  - Support for scrollable, ragged, lazy, span-styled buffers via new
    Scrollable, ScrollBar, and SpanBuffer roles
  - New HScrollBar and VScrollBar widgets with full symbol set support and
    both keyboard and mouse event handling
  - Experimental support for slice-addressed visualizations
  - New SmokeChart visualization widget
  - Support overriding default behavior of Input::Text.finish-entry
  - Add content-width and content-height helper methods to Widget

  [Performance]
  - Actually optimize copies and prints based on real dirty areas, rather than
    always assuming every widget is always fully dirty
  - Lazily cache span width in Span itself

  [Refactoring]
  - Refactor Viewer::Log in terms of SpanBuffer, vastly simplifying it


0.1.4  2024-03-02T14:00:05-08:00
  [API Simplification]
  - Provide helper methods for cleaner form group handling
  - Allow App.add-terminal to set locale and ui-prefs as well

  [Bug Fixes]
  - Silence an uninitialized warning in Menu icon handling (when a particular
    menu item doesn't have an icon associated with it)
  - Much more correct min width defaults for SingleLineInput layouts

  [Debugging]
  - Improve Input.gist-flags for glanceability

  [Examples]
  - Demo group introspection in form example

  [Functionality]
  - All Inputs will set their hint (if any) when focused
  - Initial sketch of ColorSet and ColorTheme functionality; API expected to
    change in the future, especially for theme variants and variant selection
  - Define a number of terminal capability variants on a default dark/cool theme
  - Add Tango-approximating variants of default theme, for a less harsh look
    than the highly saturated xterm-style variants
  - Convert Input widgets to use ColorSets instead of hardcoding
  - Add additional color selectors to configure additional UI elements
    (hint, link, prompt, cursor)
  - Allow Input activation flash to be turned off (activate/deactivate still
    _happen_ in that case, but don't cause a widget to flash when they do)

  [Testing]
  - Update GitHub Workflow definition to clear deprecation warning

  [Refactoring]
  - Refactor min width default handling for SingleLineInput layouts
  - Move hint handling from Input::Menu to Input base class

  [Layout Styles]
  - Pass requested layout style info into default-styles as well, so
    default-styles can build out the implications of requested styles


0.1.3  2024-02-22T23:38:50-08:00
  [Debugging]
  - Add tunable Widget compositing debugging
  - Make ACTIVE state more obvious in Input.gist-flags

  [Functionality]
  - Add support for menu item icons


0.1.2  2024-02-21T20:44:08-08:00
  [Bug fixes]
  - Update META6 to require latest versions of dependencies, and add a missing
    dependency (Text::MiscUtils)


0.1.1  2024-02-21T18:35:46-08:00
  [API Changes]
  - First *experimental* version of translatable UI elements; see Functionality
  - This release should still be compatible with existing 0.1.0 code, but
    future releases in the 0.1.x cycle may not be
  - Will almost certainly require some additional changes to work seamlessly
    with span tree coloring and proper interpolations

  [Bug Fixes]
  - Fit styles example into 80 columns (it was not intended to demonstrate
    overflow behavior and doesn't handle it well)

  [Functionality]
  - Translatable string markup operators added for lightweight code changes
  - Translations handled by Locale object, which is tied to the Terminal
  - Terminal passed as context to Layout objects, allowing the Locale
    to influence layout measurements
  - Terminal capabilities and locale can now be updated on the fly (causing
    a screen refresh)
  - Currently works with Labeled Input, Menu, and PlainText widgets
  - PlainText widgets can optionally add soft-wrapping behavior in addition
    to respecting hard-wrapped lines in the input text as before
  - Window title also translated (and sanitized for security reasons)

  [Refactoring]
  - Refactor debug-grid and improve its empty grid handling


0.1.0  2024-02-12T17:19:15-08:00
  [API Changes]
  - Begin process of rationalizing refresh handling for an easier mental model
    and fewer redundant or missing refreshes
  - Create a new global LayoutBuilt event, and issue it in TopLevel.relayout
    to notify widgets that the overall layout has finished building (and thus
    all widgets should now exist and be nominally initialized)

  [Functionality]
  - Add initial support for styling of span trees
  - Add styled span tree support to Viewer::Log

  [Examples]
  - Demo span-styled log entries and layout gists in form example

  [Refactoring]
  - Massive refactor of Viewer::Log to use LogEntry objects


0.0.13  2024-02-12T16:54:00-08:00
  [Bug Fixes]
  - Fix precedence thinko in menu width detection that caused some menus to
    overdraw their right boundary
  - Invalidate grid-string cache for full-screen composites, fixing a visual
    bug seen when switching back to a previously-viewed screen
  - Compute fixed layouts for widgets created statically from an existing grid
  - Add stub for build-layout method to clarify that TopLevel requires it

  [Debugging]
  - Show when a Widget is focused in Widget gists
  - Add a debug-grid method to Widget for dumping a widget's grid contents
    as an ANSI-colored snapshot, rather than as an array of arrays of Cells


0.0.12  2023-11-26T21:03:49-08:00
  [Bug Fixes]
  - Select correct item when using mouse-click selection on a scrolled Menu
  - Allow Text input to receive focus via mouse click
  - Make sure TopLevel's .layout object knows its own .widget object (the
    original TopLevel itself)
  - Build *base* Widget objects as internal widget tree nodes if requested
    by the layout tree
  - Draw framing on *base* Widget objects also, not just subclasses
  - Make sure Style.clone calls Style's TWEAK, just as for new/bless
  - Sort unset layout children by MarginBox size, not default sizing box
  - Simplify and fix propagate-xy box model corrections
  - Fix correction handling in child layout share computations

  [Examples]
  - Update styles example to include box model (framing) styling as well

  [Refactoring]
  - Factor color-merge() helper out to ::Utils::Color
  - Refactor, improve, and expand gist logic for both Widget and Layout objects
  - Clarify layout computation via change of variable


0.0.11  2023-11-12T17:11:18-08:00
  [Bug Fixes]
  - Prefer to autofocus on widgets that process input (falling back to widgets
    that are able to handle events of any type, as before)

  [Examples]
  - Add an example showing how to move back and forth between form pages


0.0.10  2023-11-12T14:53:56-08:00
  [Bug Fixes]
  - Fix layout bug causing max limits to be ignored when allocating extra space
    to undersized child layout nodes

  [Examples]
  - Add a scrolling, colored, responsive-layout menu example

  [Functionality]
  - Support autoscrolling Menu input widgets
  - Support per-menu-item colors


0.0.9  2023-11-08T15:34:35-08:00
  [Bug Fixes]
  - Handle menu items with no hotkeys

  [Examples]
  - Add a simple text, border, and layout style demo

  [Functionality]
  - Allow override of Menu hint target
  - Add a custom gist method for Menu


0.0.8  2023-09-03T20:24:54-07:00
  [Bug Fixes]
  - Minor tweaks, fixes, and error message improvements

  [Functionality]
  - Add missing right/bottom-correction BoxModel multis
  - Track timing for app bootup and terminal initialization
  - Add ::Progress::Tracker role to unify interface to progress tracking widgets
  - Support loading screens with optional progress tracking display
  - Allow layout objects to specify a share weight for distributing space
  - Add spacer-only layout leaf node for self-documenting convenience

  [I18n]
  - Stub in ::I18N::Locale class and ensure each Terminal gets one

  [Performance]
  - Various minor micro-optimizations

  [Quality]
  - Improve quality and performance of gray-color() utility multis
  - Better represent uneven xterm-256 color cube mapping in rgb-color() utility
    multis, adding rgb-color-flat() multis to use the old flat-mapping formulae

  [Refactoring]
  - Move all color utilities in ::Utils into a separate ::Utils::Color module
  - Move relayout phases from Terminal to TopLevel
  - Move TW_* environment var handling to ::App.add-terminal
  - Significantly refactor and simplify App booting (many commits), resulting
    in adding separate ::Simple::App class as well


0.0.7  2023-06-24T22:17:50-07:00
  [Bug Fixes]
  - Make sure ::Input::Text uses scroll markers matched to terminal caps

  [Documentation]
  - Add doc with ruminations on styles

  [Functionality]
  - Add right-correction and bottom-correction methods to BoxModel
  - Rewrite Widget compositing to clip to parent's content area

  [Packaging]
  - Bump dependencies

  [Refactoring]
  - Move ::TerminalCapabilities out to its own separate distribution,
    Terminal::Capabilities


0.0.6  2023-06-08T22:12:17-07:00
  [Bug Fixes]
  - Correct width and height when building objects
  - Fix thinkos in distributing unassigned height/width in layouts
  - Comment out seemingly-redundant callsame
  - Fix WHY for ::Input::Text

  [Examples]
  - Update form example with framing styles

  [Functionality]
  - Expand BoxModel and make it more usable
  - Add `draw-framing` and related methods to base Widget class
  - Draw and account for framing for all existing widgets

  [Refactoring]
  - Move BoxDrawing consumption to base Widget class


0.0.5  2023-06-04T12:24:07-07:00
  [Functionality]
  - Support terminal capabilities and envvars for them in ::App
  - Adjust input widget rendering based on available symbol set
  - Add initial sketch of ::I18N::Translation

  [Packaging]
  - Fix copyright years


0.0.4  2023-05-21T14:56:20-07:00
  [Functionality]
  - Add PlainText widget for simple text blocks
  - Add Input::Menu widget for trivial menus
  - Add 'highlight' as a themable color for Input widgets
  - Allow layout widgets to dynamically generate their default styles
  - Provide symbol-set helper routine for terminal capabilities

  [Refactoring/Cleanup]
  - Reduce boilerplate in building layout and widget trees
  - Remove commented-out code

  [Testing/CI]
  - Upgrade to checkout@v3 to avoid CI warning


0.0.3  2023-05-12T21:03:44-07:00
  [Bug fixes]
  - Prevent bubble-up event duplication

  [Functionality]
  - First bits of Widget dirty area handling
  - Add initial terminal capabilities tracking
  - Add initial Unicode symbol set variants
  - Add RGB -> Luma/grayscale conversion utils
  - Add convenience method for finding widget's toplevel's terminal


0.0.2  2022-08-09T18:14:58-07:00
  [Bug fixes]
  - Return Empty from Simple::TopLevel.initial-layout stub
  - Remove existing content in Input::Text.reset-entry-state
  - Don't send events to children that can't understand them
  - Recalc coordinate offsets even for unparented Widgets

  [Functionality]
  - Add a Terminal.has-initialized Promise
  - First bits of Z-order support for Widgets (API changes expected)


0.0.1  2022-07-23T16:44:48-07:00
  - Initial proof-of-concept version