|
What this is
Other links
The source code
// $Id: SelectionWButtons.java,v 1.8 2004/09/10 20:05:30 mvw Exp $
// Copyright (c) 1996-2004 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies. This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason. IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
// File: SelectionWButtons.java
// Classes: SelectionWButtons
// Original Author: jrobbins@ics.uci.edu
// $Id: SelectionWButtons.java,v 1.8 2004/09/10 20:05:30 mvw Exp $
package org.argouml.uml.diagram.ui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import org.tigris.gef.base.Editor;
import org.tigris.gef.base.Globals;
import org.tigris.gef.base.LayerPerspective;
import org.tigris.gef.base.ModeManager;
import org.tigris.gef.base.ModeModify;
import org.tigris.gef.base.SelectionManager;
import org.tigris.gef.graph.GraphModel;
import org.tigris.gef.graph.GraphNodeRenderer;
import org.tigris.gef.graph.MutableGraphModel;
import org.tigris.gef.presentation.Fig;
import org.tigris.gef.presentation.FigEdge;
import org.tigris.gef.presentation.FigPoly;
import org.tigris.gef.presentation.Handle;
/**
*
*
*/
public abstract class SelectionWButtons extends SelectionNodeClarifiers {
////////////////////////////////////////////////////////////////
// constants
private static final int IMAGE_SIZE = 22;
private static final int MARGIN = 2;
private static final Color PRESSED_COLOR = Color.gray.brighter();
/**
* The maximum number of tries to place a fig.
*/
private static final int MAX_PLACINGS = 1;
////////////////////////////////////////////////////////////////
// static variables
private static int numButtonClicks = 0;
private static boolean showRapidButtons = true;
////////////////////////////////////////////////////////////////
// instance variables
private boolean paintButtons = true;
private int pressedButton = -1;
/**
* Counter for counting the number of times there has been a try to place
* a fig.
*/
private int placeCounter = 0;
////////////////////////////////////////////////////////////////
// constructors
/**
* Construct a new SelectionWButtons for the given Fig.
*
* @param f The given Fig.
*/
public SelectionWButtons(Fig f) {
super(f);
paintButtons = showRapidButtons;
}
////////////////////////////////////////////////////////////////
// static accessors
/**
* toggle ShowRapidButtons
*/
public static void toggleShowRapidButtons() {
showRapidButtons = !showRapidButtons;
}
////////////////////////////////////////////////////////////////
// interaction utility methods
/**
* @param x x of the selection button icon
* @param y y of the selection button icon
* @param w width of the selection button icon
* @param h height of the selection button icon
* @param r outer rectangle of the fig
* @return true if the selection button above the fig was clicked
*/
public boolean hitAbove(int x, int y, int w, int h, Rectangle r) {
return intersectsRect(r, x - w / 2, y - h - MARGIN, w, h + MARGIN);
}
/**
* @param x x of the selection button icon
* @param y y of the selection button icon
* @param w width of the selection button icon
* @param h height of the selection button icon
* @param r outer rectangle of the fig
* @return true if the selection button below the fig was clicked
*/
public boolean hitBelow(int x, int y, int w, int h, Rectangle r) {
return intersectsRect(r, x - w / 2, y, w, h + MARGIN);
}
/**
* @param x x of the selection button icon
* @param y y of the selection button icon
* @param w width of the selection button icon
* @param h height of the selection button icon
* @param r outer rectangle of the fig
* @return true if the selection button left from the fig was clicked
*/
public boolean hitLeft(int x, int y, int w, int h, Rectangle r) {
return intersectsRect(r, x, y - h / 2, w + MARGIN, h);
}
/**
* @param x x of the selection button icon
* @param y y of the selection button icon
* @param w width of the selection button icon
* @param h height of the selection button icon
* @param r outer rectangle of the fig
* @return true if the selection button right from the fig was clicked
*/
public boolean hitRight(int x, int y, int w, int h, Rectangle r) {
return intersectsRect(r, x - w - MARGIN, y - h / 2, w + MARGIN, h);
}
/**
* @param x x of rectangle 2
* @param y y of rectangle 2
* @param w width of rectangle 2
* @param h height of rectangle 2
* @param r rectangle 1
* @return true if rectangle 1 intersects with the rectangle 2
*/
public boolean intersectsRect(Rectangle r, int x, int y, int w, int h) {
return !(
(r.x + r.width <= x)
|| (r.y + r.height <= y)
|| (r.x >= x + w)
|| (r.y >= y + h));
}
////////////////////////////////////////////////////////////////
// display methods
/**
* Paint the handles at the four corners and midway along each edge
* of the bounding box.
*
* @param g The Graphics where we paint this.
*/
public void paint(Graphics g) {
super.paint(g);
if (!paintButtons)
return;
Editor ce = Globals.curEditor();
SelectionManager sm = ce.getSelectionManager();
if (sm.size() != 1)
return;
ModeManager mm = ce.getModeManager();
if (mm.includes(ModeModify.class) && pressedButton == -1)
return;
paintButtons(g);
}
/**
* Paint the handles at the four corners and midway along each edge
* of the bounding box.
*
* @param g The Graphics where to paint the buttons.
*/
public abstract void paintButtons(Graphics g);
/**
* @param i the icon to be painted
* @param g the graphics to draw on
* @param x x for the icon
* @param y y for the icon
* @param hi the button identifier
*/
public void paintButtonAbove(Icon i, Graphics g, int x, int y, int hi) {
paintButton(
i,
g,
x - i.getIconWidth() / 2,
y - i.getIconHeight() - MARGIN,
hi);
}
/**
* @param i the icon to be painted
* @param g the graphics to draw on
* @param x x for the icon
* @param y y for the icon
* @param hi the button identifier
*/
public void paintButtonBelow(Icon i, Graphics g, int x, int y, int hi) {
paintButton(i, g, x - i.getIconWidth() / 2, y + MARGIN, hi);
}
/**
* @param i the icon to be painted
* @param g the graphics to draw on
* @param x x for the icon
* @param y y for the icon
* @param hi the button identifier
*/
public void paintButtonLeft(Icon i, Graphics g, int x, int y, int hi) {
paintButton(i, g, x + MARGIN, y - i.getIconHeight() / 2, hi);
}
/**
* @param i the icon to be painted
* @param g the graphics to draw on
* @param x x for the icon
* @param y y for the icon
* @param hi the button identifier
*/
public void paintButtonRight(Icon i, Graphics g, int x, int y, int hi) {
paintButton(
i,
g,
x - i.getIconWidth() - MARGIN,
y - i.getIconHeight() / 2,
hi);
}
/**
* @param i the icon to be painted
* @param g the graphics to draw on
* @param x x for the icon
* @param y y for the icon
* @param hi the button identifier
*/
public void paintButton(Icon i, Graphics g, int x, int y, int hi) {
int w = i.getIconWidth() + 4;
int h = i.getIconHeight() + 4;
if (hi == pressedButton) {
g.setColor(PRESSED_COLOR);
g.fillRect(x - 2, y - 2, w, h);
}
i.paintIcon(null, g, x, y);
g.translate(x - 2, y - 2);
Color handleColor = Globals.getPrefs().handleColorFor(_content);
g.setColor(handleColor.darker());
g.drawRect(0, 0, w - 2, h - 2);
g.setColor(handleColor.brighter().brighter().brighter());
if (hi != pressedButton) {
g.drawLine(1, h - 3, 1, 1);
g.drawLine(1, 1, w - 3, 1);
}
g.drawLine(0, h - 1, w - 1, h - 1);
g.drawLine(w - 1, h - 1, w - 1, 0);
g.translate(-x + 2, -y + 2);
}
/**
* @see org.tigris.gef.base.Selection#getBounds()
*/
public Rectangle getBounds() {
return new Rectangle(
_content.getX() - IMAGE_SIZE * 2,
_content.getY() - IMAGE_SIZE * 2,
_content.getWidth() + IMAGE_SIZE * 4,
_content.getHeight() + IMAGE_SIZE * 4);
}
/** Dont show buttons while the user is moving the Class. Called
* from FigClass when it is translated. */
public void hideButtons() {
paintButtons = false;
}
/**
* @param buttonCode the button identifier
*/
public void buttonClicked(int buttonCode) {
if (buttonCode >= 10)
numButtonClicks++;
// get a new node (modelelement) that should be added
Object newNode = getNewNode(buttonCode);
Object owner = _content.getOwner();
// get the graphmodel
Editor ce = Globals.curEditor();
GraphModel gm = ce.getGraphModel();
if (!(gm instanceof MutableGraphModel))
return;
MutableGraphModel mgm = (MutableGraphModel) gm;
// check if it is possible to add the fig for the new node and
// create it if possible
if (!mgm.canAddNode(newNode))
return;
GraphNodeRenderer renderer = ce.getGraphNodeRenderer();
LayerPerspective lay =
(LayerPerspective) ce.getLayerManager().getActiveLayer();
Fig newFC = renderer.getFigNodeFor(gm, lay, newNode);
// calculate the position of the newly created fig.
Rectangle outputRect =
new Rectangle(
Math.max(0, _content.getX() - 200),
Math.max(0, _content.getY() - 200),
_content.getWidth() + 400,
_content.getHeight() + 400);
// handle the case that it is not a self association
if (buttonCode >= 10 && buttonCode <= 13) {
int x = 0;
int y = 0;
if (buttonCode == 10) {
// superclass
x = _content.getX();
y = Math.max(0, _content.getY() - 200);
} else if (buttonCode == 11) {
x = _content.getX();
y = _content.getY() + _content.getHeight() + 100;
} else if (buttonCode == 12) {
x = _content.getX() + _content.getWidth() + 100;
y = _content.getY();
} else if (buttonCode == 13) {
x = Math.max(0, _content.getX() - 200);
y = _content.getY();
}
// place the fig if it is not a selfassociation
if (!placeFig(newFC, lay, x, y, outputRect))
return;
}
// add the new node only if required, e.g. not when we add a
// self association
if (buttonCode != 14) {
ce.add(newFC);
mgm.addNode(newNode);
}
FigPoly edgeShape = new FigPoly();
if (buttonCode != 14) {
Point fcCenter = _content.center();
edgeShape.addPoint(fcCenter.x, fcCenter.y);
Point newFCCenter = newFC.center();
edgeShape.addPoint(newFCCenter.x, newFCCenter.y);
} else {
newFC = _content;
Point fcCenter = _content.center();
Point centerRight =
new Point(
(int) (fcCenter.x
+ _content.getSize().getWidth() / 2),
fcCenter.y);
int yoffset = (int) ((_content.getSize().getHeight() / 2));
edgeShape.addPoint(fcCenter.x, fcCenter.y);
edgeShape.addPoint(centerRight.x, centerRight.y);
edgeShape.addPoint(centerRight.x + 30, centerRight.y);
edgeShape.addPoint(centerRight.x + 30, centerRight.y + yoffset);
edgeShape.addPoint(centerRight.x, centerRight.y + yoffset);
}
// create the new edge (modelelement) between newNode and the
// owner of _content
Object newEdge = null;
if (buttonCode == 10) newEdge = createEdgeAbove(mgm, newNode);
else if (buttonCode == 11) newEdge = createEdgeUnder(mgm, newNode);
else if (buttonCode == 12) newEdge = createEdgeRight(mgm, newNode);
else if (buttonCode == 13) newEdge = createEdgeLeft(mgm, newNode);
else if (buttonCode == 14) newEdge = createEdgeToSelf(mgm);
// place the edge on the layer and update the diagram
FigEdge fe = (FigEdge) lay.presentationFor(newEdge);
fe.setBetweenNearestPoints(true);
edgeShape.setLineColor(Color.black);
edgeShape.setFilled(false);
edgeShape._isComplete = true;
fe.setFig(edgeShape);
newFC.damage();
ce.getSelectionManager().select(fe);
ce.getSelectionManager().select(_content);
}
////////////////////////////////////////////////////////////////
// event handlers
/**
* @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
*/
public void mousePressed(MouseEvent me) {
Handle h = new Handle(-1);
hitHandle(me.getX(), me.getY(), 0, 0, h);
pressedButton = h.index;
Editor ce = Globals.curEditor();
ce.damaged(this);
}
/**
* @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
*/
public void mouseReleased(MouseEvent me) {
if (pressedButton < 10)
return;
Handle h = new Handle(-1);
hitHandle(me.getX(), me.getY(), 0, 0, h);
if (pressedButton == h.index) {
buttonClicked(pressedButton);
me.consume();
}
pressedButton = -1;
Editor ce = Globals.curEditor();
ce.damaged(this);
}
/**
* @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
*/
public void mouseEntered(MouseEvent me) {
super.mouseEntered(me);
if (showRapidButtons)
paintButtons = true;
Editor ce = Globals.curEditor();
ce.damaged(this);
}
/**
* @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
*/
public void mouseExited(MouseEvent me) {
super.mouseExited(me);
paintButtons = false;
Editor ce = Globals.curEditor();
ce.damaged(this);
}
/**
* Places a fig on the canvas in the correct position. Takes a
* coordinate pair x,y and a rectangle that should be avoided
* because there can be other figures. If the place action results
* in x.y coordinates for the fig to place that are not allowed
* (beyond the borders of the diagram), the operation is repeated
* with corrected parameters. If it is not possible to add the fig
* because there are allready to many figs, false is returned and
* the fig is not added.
* @param figToPlace The figure one wishes to place on a diagram
* @param layerToPlaceOn The layer that contains the figs
* @param x The x coordinate where one wishes to place the fig
* @param y The y coordinate where one wishes to place the fig
* @param bumpRect The rectangle that should be avoided since
* there can be other figs.
* @return boolean false if the fig is not placed.
*/
protected boolean placeFig(
Fig figToPlace,
LayerPerspective layerToPlaceOn,
int x,
int y,
Rectangle bumpRect) {
if (placeCounter > MAX_PLACINGS)
return false;
// to prevent outofmemory errors and stackoverflow errors
placeCounter++;
figToPlace.setLocation(x, y);
layerToPlaceOn.bumpOffOtherNodesIn(figToPlace, bumpRect, false, false);
if (figToPlace.getX() < 0) {
return placeFig(
figToPlace,
layerToPlaceOn,
((Fig) _content).getX()
+ ((Fig) _content).getWidth()
+ figToPlace.getWidth()
+ 100,
figToPlace.getY(),
bumpRect);
} else if (figToPlace.getX() + figToPlace.getWidth() >= 6000) {
return placeFig(
figToPlace,
layerToPlaceOn,
(((Fig) _content).getX()
- figToPlace.getWidth()
- 100),
figToPlace.getY(),
bumpRect);
} else if (figToPlace.getY() + figToPlace.getHeight() >= 6000) {
return placeFig(
figToPlace,
layerToPlaceOn,
figToPlace.getX(),
(((Fig) _content).getY()
- figToPlace.getHeight()
- 100),
bumpRect);
} else if (figToPlace.getY() < 0) {
return placeFig(
figToPlace,
layerToPlaceOn,
figToPlace.getX(),
((Fig) _content).getY()
+ ((Fig) _content).getHeight()
+ figToPlace.getHeight()
+ 100,
bumpRect);
}
return true;
}
/**
* Implementors should return a new node for adding via the buttons.
*
* @param buttonCode the code (identifier) for the selection button
* that was hit
* @return a newly created UML element
*/
protected abstract Object getNewNode(int buttonCode);
/**
* Subclasses should override this method if they want to provide
* a quickbutton above the _content fig. This method returns the
* edge (modelelement) that should be drawn in the case such a
* quickbutton was pressed.
* @param gm the graphmodel
* @param newNode The node (modelelement) created by pressing the
* quickbutton
* @return Object The new edge
*/
protected Object createEdgeAbove(MutableGraphModel gm, Object newNode) {
return null;
}
/**
* Subclasses should override this method if they want to provide
* a quickbutton at the left of the _content fig. This method
* returns the edge (modelelement) that should be drawn in the
* case such a quickbutton was pressed.
* @param gm the graphmodel
* @param newNode The node (modelelement) created by pressing the
* quickbutton
* @return Object The new edge
*/
protected Object createEdgeLeft(MutableGraphModel gm, Object newNode) {
return null;
}
/**
* Subclasses should override this method if they want to provide
* a quickbutton at the right of the _content fig. This method
* returns the edge (modelelement) that should be drawn in the
* case such a quickbutton was pressed.
* @param gm the graphmodel
* @param newNode The node (modelelement) created by pressing the
* quickbutton
* @return Object The new edge
*/
protected Object createEdgeRight(MutableGraphModel gm, Object newNode) {
return null;
}
/**
* Subclasses should override this method if they want to provide
* a quickbutton under the _content fig. This method returns the
* edge (modelelement) that should be drawn in the case such a
* quickbutton was pressed.
* @param gm the graphmodel
* @param newNode The node (modelelement) created by pressing the
* quickbutton
* @return Object The new edge
*/
protected Object createEdgeUnder(MutableGraphModel gm, Object newNode) {
return null;
}
/**
* Subclasses should override this method if they want to provide
* a quickbutton for selfassociation. This method returns the edge
* (modelelement) that should be drawn in the case such a
* quickbutton was pressed.
* @param gm the graphmodel
* @return Object The new edge
*/
protected Object createEdgeToSelf(MutableGraphModel gm) {
return null;
}
/**
* @param paint The _paintButtons to set.
*/
protected void setPaintButtons(boolean paint) {
this.paintButtons = paint;
}
/**
* @return Returns the _paintButtons.
*/
protected boolean isPaintButtons() {
return paintButtons;
}
/**
* @param pressed the identifier for the pressed Button
*/
protected void setPressedButton(int pressed) {
this.pressedButton = pressed;
}
/**
* @return Returns the identifier for the pressed Button.
*/
protected int getPressedButton() {
return pressedButton;
}
} /* end class SelectionWButtons */
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.