protected void updateHoverHandles(@Nullable DrawingView view, @Nullable Figure f) { if (f != hoverFigure) { Rectangle r = null; if (hoverFigure != null && hoverFigure.isSelectable()) { for (Handle h : hoverHandles) { if (r == null) { r = h.getDrawingArea(); } else { r.add(h.getDrawingArea()); } h.setView(null); h.dispose(); } hoverHandles.clear(); } hoverFigure = f; if (hoverFigure != null) { hoverHandles.addAll(hoverFigure.createHandles(-1)); for (Handle h : hoverHandles) { h.setView(view); if (r == null) { r = h.getDrawingArea(); } else { r.add(h.getDrawingArea()); } } } if (r != null) { r.grow(1, 1); fireAreaInvalidated(r); } } }
/** * Creates toolbars for the application. This class always returns an empty list. Subclasses may * return other values. */ @Override public List<JToolBar> createToolBars(Application a, @Nullable View pr) { ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels"); DrawView p = (DrawView) pr; DrawingEditor editor; if (p == null) { editor = getSharedEditor(); } else { editor = p.getEditor(); } LinkedList<JToolBar> list = new LinkedList<JToolBar>(); JToolBar tb; tb = new JToolBar(); addCreationButtonsTo(tb, editor); tb.setName(labels.getString("window.drawToolBar.title")); list.add(tb); tb = new JToolBar(); ButtonFactory.addAttributesButtonsTo(tb, editor); tb.setName(labels.getString("window.attributesToolBar.title")); list.add(tb); tb = new JToolBar(); ButtonFactory.addAlignmentButtonsTo(tb, editor); tb.setName(labels.getString("window.alignmentToolBar.title")); list.add(tb); return list; }
public Collection<Handle> createHandles(SVGPathFigure pathFigure, int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); switch (detailLevel % 2) { case 0: for (int i = 0, n = path.size(); i < n; i++) { handles.add(new BezierNodeHandle(this, i, pathFigure)); } break; case 1: TransformHandleKit.addTransformHandles(this, handles); break; default: break; } return handles; }
public static Collection<Action> createSelectionActions(DrawingEditor editor) { LinkedList<Action> a = new LinkedList<Action>(); a.add(new DuplicateAction()); a.add(null); // separator a.add(new GroupAction(editor, new SVGGroupFigure())); a.add(new UngroupAction(editor, new SVGGroupFigure())); a.add(new CombineAction(editor)); a.add(new SplitAction(editor)); a.add(null); // separator a.add(new BringToFrontAction(editor)); a.add(new SendToBackAction(editor)); return a; }
@Override public void draw(Graphics2D g) { if (hoverHandles.size() > 0 && !getView().isFigureSelected(hoverFigure)) { for (Handle h : hoverHandles) { h.draw(g); } } }
@Override public Collection<Action> getActions(Point2D.Double p) { LinkedList<Action> actions = new LinkedList<Action>(); if (get(TRANSFORM) != null) { ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.samples.odg.Labels"); actions.add( new AbstractAction(labels.getString("edit.removeTransform.text")) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent evt) { willChange(); fireUndoableEditHappened(TRANSFORM.setUndoable(ODGAttributedFigure.this, null)); changed(); } }); } return actions; }
private Drawing createDrawing() { DefaultDrawing drawing = new DefaultDrawing(); LinkedList<InputFormat> inputFormats = new LinkedList<InputFormat>(); inputFormats.add(new SVGInputFormat()); inputFormats.add(new SVGZInputFormat()); inputFormats.add(new ImageInputFormat(new SVGImageFigure())); inputFormats.add(new TextInputFormat(new SVGTextFigure())); LinkedList<OutputFormat> outputFormats = new LinkedList<OutputFormat>(); outputFormats.add(new SVGOutputFormat()); outputFormats.add(new ImageOutputFormat()); drawing.setInputFormats(inputFormats); drawing.setOutputFormats(outputFormats); return drawing; }
public Collection<Handle> createHandles(int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); switch (detailLevel % 2) { case -1: // Mouse hover handles handles.add(new BoundsOutlineHandle(this, false, true)); break; case 0: handles.add(new BoundsOutlineHandle(this)); handles.add(new MoveHandle(this, RelativeLocator.northWest())); handles.add(new MoveHandle(this, RelativeLocator.northEast())); handles.add(new MoveHandle(this, RelativeLocator.southWest())); handles.add(new MoveHandle(this, RelativeLocator.southEast())); handles.add(new FontSizeHandle(this)); handles.add(new LinkHandle(this)); break; case 1: TransformHandleKit.addTransformHandles(this, handles); break; } return handles; }
public static List<BezierPath> fromPathData(String str) throws IOException { LinkedList<BezierPath> paths = new LinkedList<BezierPath>(); BezierPath path = null; Point2D.Double p = new Point2D.Double(); Point2D.Double c1 = new Point2D.Double(); Point2D.Double c2 = new Point2D.Double(); StreamTokenizer tt = new StreamTokenizer(new StringReader(str)); tt.resetSyntax(); tt.parseNumbers(); tt.whitespaceChars(0, ' '); tt.whitespaceChars(',', ','); char nextCommand = 'M'; char command = 'M'; while (tt.nextToken() != StreamTokenizer.TT_EOF) { if (tt.ttype > 0) { command = (char) tt.ttype; } else { command = nextCommand; tt.pushBack(); } BezierPath.Node node; switch (command) { // moveto case 'M': if (path != null) { paths.add(path); } path = new BezierPath(); if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.moveTo(p.x, p.y); nextCommand = 'L'; break; case 'm': if (path != null) { paths.add(path); } path = new BezierPath(); if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.moveTo(p.x, p.y); nextCommand = 'l'; // close path break; case 'Z': case 'z': p.x = path.get(0).x[0]; p.y = path.get(0).y[0]; path.setClosed(true); // lineto break; case 'L': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.lineTo(p.x, p.y); nextCommand = 'L'; break; case 'l': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.lineTo(p.x, p.y); nextCommand = 'l'; break; case 'H': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; path.lineTo(p.x, p.y); nextCommand = 'H'; break; case 'h': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; path.lineTo(p.x, p.y); nextCommand = 'h'; break; case 'V': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.lineTo(p.x, p.y); nextCommand = 'V'; break; case 'v': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.lineTo(p.x, p.y); nextCommand = 'v'; // curveto break; case 'C': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.y = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.y = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.curveTo(c1.x, c1.y, c2.x, c2.y, p.x, p.y); nextCommand = 'C'; break; case 'c': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.x = p.x + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.y = p.y + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.x = p.x + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.y = p.y + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.curveTo(c1.x, c1.y, c2.x, c2.y, p.x, p.y); nextCommand = 'c'; break; case 'S': node = path.get(path.size() - 1); c1.x = node.x[0] * 2d - node.x[1]; c1.y = node.y[0] * 2d - node.y[1]; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.y = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.curveTo(c1.x, c1.y, c2.x, c2.y, p.x, p.y); nextCommand = 'S'; break; case 's': node = path.get(path.size() - 1); c1.x = node.x[0] * 2d - node.x[1]; c1.y = node.y[0] * 2d - node.y[1]; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.x = p.x + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c2.y = p.y + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.curveTo(c1.x, c1.y, c2.x, c2.y, p.x, p.y); nextCommand = 's'; // quadto break; case 'Q': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.y = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.quadTo(c1.x, c1.y, p.x, p.y); nextCommand = 'Q'; break; case 'q': if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.x = p.x + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); c1.y = p.y + tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.quadTo(c1.x, c1.y, p.x, p.y); nextCommand = 'q'; break; case 'T': node = path.get(path.size() - 1); c1.x = node.x[0] * 2d - node.x[1]; c1.y = node.y[0] * 2d - node.y[1]; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x = tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y = tt.nval; path.quadTo(c1.x, c1.y, p.x, p.y); nextCommand = 'T'; break; case 't': node = path.get(path.size() - 1); c1.x = node.x[0] * 2d - node.x[1]; c1.y = node.y[0] * 2d - node.y[1]; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.x += tt.nval; if (tt.nextToken() != StreamTokenizer.TT_NUMBER) throw new IOException("Number expected"); p.y += tt.nval; path.quadTo(c1.x, c1.y, p.x, p.y); nextCommand = 's'; break; default: throw new IOException("Illegal command: " + command); } } if (path != null) { paths.add(path); } return paths; }