Prototype a keyboard shortcut system #132

Open
opened 2025-11-21 01:57:38 +00:00 by Vectornaut · 3 comments
Member

This issue should be addressed on the controllers branch, which is meant to inform the architecture of the command system.

Prototype a system for carrying out user actions in response to keypresses. The system should be extensible enough to accommodate the following kinds of actions, although the prototype doesn't need to implement all of them:

  • Create an element or regulator.
    • Could be tested with existing buttons that add points, spheres, and inversive distance regulators.
  • Remove an element or regulator.
  • Switch to working on a different assembly.
  • Open, close, or save an assembly.
    • Could be tested with the existing test assembly chooser.

The shortcuts should in principle be modifiable during a user session, although the prototype doesn't need to implement an interface for modifying them.

_This issue should be addressed on the `controllers` branch, which is meant to inform the architecture of the command system._ Prototype a system for carrying out user actions in response to keypresses. The system should be extensible enough to accommodate the following kinds of actions, although the prototype doesn't need to implement all of them: - Create an element or regulator. - Could be tested with existing buttons that add points, spheres, and inversive distance regulators. - Remove an element or regulator. - Switch to working on a different assembly. - Open, close, or save an assembly. - Could be tested with the existing test assembly chooser. The shortcuts should in principle be modifiable during a user session, although the prototype doesn't need to implement an interface for modifying them.
Vectornaut added the
enhancement
ui
labels 2025-11-21 01:57:38 +00:00
Author
Member

