/*
* Created on 08-Feb-2004
*/
package pipe.controllers;
import pipe.constants.GUIConstants;
import pipe.gui.PetriNetTab;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
/**
* @author Peter Kyme, Michael Camacho
* Class to handle selection rectangle functionality
*/
@SuppressWarnings("serial")
public class SelectionManager extends javax.swing.JComponent
implements java.awt.event.MouseListener, java.awt.event.MouseWheelListener, java.awt.event.MouseMotionListener {
/**
* Color to paint selection highlighter
*/
private static final Color SELECTION_COLOR = new Color(0, 0, 255, 24);
/**
* Outline of the selection handeller
*/
private static final Color SELECTION_COLOR_OUTLINE = new Color(0, 0, 100);
/**
* Area of selection
*/
private final Rectangle selectionRectangle = new Rectangle(-1, -1);
/**
* Tab that selection is taking place on
*/
private final PetriNetTab petriNetTab;
/**
* Petri net controller for the underlying Petri net
*/
private final PetriNetController petriNetController;
/**
* Start point of selection
*/
private Point startPoint;
/**
* true if currently selecting items
*/
private boolean isSelecting;
/**
* Legacy enabled
*/
private boolean enabled = true;
/**
* Constructor
* @param controller Petri net controller
*/
public SelectionManager(PetriNetController controller) {
addMouseListener(this);
addMouseMotionListener(this);
addMouseWheelListener(this);
this.petriNetTab = controller.getPetriNetTab();
this.petriNetController = controller;
}
/**
* Enable the selection
*/
public void enableSelection() {
if (!enabled) {
petriNetTab.add(this);
enabled = true;
updateBounds();
}
}
/**
* Update the displayed selection rectangle bounds
*
* Used because there is no layout manager for the canvas
*/
public void updateBounds() {
if (enabled) {
setBounds(0, 0, petriNetTab.getWidth(), petriNetTab.getHeight());
}
}
/**
* Disable the selected items
*/
public void disableSelection() {
if (enabled) {
petriNetTab.remove(this);
enabled = false;
}
}
/**
* Paint a blue rectangle over the selected area
* @param g graphics
*/
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(SELECTION_COLOR);
g2d.fill(selectionRectangle);
g2d.setPaint(SELECTION_COLOR_OUTLINE);
g2d.draw(selectionRectangle);
}
/**
* Update the selected area
* @param e mouse event
*/
@Override
public void mouseDragged(MouseEvent e) {
if (isSelecting) {
Point point = e.getPoint();
selectionRectangle.setSize((int) Math.abs(point.getX() - startPoint.getX()),
(int) Math.abs(point.getY() - startPoint.getY()));
selectionRectangle.setLocation((int) Math.min(startPoint.getX(), point.getX()),
(int) Math.min(startPoint.getY(), point.getY()));
// Select anything that intersects with the rectangle.
processSelection(e);
repaint();
} else {
handleOutOfBoundsDrag(e);
}
}
/**
* Select the items that interact with the selection area
* @param e mouse event
*/
private void processSelection(MouseEvent e) {
if (!e.isShiftDown()) {
clearSelection();
}
petriNetController.select(selectionRectangle);
}
/**
* Deselect all components
*/
public void clearSelection() {
petriNetController.deselectAll();
}
/**
* Noop
* @param e mouse event
*/
@Override
public void mouseMoved(MouseEvent e) {
// Not needed
}
/**
* Out of bounds drags are when the mouse has moved fast enough that they no longer
* contained in the object they are dragging. Since the SelectionManager spans the whole
* screen when in selection mode, it defaults back to this class with a call to drag
*
* @param e mouse drag event
*/
private void handleOutOfBoundsDrag(MouseEvent e) {
if (!e.isConsumed()) {
petriNetController.getDragManager().drag(e.getPoint());
}
}
/**
* Noop
* @param e mouse event
*/
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
// Not used
}
/**
* Noop
* @param e mouse event
*/
@Override
public void mouseClicked(MouseEvent e) {
// Not needed
}
/**
* Select all items falling within the selected area
* @param e mouse event
*/
@Override
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
if (e.getButton() == MouseEvent.BUTTON1 && !e.isControlDown()) {
isSelecting = true;
petriNetTab.setLayer(this, GUIConstants.SELECTION_LAYER_OFFSET);
selectionRectangle.setRect(startPoint.getX(), startPoint.getY(), 0, 0);
// Select anything that intersects with the rectangle.
processSelection(e);
repaint();
}
}
/**
*
* Reset the selection area
*
* @param e mouse event
*/
@Override
public void mouseReleased(MouseEvent e) {
if (isSelecting) {
// Select anything that intersects with the rectangle.
processSelection(e);
isSelecting = false;
petriNetTab.setLayer(this, GUIConstants.LOWEST_LAYER_OFFSET);
selectionRectangle.setRect(-1, -1, 0, 0);
repaint();
}
}
/**
* Noop
* @param e mouse event
*/
@Override
public void mouseEntered(MouseEvent e) {
// Not needed
}
/**
* Noop
* @param e mouse event
*/
@Override
public void mouseExited(MouseEvent e) {
// Not needed
}
}