/* Copyright (c) 1997-2006
Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version: http://www.gnu.org/licenses/gpl.txt.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
$Project: polymake $$Id: JavaviewSchlegelFrame.java 7529 2006-12-20 16:57:12Z thilosch $
*/
package de.tuberlin.polymake.polytope;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import jv.geom.PgPolygonSet;
import jv.number.PuDouble;
import jv.object.PsDebug;
import jv.object.PsObject;
import jv.object.PsPanel;
import jv.project.PgGeometry;
import jv.project.PgGeometryIf;
import jv.project.PvDisplayIf;
import jv.project.PvGeometryIf;
import jv.project.PvPickEvent;
import jv.project.PvPickListenerIf;
import jv.vecmath.PdVector;
import jv.vecmath.PiVector;
import de.tuberlin.polymake.common.EmbeddedGeometries;
import de.tuberlin.polymake.common.JavaviewControl;
import de.tuberlin.polymake.common.PointSet;
import de.tuberlin.polymake.common.JavaviewFrame;
import de.tuberlin.polymake.common.PolymakePoint;
import de.tuberlin.polymake.common.SimpleGeometryParser;
/**
* Frame used to display a Schlegel Diagram which can be interactively
* modified by dragging vertices, changing the zoomFactor and selecting
* new projection facets. The data which is sent will be filtered using the
* MsgQueue.
*
* @author Thilo Schröder
*/
public class JavaviewSchlegelFrame extends JavaviewFrame implements PvPickListenerIf {
/** Help frame belonging to the Schlegelframe */
protected static JavaviewSchlegelHelpFrame helpFrame = null;
protected Panel topPanel = new Panel();
protected Button storeButton;
protected Button sendMarkedButton;
protected Button helpButton;
protected boolean vertexDragged = false;
static protected Color projColor = new Color(0,0,0);
static protected Color facetColor = new Color(0,0,0);
protected Vector facet = null;
/**
* Create a frame displaying the given geometry with given zoom parameter.
* The output of any event is written into a pipe.
*
* @param i_geom geometry to be displayed
* @param params non Javaview jvx parameters
* @param sink
*/
public JavaviewSchlegelFrame(EmbeddedGeometries geoms, Properties params, Properties iparams, JavaviewControl parent) {
super(geoms,params,iparams,parent);
setUpGUI();
if(System.getProperty("polymake.user.colors.proj") != null) {
StringTokenizer st = new StringTokenizer(System.getProperty("polymake.user.colors.proj"));
projColor = new Color(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()));
}
if(System.getProperty("polymake.user.colors.facets") != null) {
StringTokenizer st = new StringTokenizer(System.getProperty("polymake.user.colors.facets"));
facetColor = new Color(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()));
}
facet = SimpleGeometryParser.parseFacet(parameters.getProperty("facet"));
setPolygonColors();
disp.addPickListener(this);
// Set display in initial-pick mode, that is, the methods
// pickInitial() and dragInitial() of PvPickListenerIf
// are called on mouse events.
disp.setMajorMode(PvDisplayIf.MODE_PICK);
disp.fit();
}
/** update the frame with new values for the vertices and the zoom Factor */
public void update(PointSet ps, Properties params, boolean clearTags) {
if(!getTitle().equals(ps.getName())) {
title = ps.getName();
setTitle(title);
}
if (!params.getProperty("zoom").equals("null")) {
parameters.setProperty("zoom",params.getProperty("zoom"));
if(vertexDragged) {
((PuDouble)sliderMap.get("zoom")).setValue(Double.parseDouble(parameters.getProperty("zoom")));
vertexDragged = false;
}
}
geom.update(ps, clearTags);
}
public void update(PointSet ps, Properties params) {
update(ps, params, false);
}
// ---------------- Begin of PvPickListenerIf ------------------------
/** The name of a listeners allows the display to issue verbal debug messages. */
public String getName() {
return "SchlegelFramePicker";
}
/** Currently not supported by display yet. */
public void selectGeometry(PgGeometryIf geom) {
}
/**
* Get a location in the display with 2d display and 3d world coordinates.
* Method is called when display is in mode PvDisplayIf.MODE_DISPLAY_PICK.
* @see jv.project.PvPickListenerIf
* @param pos Pick event issued by the display
*/
public void pickDisplay(PvPickEvent pos) {
PsDebug.message("pickDisplay entered.");
}
/**
* Drag a location in the display with 2d display and 3d world coordinates.
* Method is called when display is in mode PvDisplayIf.MODE_DISPLAY_PICK.
* @see jv.project.PvPickListenerIf
* @param pos Pick event issued by the display
*/
public void dragDisplay(PvPickEvent pos) {
PsDebug.message("pickDisplay entered.");
}
/**
* Pick an arbitrary point on a geometry, point may lie inside an element.
* Method is called when display is in mode PvDisplayIf.MODE_INITIAL_PICK
* or if temporarily the i-key is pressed, and any pixel in the display is picked.
* @see jv.project.PvPickListenerIf
* @param pos Pick event issued by the display
*/
public void pickInitial(PvPickEvent pos) {
// PsDebug.message("pickInitial entered.");
}
/**
* Drag an arbitrary point along a geometry, point may lie inside an element.
* Method is called when display is in mode PvDisplayIf.MODE_INITIAL_PICK
* or if temporarily the i-key is pressed, and any pixel in the display is dragged.
* @see jv.project.PvPickListenerIf
* @param pos Pick event issued by the display
*/
public void dragInitial(PvPickEvent pos) {
// PsDebug.message("dragInitial entered = "+pos.getLocation());
}
/**
* Get a picked vertex of a geometry.
* Method is called when display is in mode PvDisplayIf.MODE_PICK
* or if temporarily the p-key is pressed, and a vertex picked.
* @see jv.project.PvPickListenerIf
* @param geom Picked geometry on which vertex lies
* @param index Index of vertex in vertex array of geometry
* @param vertex 3d coordinates of vertex position
*/
public void pickVertex(PgGeometryIf geom, int index, PdVector vertex) {
}
/**
* <p>Method is called when display is in mode PvDisplayIf.MODE_PICK
* or if temporarily the p-key is pressed, and a vertex dragged.</p>
* <p>Drag a picked vertex of a geometry and put its coordinates into
* the MsgQueue. If the queue is empty sent PolymakeFrame.ANSWER
* to sink.</p>
*
* @param geom Picked geometry on which vertex lies
* @param index Index of vertex in vertex array of geometry
* @param vertex 3d coordinates of vertex position
*/
public void dragVertex(PgGeometryIf m_geom, int index, PdVector vertex) {
try {
geom.moveVertex(m_geom.getName(),index,vertex);
PointSet outputVertices = new PointSet(geom.getName(),1);
PdVector tmpVertex = geom.getEmbeddedVertex(m_geom.getName(),index);
outputVertices.setPoint(0, new PolymakePoint(tmpVertex.getEntries(),tmpVertex.getName()));
parent.putMessage(SimpleGeometryParser.write(outputVertices,null),true);
statusBar.setText("");
vertexDragged = true;
} catch (Exception ex) {
System.err.println("SchlegelFrame: error writing to client");
ex.printStackTrace(System.err);
}
}
/**
* Mark a set of vertices of a geometry within a given bounding box.
* Method is called when display is in mode PvDisplayIf.MODE_MARK
* or if temporarily the m-key is pressed, and a rectangle is drawn.
* @param markBox contains four coplanar points on the bounding prism,
* and direction of prism.
*/
public void markVertices(PvPickEvent markBox) {
}
/**
* Unmark a set of vertices of a geometry within a given bounding box.
* Method is called when display is in mode PvDisplayIf.MODE_UNMARK
* or if temporarily the u-key is pressed, and a rectangle is drawn.
* @param markBox contains four coplanar points on the bounding prism, and direction of prism.
*/
public void unmarkVertices(PvPickEvent markBox) {
// PsDebug.message("unmarkVertices entered. Unmarked Vertex: " + pos.getVertexInd());
}
// ---------------- End of PvPickListenerIf ------------------------
private void setPolygonColors() {
PgGeometry[] geoms = geom.getGeometries();
for(int j = 0; j < geoms.length; ++j) {
if(geoms[j].getType() == PvGeometryIf.GEOM_POLYGON_SET) {
PiVector [] polygon = ((PgPolygonSet)geoms[j]).getPolygons();
for (int i=0; i < polygon.length; i++) {
if(facet.contains(new Integer(polygon[i].getEntry(0))) &&
facet.contains(new Integer(polygon[i].getEntry(1))) ) {
((PgPolygonSet)geoms[j]).setPolygonColor(i,projColor);
} else {
((PgPolygonSet)geoms[j]).setPolygonColor(i,facetColor);
}
}
}
geoms[j].update(geoms[j]);
}
}
protected void setUpGUI() {
// Standard Java technique to add a component to an applet.
setLayout(new BorderLayout());
// Create a ZOOM Slider which writes its value to the sink on change
PuDouble zoomFactor = new PuDouble("Zoom Factor", new zoomSlider());
zoomFactor.setDefBounds(0.01, 1.0, 0.01, 0.1);
zoomFactor.init();
// zoomFactor.setDefValue(0.5);
vertexDragged = true;
helpButton = new Button("Help");
helpButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (helpFrame == null)
helpFrame = new JavaviewSchlegelHelpFrame();
if (!helpFrame.isVisible()
|| helpFrame.getState() == Frame.ICONIFIED)
helpFrame.setLocation(getX() + 20, getY() + 20);
helpFrame.setState(Frame.NORMAL);
helpFrame.setVisible(true);
}
});
topPanel.setLayout(new BorderLayout());
topPanel.add(zoomFactor.assureInspector(PsPanel.INFO, PsPanel.INFO_EXT), BorderLayout.CENTER);
topPanel.add(helpButton, BorderLayout.EAST);
sliderMap.put("zoom",zoomFactor);
add((Component) disp, BorderLayout.CENTER);
add(topPanel, BorderLayout.NORTH);
storeButton = new Button("My Favorite View!");
storeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
parent.putMessage(SimpleGeometryParser.write(geom.getName(),"store",1.),false);
statusBar.setText("");
} catch (IOException ex) {
System.err.println("SchlegelFrame: error writing to client");
ex.printStackTrace(System.err);
}
}
});
sendMarkedButton = new Button("New Projection Facet");
sendMarkedButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Vector markedVertices = geom.getMarkedVertices();
if(markedVertices.isEmpty()) {
statusBar.setText("no points selected");
} else {
parent.putMessage(SimpleGeometryParser.writeFacet(geom.getName(),markedVertices),true);
statusBar.setText("");
}
} catch (IOException ex) {
System.err.println("SchlegelFrame: error writing to client");
ex.printStackTrace(System.err);
}
}
});
Panel panel = new Panel(new GridLayout(2,1));
Panel bPanel = new Panel(new GridLayout(1,2));
// bPanel.add(storeButton);
bPanel.add(sendMarkedButton);
panel.add(bPanel);
panel.add(statusBar);
add(panel, BorderLayout.SOUTH);
}
/**
* @author Thilo Schröder
*
* This class implements the update behaviour of the zoom factor slider.
*/
protected class zoomSlider extends PsObject {
public boolean update(java.lang.Object event) {
double actualValue = java.lang.Math.round(((PuDouble) event).getValue()*100)/100.0;
if (Double.parseDouble(parameters.getProperty("zoom")) == actualValue) {
return true;
}
try {
parent.putMessage(SimpleGeometryParser.write(geom.getName(),"zoom",actualValue),true);
statusBar.setText("");
} catch (IOException ex) {
System.err.println("SchlegelFrame: communication error");
ex.printStackTrace();
return false;
}
// parameters.setProperty("zoom", Double.toString(actualValue));
return true;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1