/*******************************************************************************
* Copyright (c) 2006-2012
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Berlin, Germany
* - initial API and implementation
******************************************************************************/
/*
* @(#)ODGBezierFigure.java 1.0 2007-07-28
*
* Copyright (c) 2007 by the original authors of JHotDraw
* and all its contributors.
* All rights reserved.
*
* The copyright of this software is owned by the authors and
* contributors of the JHotDraw project ("the copyright holders").
* You may not use, copy or modify this software, except in
* accordance with the license agreement you entered into with
* the copyright holders. For details see accompanying license terms.
*/
package org.jhotdraw.samples.odg.figures;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.undo.*;
import org.jhotdraw.draw.*;
import org.jhotdraw.geom.*;
import static org.jhotdraw.samples.odg.ODGAttributeKeys.*;
/**
* ODGBezierFigure is not an actual ODG element, it is used by ODGPathFigure to
* represent a single BezierPath segment within an ODG path.
*
* @author Werner Randelshofer
* @version 1.0 2007-07-28 Created.
*/
public class ODGBezierFigure extends BezierFigure {
private transient Rectangle2D.Double cachedDrawingArea;
/** Creates a new instance. */
public ODGBezierFigure() {
this(false);
}
public ODGBezierFigure(boolean isClosed) {
super(isClosed);
FILL_OPEN_PATH.basicSet(this, true);
}
public Collection<Handle> createHandles(ODGPathFigure 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;
}
@Override public boolean handleMouseClick(Point2D.Double p, MouseEvent evt, DrawingView view) {
if (evt.getClickCount() == 2/* && view.getHandleDetailLevel() == 0*/) {
willChange();
final int index = splitSegment(p, (float) (5f / view.getScaleFactor()));
if (index != -1) {
final BezierPath.Node newNode = getNode(index);
fireUndoableEditHappened(new AbstractUndoableEdit() {
public void redo() throws CannotRedoException {
super.redo();
willChange();
addNode(index, newNode);
changed();
}
public void undo() throws CannotUndoException {
super.undo();
willChange();
removeNode(index);
changed();
}
});
changed();
evt.consume();
return true;
}
}
return false;
}
public void transform(AffineTransform tx) {
if (TRANSFORM.get(this) != null ||
(tx.getType() & (AffineTransform.TYPE_TRANSLATION)) != tx.getType()) {
if (TRANSFORM.get(this) == null) {
TRANSFORM.basicSetClone(this, tx);
} else {
AffineTransform t = TRANSFORM.getClone(this);
t.preConcatenate(tx);
TRANSFORM.basicSet(this, t);
}
} else {
super.transform(tx);
}
}
public Rectangle2D.Double getDrawingArea() {
if (cachedDrawingArea == null) {
if (TRANSFORM.get(this) == null) {
cachedDrawingArea = path.getBounds2D();
} else {
BezierPath p2 = (BezierPath) path.clone();
p2.transform(TRANSFORM.get(this));
cachedDrawingArea = p2.getBounds2D();
}
}
return (Rectangle2D.Double) cachedDrawingArea.clone();
}
/**
* Transforms all coords of the figure by the current TRANSFORM attribute
* and then sets the TRANSFORM attribute to null.
*/
public void flattenTransform() {
if (TRANSFORM.get(this) != null) {
path.transform(TRANSFORM.get(this));
TRANSFORM.basicSet(this, null);
}
invalidate();
}
public void invalidate() {
super.invalidate();
cachedDrawingArea = null;
}
}