/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.mindmap; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.xmind.gef.draw2d.ReferencedFigure; import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; import org.xmind.gef.draw2d.geometry.PrecisionPoint; import org.xmind.gef.draw2d.geometry.PrecisionTransposer; import org.xmind.gef.draw2d.geometry.PrecisionVerticalFlipper; import org.xmind.gef.draw2d.graphics.Path; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.resources.ColorUtils; class RangeMoveHandleFigure extends ReferencedFigure { private static final int PREF_MIN_WIDTH = 16; private static final double RATIO = 0.7; private static final int HEIGHT = (MindMapUI.SELECTION_LINE_WIDTH + (int) Math .ceil(PREF_MIN_WIDTH * RATIO / 4)) * 2; private static final int LINE_WIDTH = 2; private static final double CORNER_WIDTH = LINE_WIDTH * RATIO; private static PrecisionPoint p1 = new PrecisionPoint(); private static PrecisionPoint p2 = new PrecisionPoint(); private static PrecisionPoint p3 = new PrecisionPoint(); private static PrecisionPoint p4 = new PrecisionPoint(); private static PrecisionPoint p5 = new PrecisionPoint(); private static PrecisionPoint p6 = new PrecisionPoint(); private static PrecisionPoint p7 = new PrecisionPoint(); private static IPrecisionTransformer t = new PrecisionTransposer(); private static IPrecisionTransformer v = new PrecisionVerticalFlipper(); private int orientation; private int alpha = 0xff; public RangeMoveHandleFigure(int orientation) { this.orientation = orientation; // int width = LINE_WIDTH;//vertical ? 17 : 7; // int height = LINE_WIDTH; //vertical ? 7 : 17; // setSize(width, height); // setPreferredSize(width, height); setForegroundColor(ColorUtils.getColor("#0033cc")); //$NON-NLS-1$ setBackgroundColor(ColorUtils.getColor("#90c8f0")); //$NON-NLS-1$ } public void setClientSize(Dimension client) { if (isVertical()) { int w = Math.min(client.width, Math.max(client.width / 2, PREF_MIN_WIDTH)); setPreferredSize(w, HEIGHT); setSize(w, HEIGHT); } else { int h = Math.min(client.height, Math.max(client.height / 2, PREF_MIN_WIDTH)); setPreferredSize(HEIGHT, h); setSize(HEIGHT, h); } } private boolean isVertical() { return (orientation & PositionConstants.NORTH_SOUTH) != 0; } public int getAlpha() { return alpha; } public void setAlpha(int alpha) { this.alpha = alpha; repaint(); } protected void paintFigure(Graphics graphics) { super.paintFigure(graphics); graphics.setAntialias(SWT.ON); graphics.setAlpha(getAlpha()); graphics.setLineWidth(1); graphics.setLineStyle(SWT.LINE_SOLID); Path shape = new Path(Display.getCurrent()); createShape2(shape); graphics.fillPath(shape); graphics.drawPath(shape); shape.dispose(); } protected void createShape2(Path shape) { Rectangle r = getBounds(); p1.setLocation(r.x, r.y); p6.setLocation(r.right(), r.bottom()); t.setEnabled((orientation & PositionConstants.EAST_WEST) != 0); v.setEnabled((orientation & PositionConstants.SOUTH_EAST) != 0); t.setOrigin((p1.x + p6.x) / 2, (p1.y + p6.y) / 2); v.setOrigin(t.getOrigin()); v.t(t.t(p1)); v.t(t.t(p6)); if (p6.x < p1.x) { double temp = p1.x; p1.x = p6.x; p6.x = temp; } if (p6.y < p1.y) { double temp = p1.y; p1.y = p6.y; p6.y = temp; } p6.y = (p6.y + p1.y) / 2; p1.y = p6.y - LINE_WIDTH; double width = p6.x - p1.x; double a; if (width < PREF_MIN_WIDTH) { a = width / 4; } else { a = PREF_MIN_WIDTH / 4; } double b = a * RATIO; double c = p1.x + width / 2; p2.setLocation(c - a, p1.y); p3.setLocation(c, p1.y - b); p4.setLocation(c + a, p1.y); p5.setLocation(p6.x, p1.y); p7.setLocation(p1.x, p6.y); double d = Math.min(CORNER_WIDTH, (width - a * 2) / 2); p1.x += d; p5.x -= d; t.r(v.r(p1)); t.r(v.r(p2)); t.r(v.r(p3)); t.r(v.r(p4)); t.r(v.r(p5)); t.r(v.r(p6)); t.r(v.r(p7)); shape.moveTo(p1); shape.lineTo(p2); shape.lineTo(p3); shape.lineTo(p4); shape.lineTo(p5); shape.lineTo(p6); shape.lineTo(p7); shape.close(); } protected void createShape1(Path shape) { Rectangle r = getBounds().getResized(-1, -1); switch (orientation) { case PositionConstants.NORTH: shape.moveTo(r.x, r.bottom()); shape.lineTo(r.x + r.width * 0.5f, r.y); shape.lineTo(r.right(), r.bottom()); shape.close(); break; case PositionConstants.SOUTH: shape.moveTo(r.x, r.y); shape.lineTo(r.right(), r.y); shape.lineTo(r.x + r.width * 0.5f, r.bottom()); shape.close(); break; case PositionConstants.EAST: shape.moveTo(r.x, r.y); shape.lineTo(r.right(), r.y + r.height * 0.5f); shape.lineTo(r.x, r.bottom()); shape.close(); break; case PositionConstants.WEST: shape.moveTo(r.right(), r.y); shape.lineTo(r.right(), r.bottom()); shape.lineTo(r.x, r.y + r.height * 0.5f); shape.close(); break; } } }