/* VisualReferenceEditorMouseHandler.java created 2007-12-01
*
*/
package org.signalml.app.view.montage.visualreference;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
/** VisualReferenceEditorMouseHandler
*
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class VisualReferenceEditorMouseHandler extends MouseAdapter {
private VisualReferenceEditor editor;
private VisualReferenceModel model;
private Point dragStart = null;
private VisualReferenceSourceChannel draggedChannel;
private int pickupOffsetX;
private int pickupOffsetY;
private boolean dragVisible = false;
private int prospectiveDropChannel = -1;
private ArrayList<VisualReferenceArrow> tempArrowList = new ArrayList<VisualReferenceArrow>();
private VisualReferenceDraggedChannel draggedChannelComponent;
public VisualReferenceEditorMouseHandler(VisualReferenceEditor editor) {
this.editor = editor;
model = editor.getModel();
draggedChannelComponent = new VisualReferenceDraggedChannel(editor);
}
@Override
public void mousePressed(MouseEvent e) {
editor.requestFocusInWindow();
dragStart = e.getPoint();
draggedChannel = null;
setProspectiveDropChannel(-1);
}
@Override
public void mouseReleased(MouseEvent e) {
if (dragStart != null) {
hideDrag();
if (draggedChannel != null) {
if (prospectiveDropChannel >= 0) {
if (model.isBipolarMode()) {
model.addReference(prospectiveDropChannel, draggedChannel.getChannel());
model.setActiveChannel(null);
} else {
model.addReference(model.indexOfChannel(model.getActiveChannel()), draggedChannel.getChannel());
}
}
}
dragStart = null;
draggedChannel = null;
setProspectiveDropChannel(-1);
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (dragStart != null) {
Point point = e.getPoint();
boolean bipolarMode = model.isBipolarMode();
VisualReferenceChannel activeChannel = model.getActiveChannel();
if (!bipolarMode && activeChannel == null) {
dragStart = null;
return;
}
if (draggedChannel == null) {
draggedChannel = editor.findChannelAt(dragStart);
if (draggedChannel == null) {
dragStart = null;
return;
}
else if (activeChannel != null && draggedChannel == model.getSourceChannel(activeChannel.getPrimaryChannel())) {
dragStart = null;
return;
}
Point location = draggedChannel.getLocation();
pickupOffsetX = dragStart.x - location.x;
pickupOffsetY = dragStart.y - location.y;
draggedChannelComponent.setChannel(draggedChannel);
showDrag(point);
} else {
moveDrag(point);
}
VisualReferenceSourceChannel dropChannel = editor.findChannelAt(point);
if (dropChannel != null) {
if (activeChannel == null && bipolarMode && dropChannel != draggedChannel) {
setProspectiveDropChannel(dropChannel.getChannel());
}
else if (activeChannel != null && dropChannel != draggedChannel && dropChannel == model.getSourceChannel(activeChannel.getPrimaryChannel())) {
setProspectiveDropChannel(dropChannel.getChannel());
} else {
setProspectiveDropChannel(-1);
}
} else {
setProspectiveDropChannel(-1);
}
}
}
public int getProspectiveDropChannel() {
return prospectiveDropChannel;
}
public void setProspectiveDropChannel(int prospectiveDropChannel) {
if (this.prospectiveDropChannel != prospectiveDropChannel) {
this.prospectiveDropChannel = prospectiveDropChannel;
VisualReferenceArrow arrow = null;
if (prospectiveDropChannel >= 0) {
// note!!! in case of the "prospective" arrow the target index is that of a SOURCE channel
// at the given location
arrow = new VisualReferenceArrow(draggedChannel.getChannel(), prospectiveDropChannel);
}
editor.setProspectiveArrow(arrow);
}
}
private void moveDrag(Point point) {
if (dragVisible) {
JLayeredPane layeredPane = editor.getRootPane().getLayeredPane();
Point location = SwingUtilities.convertPoint(editor, point, layeredPane);
draggedChannelComponent.setLocation(location.x-pickupOffsetX, location.y-pickupOffsetY);
}
}
private void showDrag(Point point) {
if (!dragVisible) {
JLayeredPane layeredPane = editor.getRootPane().getLayeredPane();
Point location = SwingUtilities.convertPoint(editor, point, layeredPane);
Dimension size = draggedChannelComponent.getPreferredSize();
draggedChannelComponent.setBounds(location.x-pickupOffsetX, location.y-pickupOffsetY, size.width, size.height);
layeredPane.add(draggedChannelComponent, new Integer(JLayeredPane.DRAG_LAYER));
dragVisible = true;
}
}
private void hideDrag() {
if (dragVisible) {
JLayeredPane layeredPane = editor.getRootPane().getLayeredPane();
layeredPane.remove(draggedChannelComponent);
dragVisible = false;
editor.repaint();
}
}
@Override
public void mouseClicked(MouseEvent e) {
Point point = e.getPoint();
if (SwingUtilities.isLeftMouseButton(e)) {
VisualReferenceSourceChannel selChannel = editor.findChannelAt(point);
if (selChannel != null) {
// this was a click on a channel
int index = selChannel.getChannel();
VisualReferenceChannel oldActiveChannel = model.getActiveChannel();
VisualReferenceChannel newActiveChannel;
if (model.isChannelsPerPrimaryEmpty(index)) {
newActiveChannel = null;
}
else if (oldActiveChannel == null) {
newActiveChannel = model.getChannelPerPrimary(index, 0);
}
else if (oldActiveChannel.getPrimaryChannel() != index) {
newActiveChannel = model.getChannelPerPrimary(index, 0);
} else {
int oldActiveIndex = model.indexOfChannelPerPrimary(index, oldActiveChannel);
int newActiveIndex = (oldActiveIndex + 1) % model.channelsPerPrimarySize(index);
newActiveChannel = model.getChannelPerPrimary(index, newActiveIndex);
}
model.setActiveChannel(newActiveChannel);
return;
}
// check arrows, return if matches
editor.findArrowsAtPoint(point, tempArrowList);
if (!tempArrowList.isEmpty()) {
// this was a click on some arrows
VisualReferenceArrow oldActiveArrow = model.getActiveArrow();
VisualReferenceArrow newActiveArrow = null;
if (oldActiveArrow == null) {
newActiveArrow = tempArrowList.get(0);
} else {
int index = tempArrowList.indexOf(oldActiveArrow);
if (index < 0) {
index = -1;
}
index = (index + 1) % tempArrowList.size();
newActiveArrow = tempArrowList.get(index);
}
model.setActiveArrow(newActiveArrow);
return;
}
// if nothing was clicked
model.setActiveChannel(null);
}
}
}