labkit-ui icon indicating copy to clipboard operation
labkit-ui copied to clipboard

Configurable keymap prototype.

Open tinevez opened this issue 9 months ago • 2 comments

This PR is a prototype for a version of LabKit that ships configurable keymaps.

Only a subset of the actions in LabKit have configurable shortcuts for now. The configurability was introduced by changing as little code as possible, and retaining the original shortcuts in full. Supporting all actions and replacing the old keymap system with a new one involve quite some changes I would like to submit to @maarzt judgement first. So here is the PR for it.

There is now a Preferences dialog that can be opened from the Help menu. It contains only one page, allowing to configure keymaps. This is the same framework used in BDV and Mastodon:

Screenshot 2023-09-11 at 10 19 56

In the code, I added several Actions and Behaviors to key UI classes, that are linked to a common KeymapManager, special to LabKit (it can discover key bindings for the LabKit context and for the BDV context).

For instance, to support editing keys for BDV navigation, the initBdv() method of the BasicLabellingComponent class is now the following:

private void initBdv(boolean is2D) {
  final BdvOptions options = BdvOptions.options();
  if (is2D) options.is2D();
  if (keymapManager != null) options.keymapManager(keymapManager);
  
  bdvHandle = new BdvHandlePanel(dialogBoxOwner, options);
  bdvHandle.getViewerPanel().setDisplayMode(DisplayMode.FUSED);
  
  if (keymapManager != null) {
	  ViewerPanel viewer = bdvHandle.getViewerPanel();
  
	  InputActionBindings keybindings = bdvHandle.getKeybindings();
	  TriggerBehaviourBindings triggerbindings = bdvHandle.getTriggerbindings();
  
	  Keymap keymap = keymapManager.getForwardSelectedKeymap();
  
	  final Actions actions = new Actions(keymap.getConfig(), "bdv");
	  actions.install(keybindings, "view");
  
	  Behaviours behaviours = new Behaviours(keymap.getConfig(), "bdv");
	  behaviours.install(triggerbindings, "view");
  
	  viewer.getTransformEventHandler().install(behaviours);
	  NavigationActions.install(actions, viewer, is2D);
  
	  keymap.updateListeners().add(() -> {
		  actions.updateKeyConfig(keymap.getConfig());
		  behaviours.updateKeyConfig(keymap.getConfig());
	  });
	}
  }

Ultimately, if we go this way, we will have to resolve duplicate keybindings (in the KeymapManager and in the ACCELERATOR of the buttons). There is also a custom class in LabKit ActionsAndBehaviors that also uses Actions and Behaviors, but are not linked to a keymap manager. It controls the painting actions and I could not find a way to have it listen to keymap changes properly yet.

tinevez avatar Sep 11 '23 08:09 tinevez

Here is my preliminary cheat sheet to help me understand SciJava behavoirs:

InputMap - A map: short cuts -> action ID ActionMap - A map: action ID -> actions InputTriggerMap - A map: short cuts -> behaviour ID BehaviourMap - A map: behaviour ID -> behaviours

Actions - wraps around InputMap and ActionMap Behaviours - wraps around InputTriggerMap and BehaviourMap InputTriggerConfig - contains configuration SwingUtilities.replaceUIActionMap SwingUtilities.replaceUIInputMap

MouseAndKeyHandler - binds InputTriggerMap and BehaviourMap to a JComponent

InputActionBindings - chain multiple InputMaps and ActionMaps TriggerBehaviourBindings - chain multiple InputTriggerMaps and BehaviorsMaps

maarzt avatar Sep 25 '23 14:09 maarzt

If I can help with anything don't hesitate to ring my bell.

tinevez avatar Sep 29 '23 10:09 tinevez