Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable keymap prototype. #109

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
91 changes: 82 additions & 9 deletions src/main/java/sc/fiji/labkit/ui/BasicLabelingComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,43 @@

package sc.fiji.labkit.ui;

import java.awt.Adjustable;
import java.awt.BorderLayout;
import java.util.Collection;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;

import org.scijava.ui.behaviour.util.AbstractNamedAction;
import org.scijava.ui.behaviour.util.Actions;
import org.scijava.ui.behaviour.util.Behaviours;
import org.scijava.ui.behaviour.util.InputActionBindings;
import org.scijava.ui.behaviour.util.TriggerBehaviourBindings;

import bdv.ui.keymap.Keymap;
import bdv.ui.keymap.KeymapManager;
import bdv.ui.splitpanel.SplitPanel;
import bdv.util.BdvHandle;
import bdv.util.BdvHandlePanel;
import bdv.util.BdvOptions;
import bdv.util.BdvStackSource;
import bdv.viewer.DisplayMode;
import bdv.viewer.NavigationActions;
import bdv.viewer.ViewerPanel;
import net.miginfocom.swing.MigLayout;
import sc.fiji.labkit.ui.bdv.BdvAutoContrast;
import sc.fiji.labkit.ui.bdv.BdvLayer;
import sc.fiji.labkit.ui.bdv.BdvLayerLink;
import sc.fiji.labkit.ui.brush.*;
import sc.fiji.labkit.ui.brush.ChangeLabel;
import sc.fiji.labkit.ui.brush.FloodFillController;
import sc.fiji.labkit.ui.brush.LabelBrushController;
import sc.fiji.labkit.ui.brush.PlanarModeController;
import sc.fiji.labkit.ui.brush.SelectLabelController;
import sc.fiji.labkit.ui.labeling.LabelsLayer;
import sc.fiji.labkit.ui.models.Holder;
import sc.fiji.labkit.ui.models.ImageLabelingModel;
import sc.fiji.labkit.ui.panel.LabelToolsPanel;
import net.miginfocom.swing.MigLayout;
import org.scijava.ui.behaviour.util.AbstractNamedAction;

import javax.swing.*;
import java.awt.*;
import java.util.Collection;

/**
* A swing UI component that shows a Big Data Viewer panel and a tool bar for
Expand All @@ -68,11 +85,19 @@ public class BasicLabelingComponent extends JPanel implements AutoCloseable {

private JSlider zSlider;

private KeymapManager keymapManager;

public BasicLabelingComponent(final JFrame dialogBoxOwner,
final ImageLabelingModel model)
{
this(dialogBoxOwner, model, null);
}

public BasicLabelingComponent(final JFrame dialogBoxOwner, final ImageLabelingModel model,
KeymapManager keymapManager) {
this.model = model;
this.dialogBoxOwner = dialogBoxOwner;
this.keymapManager = keymapManager;

initBdv(model.spatialDimensions().numDimensions() < 3);
actionsAndBehaviours = new ActionsAndBehaviours(bdvHandle);
Expand All @@ -85,8 +110,33 @@ public BasicLabelingComponent(final JFrame dialogBoxOwner,
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());
});
}
}

private void initPanel() {
Expand Down Expand Up @@ -115,6 +165,7 @@ public Holder<BdvStackSource<?>> addBdvLayer(BdvLayer layer) {
}

private JPanel initToolsPanel() {

final PlanarModeController planarModeController = new PlanarModeController(
bdvHandle, model, zSlider);
final LabelBrushController brushController = new LabelBrushController(
Expand All @@ -123,9 +174,31 @@ private JPanel initToolsPanel() {
bdvHandle, model, actionsAndBehaviours);
final SelectLabelController selectLabelController =
new SelectLabelController(bdvHandle, model, actionsAndBehaviours);
final JPanel toolsPanel = new LabelToolsPanel(brushController,
final LabelToolsPanel toolsPanel = new LabelToolsPanel(brushController,
floodFillController, selectLabelController, planarModeController);
actionsAndBehaviours.addAction(new ChangeLabel(model));
ChangeLabel changeLabel = new ChangeLabel(model);
actionsAndBehaviours.addAction(changeLabel);

if (keymapManager != null) {
InputActionBindings keybindings = bdvHandle.getKeybindings();
TriggerBehaviourBindings triggerbindings = bdvHandle.getTriggerbindings();

Keymap keymap = keymapManager.getForwardSelectedKeymap();

final Actions actions = new Actions(keymap.getConfig(), "labkit");
actions.install(keybindings, "annotating");

Behaviours behaviours = new Behaviours(keymap.getConfig(), "labkit");
behaviours.install(triggerbindings, "annotating");

keymap.updateListeners().add(() -> {
actions.updateKeyConfig(keymap.getConfig());
behaviours.updateKeyConfig(keymap.getConfig());
});

toolsPanel.install(actions);
changeLabel.install(actions);
}
return toolsPanel;
}

Expand Down
42 changes: 42 additions & 0 deletions src/main/java/sc/fiji/labkit/ui/LabKitKeymapManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package sc.fiji.labkit.ui;

import org.scijava.Context;
import org.scijava.plugin.PluginService;
import org.scijava.ui.behaviour.io.gui.CommandDescriptionProvider.Scope;
import org.scijava.ui.behaviour.io.gui.CommandDescriptionsBuilder;

import bdv.KeyConfigScopes;
import bdv.ui.keymap.KeymapManager;

public class LabKitKeymapManager extends KeymapManager
{

private static final String LABKIT_KEYMAP_DIR = System.getProperty( "user.home" ) + "/.labkit/keymaps";

/** The key-config scope for LabKit actions. */
public static final Scope LABKIT_SCOPE = new Scope( "sc.fiji.labkit" );

