better d&d of control points

doc
This commit is contained in:
bancika
2011-01-06 00:23:59 +00:00
parent b33d1c3e37
commit e612b39b26
10 changed files with 124 additions and 70 deletions
@@ -1,31 +1,6 @@
<map>
<entry>
<string>defaults</string>
<map>
<entry>
<string>com.diyfever.diylc.components.MockComponentInstance:C</string>
<com.diyfever.diylc.model.measures.Capacitance>
<value>22.0</value>
<unit class="com.diyfever.diylc.model.measures.CapacitanceUnit">uF</unit>
</com.diyfever.diylc.model.measures.Capacitance>
</entry>
<entry>
<string>com.diyfever.diylc.components.MockComponentInstance:Color</string>
<awt-color>
<red>255</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</awt-color>
</entry>
</map>
</entry>
<entry>
<string>metric</string>
<boolean>true</boolean>
</entry>
<entry>
<string>lastPath</string>
<string>C:\Documents and Settings\Branislav Stojkovic\Desktop</string>
</entry>
</map>
@@ -127,7 +127,7 @@ public abstract class AbstractLeadedDIYComponent<T> implements IDIYComponent<T>
(int) (shapeRect.height - textRect.getHeight()) / 2 + fontMetrics.getAscent());
}
@EditableProperty
@EditableProperty(defaultable = false)
public String getName() {
return name;
}
@@ -162,6 +162,7 @@ public abstract class AbstractLeadedDIYComponent<T> implements IDIYComponent<T>
return result;
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (this == obj)
@@ -38,7 +38,7 @@ public class DIL_IC implements IDIYComponent<String> {
new Point((int) (3 * Constants.GRID), (int) (2 * Constants.GRID)),
new Point((int) (3 * Constants.GRID), (int) (3 * Constants.GRID)) };
@EditableProperty
@EditableProperty(defaultable = false)
public String getName() {
return name;
}
@@ -17,7 +17,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Mock", author = "bancika", category = "Sample", instanceNamePrefix = "M", desciption = "test")
public class MockDIYComponent implements IDIYComponent<Object> {
public class MockDIYComponent implements IDIYComponent<Capacitance> {
private static final long serialVersionUID = 1L;
@@ -82,7 +82,7 @@ public class MockDIYComponent implements IDIYComponent<Object> {
return c;
}
public void setC(Capacitance c) {
public void setValue(Capacitance c) {
this.c = c;
}
@@ -23,11 +23,12 @@ public class ComponentType {
@SuppressWarnings("unchecked")
private Class<? extends IDIYComponent> instanceClass;
private ComponentLayer layer;
private boolean stretchable;
@SuppressWarnings("unchecked")
public ComponentType(String name, String description, String category, String namePrefix,
String author, Icon icon, Class<? extends IDIYComponent> instanceClass,
ComponentLayer layer) {
ComponentLayer layer, boolean stretchable) {
super();
this.name = name;
this.description = description;
@@ -37,6 +38,7 @@ public class ComponentType {
this.icon = icon;
this.instanceClass = instanceClass;
this.layer = layer;
this.stretchable = stretchable;
}
public String getName() {
@@ -72,6 +74,10 @@ public class ComponentType {
return layer;
}
public boolean isStretchable() {
return stretchable;
}
@Override
public String toString() {
return name;
@@ -30,16 +30,49 @@ import org.diylc.core.annotations.EditableProperty;
*/
public interface IDIYComponent<T> extends Serializable {
/**
* @return component instance name.
*/
String getName();
/**
* Updates component instance name.
*
* @param name
*/
void setName(String name);
/**
* @return component value.
*/
T getValue();
/**
* Updates component value.
*
* @param value
*/
void setValue(T value);
/**
* @return number of control points for this component instance. May vary
* between two instances of the same type, e.g. DIL IC with 8 and 16
* pins will have 8 or 16 pins although they are of the same type.
*/
int getControlPointCount();
/**
* @param index
* @return control point at the specified index.
*/
Point getControlPoint(int index);
/**
* Updates the control point at the specified index.
*
* @param point
* @param index
*/
void setControlPoint(Point point, int index);
/**
@@ -52,7 +85,8 @@ public interface IDIYComponent<T> extends Serializable {
void draw(Graphics2D g2d, ComponentState componentState, Project project);
/**
* Draws icon representation of the component.
* Draws icon representation of the component. This should not depend on
* component state, i.e. it should be treated as a static method.
*
* @param g2d
* @param width
@@ -16,16 +16,18 @@ public @interface EditableProperty {
/**
* Returns property name. If left blank property name will be extracted from
* the getter name, e.g. getter <code>getXYZ</code> will induce property
* name <code>XYZ</code>.
* name <code>XYZ</code>. <br>
* Default value is blank.
*
* @return
*/
String name() default "";
/**
* If true, application may set default value for this property.
* If true, application may set default value for this property. <br>
* Default value is true.
*
* @return
*/
boolean defaultable() default false;
boolean defaultable() default true;
}
@@ -19,6 +19,7 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -66,17 +67,19 @@ public class Presenter implements IPlugInPort {
public static final int CONTROL_POINT_SENSITIVITY = 4;
public static final int ICON_SIZE = 32;
public static boolean ENABLE_ANTIALIASING = true;
public static boolean DEBUG_COMPONENT_AREAS = false;
private double zoomLevel = 1;
private Map<IDIYComponent<?>, Area> componentAreaMap;
private Project currentProject;
private Map<String, List<ComponentType>> componentTypes;
private Map<Class<? extends IDIYComponent>, ComponentType> componentTypeMap;
private List<IPlugIn> plugIns;
private ComponentSelection selectedComponents;
// List of components that have at least one of their control points
// under the last recorded mouse position.
private Map<IDIYComponent<?>, Integer> componentControlPointMap;
// Maps components that have at least one dragged point to set of indices
// that designate which of their control points are being dragged.
private Map<IDIYComponent<?>, Set<Integer>> controlPointMap;
private Cloner cloner;
@@ -98,6 +101,8 @@ public class Presenter implements IPlugInPort {
private ComponentType componentSlot;
private boolean snapToGrid = true;
public Presenter(IView view) {
super();
this.view = view;
@@ -151,7 +156,7 @@ public class Presenter implements IPlugInPort {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
}
}
if (componentControlPointMap != null && !componentControlPointMap.isEmpty()) {
if (controlPointMap != null && !controlPointMap.isEmpty()) {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
}
}
@@ -189,6 +194,7 @@ public class Presenter implements IPlugInPort {
if (componentTypes == null) {
LOG.info("Loading component types.");
componentTypes = new HashMap<String, List<ComponentType>>();
componentTypeMap = new HashMap<Class<? extends IDIYComponent>, ComponentType>();
List<Class<?>> componentTypeClasses = JarScanner.getInstance().scanFolder("library/",
IDIYComponent.class);
for (Class<?> clazz : componentTypeClasses) {
@@ -202,6 +208,7 @@ public class Presenter implements IPlugInPort {
Icon icon;
Class<? extends IDIYComponent> instanceClass = (Class<? extends IDIYComponent>) clazz;
ComponentLayer layer;
boolean stretchable;
if (annotation == null) {
name = clazz.getSimpleName();
description = "";
@@ -209,6 +216,7 @@ public class Presenter implements IPlugInPort {
namePrefix = "Unknown";
author = "Unknown";
layer = ComponentLayer.COMPONENT;
stretchable = true;
} else {
name = annotation.name();
description = annotation.desciption();
@@ -216,6 +224,7 @@ public class Presenter implements IPlugInPort {
namePrefix = annotation.instanceNamePrefix();
author = annotation.author();
layer = annotation.componentLayer();
stretchable = annotation.stretchable();
}
icon = null;
// Draw component icon.
@@ -232,7 +241,8 @@ public class Presenter implements IPlugInPort {
e.printStackTrace();
}
ComponentType componentType = new ComponentType(name, description, category,
namePrefix, author, icon, instanceClass, layer);
namePrefix, author, icon, instanceClass, layer, stretchable);
componentTypeMap.put(instanceClass, componentType);
List<ComponentType> nestedList;
if (componentTypes.containsKey(componentType.getCategory())) {
nestedList = componentTypes.get(componentType.getCategory());
@@ -353,11 +363,13 @@ public class Presenter implements IPlugInPort {
}
// // Draw component area for test
// g2d.setStroke(new BasicStroke());
// g2d.setColor(Color.red);
// for (Area area : componentAreaMap.values()) {
// g2d.draw(area);
// }
if (DEBUG_COMPONENT_AREAS) {
g2d.setStroke(new BasicStroke());
g2d.setColor(Color.red);
for (Area area : componentAreaMap.values()) {
g2d.draw(area);
}
}
}
@Override
@@ -433,7 +445,7 @@ public class Presenter implements IPlugInPort {
@Override
public void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown) {
Map<IDIYComponent<?>, Integer> components = new HashMap<IDIYComponent<?>, Integer>();
Map<IDIYComponent<?>, Set<Integer>> components = new HashMap<IDIYComponent<?>, Set<Integer>>();
Point scaledPoint = scalePoint(point);
for (IDIYComponent<?> component : currentProject.getComponents()) {
for (int i = 0; i < component.getControlPointCount(); i++) {
@@ -441,7 +453,17 @@ public class Presenter implements IPlugInPort {
if (shouldShowControlPointsFor(component)) {
try {
if (scaledPoint.distance(controlPoint) < CONTROL_POINT_SENSITIVITY) {
components.put(component, i);
Set<Integer> indices = new HashSet<Integer>();
ComponentType componentType = componentTypeMap
.get(component.getClass());
if (componentType.isStretchable()) {
indices.add(i);
} else {
for (int j = 0; j < component.getControlPointCount(); j++) {
indices.add(j);
}
}
components.put(component, indices);
break;
}
} catch (Exception e) {
@@ -455,8 +477,8 @@ public class Presenter implements IPlugInPort {
break;
}
}
if (!components.equals(componentControlPointMap)) {
componentControlPointMap = components;
if (!components.equals(controlPointMap)) {
controlPointMap = components;
messageDispatcher.dispatchMessage(EventType.AVAILABLE_CTRL_POINTS_CHANGED, components);
}
}
@@ -484,10 +506,10 @@ public class Presenter implements IPlugInPort {
Point scaledPoint = scalePoint(point);
previousDragPoint = scaledPoint;
List<IDIYComponent<?>> components = findComponentsAt(scaledPoint);
if (!componentControlPointMap.isEmpty()) {
if (!controlPointMap.isEmpty()) {
// If we're dragging control points reset selection.
selectedComponents.clear();
selectedComponents.addAll(componentControlPointMap.keySet());
selectedComponents.addAll(controlPointMap.keySet());
messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, selectedComponents);
messageDispatcher.dispatchMessage(EventType.REPAINT);
} else if (components.isEmpty()) {
@@ -514,24 +536,39 @@ public class Presenter implements IPlugInPort {
return false;
}
Point scaledPoint = scalePoint(point);
if (!componentControlPointMap.isEmpty()) {
if (!controlPointMap.isEmpty()) {
// We're dragging control point(s).
IDIYComponent<?> firstComponent = componentControlPointMap.keySet().iterator().next();
Point controlPoint = firstComponent.getControlPoint(componentControlPointMap
.get(firstComponent));
if (controlPoint == null) {
LOG.warn("Control point not found in the map!");
// IDIYComponent<?> firstComponent =
// controlPointMap.keySet().iterator().next();
// Point controlPoint = firstComponent
// .getControlPoint(controlPointMap.get(firstComponent));
// if (controlPoint == null) {
// LOG.warn("Control point not found in the map!");
// }
// int x = (int) (Math.round((controlPoint.x + scaledPoint.x -
// previousDragPoint.x)
// / Constants.GRID) * Constants.GRID);
// int y = (int) (Math.round((controlPoint.y + scaledPoint.y -
// previousDragPoint.y)
// / Constants.GRID) * Constants.GRID);
// previousDragPoint.setLocation(x, y);
int dx = (point.x - previousDragPoint.x);
int dy = (point.y - previousDragPoint.y);
if (snapToGrid) {
dx = (int) (Math.round(dx / Constants.GRID) * Constants.GRID);
dy = (int) (Math.round(dy / Constants.GRID) * Constants.GRID);
}
int x = (int) (Math.round((controlPoint.x + scaledPoint.x - previousDragPoint.x)
/ Constants.GRID) * Constants.GRID);
int y = (int) (Math.round((controlPoint.y + scaledPoint.y - previousDragPoint.y)
/ Constants.GRID) * Constants.GRID);
previousDragPoint.setLocation(x, y);
previousDragPoint.translate(dx, dy);
// Update all points.
for (Map.Entry<IDIYComponent<?>, Integer> entry : componentControlPointMap.entrySet()) {
Point p = new Point(x, y);
entry.getKey().setControlPoint(p, entry.getValue());
for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap.entrySet()) {
IDIYComponent<?> c = entry.getKey();
for (Integer index : entry.getValue()) {
Point p = c.getControlPoint(index);
p.translate(dx, dy);
c.setControlPoint(p, index);
}
}
// dragStartPoint = point;
} else if (selectedComponents.isEmpty()) {
@@ -8,7 +8,7 @@ import java.awt.Toolkit;
public class Constants {
public static final float GRID = Toolkit.getDefaultToolkit().getScreenResolution() / 10f;
public static final float GRID = (int) (Toolkit.getDefaultToolkit().getScreenResolution() / 10f);
public static Color CANVAS_COLOR = Color.white;
public static Color GRID_COLOR = new Color(240, 240, 240);
@@ -13,14 +13,13 @@ import org.diylc.plugins.file.BomEntry;
import org.diylc.plugins.file.BomMaker;
import org.junit.Test;
public class BomMakerTest {
@Test
public void testCreateBom() {
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
MockDIYComponent c1 = new MockDIYComponent();
c1.setC(new Capacitance(3d, CapacitanceUnit.pF));
c1.setValue(new Capacitance(3d, CapacitanceUnit.pF));
components.add(c1);
components.add(new MockDIYComponent());
components.add(new MockDIYComponent());