use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class Graph method extractGraph.
public static final <T extends Displayable> Map<String, StringBuilder> extractGraph(final LayerSet ls, final Set<Class<T>> only) {
final StringBuilder sif = new StringBuilder(4096), xml = new StringBuilder(4096).append("<graph>\n"), names = new StringBuilder(4096);
final Set<Displayable> seen = new HashSet<Displayable>();
for (final Connector con : ls.getAll(Connector.class)) {
Set<Displayable> origins = con.getOrigins();
if (origins.isEmpty()) {
Utils.log("Graph: ignoring connector without origins: #" + con.getId());
continue;
}
List<Set<Displayable>> target_lists = con.getTargets();
if (target_lists.isEmpty()) {
Utils.log("Graph: ignoring connector without targets: #" + con.getId());
continue;
}
for (final Displayable origin : origins) {
if (Thread.currentThread().isInterrupted())
return null;
if (null != only && !only.contains(origin.getClass()))
continue;
seen.add(origin);
for (final Set<Displayable> targets : target_lists) {
for (final Displayable target : targets) {
if (null != only && !only.contains(target.getClass()))
continue;
sif.append(origin.getId()).append(" pd ").append(target.getId()).append('\n');
xml.append('\t').append("<edge cid=\"").append(con.getId()).append("\" origin=\"").append(origin.getId()).append("\" target=\"").append(target.getId()).append("\" />\n");
seen.add(target);
}
}
}
}
xml.append("</graph>\n");
for (final Displayable d : seen) {
names.append(d.getId()).append('\t').append(d.getProject().getMeaningfulTitle(d)).append('\n');
}
final Map<String, StringBuilder> m = new HashMap<String, StringBuilder>();
m.put("sif", sif);
m.put("xml", xml);
m.put("names", names);
return m;
}
use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class Display3D method getProfileContent.
/**
* Checks if the given Displayable is a Profile, and tries to find a possible Content object in the Image3DUniverse of its LayerSet according to the title as created from its profile_list ProjectThing.
*/
public static Content getProfileContent(final Displayable d) {
if (null == d)
return null;
if (d.getClass() != Profile.class)
return null;
final Display3D d3d = get(d.getLayer().getParent());
if (null == d3d)
return null;
ProjectThing pt = d.getProject().findProjectThing(d);
if (null == pt)
return null;
pt = (ProjectThing) pt.getParent();
return d3d.universe.getContent(new StringBuilder(pt.toString()).append(" #").append(pt.getId()).toString());
}
use of ini.trakem2.display.Displayable 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);
}
use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class Layer method exportXML.
@Override
public void exportXML(final StringBuilder sb_body, final String indent, final XMLOptions options) {
final String in = indent + "\t";
// 1 - open tag
sb_body.append(indent).append("<t2_layer oid=\"").append(id).append("\"\n").append(in).append(" thickness=\"").append(thickness).append("\"\n").append(in).append(" z=\"").append(z).append("\"\n");
// TODO this search is linear!
final LayerThing lt = project.findLayerThing(this);
String title;
if (null == lt)
title = null;
else
title = lt.getTitle();
if (null == title)
title = "";
// TODO 'title' should be a property of the Layer, not the LayerThing. Also, the LayerThing should not exist: LayerSet and Layer should be directly presentable in a tree. They are not Things as in "objects of the sample", but rather, structural necessities such as Patch.
sb_body.append(in).append(" title=\"").append(title).append("\"\n");
sb_body.append(indent).append(">\n");
// 2 - export children
if (null != al_displayables) {
for (final Displayable d : al_displayables) {
d.exportXML(sb_body, in, options);
}
}
// 3 - close tag
sb_body.append(indent).append("</t2_layer>\n");
}
use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class Project method removeAll.
/**
* Remove any set of Displayable objects from the Layer, LayerSet and Project Tree as necessary.
* ASSUMES there aren't any nested LayerSet objects in @param col.
*/
public final boolean removeAll(final Set<Displayable> col, final DefaultMutableTreeNode top_node) {
// 0. Sort into Displayable and ZDisplayable
final Set<ZDisplayable> zds = new HashSet<ZDisplayable>();
final List<Displayable> ds = new ArrayList<Displayable>();
for (final Displayable d : col) {
if (d instanceof ZDisplayable) {
zds.add((ZDisplayable) d);
} else {
ds.add(d);
}
}
// Displayable:
// 1. First the Profile from the Project Tree, one by one,
// while creating a map of Layer vs Displayable list to remove in that layer:
final HashMap<Layer, Set<Displayable>> ml = new HashMap<Layer, Set<Displayable>>();
for (final Iterator<Displayable> it = ds.iterator(); it.hasNext(); ) {
final Displayable d = it.next();
if (d.getClass() == Profile.class) {
if (!project_tree.remove(false, findProjectThing(d), null)) {
// like Profile.remove2
Utils.log("Could NOT delete " + d);
continue;
}
// remove the Profile
it.remove();
continue;
}
// The map of Layer vs Displayable list
Set<Displayable> l = ml.get(d.getLayer());
if (null == l) {
l = new HashSet<Displayable>();
ml.put(d.getLayer(), l);
}
l.add(d);
}
// 2. Then the rest, in bulk:
if (ml.size() > 0) {
for (final Map.Entry<Layer, Set<Displayable>> e : ml.entrySet()) {
e.getKey().removeAll(e.getValue());
}
}
// 3. Stacks
if (zds.size() > 0) {
final Set<ZDisplayable> stacks = new HashSet<ZDisplayable>();
for (final Iterator<ZDisplayable> it = zds.iterator(); it.hasNext(); ) {
final ZDisplayable zd = it.next();
if (zd.getClass() == Stack.class) {
it.remove();
stacks.add(zd);
}
}
layer_set.removeAll(stacks);
}
// 4. ZDisplayable: bulk removal
if (zds.size() > 0) {
// 1. From the Project Tree:
Set<Displayable> not_removed = project_tree.remove(zds, top_node);
// 2. Then only those successfully removed, from the LayerSet:
zds.removeAll(not_removed);
layer_set.removeAll(zds);
}
// TODO
return true;
}
Aggregations