/** The key-config context for LabKit actions. */
public static final String LABKIT_CONTEXT = "labkit";

public LabKitKeymapManager()
{
super( LABKIT_KEYMAP_DIR );
}

/**
* Discover all {@code CommandDescriptionProvider}s with the LabKit scope.
*/
@Override
public synchronized void discoverCommandDescriptions()
{
final CommandDescriptionsBuilder builder = new CommandDescriptionsBuilder();
try (final Context context = new Context( PluginService.class ))
{
context.inject( builder );
builder.discoverProviders(LABKIT_SCOPE, KeyConfigScopes.BIGDATAVIEWER);
context.dispose();
setCommandDescriptions( builder.build() );
}
}
}
90 changes: 80 additions & 10 deletions src/main/java/sc/fiji/labkit/ui/SegmentationComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Expand All @@ -29,7 +29,40 @@

package sc.fiji.labkit.ui;

import sc.fiji.labkit.ui.actions.*;
import java.awt.BorderLayout;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;

import org.scijava.plugin.Plugin;
import org.scijava.ui.behaviour.io.gui.CommandDescriptionProvider;
import org.scijava.ui.behaviour.io.gui.CommandDescriptions;
import org.scijava.ui.behaviour.util.Actions;
import org.scijava.ui.behaviour.util.InputActionBindings;

import bdv.ui.keymap.Keymap;
import bdv.ui.keymap.Keymap.UpdateListener;
import bdv.ui.keymap.KeymapManager;
import net.miginfocom.swing.MigLayout;
import sc.fiji.labkit.ui.actions.AddLabelingIoAction;
import sc.fiji.labkit.ui.actions.BatchSegmentAction;
import sc.fiji.labkit.ui.actions.BitmapImportExportAction;
import sc.fiji.labkit.ui.actions.ClassifierIoAction;
import sc.fiji.labkit.ui.actions.ClassifierSettingsAction;
import sc.fiji.labkit.ui.actions.ExampleAction;
import sc.fiji.labkit.ui.actions.LabelEditAction;
import sc.fiji.labkit.ui.actions.LabelingIoAction;
import sc.fiji.labkit.ui.actions.ResetViewAction;
import sc.fiji.labkit.ui.actions.SegmentationAsLabelAction;
import sc.fiji.labkit.ui.actions.SegmentationExportAction;
import sc.fiji.labkit.ui.actions.ShowHelpAction;
import sc.fiji.labkit.ui.actions.ShowPreferencesDialogAction;
import sc.fiji.labkit.ui.menu.MenuKey;
import sc.fiji.labkit.ui.models.ColoredLabelsModel;
import sc.fiji.labkit.ui.models.Holder;
Expand All @@ -42,10 +75,6 @@
import sc.fiji.labkit.ui.plugin.MeasureConnectedComponents;
import sc.fiji.labkit.ui.segmentation.PredictionLayer;
import sc.fiji.labkit.ui.segmentation.TrainClassifier;
import net.miginfocom.swing.MigLayout;

import javax.swing.*;
import java.awt.*;

