This commit is contained in:
bancika
2010-01-12 18:36:49 +00:00
parent 0ef611fe40
commit 9fecfe947c
14 changed files with 251 additions and 136 deletions
@@ -1,66 +0,0 @@
package com.diyfever.diylc.common;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
public class ActivePoint extends Point {
private static final long serialVersionUID = 1L;
private List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
public ActivePoint() {
super();
}
public ActivePoint(int x, int y) {
super(x, y);
}
public ActivePoint(Point p) {
super(p);
}
public void addPropertyChangeListener(PropertyChangeListener element) {
listeners.add(element);
}
public boolean removePropertyChangeListener(Object o) {
return listeners.remove(o);
}
@Override
public void setLocation(double x, double y) {
this.setLocation(new Point2D.Double(x, y));
}
@Override
public void setLocation(int x, int y) {
this.setLocation(new Point(x, y));
}
@Override
public void setLocation(Point p) {
for (PropertyChangeListener listener : listeners) {
listener.propertyChange(new PropertyChangeEvent(this, "value",
this, p));
}
super.setLocation(p);
}
public void setLocationSilent(double x, double y) {
super.setLocation(x, y);
}
public void setLocationSilent(int x, int y) {
super.setLocation(x, y);
}
public void setLocationSilent(Point p) {
super.setLocation(p);
}
}
@@ -10,7 +10,7 @@ import com.diyfever.diylc.model.VisibilityPolicy;
public class ControlPointWrapper {
private String name;
private ActivePoint value;
private Point value;
private Method setter;
private Method getter;
private boolean editable;
@@ -31,12 +31,7 @@ public class ControlPointWrapper {
public void readFrom(IComponentInstance component)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
Object object = getter.invoke(component);
if (object instanceof ActivePoint) {
value = (ActivePoint) getter.invoke(component);
} else {
value = new ActivePoint((Point) object);
}
value = (Point) getter.invoke(component);
}
public void writeTo(IComponentInstance component)
@@ -57,11 +52,11 @@ public class ControlPointWrapper {
return sticky;
}
public ActivePoint getValue() {
public Point getValue() {
return value;
}
public void setValue(ActivePoint value) {
public void setValue(Point value) {
this.value = value;
}
@@ -1,6 +1,36 @@
package com.diyfever.diylc.common;
import java.awt.Graphics;
/**
* Enumerates all options that can be used when drawing a project.
*
* @see IPlugInPort#draw(java.awt.Graphics2D, java.util.EnumSet)
*
* @author Branislav Stojkovic
*/
public enum DrawOption {
SELECTION, ZOOM, GRID, CONTROL_POINTS, ANTIALIASING;
/**
* Selection rectangle will be drawn when needed and selected components may
* be rendered differently.
*/
SELECTION,
/**
* Selected zoom level will be applied to scale the {@link Graphics} before
* drawing.
*/
ZOOM,
/**
* Grid lines are drawn.
*/
GRID,
/**
* Control points are drawn.
*/
CONTROL_POINTS,
/**
* Anti-aliasing is used when drawing.
*/
ANTIALIASING;
}
@@ -51,5 +51,5 @@ public enum EventType {
* {@link Project} are passed as parameters, one before and one after the
* change. The third parameter is a string containing change description.
*/
PROJECT_MODIFIED;
PROJECT_MODIFIED, AVAILABLE_CTRL_POINTS_CHANGED, SELECTED_CTRL_POINTS_CHANGED, ;
}
@@ -16,5 +16,4 @@ public interface IPlugIn extends IMessageListener<EventType> {
* @param plugInPort
*/
void connect(IPlugInPort plugInPort);
}
@@ -144,11 +144,13 @@ public interface IPlugInPort {
*
* @param point
*/
void pointClickedOn(Point point, boolean ctrlDown, boolean shiftDown,
void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown,
boolean altDown);
void mouseMoved(Point point);
/**
* Returns a list of currently selected components.
* Returns the current {@link ComponentSelection}.
*
* @return
*/
@@ -37,4 +37,12 @@ public @interface ControlPoint {
* @return
*/
boolean sticky() default true;
// /**
// * If true, the control point is the main control point for the component.
// * There cannot be more than one control point for a single component.
// *
// * @return
// */
// boolean main() default false;
}
@@ -142,6 +142,7 @@ class CanvasPanel extends JComponent implements Autoscroll {
@Override
public void mouseMoved(MouseEvent e) {
setCursor(plugInPort.getCursorAt(e.getPoint()));
plugInPort.mouseMoved(e.getPoint());
}
});
addMouseListener(new MouseAdapter() {
@@ -181,9 +182,9 @@ class CanvasPanel extends JComponent implements Autoscroll {
}
}
} else {
plugInPort.pointClickedOn(e.getPoint(), e
.isControlDown(), e.isShiftDown(), e
.isAltDown());
plugInPort.mouseClicked(e.getPoint(),
e.isControlDown(), e.isShiftDown(), e
.isAltDown());
}
}
}
@@ -1,6 +1,5 @@
package com.diyfever.diylc.plugins.file;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -9,8 +8,7 @@ import java.util.List;
import java.util.Map;
import com.diyfever.diylc.model.IComponentInstance;
import com.diyfever.diylc.model.annotations.BomName;
import com.diyfever.diylc.model.annotations.BomValue;
import com.diyfever.diylc.presenter.ComponentProcessor;
public class BomMaker {
@@ -29,24 +27,8 @@ public class BomMaker {
public List<BomEntry> createBom(List<IComponentInstance> components) {
Map<String, BomEntry> entryMap = new HashMap<String, BomEntry>();
for (IComponentInstance component : components) {
String name = null;
String value = null;
for (Method method : component.getClass().getMethods()) {
if (method.isAnnotationPresent(BomName.class)) {
try {
name = method.invoke(component).toString();
} catch (Exception e) {
name = null;
}
}
if (method.isAnnotationPresent(BomValue.class)) {
try {
value = method.invoke(component).toString();
} catch (Exception e) {
value = null;
}
}
}
String name = ComponentProcessor.getInstance().extractBomName(component);
String value = ComponentProcessor.getInstance().extractBomValue(component);
if ((name != null) && (value != null)) {
String key = name + "|" + value;
if (entryMap.containsKey(key)) {
@@ -6,6 +6,7 @@ import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EnumSet;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
@@ -17,7 +18,9 @@ import com.diyfever.diylc.common.BadPositionException;
import com.diyfever.diylc.common.EventType;
import com.diyfever.diylc.common.IPlugIn;
import com.diyfever.diylc.common.IPlugInPort;
import com.diyfever.diylc.model.IComponentInstance;
import com.diyfever.diylc.model.IComponentType;
import com.diyfever.diylc.presenter.ComponentProcessor;
import com.diyfever.gui.MemoryBar;
import com.diyfever.gui.miscutils.PercentageListCellRenderer;
import com.diyfever.gui.update.UpdateLabel;
@@ -33,6 +36,10 @@ public class StatusBar extends JPanel implements IPlugIn {
private IPlugInPort plugInPort;
// State variables
private IComponentType componentSlot;
private List<IComponentInstance> componentsUnderCursor;
public StatusBar() {
super();
@@ -135,9 +142,11 @@ public class StatusBar extends JPanel implements IPlugIn {
@Override
public EnumSet<EventType> getSubscribedEventTypes() {
return EnumSet.of(EventType.ZOOM_CHANGED, EventType.SLOT_CHANGED);
return EnumSet.of(EventType.ZOOM_CHANGED, EventType.SLOT_CHANGED,
EventType.AVAILABLE_CTRL_POINTS_CHANGED);
}
@SuppressWarnings("unchecked")
@Override
public void processMessage(EventType eventType, Object... params) {
switch (eventType) {
@@ -147,16 +156,40 @@ public class StatusBar extends JPanel implements IPlugIn {
}
break;
case SLOT_CHANGED:
IComponentType componentType = (IComponentType) params[0];
if (componentType == null) {
getStatusLabel().setText("");
} else {
getStatusLabel().setText(
"Click on the canvas to create a new "
+ componentType.getName()
+ " or press Esc to cancel");
}
componentSlot = (IComponentType) params[0];
refreshStatusText();
break;
case AVAILABLE_CTRL_POINTS_CHANGED:
componentsUnderCursor = (List<IComponentInstance>) params[0];
refreshStatusText();
break;
}
}
private void refreshStatusText() {
if (componentSlot == null) {
if ((componentsUnderCursor == null)
|| (componentsUnderCursor.isEmpty())) {
getStatusLabel().setText("");
} else {
String formattedNames = "";
int n = 1;
for (IComponentInstance component : componentsUnderCursor) {
if (n > 1) {
formattedNames += ", ";
}
formattedNames += ComponentProcessor.getInstance()
.extractBomName(component)
+ " (<b><font color=\"blue\">" + n++ + "</font></b>)";
}
getStatusLabel().setText(
"<html>" + "Edit: " + formattedNames + "</html>");
}
} else {
getStatusLabel().setText(
"Click on the canvas to create a new "
+ componentSlot.getName()
+ " or press Esc to cancel");
}
}
}
@@ -12,11 +12,13 @@ import org.apache.log4j.Logger;
import com.diyfever.diylc.common.ControlPointWrapper;
import com.diyfever.diylc.common.PropertyWrapper;
import com.diyfever.diylc.model.IComponentInstance;
import com.diyfever.diylc.model.annotations.BomName;
import com.diyfever.diylc.model.annotations.BomValue;
import com.diyfever.diylc.model.annotations.ControlPoint;
import com.diyfever.diylc.model.annotations.EditableProperty;
import com.rits.cloning.Cloner;
class ComponentProcessor {
public class ComponentProcessor {
private static final Logger LOG = Logger
.getLogger(ComponentProcessor.class);
@@ -158,4 +160,32 @@ class ComponentProcessor {
}
return properties;
}
public String extractBomName(IComponentInstance component) {
String name = null;
for (Method method : component.getClass().getMethods()) {
if (method.isAnnotationPresent(BomName.class)) {
try {
name = method.invoke(component).toString();
} catch (Exception e) {
name = null;
}
}
}
return name;
}
public String extractBomValue(IComponentInstance component) {
String value = null;
for (Method method : component.getClass().getMethods()) {
if (method.isAnnotationPresent(BomValue.class)) {
try {
value = method.invoke(component).toString();
} catch (Exception e) {
value = null;
}
}
}
return value;
}
}
@@ -58,13 +58,19 @@ public class Presenter implements IPlugInPort {
private static final VersionNumber CURRENT_VERSION = new VersionNumber(0,
0, 0);
private static final String DEFAULTS_KEY = "defaults";
private static final int CONTROL_POINT_SENSITIVITY = 4;
private double zoomLevel = 1;
private Map<IComponentInstance, Area> componentAreaMap;
private Project currentProject;
private Map<String, List<IComponentType>> componentTypes;
private List<IPlugIn> plugIns;
private ComponentSelection selectedComponents;
// List of component names that have at least one of their control points
// under the last recorded mouse position.
private List<IComponentInstance> componentsUnderCursor;
private Cloner cloner;
private Rectangle selectionRect;
@@ -210,8 +216,7 @@ public class Presenter implements IPlugInPort {
}
AffineTransform initialTx = g2d.getTransform();
Dimension d = getCanvasDimensions(drawOptions
.contains(DrawOption.ZOOM));
Dimension d = getCanvasDimensions(drawOptions.contains(DrawOption.ZOOM));
g2dWrapper.setColor(Color.white);
g2dWrapper.fillRect(0, 0, d.width, d.height);
@@ -256,18 +261,14 @@ public class Presenter implements IPlugInPort {
List<ControlPointWrapper> controlPoints = ComponentProcessor
.getInstance().extractControlPoints(
component.getClass());
for (ControlPointWrapper point : controlPoints) {
for (ControlPointWrapper controlPoint : controlPoints) {
try {
point.readFrom(component);
if (point.getVisibilityPolicy().equals(
VisibilityPolicy.ALWAYS)
|| ((point.getVisibilityPolicy()
.equals(VisibilityPolicy.WHEN_SELECTED)) && (getSelectedComponents()
.contains(component)))) {
controlPoint.readFrom(component);
if (shouldShowControlPoint(controlPoint, component)) {
g2d.setColor(Color.blue);
g2d.setStroke(new BasicStroke(2));
g2d.drawOval(point.getValue().x - 2, point
.getValue().y - 2, 4, 4);
g2d.drawOval(controlPoint.getValue().x - 2,
controlPoint.getValue().y - 2, 4, 4);
// g2d.fillOval(point.getValue().x - 2, point
// .getValue().y - 2, 5, 5);
}
@@ -312,12 +313,17 @@ public class Presenter implements IPlugInPort {
// view.setCursorIcon(icon);
// }
/**
* Finds all components whose areas include the specified {@link Point}.
* Point is <b>not</b> scaled by the zoom factor.
*
* @return
*/
private List<IComponentInstance> findComponentsAt(Point point) {
List<IComponentInstance> components = new ArrayList<IComponentInstance>();
for (Map.Entry<IComponentInstance, Area> entry : componentAreaMap
.entrySet()) {
if (entry.getValue().contains(point.x / zoomLevel,
point.y / zoomLevel)) {
if (entry.getValue().contains(point)) {
components.add(entry.getKey());
}
}
@@ -325,21 +331,22 @@ public class Presenter implements IPlugInPort {
}
@Override
public void pointClickedOn(Point point, boolean ctrlDown,
boolean shiftDown, boolean altDown) {
LOG.debug(String.format("pointClickedOn(%s, %s, %s, %s)", point,
public void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown,
boolean altDown) {
LOG.debug(String.format("mouseClicked(%s, %s, %s, %s)", point,
ctrlDown, shiftDown, altDown));
Point scaledPoint = scalePoint(point);
if (componentSlot != null) {
try {
instantiateComponent(componentSlot.getComponentInstanceClass(),
point);
scaledPoint);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
LOG.error("Error instatiating component of type: "
+ componentSlot.getComponentInstanceClass().getName());
}
setNewComponentSlot(null);
} else {
List<IComponentInstance> components = findComponentsAt(point);
List<IComponentInstance> components = findComponentsAt(scaledPoint);
// If there's nothing under mouse cursor deselect all.
if (components.isEmpty()) {
selectedComponents.clear();
@@ -365,6 +372,36 @@ public class Presenter implements IPlugInPort {
}
}
@Override
public void mouseMoved(Point point) {
List<IComponentInstance> components = new ArrayList<IComponentInstance>();
Point scaledPoint = scalePoint(point);
for (IComponentInstance component : currentProject.getComponents()) {
List<ControlPointWrapper> currentPoints = ComponentProcessor
.getInstance().extractControlPoints(component.getClass());
for (ControlPointWrapper controlPoint : currentPoints) {
if (shouldShowControlPoint(controlPoint, component)) {
try {
controlPoint.readFrom(component);
if (scaledPoint.distance(controlPoint.getValue()) < CONTROL_POINT_SENSITIVITY) {
components.add(component);
break;
}
} catch (Exception e) {
LOG
.warn("Error reading control point for component of type: "
+ component.getClass().getName());
}
}
}
}
if (!components.equals(componentsUnderCursor)) {
componentsUnderCursor = components;
messageDispatcher.dispatchMessage(
EventType.AVAILABLE_CTRL_POINTS_CHANGED, components);
}
}
@Override
public ComponentSelection getSelectedComponents() {
return new ComponentSelection(selectedComponents);
@@ -385,7 +422,8 @@ public class Presenter implements IPlugInPort {
LOG.debug(String.format("dragStarted(%s)", point));
dragInProgress = true;
dragStartPoint = point;
List<IComponentInstance> components = findComponentsAt(point);
Point scaledPoint = scalePoint(point);
List<IComponentInstance> components = findComponentsAt(scaledPoint);
if (components.isEmpty()) {
selectedComponents.clear();
messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
@@ -625,4 +663,18 @@ public class Presenter implements IPlugInPort {
messageDispatcher
.dispatchMessage(EventType.SLOT_CHANGED, componentSlot);
}
private Point scalePoint(Point point) {
return new Point((int) (point.x / zoomLevel),
(int) (point.y / zoomLevel));
}
private boolean shouldShowControlPoint(ControlPointWrapper controlPoint,
IComponentInstance component) {
return controlPoint.getVisibilityPolicy().equals(
VisibilityPolicy.ALWAYS)
|| ((controlPoint.getVisibilityPolicy()
.equals(VisibilityPolicy.WHEN_SELECTED)) && (getSelectedComponents()
.contains(component)));
}
}
@@ -0,0 +1,10 @@
package com.diyfever.diylc;
import java.util.List;
import com.diyfever.diylc.plugins.online.model.ProjectEntity;
import com.diyfever.httpproxy.ParamName;
public interface ProjectSearch {
List<ProjectEntity> project_search(@ParamName("criteria") String criteria);
}
@@ -0,0 +1,39 @@
package com.diyfever.diylc;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.BasicConfigurator;
import com.diyfever.diylc.plugins.online.model.ProjectEntity;
import com.diyfever.httpproxy.ParamName;
import com.diyfever.httpproxy.PhpFlatProxy;
import com.diyfever.httpproxy.ProxyFactory;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// XStream xstream = new XStream(new JettisonMappedXmlDriver());
// xstream.setMode(XStream.NO_REFERENCES);
//
// List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
//// projects.add(new ProjectEntity(1, "first project", "some text",
//// "bancika", "some category"));
//// projects.add(new ProjectEntity(2, "second project", "some text",
//// "bancika", "some category"));
// System.out.println(xstream.toXML(projects));
BasicConfigurator.configure();
ProjectSearch search = new ProxyFactory(new PhpFlatProxy())
.createProxy(ProjectSearch.class,
"http://host07.dwhost.net/~diyfever/diylc/db/");
List<ProjectEntity> results = search.project_search("TestProject");
System.out.println(results);
}
}