@glen If you can think of more actions that definitely need to be accessible through a shortcut (or if you think any of the actions listed don't necessarily need to be accessible through a shortcut), it would be helpful to mention them in comments here. Here are some actions that I was uncertain about putting on the list; thoughts about whether they're must-haves would also be helpful.

  • Switch focus to a different view. I suspect this would be more appropriately done through the browser's keyboard focus controls. I'm also not sure it would make sense as a console command, because it's navigating views rather than acting on the app state, and it would be meaningless in a console-only session.
  • Focus on an element or regulator. Like the previous example, I'm not sure this would make sense as a console command. We'd likely want its effects to depend on which view is active.
  • Control the selection. This might depend heavily on which view is active. In a list view of elements, for example, it could make sense to use arrow keys to navigate between the elements and another key to select and deselect. In the display view, the arrow keys should probably affect the camera instead, and any affordance for keyboard selection would probably have to involve the visual arrangement of elements.
@glen If you can think of more actions that definitely need to be accessible through a shortcut (or if you think any of the actions listed don't necessarily need to be accessible through a shortcut), it would be helpful to mention them in comments here. Here are some actions that I was uncertain about putting on the list; thoughts about whether they're must-haves would also be helpful. - **Switch focus to a different view.** I suspect this would be more appropriately done through the browser's keyboard focus controls. I'm also not sure it would make sense as a console command, because it's navigating views rather than acting on the app state, and it would be meaningless in a console-only session. - **Focus on an element or regulator.** Like the previous example, I'm not sure this would make sense as a console command. We'd likely want its effects to depend on which view is active. - **Control the selection.** This might depend heavily on which view is active. In a list view of elements, for example, it could make sense to use arrow keys to navigate between the elements and another key to select and deselect. In the display view, the arrow keys should probably affect the camera instead, and any affordance for keyboard selection would probably have to involve the visual arrangement of elements.
Owner
  • As we've discussed, I am not yet convinced that dyna3 needs to be engineered to handle multiple assemblies. Perhaps different instances of dyna3 in different tabs are the method of dealing with more than one assembly. So don't worry about a switch-assembly command/key for now.
  • Similarly, not sure there is any need to close an assembly. Maybe you just close the tab (although we do have to have a don't-lose-unsaved-work mechanism for that).
  • We do need to decide what items are eligible for input focus. It's not clear that elements are, but maybe there's a case for it. I think initially we should have the perspective that only views or some widgets within views can be focused (like regulator input bars in the outline view). Certainly elements can be selected, whereas I do not think that a view can be "selected".
  • Several points in your discussion above show that key and/or gesture bindings require the ability to depend on what element has the focus. Another example is that in the command listeners, all un-modified character keystrokes insert themselves, whereas quite possibly in the graphical view, "p" inserts a Point, for example.
  • With all those caveats, yes, any effect that a key or gesture can have must be available for "shortcut" assignment or reassignment, which means they are a command, which means they can be done in the command listener. I believe we discussed this as a potential accessibility feature: it means someone restricted to ascii input to the command listener, for whatever reason, can access the full graphical capabilities of the system. So yes, that goes for manipulating focus and/or selection. There is no requirement that every command must change the assembly or even the broader app state. There might even be use for a no-op command, although I can't think of an example at the moment (so we shouldn't have one til there is a need).
  • Indeed, some commands could become no-ops in a console-only session. That's OK.
  • As we've discussed, some (likely UI-related commands, especially ones related to mouse motion) should not instantly enter the command history, but need to "bundle" and/or "finalize" before showing. (Perhaps there is some notion of some commands being "transient" and therefore merging with similar transient commands and not showing up until something else non-transient happens.) And possibly even with good "bundling" and/or "transience" there need to be options, some possibly on by default, to filter commands like ChangeFocus from showing in the command history, but I can imagine at least for debugging the UI there will be times when it will be quite handy to have them show.
  • Note that at the very least, the "undo" command in GeoGebra allows you to undo a camera repositioning, which for us is an action that does not affect the assembly, although arguably does affect the app state. And it is meaningful in a console-only session, if that session has, say, the ability to take a snapshot and write it as a graphics file, which I think it should. Incidentally, that snapshot command is another example of one that has no effect on any app state whatsoever, cementing that as a non-criterion for whether something is a command. In short, the presumption is that anything you can do is a command, and the only things you can do are commands, unless/until we encounter a substantive reason for otherwise.
* As we've discussed, I am not yet convinced that dyna3 needs to be engineered to handle multiple assemblies. Perhaps different instances of dyna3 in different tabs are the method of dealing with more than one assembly. So don't worry about a switch-assembly command/key for now. * Similarly, not sure there is any need to close an assembly. Maybe you just close the tab (although we do have to have a don't-lose-unsaved-work mechanism for that). * We do need to decide what items are eligible for input focus. It's not clear that elements are, but maybe there's a case for it. I think initially we should have the perspective that only views or some widgets within views can be focused (like regulator input bars in the outline view). Certainly elements can be _selected_, whereas I do not think that a view can be "selected". * Several points in your discussion above show that key and/or gesture bindings require the ability to depend on what element has the focus. Another example is that in the command listeners, all un-modified character keystrokes insert themselves, whereas quite possibly in the graphical view, "p" inserts a Point, for example. * With all those caveats, yes, any effect that a key or gesture can have must be available for "shortcut" assignment or reassignment, which means they are a command, which means they can be done in the command listener. I believe we discussed this as a potential accessibility feature: it means someone restricted to ascii input to the command listener, for whatever reason, can access the full graphical capabilities of the system. So yes, that goes for manipulating focus and/or selection. There is no requirement that every command must change the assembly or even the broader app state. There might even be use for a no-op command, although I can't think of an example at the moment (so we shouldn't have one til there is a need). * Indeed, some commands could _become_ no-ops in a console-only session. That's OK. * As we've discussed, some (likely UI-related commands, especially ones related to mouse motion) should not instantly enter the command history, but need to "bundle" and/or "finalize" before showing. (Perhaps there is some notion of some commands being "transient" and therefore merging with similar transient commands and not showing up until something else non-transient happens.) And possibly even with good "bundling" and/or "transience" there need to be options, some possibly on by default, to filter commands like ChangeFocus from showing in the command history, but I can imagine at least for debugging the UI there will be times when it will be quite handy to have them show. * Note that at the very least, the "undo" command in GeoGebra allows you to undo a camera repositioning, which for us is an action that does not affect the assembly, although arguably does affect the app state. And it is meaningful in a console-only session, if that session has, say, the ability to take a snapshot and write it as a graphics file, which I think it should. Incidentally, that snapshot command is another example of one that has no effect on any app state whatsoever, cementing that as a non-criterion for whether something is a command. In short, the presumption is that anything you can do is a command, and the only things you can do are commands, unless/until we encounter a substantive reason for otherwise.
Owner

@glen wrote in #132 (comment):

  • Certainly elements can be selected, whereas I do not think that a view can be "selected".

The key point here is that the location of the focus and the contents of the selection need to be independent.

@glen wrote in https://code.studioinfinity.org/StudioInfinity/dyna3/issues/132#issuecomment-3441: > * Certainly elements can be _selected_, whereas I do not think that a view can be "selected". The key point here is that the location of the focus and the contents of the selection need to be independent.
Sign in to join this conversation.
No description provided.