/**
* {@link SegmentationComponent} is the central Labkit UI component. Provides UI
Expand All @@ -67,16 +96,38 @@ public class SegmentationComponent extends JPanel implements AutoCloseable {

private final SegmentationModel segmentationModel;

private final KeymapManager keymapManager;

private final Actions actions;

private final InputActionBindings keybindings;

private final JFrame dialogBoxOwner;


public SegmentationComponent(JFrame dialogBoxOwner,
SegmentationModel segmentationModel, boolean unmodifiableLabels)
{
this.dialogBoxOwner = dialogBoxOwner;
this.extensible = new DefaultExtensible(segmentationModel.context(),
dialogBoxOwner);
this.unmodifiableLabels = unmodifiableLabels;
this.segmentationModel = segmentationModel;

keybindings = new InputActionBindings();
SwingUtilities.replaceUIActionMap( this, keybindings.getConcatenatedActionMap() );
SwingUtilities.replaceUIInputMap( this, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keybindings.getConcatenatedInputMap() );
keymapManager = new LabKitKeymapManager();
final Keymap keymap = keymapManager.getForwardSelectedKeymap();
actions = new Actions( keymap.getConfig(), new String[] { LabKitKeymapManager.LABKIT_CONTEXT } );
actions.install( keybindings, "labkit" );
final UpdateListener updateListener = () -> actions.updateKeyConfig( keymap.getConfig() );
keymap.updateListeners().add( updateListener );

ImageLabelingModel imageLabelingModel = segmentationModel.imageLabelingModel();
labelingComponent = new BasicLabelingComponent(dialogBoxOwner, imageLabelingModel);
labelingComponent = new BasicLabelingComponent(dialogBoxOwner, imageLabelingModel, keymapManager);
labelingComponent.addBdvLayer(PredictionLayer.createPredictionLayer(segmentationModel));

initActions();
setLayout(new BorderLayout());
add(initGui());
Expand All @@ -93,14 +144,17 @@ private void initActions() {
new LabelingIoAction(extensible, labelingModel);
new AddLabelingIoAction(extensible, labelingModel.labeling());
new SegmentationExportAction(extensible, labelingModel);
new ResetViewAction(extensible, labelingModel);
new ResetViewAction(actions, extensible, labelingModel);
new BatchSegmentAction(extensible, selectedSegmenter);
new SegmentationAsLabelAction(extensible, segmentationModel);
new BitmapImportExportAction(extensible, labelingModel);
new LabelEditAction(extensible, unmodifiableLabels, new ColoredLabelsModel(
new LabelEditAction(actions, extensible, unmodifiableLabels, new ColoredLabelsModel(
labelingModel));
MeasureConnectedComponents.addAction(extensible, labelingModel);
new ShowHelpAction(extensible);
ShowPreferencesDialogAction.install(actions, extensible, keymapManager, dialogBoxOwner);
ExampleAction.install(actions);
actions.runnableAction(() -> labelingComponent.autoContrast(), AUTO_CONTRAST_ACTION, AUTO_CONTRAST_KEYS);
labelingComponent.addShortcuts(extensible.getShortCuts());
}

Expand Down Expand Up @@ -152,4 +206,20 @@ public JMenuBar getMenuBar() {
public void autoContrast() {
labelingComponent.autoContrast();
}

private static final String AUTO_CONTRAST_ACTION = "auto contrast";
private static final String[] AUTO_CONTRAST_KEYS = new String[] { "not mapped" };
private static final String AUTO_CONTRAST_DESCRIPTION = "Perform auto-contrast on the current image.";

@Plugin(type = CommandDescriptionProvider.class)
public static class Descriptions extends CommandDescriptionProvider {
public Descriptions() {
super(LabKitKeymapManager.LABKIT_SCOPE, LabKitKeymapManager.LABKIT_CONTEXT);
}

@Override
public void getCommandDescriptions(final CommandDescriptions descriptions) {
descriptions.add(AUTO_CONTRAST_ACTION, AUTO_CONTRAST_KEYS, AUTO_CONTRAST_DESCRIPTION);
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/sc/fiji/labkit/ui/actions/ExampleAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sc.fiji.labkit.ui.actions;

import java.awt.event.ActionEvent;

import org.scijava.plugin.Plugin;
import org.scijava.ui.behaviour.io.gui.CommandDescriptionProvider;
import org.scijava.ui.behaviour.io.gui.CommandDescriptions;
import org.scijava.ui.behaviour.util.AbstractNamedAction;
import org.scijava.ui.behaviour.util.Actions;

import sc.fiji.labkit.ui.LabKitKeymapManager;

public class ExampleAction extends AbstractNamedAction {

private static final long serialVersionUID = 1L;

public static final String ACTION_NAME = "example action";

public static final String[] ACTION_DEFAULT_KEYS = new String[] { "A" };

public static final String ACTION_DESCRIPTION = "Print a useless message.";

public static void install(Actions actions) {
actions.namedAction(new ExampleAction(), ACTION_DEFAULT_KEYS);
}

public ExampleAction() {
super(ACTION_NAME);
}

@Override
public void actionPerformed(final ActionEvent e) {
System.out.println("TROLOLO"); // DEBUG
}

@Plugin(type = CommandDescriptionProvider.class)
public static class Descriptions extends CommandDescriptionProvider {
public Descriptions() {
super(LabKitKeymapManager.LABKIT_SCOPE, LabKitKeymapManager.LABKIT_CONTEXT);
}

@Override
public void getCommandDescriptions(final CommandDescriptions descriptions) {
descriptions.add(ACTION_NAME, ACTION_DEFAULT_KEYS, ACTION_DESCRIPTION);
}
}
}
Loading