visualizer plugin major update: support for zooming and panning, hiding window decorations, and a more powerful visualization skin api
This commit is contained in:
parent
b8e268e598
commit
23f13a2b6f
2 changed files with 440 additions and 198 deletions
|
@ -26,12 +26,18 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: Visualizer.java,v 1.9 2009/07/03 14:06:20 fros4943 Exp $
|
* $Id: Visualizer.java,v 1.10 2009/08/27 13:57:43 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Cursor;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.MouseInfo;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.datatransfer.DataFlavor;
|
import java.awt.datatransfer.DataFlavor;
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||||
|
@ -41,26 +47,59 @@ import java.awt.dnd.DropTargetDragEvent;
|
||||||
import java.awt.dnd.DropTargetDropEvent;
|
import java.awt.dnd.DropTargetDropEvent;
|
||||||
import java.awt.dnd.DropTargetEvent;
|
import java.awt.dnd.DropTargetEvent;
|
||||||
import java.awt.dnd.DropTargetListener;
|
import java.awt.dnd.DropTargetListener;
|
||||||
import java.awt.event.*;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.awt.event.ItemListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.JSeparator;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.ClassDescription;
|
||||||
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.Mote;
|
||||||
|
import se.sics.cooja.MoteInterface;
|
||||||
|
import se.sics.cooja.PluginType;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.GUI.MoteRelation;
|
import se.sics.cooja.GUI.MoteRelation;
|
||||||
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||||
import se.sics.cooja.interfaces.*;
|
import se.sics.cooja.interfaces.LED;
|
||||||
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
import se.sics.cooja.interfaces.SerialPort;
|
||||||
import se.sics.cooja.plugins.skins.AddressVisualizerSkin;
|
import se.sics.cooja.plugins.skins.AddressVisualizerSkin;
|
||||||
|
import se.sics.cooja.plugins.skins.GridVisualizerSkin;
|
||||||
import se.sics.cooja.plugins.skins.IDVisualizerSkin;
|
import se.sics.cooja.plugins.skins.IDVisualizerSkin;
|
||||||
import se.sics.cooja.plugins.skins.LEDVisualizerSkin;
|
import se.sics.cooja.plugins.skins.LEDVisualizerSkin;
|
||||||
import se.sics.cooja.plugins.skins.LogVisualizerSkin;
|
import se.sics.cooja.plugins.skins.LogVisualizerSkin;
|
||||||
|
import se.sics.cooja.plugins.skins.PositionVisualizerSkin;
|
||||||
|
import se.sics.cooja.plugins.skins.TrafficVisualizerSkin;
|
||||||
|
import se.sics.cooja.plugins.skins.UDGMVisualizerSkin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulation visualizer supporting visualization skins.
|
* Simulation visualizer supporting visualization skins.
|
||||||
|
@ -79,29 +118,30 @@ import se.sics.cooja.plugins.skins.LogVisualizerSkin;
|
||||||
@ClassDescription("Simulation visualizer")
|
@ClassDescription("Simulation visualizer")
|
||||||
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
||||||
public class Visualizer extends VisPlugin {
|
public class Visualizer extends VisPlugin {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(Visualizer.class);
|
private static Logger logger = Logger.getLogger(Visualizer.class);
|
||||||
|
|
||||||
private static final int CANVAS_BORDER_WIDTH = 25;
|
|
||||||
public static final int MOTE_RADIUS = 8;
|
public static final int MOTE_RADIUS = 8;
|
||||||
|
|
||||||
private static final Color[] DEFAULT_MOTE_COLORS = { Color.WHITE };
|
private static final Color[] DEFAULT_MOTE_COLORS = { Color.WHITE };
|
||||||
|
|
||||||
private GUI gui = null;
|
private GUI gui = null;
|
||||||
private Simulation simulation = null;
|
private Simulation simulation = null;
|
||||||
private final JPanel canvas;
|
private final JPanel canvas;
|
||||||
|
|
||||||
/* Transformation */
|
/* Viewport */
|
||||||
private double factorXCoordToPixel;
|
private AffineTransform viewportTransform;
|
||||||
private double factorYCoordToPixel;
|
public int resetViewport = 0;
|
||||||
private double smallestXCoord;
|
|
||||||
private double smallestYCoord;
|
|
||||||
|
|
||||||
/* Moving motes */
|
/* Actions: move motes, pan view, and zoom view */
|
||||||
private boolean moteIsBeingMoved = false;
|
private boolean panning = false;
|
||||||
private long moteMoveBeginTime = -1;
|
private Position panningPosition = null; /* Panning start position */
|
||||||
private Mote moteToMove = null;
|
private boolean zooming = false;
|
||||||
|
private double zoomStart = 0;
|
||||||
|
private Position zoomingPosition = null; /* Zooming center position */
|
||||||
|
private Point zoomingPixel = null; /* Zooming center pixel */
|
||||||
|
private boolean moving = false;
|
||||||
|
private Mote movedMote = null;
|
||||||
|
private long moveStartTime = -1;
|
||||||
private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
||||||
|
|
||||||
/* Visualizer skins */
|
/* Visualizer skins */
|
||||||
|
@ -114,6 +154,9 @@ public class Visualizer extends VisPlugin {
|
||||||
registerVisualizerSkin(AddressVisualizerSkin.class);
|
registerVisualizerSkin(AddressVisualizerSkin.class);
|
||||||
registerVisualizerSkin(LogVisualizerSkin.class);
|
registerVisualizerSkin(LogVisualizerSkin.class);
|
||||||
registerVisualizerSkin(LEDVisualizerSkin.class);
|
registerVisualizerSkin(LEDVisualizerSkin.class);
|
||||||
|
registerVisualizerSkin(TrafficVisualizerSkin.class);
|
||||||
|
registerVisualizerSkin(PositionVisualizerSkin.class);
|
||||||
|
registerVisualizerSkin(GridVisualizerSkin.class);
|
||||||
}
|
}
|
||||||
private ArrayList<VisualizerSkin> currentSkins = new ArrayList<VisualizerSkin>();
|
private ArrayList<VisualizerSkin> currentSkins = new ArrayList<VisualizerSkin>();
|
||||||
|
|
||||||
|
@ -127,14 +170,13 @@ public class Visualizer extends VisPlugin {
|
||||||
|
|
||||||
/* Popup menu */
|
/* Popup menu */
|
||||||
public static interface SimulationMenuAction {
|
public static interface SimulationMenuAction {
|
||||||
public boolean isEnabled(Simulation simulation);
|
public boolean isEnabled(Visualizer visualizer, Simulation simulation);
|
||||||
public String getDescription(Simulation simulation);
|
public String getDescription(Visualizer visualizer, Simulation simulation);
|
||||||
public void doAction(Visualizer visualizer, Simulation simulation);
|
public void doAction(Visualizer visualizer, Simulation simulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface MoteMenuAction {
|
public static interface MoteMenuAction {
|
||||||
public boolean isEnabled(Mote mote);
|
public boolean isEnabled(Visualizer visualizer, Mote mote);
|
||||||
public String getDescription(Mote mote);
|
public String getDescription(Visualizer visualizer, Mote mote);
|
||||||
public void doAction(Visualizer visualizer, Mote mote);
|
public void doAction(Visualizer visualizer, Mote mote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,14 +195,23 @@ public class Visualizer extends VisPlugin {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
public void paintComponent(Graphics g) {
|
public void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
paintSkinGeneric(g);
|
|
||||||
|
if (resetViewport > 0) {
|
||||||
|
resetViewport();
|
||||||
|
resetViewport--;
|
||||||
|
}
|
||||||
|
|
||||||
for (VisualizerSkin skin: currentSkins) {
|
for (VisualizerSkin skin: currentSkins) {
|
||||||
skin.paintSkin(g);
|
skin.paintBeforeMotes(g);
|
||||||
|
}
|
||||||
|
paintMotes(g);
|
||||||
|
for (VisualizerSkin skin: currentSkins) {
|
||||||
|
skin.paintAfterMotes(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
canvas.setBackground(Color.WHITE);
|
canvas.setBackground(Color.WHITE);
|
||||||
calculateTransformations();
|
viewportTransform = new AffineTransform();
|
||||||
|
|
||||||
/* Skin selector */
|
/* Skin selector */
|
||||||
skinButton.addActionListener(new ActionListener() {
|
skinButton.addActionListener(new ActionListener() {
|
||||||
|
@ -236,7 +287,6 @@ public class Visualizer extends VisPlugin {
|
||||||
/* Observe simulation and mote positions */
|
/* Observe simulation and mote positions */
|
||||||
posObserver = new Observer() {
|
posObserver = new Observer() {
|
||||||
public void update(Observable obs, Object obj) {
|
public void update(Observable obs, Object obj) {
|
||||||
calculateTransformations();
|
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -245,18 +295,21 @@ public class Visualizer extends VisPlugin {
|
||||||
Position pos = mote.getInterfaces().getPosition();
|
Position pos = mote.getInterfaces().getPosition();
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
pos.addObserver(posObserver);
|
pos.addObserver(posObserver);
|
||||||
}
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
calculateTransformations();
|
public void run() {
|
||||||
|
resetViewport = 1;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
public void moteWasRemoved(Mote mote) {
|
public void moteWasRemoved(Mote mote) {
|
||||||
Position pos = mote.getInterfaces().getPosition();
|
Position pos = mote.getInterfaces().getPosition();
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
pos.deleteObserver(posObserver);
|
pos.deleteObserver(posObserver);
|
||||||
}
|
|
||||||
calculateTransformations();
|
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
for (Mote mote: simulation.getMotes()) {
|
for (Mote mote: simulation.getMotes()) {
|
||||||
Position pos = mote.getInterfaces().getPosition();
|
Position pos = mote.getInterfaces().getPosition();
|
||||||
|
@ -264,8 +317,6 @@ public class Visualizer extends VisPlugin {
|
||||||
pos.addObserver(posObserver);
|
pos.addObserver(posObserver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
calculateTransformations();
|
|
||||||
repaint();
|
|
||||||
|
|
||||||
/* Observe mote highlights */
|
/* Observe mote highlights */
|
||||||
gui.addMoteHighlightObserver(moteHighligtObserver = new Observer() {
|
gui.addMoteHighlightObserver(moteHighligtObserver = new Observer() {
|
||||||
|
@ -310,49 +361,37 @@ public class Visualizer extends VisPlugin {
|
||||||
/* Popup menu */
|
/* Popup menu */
|
||||||
canvas.addMouseMotionListener(new MouseMotionListener() {
|
canvas.addMouseMotionListener(new MouseMotionListener() {
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
handleMoveRequest(e.getPoint().x, e.getPoint().y, false);
|
handleMouseMove(e, false);
|
||||||
}
|
}
|
||||||
public void mouseDragged(MouseEvent e) {
|
public void mouseDragged(MouseEvent e) {
|
||||||
handleMoveRequest(e.getPoint().x, e.getPoint().y, false);
|
handleMouseMove(e, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
canvas.addMouseListener(new MouseListener() {
|
canvas.addMouseListener(new MouseAdapter() {
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
if (e.isPopupTrigger()) {
|
if (e.isPopupTrigger()) {
|
||||||
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
||||||
} else if (SwingUtilities.isLeftMouseButton(e)){
|
return;
|
||||||
//handleMoveRequest(e.getPoint().x, e.getPoint().y, false);
|
}
|
||||||
beginMoveRequest(e.getPoint().x, e.getPoint().y);
|
|
||||||
|
if (SwingUtilities.isLeftMouseButton(e)){
|
||||||
|
handleMousePress(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
if (e.isPopupTrigger()) {
|
if (e.isPopupTrigger()) {
|
||||||
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
||||||
} else {
|
return;
|
||||||
handleMoveRequest(e.getPoint().x, e.getPoint().y, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void mouseEntered(MouseEvent e) {
|
|
||||||
if (e.isPopupTrigger()) {
|
|
||||||
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void mouseExited(MouseEvent e) {
|
|
||||||
if (e.isPopupTrigger()) {
|
|
||||||
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleMouseMove(e, true);
|
||||||
}
|
}
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
if (e.isPopupTrigger()) {
|
if (e.isPopupTrigger()) {
|
||||||
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
handlePopupRequest(e.getPoint().x, e.getPoint().y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addComponentListener(new ComponentAdapter() {
|
handleMouseMove(e, true);
|
||||||
public void componentResized(ComponentEvent ce) {
|
|
||||||
calculateTransformations();
|
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -364,7 +403,8 @@ public class Visualizer extends VisPlugin {
|
||||||
registerMoteMenuAction(DeleteMoteMenuAction.class);
|
registerMoteMenuAction(DeleteMoteMenuAction.class);
|
||||||
|
|
||||||
/* Register simulation menu actions */
|
/* Register simulation menu actions */
|
||||||
/* ... */
|
registerSimulationMenuAction(ResetViewportAction.class);
|
||||||
|
registerSimulationMenuAction(ToggleDecorationsMenuAction.class);
|
||||||
|
|
||||||
/* Drag and drop files to motes */
|
/* Drag and drop files to motes */
|
||||||
DropTargetListener dTargetListener = new DropTargetListener() {
|
DropTargetListener dTargetListener = new DropTargetListener() {
|
||||||
|
@ -469,7 +509,7 @@ public class Visualizer extends VisPlugin {
|
||||||
|
|
||||||
this.setSize(300, 300);
|
this.setSize(300, 300);
|
||||||
setLocation(gui.getDesktopPane().getWidth() - getWidth(), 0);
|
setLocation(gui.getDesktopPane().getWidth() - getWidth(), 0);
|
||||||
setVisible(true);
|
resetViewport = 3; /* XXX Quick-fix */
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateAndActivateSkin(Class<? extends VisualizerSkin> skinClass) {
|
private void generateAndActivateSkin(Class<? extends VisualizerSkin> skinClass) {
|
||||||
|
@ -548,9 +588,7 @@ public class Visualizer extends VisPlugin {
|
||||||
visualizerSkins.remove(skin);
|
visualizerSkins.remove(skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void handlePopupRequest(final int x, final int y) {
|
private void handlePopupRequest(final int x, final int y) {
|
||||||
|
|
||||||
JPopupMenu menu = new JPopupMenu();
|
JPopupMenu menu = new JPopupMenu();
|
||||||
menu.add(new JLabel("Select action:"));
|
menu.add(new JLabel("Select action:"));
|
||||||
|
|
||||||
|
@ -565,8 +603,8 @@ public class Visualizer extends VisPlugin {
|
||||||
for (Class<? extends MoteMenuAction> menuActionClass: moteMenuActions) {
|
for (Class<? extends MoteMenuAction> menuActionClass: moteMenuActions) {
|
||||||
try {
|
try {
|
||||||
final MoteMenuAction menuAction = menuActionClass.newInstance();
|
final MoteMenuAction menuAction = menuActionClass.newInstance();
|
||||||
if (menuAction.isEnabled(mote)) {
|
if (menuAction.isEnabled(this, mote)) {
|
||||||
JMenuItem menuItem = new JMenuItem(menuAction.getDescription(mote));
|
JMenuItem menuItem = new JMenuItem(menuAction.getDescription(this, mote));
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
menuAction.doAction(Visualizer.this, mote);
|
menuAction.doAction(Visualizer.this, mote);
|
||||||
|
@ -581,7 +619,6 @@ public class Visualizer extends VisPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simulation specific actions */
|
/* Simulation specific actions */
|
||||||
|
@ -589,8 +626,8 @@ public class Visualizer extends VisPlugin {
|
||||||
for (Class<? extends SimulationMenuAction> menuActionClass: simulationMenuActions) {
|
for (Class<? extends SimulationMenuAction> menuActionClass: simulationMenuActions) {
|
||||||
try {
|
try {
|
||||||
final SimulationMenuAction menuAction = menuActionClass.newInstance();
|
final SimulationMenuAction menuAction = menuActionClass.newInstance();
|
||||||
if (menuAction.isEnabled(simulation)) {
|
if (menuAction.isEnabled(this, simulation)) {
|
||||||
JMenuItem menuItem = new JMenuItem(menuAction.getDescription(simulation));
|
JMenuItem menuItem = new JMenuItem(menuAction.getDescription(this, simulation));
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
menuAction.doAction(Visualizer.this, simulation);
|
menuAction.doAction(Visualizer.this, simulation);
|
||||||
|
@ -613,57 +650,127 @@ public class Visualizer extends VisPlugin {
|
||||||
menu.setVisible(true);
|
menu.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beginMoveRequest(final int x, final int y) {
|
private void handleMousePress(MouseEvent mouseEvent) {
|
||||||
|
int x = mouseEvent.getPoint().x;
|
||||||
|
int y = mouseEvent.getPoint().y;
|
||||||
final Mote[] motes = findMotesAtPosition(x, y);
|
final Mote[] motes = findMotesAtPosition(x, y);
|
||||||
if (motes == null || motes.length == 0) {
|
|
||||||
|
/* No motes clicked: We should either pan or zoom.
|
||||||
|
* Control or Shift pressed: We should either pan or zoom */
|
||||||
|
if (mouseEvent.isControlDown() || mouseEvent.isShiftDown()
|
||||||
|
|| motes == null || motes.length == 0) {
|
||||||
|
if (mouseEvent.isControlDown()) {
|
||||||
|
/* Zoom */
|
||||||
|
zooming = true;
|
||||||
|
zoomingPixel = new Point(x, y);
|
||||||
|
zoomingPosition = transformPixelToPosition(zoomingPixel);
|
||||||
|
zoomStart = viewportTransform.getScaleX();
|
||||||
|
} else {
|
||||||
|
/* Pan */
|
||||||
|
panning = true;
|
||||||
|
panningPosition = transformPixelToPosition(x, y);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
moteMoveBeginTime = System.currentTimeMillis();
|
/* One of the clicked motes should be moved */
|
||||||
beginMoveRequest(motes[0]);
|
beginMoveRequest(motes[0], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beginMoveRequest(Mote moteToMove) {
|
private void beginMoveRequest(Mote moteToMove, boolean withTiming) {
|
||||||
moteIsBeingMoved = true;
|
if (withTiming) {
|
||||||
this.moteToMove = moteToMove;
|
moveStartTime = System.currentTimeMillis();
|
||||||
|
} else {
|
||||||
|
moveStartTime = -1;
|
||||||
|
}
|
||||||
|
moving = true;
|
||||||
|
movedMote = moteToMove;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMoveRequest(final int x, final int y,
|
private void handleMouseMove(MouseEvent e, boolean stop) {
|
||||||
boolean wasJustReleased) {
|
int x = e.getX();
|
||||||
|
int y = e.getY();
|
||||||
|
|
||||||
if (!moteIsBeingMoved) {
|
/* Panning */
|
||||||
|
if (panning) {
|
||||||
|
if (panningPosition == null || stop) {
|
||||||
|
panning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wasJustReleased) {
|
/* The current mouse position should correspond to where panning started */
|
||||||
// Still moving mote
|
Position moved = transformPixelToPosition(x,y);
|
||||||
|
viewportTransform.translate(
|
||||||
|
moved.getXCoordinate() - panningPosition.getXCoordinate(),
|
||||||
|
moved.getYCoordinate() - panningPosition.getYCoordinate()
|
||||||
|
);
|
||||||
|
repaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zooming */
|
||||||
|
if (zooming) {
|
||||||
|
if (zoomingPosition == null || zoomingPixel == null || stop) {
|
||||||
|
zooming = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The zooming start pixel should correspond to the zooming center position */
|
||||||
|
/* The current mouse position should correspond to where panning started */
|
||||||
|
double zoomFactor = 1.0 + Math.abs((double) zoomingPixel.y - y)/100.0;
|
||||||
|
double newZoom = (zoomingPixel.y - y)>0?zoomStart*zoomFactor: zoomStart/zoomFactor;
|
||||||
|
if (newZoom < 0.00001) {
|
||||||
|
newZoom = 0.00001;
|
||||||
|
}
|
||||||
|
viewportTransform.setToScale(
|
||||||
|
newZoom,
|
||||||
|
newZoom
|
||||||
|
);
|
||||||
|
Position moved = transformPixelToPosition(zoomingPixel);
|
||||||
|
viewportTransform.translate(
|
||||||
|
moved.getXCoordinate() - zoomingPosition.getXCoordinate(),
|
||||||
|
moved.getYCoordinate() - zoomingPosition.getYCoordinate()
|
||||||
|
);
|
||||||
|
repaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Moving */
|
||||||
|
if (moving) {
|
||||||
|
if (!stop) {
|
||||||
canvas.setCursor(moveCursor);
|
canvas.setCursor(moveCursor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stopped moving mote
|
/* Restore cursor */
|
||||||
canvas.setCursor(Cursor.getDefaultCursor());
|
canvas.setCursor(Cursor.getDefaultCursor());
|
||||||
moteIsBeingMoved = false;
|
|
||||||
|
|
||||||
Position newXYValues = transformPixelToPositon(new Point(x, y));
|
/* Move mote */
|
||||||
|
Position newPos = transformPixelToPosition(x, y);
|
||||||
if (moteMoveBeginTime <= 0 || System.currentTimeMillis() - moteMoveBeginTime > 300) {
|
if (moveStartTime < 0 || System.currentTimeMillis() - moveStartTime > 300) {
|
||||||
int returnValue = JOptionPane.showConfirmDialog(Visualizer.this, "Move mote to"
|
String options[] = {"Yes", "Cancel"};
|
||||||
+ "\nX=" + newXYValues.getXCoordinate() + "\nY="
|
int returnValue = JOptionPane.showOptionDialog(Visualizer.this,
|
||||||
+ newXYValues.getYCoordinate() + "\nZ="
|
"Move mote to" +
|
||||||
+ moteToMove.getInterfaces().getPosition().getZCoordinate());
|
"\nX=" + newPos.getXCoordinate() +
|
||||||
|
"\nY=" + newPos.getYCoordinate() +
|
||||||
if (returnValue == JOptionPane.OK_OPTION) {
|
"\nZ=" + movedMote.getInterfaces().getPosition().getZCoordinate(),
|
||||||
moteToMove.getInterfaces().getPosition().setCoordinates(
|
"Move mote?",
|
||||||
newXYValues.getXCoordinate(), newXYValues.getYCoordinate(),
|
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
|
||||||
moteToMove.getInterfaces().getPosition().getZCoordinate());
|
null, options, options[0]);
|
||||||
|
if (returnValue == JOptionPane.YES_OPTION) {
|
||||||
|
movedMote.getInterfaces().getPosition().setCoordinates(
|
||||||
|
newPos.getXCoordinate(),
|
||||||
|
newPos.getYCoordinate(),
|
||||||
|
movedMote.getInterfaces().getPosition().getZCoordinate()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
moteMoveBeginTime = -1;
|
|
||||||
moteToMove = null;
|
moving = false;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all motes at given position.
|
* Returns all motes at given position.
|
||||||
|
@ -675,16 +782,16 @@ public class Visualizer extends VisPlugin {
|
||||||
* @return All motes at given position
|
* @return All motes at given position
|
||||||
*/
|
*/
|
||||||
public Mote[] findMotesAtPosition(int clickedX, int clickedY) {
|
public Mote[] findMotesAtPosition(int clickedX, int clickedY) {
|
||||||
double xCoord = factorXPixelToCoord(clickedX);
|
double xCoord = transformToPositionX(clickedX);
|
||||||
double yCoord = factorYPixelToCoord(clickedY);
|
double yCoord = transformToPositionY(clickedY);
|
||||||
|
|
||||||
ArrayList<Mote> motes = new ArrayList<Mote>();
|
ArrayList<Mote> motes = new ArrayList<Mote>();
|
||||||
|
|
||||||
// Calculate painted mote radius in coordinates
|
// Calculate painted mote radius in coordinates
|
||||||
double paintedMoteWidth = factorXPixelToCoord(MOTE_RADIUS)
|
double paintedMoteWidth = transformToPositionX(MOTE_RADIUS)
|
||||||
- factorXPixelToCoord(0);
|
- transformToPositionX(0);
|
||||||
double paintedMoteHeight = factorYPixelToCoord(MOTE_RADIUS)
|
double paintedMoteHeight = transformToPositionY(MOTE_RADIUS)
|
||||||
- factorYPixelToCoord(0);
|
- transformToPositionY(0);
|
||||||
|
|
||||||
for (int i = 0; i < simulation.getMotesCount(); i++) {
|
for (int i = 0; i < simulation.getMotesCount(); i++) {
|
||||||
Position pos = simulation.getMote(i).getInterfaces().getPosition();
|
Position pos = simulation.getMote(i).getInterfaces().getPosition();
|
||||||
|
@ -707,8 +814,9 @@ public class Visualizer extends VisPlugin {
|
||||||
return motes.toArray(motesArr);
|
return motes.toArray(motesArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paintSkinGeneric(Graphics g) {
|
public void paintMotes(Graphics g) {
|
||||||
Mote[] allMotes = simulation.getMotes();
|
Mote[] allMotes = simulation.getMotes();
|
||||||
|
|
||||||
for (Mote mote: allMotes) {
|
for (Mote mote: allMotes) {
|
||||||
|
|
||||||
/* Use the first skin's non-null mote colors */
|
/* Use the first skin's non-null mote colors */
|
||||||
|
@ -733,8 +841,8 @@ public class Visualizer extends VisPlugin {
|
||||||
g.setColor(HIGHLIGHT_COLOR);
|
g.setColor(HIGHLIGHT_COLOR);
|
||||||
g.fillOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS,
|
g.fillOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS,
|
||||||
2 * MOTE_RADIUS);
|
2 * MOTE_RADIUS);
|
||||||
} else if (mote == moteToMove) {
|
} else if (mote == movedMote) {
|
||||||
// Don't fill mote
|
/* No fill */
|
||||||
} else if (moteColors.length >= 2) {
|
} else if (moteColors.length >= 2) {
|
||||||
g.setColor(moteColors[0]);
|
g.setColor(moteColors[0]);
|
||||||
g.fillOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS,
|
g.fillOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS,
|
||||||
|
@ -779,55 +887,70 @@ public class Visualizer extends VisPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recalculate size of canvas and factors for transforming between real and
|
* Reset transform to show all motes.
|
||||||
* pixel coordinates. This method is called every time this frame is resized
|
|
||||||
* or created.
|
|
||||||
*/
|
*/
|
||||||
protected void calculateTransformations() {
|
protected void resetViewport() {
|
||||||
if (simulation.getMotesCount() == 0) {
|
Mote[] motes = simulation.getMotes();
|
||||||
smallestXCoord = 0;
|
if (motes.length == 0) {
|
||||||
smallestYCoord = 0;
|
/* No motes */
|
||||||
factorXCoordToPixel = 1;
|
viewportTransform.setToIdentity();
|
||||||
factorYCoordToPixel = 1;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double biggestXCoord, biggestYCoord;
|
final double BORDER_SCALE_FACTOR = 1.1;
|
||||||
|
double smallX, bigX, smallY, bigY, scaleX, scaleY;
|
||||||
|
|
||||||
Position pos = simulation.getMote(0).getInterfaces().getPosition();
|
/* Init values */
|
||||||
smallestXCoord = biggestXCoord = pos.getXCoordinate();
|
{
|
||||||
smallestYCoord = biggestYCoord = pos.getYCoordinate();
|
Position pos = motes[0].getInterfaces().getPosition();
|
||||||
|
smallX = bigX = pos.getXCoordinate();
|
||||||
|
smallY = bigY = pos.getYCoordinate();
|
||||||
|
}
|
||||||
|
|
||||||
// Get extreme coordinates
|
/* Extremes */
|
||||||
Mote[] motes = simulation.getMotes();
|
|
||||||
for (Mote mote: motes) {
|
for (Mote mote: motes) {
|
||||||
pos = mote.getInterfaces().getPosition();
|
Position pos = mote.getInterfaces().getPosition();
|
||||||
|
smallX = Math.min(smallX, pos.getXCoordinate());
|
||||||
smallestXCoord = Math.min(smallestXCoord, pos.getXCoordinate());
|
bigX = Math.max(bigX, pos.getXCoordinate());
|
||||||
smallestYCoord = Math.min(smallestYCoord, pos.getYCoordinate());
|
smallY = Math.min(smallY, pos.getYCoordinate());
|
||||||
biggestXCoord = Math.max(biggestXCoord, pos.getXCoordinate());
|
bigY = Math.max(bigY, pos.getYCoordinate());
|
||||||
biggestYCoord = Math.max(biggestYCoord, pos.getYCoordinate());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((biggestXCoord - smallestXCoord) == 0) {
|
/* Scale viewport */
|
||||||
factorXCoordToPixel = 1;
|
if (smallX == bigX) {
|
||||||
|
scaleX = 1;
|
||||||
} else {
|
} else {
|
||||||
factorXCoordToPixel = ((double)
|
scaleX = (bigX - smallX) / (double) (canvas.getWidth());
|
||||||
canvas.getSize().width - 2
|
}
|
||||||
* CANVAS_BORDER_WIDTH)
|
if (smallY == bigY) {
|
||||||
/ (biggestXCoord - smallestXCoord);
|
scaleY = 1;
|
||||||
|
} else {
|
||||||
|
scaleY = (bigY - smallY) / (double) (canvas.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((biggestYCoord - smallestYCoord) == 0) {
|
viewportTransform.setToIdentity();
|
||||||
factorYCoordToPixel = 1;
|
double newZoom = (1.0/(BORDER_SCALE_FACTOR*Math.max(scaleX, scaleY)));
|
||||||
} else {
|
viewportTransform.setToScale(
|
||||||
factorYCoordToPixel = ((double)
|
newZoom,
|
||||||
canvas.getSize().height - 2
|
newZoom
|
||||||
* CANVAS_BORDER_WIDTH)
|
);
|
||||||
/ (biggestYCoord - smallestYCoord);
|
|
||||||
|
/* Center visible motes */
|
||||||
|
final double smallXfinal = smallX, bigXfinal = bigX, smallYfinal = smallY, bigYfinal = bigY;
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Position viewMid =
|
||||||
|
transformPixelToPosition(canvas.getWidth()/2, canvas.getHeight()/2);
|
||||||
|
double motesMidX = (smallXfinal + bigXfinal) / 2.0;
|
||||||
|
double motesMidY = (smallYfinal + bigYfinal) / 2.0;
|
||||||
|
|
||||||
|
viewportTransform.translate(
|
||||||
|
viewMid.getXCoordinate() - motesMidX,
|
||||||
|
viewMid.getYCoordinate() - motesMidY);
|
||||||
|
canvas.repaint();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -839,8 +962,11 @@ public class Visualizer extends VisPlugin {
|
||||||
* @return Pixel coordinates
|
* @return Pixel coordinates
|
||||||
*/
|
*/
|
||||||
public Point transformPositionToPixel(Position pos) {
|
public Point transformPositionToPixel(Position pos) {
|
||||||
return new Point(factorXCoordToPixel(pos.getXCoordinate()),
|
return transformPositionToPixel(
|
||||||
factorYCoordToPixel(pos.getYCoordinate()));
|
pos.getXCoordinate(),
|
||||||
|
pos.getYCoordinate(),
|
||||||
|
pos.getZCoordinate()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -853,7 +979,14 @@ public class Visualizer extends VisPlugin {
|
||||||
* @return Pixel coordinates
|
* @return Pixel coordinates
|
||||||
*/
|
*/
|
||||||
public Point transformPositionToPixel(double x, double y, double z) {
|
public Point transformPositionToPixel(double x, double y, double z) {
|
||||||
return new Point(factorXCoordToPixel(x), factorYCoordToPixel(y));
|
return new Point(transformToPixelX(x), transformToPixelY(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Canvas
|
||||||
|
*/
|
||||||
|
public JPanel getCurrentCanvas() {
|
||||||
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -863,31 +996,30 @@ public class Visualizer extends VisPlugin {
|
||||||
* On-screen pixel coordinate
|
* On-screen pixel coordinate
|
||||||
* @return Real world coordinate (z=0).
|
* @return Real world coordinate (z=0).
|
||||||
*/
|
*/
|
||||||
public Position transformPixelToPositon(Point pixelPos) {
|
public Position transformPixelToPosition(Point pixelPos) {
|
||||||
Position dummyPosition = new Position(null);
|
return transformPixelToPosition(pixelPos.x, pixelPos.y);
|
||||||
dummyPosition.setCoordinates(factorXPixelToCoord(pixelPos.x),
|
}
|
||||||
factorYPixelToCoord(pixelPos.y), 0.0);
|
public Position transformPixelToPosition(int x, int y) {
|
||||||
return dummyPosition;
|
Position position = new Position(null);
|
||||||
|
position.setCoordinates(
|
||||||
|
transformToPositionX(x),
|
||||||
|
transformToPositionY(y),
|
||||||
|
0.0
|
||||||
|
);
|
||||||
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private int transformToPixelX(double x) {
|
||||||
* @return The current canvas to paint on
|
return (int) (viewportTransform.getScaleX()*x + viewportTransform.getTranslateX());
|
||||||
*/
|
|
||||||
public JPanel getCurrentCanvas() {
|
|
||||||
return canvas;
|
|
||||||
}
|
}
|
||||||
|
private int transformToPixelY(double y) {
|
||||||
private int factorXCoordToPixel(double xCoordinate) {
|
return (int) (viewportTransform.getScaleY()*y + viewportTransform.getTranslateY());
|
||||||
return (int) ((xCoordinate - smallestXCoord) * factorXCoordToPixel + CANVAS_BORDER_WIDTH);
|
|
||||||
}
|
}
|
||||||
private int factorYCoordToPixel(double yCoordinate) {
|
private double transformToPositionX(int x) {
|
||||||
return (int) ((yCoordinate - smallestYCoord) * factorYCoordToPixel) + CANVAS_BORDER_WIDTH;
|
return (x - viewportTransform.getTranslateX())/viewportTransform.getScaleX() ;
|
||||||
}
|
}
|
||||||
private double factorXPixelToCoord(int xPixel) {
|
private double transformToPositionY(int y) {
|
||||||
return ((xPixel - CANVAS_BORDER_WIDTH) / factorXCoordToPixel) + smallestXCoord;
|
return (y - viewportTransform.getTranslateY())/viewportTransform.getScaleY() ;
|
||||||
}
|
|
||||||
private double factorYPixelToCoord(int yPixel) {
|
|
||||||
return ((yPixel - CANVAS_BORDER_WIDTH) / factorYCoordToPixel) + smallestYCoord;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closePlugin() {
|
public void closePlugin() {
|
||||||
|
@ -923,9 +1055,32 @@ public class Visualizer extends VisPlugin {
|
||||||
Vector<Element> config = new Vector<Element>();
|
Vector<Element> config = new Vector<Element>();
|
||||||
Element element;
|
Element element;
|
||||||
|
|
||||||
|
/* Skins */
|
||||||
for (VisualizerSkin skin: currentSkins) {
|
for (VisualizerSkin skin: currentSkins) {
|
||||||
element = new Element("skin");
|
element = new Element("skin");
|
||||||
element.setText(GUI.getDescriptionOf(skin.getClass()));
|
element.setText(skin.getClass().getName());
|
||||||
|
config.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Viewport */
|
||||||
|
element = new Element("viewport");
|
||||||
|
double[] matrix = new double[6];
|
||||||
|
viewportTransform.getMatrix(matrix);
|
||||||
|
element.setText(
|
||||||
|
matrix[0] + " " +
|
||||||
|
matrix[1] + " " +
|
||||||
|
matrix[2] + " " +
|
||||||
|
matrix[3] + " " +
|
||||||
|
matrix[4] + " " +
|
||||||
|
matrix[5]
|
||||||
|
);
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
|
/* Hide decorations */
|
||||||
|
BasicInternalFrameUI ui = (BasicInternalFrameUI) getUI();
|
||||||
|
if (ui.getNorthPane().getPreferredSize() == null ||
|
||||||
|
ui.getNorthPane().getPreferredSize().height == 0) {
|
||||||
|
element = new Element("hidden");
|
||||||
config.add(element);
|
config.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,7 +1092,9 @@ public class Visualizer extends VisPlugin {
|
||||||
if (element.getName().equals("skin")) {
|
if (element.getName().equals("skin")) {
|
||||||
String wanted = element.getText();
|
String wanted = element.getText();
|
||||||
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
|
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
|
||||||
if (wanted.equals(GUI.getDescriptionOf(skinClass))) {
|
if (wanted.equals(skinClass.getName())
|
||||||
|
/* Backwards compatibility */
|
||||||
|
|| wanted.equals(GUI.getDescriptionOf(skinClass))) {
|
||||||
final Class<? extends VisualizerSkin> skin = skinClass;
|
final Class<? extends VisualizerSkin> skin = skinClass;
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -951,17 +1108,37 @@ public class Visualizer extends VisPlugin {
|
||||||
if (wanted != null) {
|
if (wanted != null) {
|
||||||
logger.warn("Could not load skin: " + element.getText());
|
logger.warn("Could not load skin: " + element.getText());
|
||||||
}
|
}
|
||||||
|
} else if (element.getName().equals("viewport")) {
|
||||||
|
try {
|
||||||
|
String[] matrix = element.getText().split(" ");
|
||||||
|
viewportTransform.setTransform(
|
||||||
|
Double.parseDouble(matrix[0]),
|
||||||
|
Double.parseDouble(matrix[1]),
|
||||||
|
Double.parseDouble(matrix[2]),
|
||||||
|
Double.parseDouble(matrix[3]),
|
||||||
|
Double.parseDouble(matrix[4]),
|
||||||
|
Double.parseDouble(matrix[5])
|
||||||
|
);
|
||||||
|
resetViewport = 0;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("Bad viewport: " + e.getMessage());
|
||||||
|
resetViewport();
|
||||||
|
}
|
||||||
|
} else if (element.getName().equals("hidden")) {
|
||||||
|
BasicInternalFrameUI ui = (BasicInternalFrameUI) getUI();
|
||||||
|
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
||||||
|
skinButton.setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class ButtonClickMoteMenuAction implements MoteMenuAction {
|
protected static class ButtonClickMoteMenuAction implements MoteMenuAction {
|
||||||
public boolean isEnabled(Mote mote) {
|
public boolean isEnabled(Visualizer visualizer, Mote mote) {
|
||||||
return mote.getInterfaces().getButton() != null
|
return mote.getInterfaces().getButton() != null
|
||||||
&& !mote.getInterfaces().getButton().isPressed();
|
&& !mote.getInterfaces().getButton().isPressed();
|
||||||
}
|
}
|
||||||
public String getDescription(Mote mote) {
|
public String getDescription(Visualizer visualizer, Mote mote) {
|
||||||
return "Click button on " + mote;
|
return "Click button on " + mote;
|
||||||
}
|
}
|
||||||
public void doAction(Visualizer visualizer, Mote mote) {
|
public void doAction(Visualizer visualizer, Mote mote) {
|
||||||
|
@ -970,10 +1147,10 @@ public class Visualizer extends VisPlugin {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static class DeleteMoteMenuAction implements MoteMenuAction {
|
protected static class DeleteMoteMenuAction implements MoteMenuAction {
|
||||||
public boolean isEnabled(Mote mote) {
|
public boolean isEnabled(Visualizer visualizer, Mote mote) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public String getDescription(Mote mote) {
|
public String getDescription(Visualizer visualizer, Mote mote) {
|
||||||
return "Delete " + mote;
|
return "Delete " + mote;
|
||||||
}
|
}
|
||||||
public void doAction(Visualizer visualizer, Mote mote) {
|
public void doAction(Visualizer visualizer, Mote mote) {
|
||||||
|
@ -982,10 +1159,10 @@ public class Visualizer extends VisPlugin {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static class ShowLEDMoteMenuAction implements MoteMenuAction {
|
protected static class ShowLEDMoteMenuAction implements MoteMenuAction {
|
||||||
public boolean isEnabled(Mote mote) {
|
public boolean isEnabled(Visualizer visualizer, Mote mote) {
|
||||||
return mote.getInterfaces().getLED() != null;
|
return mote.getInterfaces().getLED() != null;
|
||||||
}
|
}
|
||||||
public String getDescription(Mote mote) {
|
public String getDescription(Visualizer visualizer, Mote mote) {
|
||||||
return "Show LEDs on " + mote;
|
return "Show LEDs on " + mote;
|
||||||
}
|
}
|
||||||
public void doAction(Visualizer visualizer, Mote mote) {
|
public void doAction(Visualizer visualizer, Mote mote) {
|
||||||
|
@ -1013,7 +1190,7 @@ public class Visualizer extends VisPlugin {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static class ShowSerialMoteMenuAction implements MoteMenuAction {
|
protected static class ShowSerialMoteMenuAction implements MoteMenuAction {
|
||||||
public boolean isEnabled(Mote mote) {
|
public boolean isEnabled(Visualizer visualizer, Mote mote) {
|
||||||
for (MoteInterface intf: mote.getInterfaces().getInterfaces()) {
|
for (MoteInterface intf: mote.getInterfaces().getInterfaces()) {
|
||||||
if (intf instanceof SerialPort) {
|
if (intf instanceof SerialPort) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1021,7 +1198,7 @@ public class Visualizer extends VisPlugin {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public String getDescription(Mote mote) {
|
public String getDescription(Visualizer visualizer, Mote mote) {
|
||||||
return "Show serial port on " + mote;
|
return "Show serial port on " + mote;
|
||||||
}
|
}
|
||||||
public void doAction(Visualizer visualizer, Mote mote) {
|
public void doAction(Visualizer visualizer, Mote mote) {
|
||||||
|
@ -1056,15 +1233,71 @@ public class Visualizer extends VisPlugin {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static class MoveMoteMenuAction implements MoteMenuAction {
|
protected static class MoveMoteMenuAction implements MoteMenuAction {
|
||||||
public boolean isEnabled(Mote mote) {
|
public boolean isEnabled(Visualizer visualizer, Mote mote) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public String getDescription(Mote mote) {
|
public String getDescription(Visualizer visualizer, Mote mote) {
|
||||||
return "Move " + mote;
|
return "Move " + mote;
|
||||||
}
|
}
|
||||||
public void doAction(Visualizer visualizer, Mote mote) {
|
public void doAction(Visualizer visualizer, Mote mote) {
|
||||||
visualizer.moteMoveBeginTime = -1;
|
visualizer.beginMoveRequest(mote, false);
|
||||||
visualizer.beginMoveRequest(mote);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected static class ResetViewportAction implements SimulationMenuAction {
|
||||||
|
public void doAction(Visualizer visualizer, Simulation simulation) {
|
||||||
|
visualizer.resetViewport = 1;
|
||||||
|
visualizer.repaint();
|
||||||
|
}
|
||||||
|
public String getDescription(Visualizer visualizer, Simulation simulation) {
|
||||||
|
return "Reset viewport";
|
||||||
|
}
|
||||||
|
public boolean isEnabled(Visualizer visualizer, Simulation simulation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected static class ToggleDecorationsMenuAction implements SimulationMenuAction {
|
||||||
|
public void doAction(final Visualizer visualizer, Simulation simulation) {
|
||||||
|
if (!(visualizer.getUI() instanceof BasicInternalFrameUI)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BasicInternalFrameUI ui = (BasicInternalFrameUI) visualizer.getUI();
|
||||||
|
|
||||||
|
if (ui.getNorthPane().getPreferredSize() == null ||
|
||||||
|
ui.getNorthPane().getPreferredSize().height == 0) {
|
||||||
|
/* Restore window decorations */
|
||||||
|
ui.getNorthPane().setPreferredSize(null);
|
||||||
|
visualizer.skinButton.setVisible(true);
|
||||||
|
} else {
|
||||||
|
/* Hide window decorations */
|
||||||
|
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
||||||
|
visualizer.skinButton.setVisible(false);
|
||||||
|
}
|
||||||
|
visualizer.revalidate();
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
visualizer.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public String getDescription(Visualizer visualizer, Simulation simulation) {
|
||||||
|
if (!(visualizer.getUI() instanceof BasicInternalFrameUI)) {
|
||||||
|
return "Hide window decorations";
|
||||||
|
}
|
||||||
|
BasicInternalFrameUI ui = (BasicInternalFrameUI) visualizer.getUI();
|
||||||
|
|
||||||
|
if (ui.getNorthPane().getPreferredSize() == null ||
|
||||||
|
ui.getNorthPane().getPreferredSize().height == 0) {
|
||||||
|
return "Restore window decorations";
|
||||||
|
}
|
||||||
|
return "Hide window decorations";
|
||||||
|
}
|
||||||
|
public boolean isEnabled(Visualizer visualizer, Simulation simulation) {
|
||||||
|
if (!(visualizer.getUI() instanceof BasicInternalFrameUI)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: VisualizerSkin.java,v 1.2 2009/04/14 15:40:26 fros4943 Exp $
|
* $Id: VisualizerSkin.java,v 1.3 2009/08/27 13:57:42 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
@ -70,7 +70,7 @@ public interface VisualizerSkin {
|
||||||
* Used by skin generic visualization.
|
* Used by skin generic visualization.
|
||||||
* May return a single color, or two colors.
|
* May return a single color, or two colors.
|
||||||
*
|
*
|
||||||
* @see Visualizer#paintSkinGeneric(Graphics)
|
* @see Visualizer#paintMotes(Graphics)
|
||||||
*
|
*
|
||||||
* @param mote Mote
|
* @param mote Mote
|
||||||
* @return Color[] { Inner color, Outer color }
|
* @return Color[] { Inner color, Outer color }
|
||||||
|
@ -78,11 +78,20 @@ public interface VisualizerSkin {
|
||||||
public Color[] getColorOf(Mote mote);
|
public Color[] getColorOf(Mote mote);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when plugin is repainted on the currently active skin.
|
* Called every time the visualizer plugin is repainted.
|
||||||
|
* Paints graphics that should be underneath the motes.
|
||||||
*
|
*
|
||||||
* @param g Graphics
|
* @param g Graphics
|
||||||
*/
|
*/
|
||||||
public void paintSkin(Graphics g);
|
public void paintBeforeMotes(Graphics g);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called every time the visualizer plugin is repainted.
|
||||||
|
* Paints graphics that should be on top of the motes.
|
||||||
|
*
|
||||||
|
* @param g Graphics
|
||||||
|
*/
|
||||||
|
public void paintAfterMotes(Graphics g);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Visualizer plugin where this skin is showing
|
* @return Visualizer plugin where this skin is showing
|
||||||
|
|
Loading…
Add table
Reference in a new issue