Command Registry
To remove the friction of a user not finding the command they need when they need it, Stuck can duplicate commands with variant names to match different mindsets or have commands that behave slightly differently based on different contexts.
This is likely to become unsustainable very fast if not designed well, so I'm orienting myself towards the implementation of a command registry that acts as the source of truths for commands.
The idea is to classify commands as follows:
- Command name: what it does from the system's perspective.
- Views (list): the views in which this command is valid.
- Shortcut (per view): shortcuts are contextual and hierarchical.
- For instance: a shortcut valid in bookshelf is valid anywhere else unless overriden by another command's more specific shortcut.
- User shortcuts are not stored in the command registry which is read-only.
- Shortcut (per view): shortcuts are contextual and hierarchical.
- Locations (list): all the places that command can be found.
- Crucial Rule: All actionable UI elements (buttons, menu items, etc.) are dynamically generated by binding to these location strings. There should be NO hardcoded
<Button>tags in the application. - It should be hierarchically organized and every space should be named.
- Each location must have an intent associated.
- for instance:
menu.books.view:exit_to_librarymenu.manuscript.management:close_active_bookdialog.settings.actions:confirm_changes
- Crucial Rule: All actionable UI elements (buttons, menu items, etc.) are dynamically generated by binding to these location strings. There should be NO hardcoded
- Intents (list): all the intents by which this command is represented. For instance:
exit_to_libraryclose_active_book
- Views (list): the views in which this command is valid.
It should only ever concern an entire command. For instance, a command to open a book will close a book already open, but it doesn't mean it actually has any of the intents that close_active_book carries.
Ephemeral Commands (Confirm / Cancel)
Even highly localized, temporary actions—such as clicking "Confirm", "Apply", or "Cancel" inside a specific dialog box—MUST be registered in the Command Registry (often as ephemeral/scoped commands).
Why do this?
1. Shortcut Standardization: Global dialog shortcuts (e.g., Enter to confirm, Escape to cancel) must be predictably handled. Routing them through the registry prevents views from creating their own isolated, conflicting key-handling spaghetti.
2. Strict UI Generation: It enforces the rule that all buttons are generated. The moment you hardcode a <Button Content="Confirm"> in XAML, you break the dynamic rendering and localization pipelines.
3. Architectural Purity: It ensures the UI engine treats a temporary dialog action exactly the same as a global menu item, reusing the exact same XAML DataTemplates.
Styling Generated Commands
If all buttons in a view (like a dialog footer) are generated dynamically via an ItemsControl bound to a specific Location subset, how do you visually distinguish a blue "Confirm" button from a gray "Cancel" button, or a red "Delete" button?
Commands mapped to a location should carry an additional metadata flag for their visual weight (e.g., CommandType.Primary, CommandType.Secondary, CommandType.Destructive).
The Avalonia DataTemplate that renders the button will bind directly to this property, using a converter or a style selector to apply the correct visual classes to the generated button.