use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Merger method compare.
/**
* Take two projects and find out what is different among them,
* independent of id.
*/
public static final void compare(final Project p1, final Project p2) {
Utils.log("Be warned: only Treeline, AreaTree and Connector are considered at the moment.");
final LayerSet ls1 = p1.getRootLayerSet(), ls2 = p2.getRootLayerSet();
final Collection<ZDisplayable> zds1 = ls1.getZDisplayables(), zds2 = ls2.getZDisplayables();
final HashSet<Class<?>> accepted = new HashSet<Class<?>>();
accepted.add(Treeline.class);
accepted.add(AreaTree.class);
accepted.add(Connector.class);
final HashMap<Displayable, List<Change>> matched = new HashMap<Displayable, List<Change>>();
final HashSet<ZDisplayable> empty1 = new HashSet<ZDisplayable>(), empty2 = new HashSet<ZDisplayable>();
final HashSet<ZDisplayable> unmatched1 = new HashSet<ZDisplayable>(), unmatched2 = new HashSet<ZDisplayable>(zds2);
// Remove instances of classes not accepted
for (final Iterator<ZDisplayable> it = unmatched2.iterator(); it.hasNext(); ) {
ZDisplayable zd = it.next();
if (!accepted.contains(zd.getClass())) {
it.remove();
continue;
}
if (zd.isDeletable()) {
it.remove();
empty2.add(zd);
}
}
zds2.removeAll(empty2);
final AtomicInteger counter = new AtomicInteger(0);
// or at least one or more that are similar in that they have some nodes in common.
try {
ini.trakem2.parallel.Process.unbound(zds1, new TaskFactory<ZDisplayable, Object>() {
@Override
public Object process(final ZDisplayable zd1) {
Utils.showProgress(counter.getAndIncrement() / (float) zds1.size());
if (!accepted.contains(zd1.getClass())) {
Utils.log("Ignoring: [A] " + zd1);
return null;
}
if (zd1.isDeletable()) {
synchronized (empty1) {
empty1.add(zd1);
}
return null;
}
final List<Change> cs = new ArrayList<Change>();
for (final ZDisplayable zd2 : zds2) {
// Same class?
if (zd1.getClass() != zd2.getClass())
continue;
if (zd1 instanceof Tree<?> && zd2 instanceof Tree<?>) {
Change c = compareTrees(zd1, zd2);
if (c.hasSimilarNodes()) {
cs.add(c);
if (1 == cs.size()) {
synchronized (matched) {
matched.put(zd1, cs);
}
}
synchronized (unmatched2) {
unmatched2.remove(zd2);
}
}
// debug
if (zd1.getId() == zd2.getId()) {
Utils.log("zd1 #" + zd1.getId() + " is similar to #" + zd2.getId() + ": " + c.hasSimilarNodes());
}
}
}
if (cs.isEmpty()) {
synchronized (unmatched1) {
unmatched1.add(zd1);
}
}
return null;
}
});
} catch (Exception e) {
IJError.print(e);
}
// reset
Utils.showProgress(1);
Utils.log("matched.size(): " + matched.size());
makeGUI(p1, p2, empty1, empty2, matched, unmatched1, unmatched2);
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Search method createCoordinate.
private Coordinate<Displayable> createCoordinate(final Displayable d) {
Rectangle r = d.getBoundingBox();
Layer la = d instanceof ZDisplayable ? ((ZDisplayable) d).getFirstLayer() : d.getLayer();
if (null == la) {
Display display = Display.getFront(d.getProject());
if (null == display)
la = d.getProject().getRootLayerSet().getLayer(0);
else
la = display.getLayer();
}
return new Coordinate<Displayable>(r.x + r.width / 2, r.y + r.height / 2, la, d);
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Compare method findFirstXYZAxes.
/**
* Finds the first three X,Y,Z axes as specified by the names in preset.
*/
private static int[] findFirstXYZAxes(final String[] preset, final ArrayList<ZDisplayable> pipes, final String[] pipe_names) {
final int[] s = new int[] { -1, -1, -1 };
int next = 0;
for (final ZDisplayable zd : pipes) {
pipe_names[next] = zd.getProject().getShortMeaningfulTitle(zd);
if (-1 != s[0] && -1 != s[1] && -1 != s[2]) {
// Already all found, just filling names
next++;
continue;
}
final String name = pipe_names[next].toLowerCase();
if (-1 != name.indexOf(preset[0]))
s[0] = next;
else if (-1 != name.indexOf(preset[1]))
s[1] = next;
else if (-1 != name.indexOf(preset[2]))
s[2] = next;
next++;
}
return s;
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Compare method gatherChains.
/**
* Gather chains for all projects considering the cp.regex, and transforms all relative to the reference Project p[0].
* Will ignore any for which a match exists in @param ignore.
*/
public static final Object[] gatherChains(final Project[] p, final CATAParameters cp, final String[] ignore) throws Exception {
String regex_exclude = null;
if (null != ignore) {
final StringBuilder sb = new StringBuilder();
for (final String ig : ignore) {
sb.append("(.*").append(ig).append(".*)|");
}
sb.setLength(sb.length() - 1);
regex_exclude = sb.toString();
}
Utils.logAll("Compare/gatherChains: using ignore string: " + regex_exclude);
Utils.logAll("Compare/gatherChains: using regex: " + cp.regex);
// gather all chains
// to keep track of each project's chains
final ArrayList[] p_chains = new ArrayList[p.length];
final ArrayList<Chain> chains = new ArrayList<Chain>();
for (int i = 0; i < p.length; i++) {
// for each project:
if (null == cp.regex) {
p_chains[i] = createPipeChains(p[i].getRootProjectThing(), p[i].getRootLayerSet(), regex_exclude);
} else {
// Search (shallow) for cp.regex matches
for (final ProjectThing pt : p[i].getRootProjectThing().findChildren(cp.regex, regex_exclude, true)) {
final ArrayList<Chain> ac = createPipeChains(pt, p[i].getRootLayerSet(), regex_exclude);
if (null == p_chains[i])
p_chains[i] = ac;
else
p_chains[i].addAll(ac);
}
// empty
if (null == p_chains[i])
p_chains[i] = new ArrayList<Chain>();
}
chains.addAll(p_chains[i]);
// calibrate
final Calibration cal = p[i].getRootLayerSet().getCalibrationCopy();
for (final Chain chain : (ArrayList<Chain>) p_chains[i]) chain.vs.calibrate(cal);
}
final int n_chains = chains.size();
// register all, or relative
if (4 == cp.transform_type) {
// compute global average delta
if (0 == cp.delta) {
for (final Chain chain : chains) {
cp.delta += (chain.vs.getAverageDelta() / n_chains);
}
}
Utils.log2("Using delta: " + cp.delta);
for (final Chain chain : chains) {
// BEFORE making it relative
chain.vs.resample(cp.delta, cp.with_source);
chain.vs.relative();
}
} else {
if (3 == cp.transform_type) {
// '3' means moving least squares computed from 3D landmarks
Utils.log2("Moving Least Squares Registration based on common fiducial points");
// Find fiducial points, if any
final HashMap<Project, Map<String, Tuple3d>> fiducials = new HashMap<Project, Map<String, Tuple3d>>();
for (final Project pr : p) {
final Set<ProjectThing> fids = pr.getRootProjectThing().findChildrenOfTypeR("fiducial_points");
if (null == fids || 0 == fids.size()) {
Utils.log("No fiducial points found in project: " + pr);
} else {
// the first fiducial group
fiducials.put(pr, Compare.extractPoints(fids.iterator().next()));
}
}
if (!fiducials.isEmpty()) {
// Register all VectorString3D relative to the first project:
final List<VectorString3D> lvs = new ArrayList<VectorString3D>();
final Calibration cal2 = p[0].getRootLayerSet().getCalibrationCopy();
for (final Chain chain : chains) {
final Project pr = chain.pipes.get(0).getProject();
// first project is reference, no need to transform.
if (pr == p[0])
continue;
lvs.clear();
lvs.add(chain.vs);
chain.vs = transferVectorStrings(lvs, fiducials.get(pr), fiducials.get(p[0])).get(0);
// Set (but do not apply!) the calibration of the reference project
chain.vs.setCalibration(cal2);
}
}
} else if (cp.transform_type < 3) {
// '0', '1' and '2' involve a 3D affine computed from the 3 axes
// no need //VectorString3D[][] vs_axes = new VectorString3D[p.length][];
Vector3d[][] o = new Vector3d[p.length][];
for (int i = 0; i < p.length; i++) {
// 1 - find pipes to work as axes for each project
final ArrayList<ZDisplayable> pipes = p[i].getRootLayerSet().getZDisplayables(Line3D.class, true);
final String[] pipe_names = new String[pipes.size()];
for (int k = 0; k < pipes.size(); k++) {
pipe_names[k] = p[i].getMeaningfulTitle(pipes.get(k));
}
final int[] s = findFirstXYZAxes(cp.preset, pipes, pipe_names);
// if axes are -1, forget it: not found
if (-1 == s[0] || -1 == s[1] || -1 == s[2]) {
Utils.log("Can't find axes for project " + p[i]);
o = null;
return null;
}
// obtain axes and origin
final Object[] pack = obtainOrigin(new Line3D[] { (Line3D) pipes.get(s[0]), (Line3D) pipes.get(s[1]), (Line3D) pipes.get(s[2]) }, cp.transform_type, // will be null for the first, which will then be non-null and act as the reference for the others.
o[0]);
// no need //vs_axes[i] = (VectorString3D[])pack[0];
o[i] = (Vector3d[]) pack[1];
}
/* // OLD WAY
// match the scales to make the largest be 1.0
final double scaling_factor = VectorString3D.matchOrigins(o, transform_type);
Utils.log2("matchOrigins scaling factor: " + scaling_factor + " for transform_type " + transform_type);
*/
// transform all except the first (which acts as reference)
final Transform3D M_ref = Compare.createTransform(o[0]);
for (int i = 1; i < p.length; i++) {
final Vector3d trans = new Vector3d(-o[i][3].x, -o[i][3].y, -o[i][3].z);
final Transform3D M_query = Compare.createTransform(o[i]);
// The transfer T transform: from query space to reference space.
final Transform3D T = new Transform3D(M_ref);
T.mulInverse(M_query);
for (final Chain chain : (ArrayList<Chain>) p_chains[i]) {
// in place
chain.vs.transform(T);
}
}
}
// compute global average delta, after correcting calibration and transformation
if (0 == cp.delta) {
for (final Chain chain : chains) {
cp.delta += (chain.vs.getAverageDelta() / n_chains);
}
}
Utils.log2("Using delta: " + cp.delta);
// After calibration and transformation, resample all to the same delta
for (final Chain chain : chains) chain.vs.resample(cp.delta, cp.with_source);
}
return new Object[] { chains, p_chains };
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class DisplayCanvas method keyPressed.
@Override
public void keyPressed(final KeyEvent ke) {
final Displayable active = display.getActive();
if (null != freehandProfile && ProjectToolbar.getToolId() == ProjectToolbar.PENCIL && ke.getKeyCode() == KeyEvent.VK_ESCAPE && null != freehandProfile) {
freehandProfile.abort();
ke.consume();
return;
}
final int keyCode = ke.getKeyCode();
try {
// Enable tagging system for any alphanumeric key:
if (!input_disabled && null != active && active instanceof Tree<?> && ProjectToolbar.isDataEditTool(ProjectToolbar.getToolId())) {
if (tagging) {
if (KeyEvent.VK_0 == keyCode && KeyEvent.VK_0 != last_keyCode) {
// do nothing: keep tagging as true
} else {
// last step of tagging: a char after t or after t and a number (and the char itself can be a number)
tagging = false;
}
active.keyPressed(ke);
return;
} else if (KeyEvent.VK_T == keyCode) {
tagging = true;
active.keyPressed(ke);
return;
}
}
} finally {
last_keyCode = keyCode;
}
tagging = false;
if (ke.isConsumed())
return;
if (!zoom_and_pan) {
if (KeyEvent.VK_ESCAPE == keyCode) {
cancelAnimations();
}
return;
}
final int keyChar = ke.getKeyChar();
boolean used = false;
switch(keyChar) {
case '+':
case '=':
zoomIn();
used = true;
break;
case '-':
case '_':
zoomOut();
used = true;
break;
default:
break;
}
if (used) {
// otherwise ImageJ would use it!
ke.consume();
return;
}
if (input_disabled) {
if (KeyEvent.VK_ESCAPE == keyCode) {
// cancel last job if any
if (Utils.checkYN("Really cancel job?")) {
display.getProject().getLoader().quitJob(null);
display.repairGUI();
}
}
ke.consume();
// only zoom is enabled, above
return;
}
if (KeyEvent.VK_S == keyCode && 0 == ke.getModifiers() && display.getProject().getLoader().isAsynchronous()) {
display.getProject().getLoader().saveTask(display.getProject(), "Save");
ke.consume();
return;
} else if (KeyEvent.VK_F == keyCode && Utils.isControlDown(ke)) {
Search.showWindow();
ke.consume();
return;
}
// if display is not read-only, check for other keys:
switch(keyChar) {
case '<':
case // select next Layer up
',':
// repaints as well
display.previousLayer(ke.getModifiers());
ke.consume();
return;
case '>':
case // select next Layer down
'.':
display.nextLayer(ke.getModifiers());
ke.consume();
return;
}
if (null == active && null != imp.getRoi() && KeyEvent.VK_A != keyCode) {
// control+a and a roi should select under roi
IJ.getInstance().keyPressed(ke);
return;
}
// end here if display is read-only
if (display.isReadOnly()) {
ke.consume();
display.repaintAll();
return;
}
if (KeyEvent.VK_ENTER == keyCode) {
if (isTransforming()) {
applyTransform();
ke.consume();
return;
} else {
IJ.getInstance().toFront();
ke.consume();
return;
}
}
// check preconditions (or the keys are meaningless). Allow 'enter' to
// bring forward the ImageJ window, and 'v' to paste a patch.
/*if (null == active && KeyEvent.VK_ENTER != keyCode && KeyEvent.VK_V != keyCode && KeyEvent) {
return;
}*/
final Layer layer = display.getLayer();
final int mod = ke.getModifiers();
switch(keyCode) {
case KeyEvent.VK_COMMA:
case // select next Layer up
0xbc:
display.nextLayer(ke.getModifiers());
break;
case KeyEvent.VK_PERIOD:
case // select next Layer down
0xbe:
display.previousLayer(ke.getModifiers());
break;
case KeyEvent.VK_Z:
// UNDO: shift+z or ctrl+z
if (0 == (mod ^ Event.SHIFT_MASK) || 0 == (mod ^ Utils.getControlModifier())) {
Bureaucrat.createAndStart(new Worker.Task("Undo") {
@Override
public void exec() {
if (isTransforming())
display.getMode().undoOneStep();
else
display.getLayerSet().undoOneStep();
Display.repaint(display.getLayerSet());
}
}, display.getProject());
ke.consume();
// REDO: alt+z or ctrl+shift+z
} else if (0 == (mod ^ Event.ALT_MASK) || 0 == (mod ^ (Event.SHIFT_MASK | Utils.getControlModifier()))) {
Bureaucrat.createAndStart(new Worker.Task("Redo") {
@Override
public void exec() {
if (isTransforming())
display.getMode().redoOneStep();
else
display.getLayerSet().redoOneStep();
Display.repaint(display.getLayerSet());
}
}, display.getProject());
ke.consume();
}
// else, the 'z' command restores the image using ImageJ internal undo
break;
case KeyEvent.VK_T:
// Enable with any tool to the left of the PENCIL
if (null != active && !isTransforming() && ProjectToolbar.getToolId() < ProjectToolbar.PENCIL) {
ProjectToolbar.setTool(ProjectToolbar.SELECT);
if (0 == ke.getModifiers()) {
display.setMode(new AffineTransformMode(display));
} else if (Event.SHIFT_MASK == ke.getModifiers()) {
for (final Displayable d : display.getSelection().getSelected()) {
if (d.isLinked()) {
Utils.showMessage("Can't enter manual non-linear transformation mode:\nat least one image is linked.");
return;
}
}
display.setMode(new NonLinearTransformMode(display));
}
ke.consume();
}
// else, let ImageJ grab the ROI into the Manager, if any
break;
case KeyEvent.VK_A:
if (0 == (ke.getModifiers() ^ Utils.getControlModifier())) {
final Roi roi = getFakeImagePlus().getRoi();
if (null != roi)
display.getSelection().selectAll(roi, true);
else
display.getSelection().selectAllVisible();
Display.repaint(display.getLayer(), display.getSelection().getBox(), 0);
ke.consume();
// INSIDE the 'if' block, so that it can bleed to the default block which forwards to active!
break;
} else if (null != active) {
active.keyPressed(ke);
if (ke.isConsumed())
break;
// TODO this is just a hack really. Should just fall back to default switch option.
// The whole keyPressed method needs revision: should not break from it when not using the key.
}
break;
case // cancel transformation
KeyEvent.VK_ESCAPE:
if (isTransforming())
cancelTransform();
else {
// deselect
display.select(null);
// repaint out the brush if present
if (ProjectToolbar.BRUSH == ProjectToolbar.getToolId()) {
repaint(old_brush_box, 0);
}
}
ke.consume();
break;
case KeyEvent.VK_SPACE:
if (0 == ke.getModifiers()) {
if (null != active) {
invalidateVolatile();
if (Math.abs(active.getAlpha() - 0.5f) > 0.001f)
active.setAlpha(0.5f);
else
active.setAlpha(1.0f);
display.setTransparencySlider(active.getAlpha());
Display.repaint();
ke.consume();
}
} else {
// ;)
final int kem = ke.getModifiers();
if (0 != (kem & KeyEvent.SHIFT_MASK) && 0 != (kem & KeyEvent.ALT_MASK) && 0 != (kem & KeyEvent.CTRL_MASK)) {
Utils.showMessage("A mathematician, like a painter or poet,\nis a maker of patterns.\nIf his patterns are more permanent than theirs,\nit is because they are made with ideas\n \nG. H. Hardy.");
ke.consume();
}
}
break;
case KeyEvent.VK_S:
if (ke.isAltDown()) {
snapping = true;
ke.consume();
} else if (dragging) {
// ignore improper 's' that open ImageJ's save dialog (linux problem ... in macosx, a single dialog opens with lots of 'ssss...' in the text field)
ke.consume();
}
break;
case KeyEvent.VK_H:
handleHide(ke);
ke.consume();
break;
case KeyEvent.VK_J:
if (!display.getSelection().isEmpty()) {
display.adjustMinAndMaxGUI();
ke.consume();
}
break;
case KeyEvent.VK_F1:
case KeyEvent.VK_F2:
case KeyEvent.VK_F3:
case KeyEvent.VK_F4:
case KeyEvent.VK_F5:
case KeyEvent.VK_F6:
case KeyEvent.VK_F7:
case KeyEvent.VK_F8:
case KeyEvent.VK_F9:
case KeyEvent.VK_F10:
case KeyEvent.VK_F11:
case KeyEvent.VK_F12:
ProjectToolbar.keyPressed(ke);
ke.consume();
break;
case KeyEvent.VK_M:
if (0 == ke.getModifiers() && ProjectToolbar.getToolId() == ProjectToolbar.SELECT) {
display.getSelection().measure();
ke.consume();
}
break;
}
switch(keyChar) {
case ':':
case ';':
if (null != active && active instanceof ZDisplayable) {
if (null != display.getProject().getProjectTree().tryAddNewConnector(active, true)) {
ProjectToolbar.setTool(ProjectToolbar.PEN);
}
ke.consume();
}
break;
}
if (ke.isConsumed())
return;
if (null != active) {
if (display.getMode().getClass() == DefaultMode.class) {
active.keyPressed(ke);
}
if (ke.isConsumed())
return;
}
// Else:
switch(keyCode) {
case KeyEvent.VK_G:
if (browseToNodeLayer(ke.isShiftDown())) {
ke.consume();
}
break;
case KeyEvent.VK_I:
if (ke.isAltDown()) {
if (ke.isShiftDown())
display.importImage();
else
display.importNextImage();
ke.consume();
}
break;
case // as in Inkscape
KeyEvent.VK_PAGE_UP:
if (null != active) {
update_graphics = true;
layer.getParent().addUndoMoveStep(active);
layer.getParent().move(LayerSet.UP, active);
layer.getParent().addUndoMoveStep(active);
Display.repaint(layer, active, 5);
Display.updatePanelIndex(layer, active);
ke.consume();
}
break;
case // as in Inkscape
KeyEvent.VK_PAGE_DOWN:
if (null != active) {
update_graphics = true;
layer.getParent().addUndoMoveStep(active);
layer.getParent().move(LayerSet.DOWN, active);
layer.getParent().addUndoMoveStep(active);
Display.repaint(layer, active, 5);
Display.updatePanelIndex(layer, active);
ke.consume();
}
break;
case // as in Inkscape
KeyEvent.VK_HOME:
if (null != active) {
update_graphics = true;
layer.getParent().addUndoMoveStep(active);
layer.getParent().move(LayerSet.TOP, active);
layer.getParent().addUndoMoveStep(active);
Display.repaint(layer, active, 5);
Display.updatePanelIndex(layer, active);
ke.consume();
}
break;
case // as in Inkscape
KeyEvent.VK_END:
if (null != active) {
update_graphics = true;
layer.getParent().addUndoMoveStep(active);
layer.getParent().move(LayerSet.BOTTOM, active);
layer.getParent().addUndoMoveStep(active);
Display.repaint(layer, active, 5);
Display.updatePanelIndex(layer, active);
ke.consume();
}
break;
case KeyEvent.VK_V:
if (0 == ke.getModifiers()) {
if (null == active || active.getClass() == Patch.class) {
// paste a new image
final ImagePlus clipboard = ImagePlus.getClipboard();
if (null != clipboard) {
final ImagePlus imp = new ImagePlus(clipboard.getTitle() + "_" + System.currentTimeMillis(), clipboard.getProcessor().crop());
final Object info = clipboard.getProperty("Info");
if (null != info)
imp.setProperty("Info", (String) info);
final double x = srcRect.x + srcRect.width / 2 - imp.getWidth() / 2;
final double y = srcRect.y + srcRect.height / 2 - imp.getHeight() / 2;
// save the image somewhere:
final Patch pa = display.getProject().getLoader().addNewImage(imp, x, y);
display.getLayer().add(pa);
ke.consume();
}
// TODO there isn't much ImageJ integration in the pasting. Can't paste to a selected image, for example.
} else {
// Each type may know how to paste data from the copy buffer into itself:
active.keyPressed(ke);
ke.consume();
}
}
break;
case KeyEvent.VK_P:
if (0 == ke.getModifiers()) {
display.getLayerSet().color_cues = !display.getLayerSet().color_cues;
Display.repaint(display.getLayerSet());
ke.consume();
}
break;
case KeyEvent.VK_F:
if (0 == (ke.getModifiers() ^ KeyEvent.SHIFT_MASK)) {
// toggle visibility of tags
display.getLayerSet().paint_tags = !display.getLayerSet().paint_tags;
Display.repaint();
ke.consume();
} else if (0 == (ke.getModifiers() ^ KeyEvent.ALT_MASK)) {
// toggle visibility of edge arrows
display.getLayerSet().paint_arrows = !display.getLayerSet().paint_arrows;
Display.repaint();
ke.consume();
} else if (0 == ke.getModifiers()) {
// toggle visibility of edge confidence boxes
display.getLayerSet().paint_edge_confidence_boxes = !display.getLayerSet().paint_edge_confidence_boxes;
Display.repaint();
ke.consume();
}
break;
case KeyEvent.VK_DELETE:
if (0 == ke.getModifiers()) {
display.getSelection().deleteAll();
}
break;
case KeyEvent.VK_B:
if (0 == ke.getModifiers() && null != active && active.getClass() == Profile.class) {
display.duplicateLinkAndSendTo(active, 0, active.getLayer().getParent().previous(layer));
ke.consume();
}
break;
case KeyEvent.VK_N:
if (0 == ke.getModifiers() && null != active && active.getClass() == Profile.class) {
display.duplicateLinkAndSendTo(active, 1, active.getLayer().getParent().next(layer));
ke.consume();
}
break;
case KeyEvent.VK_1:
case KeyEvent.VK_2:
case KeyEvent.VK_3:
case KeyEvent.VK_4:
case KeyEvent.VK_5:
case KeyEvent.VK_6:
case KeyEvent.VK_7:
case KeyEvent.VK_8:
case KeyEvent.VK_9:
// run a plugin, if any
if (null != Utils.launchTPlugIn(ke, "Display", display.getProject(), display.getActive())) {
ke.consume();
break;
}
}
if (!(keyCode == KeyEvent.VK_UNDEFINED || keyChar == KeyEvent.CHAR_UNDEFINED) && !ke.isConsumed() && null != active && active instanceof Patch) {
// TODO should allow forwarding for all, not just Patch
// forward to ImageJ for a final try
IJ.getInstance().keyPressed(ke);
repaint(active, 5);
ke.consume();
}
// Utils.log2("keyCode, keyChar: " + keyCode + ", " + keyChar + " ref: " + KeyEvent.VK_UNDEFINED + ", " + KeyEvent.CHAR_UNDEFINED);
}
Aggregations