include stuck components in drag

This commit is contained in:
bancika
2011-01-13 21:34:45 +00:00
parent f3ed8d1a7c
commit e5c0b01aca
18 changed files with 113 additions and 41 deletions
@@ -6,14 +6,14 @@
<unit class="org.diylc.core.measures.ResistanceUnit">K</unit> <unit class="org.diylc.core.measures.ResistanceUnit">K</unit>
</org.diylc.core.measures.Resistance> </org.diylc.core.measures.Resistance>
</entry> </entry>
<entry>
<string>metric</string>
<boolean>true</boolean>
</entry>
<entry> <entry>
<string>lastPath</string> <string>lastPath</string>
<string>C:\Documents and Settings\Branislav Stojkovic\Desktop</string> <string>C:\Documents and Settings\Branislav Stojkovic\Desktop</string>
</entry> </entry>
<entry>
<string>metric</string>
<boolean>true</boolean>
</entry>
<entry> <entry>
<string>default.org.diylc.components.semiconductors.DIL_IC:Value</string> <string>default.org.diylc.components.semiconductors.DIL_IC:Value</string>
<string>LM366</string> <string>LM366</string>
@@ -23,11 +23,12 @@ public class ComponentType {
private Class<? extends IDIYComponent> instanceClass; private Class<? extends IDIYComponent> instanceClass;
private double zOrder; private double zOrder;
private boolean stretchable; private boolean stretchable;
private boolean sticky;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public ComponentType(String name, String description, String category, String namePrefix, public ComponentType(String name, String description, String category, String namePrefix,
String author, Icon icon, Class<? extends IDIYComponent> instanceClass, String author, Icon icon, Class<? extends IDIYComponent> instanceClass,
double zOrder, boolean stretchable) { double zOrder, boolean stretchable, boolean sticky) {
super(); super();
this.name = name; this.name = name;
this.description = description; this.description = description;
@@ -38,6 +39,7 @@ public class ComponentType {
this.instanceClass = instanceClass; this.instanceClass = instanceClass;
this.zOrder = zOrder; this.zOrder = zOrder;
this.stretchable = stretchable; this.stretchable = stretchable;
this.sticky = sticky;
} }
public String getName() { public String getName() {
@@ -76,6 +78,10 @@ public class ComponentType {
public boolean isStretchable() { public boolean isStretchable() {
return stretchable; return stretchable;
} }
public boolean isSticky() {
return sticky;
}
@Override @Override
public String toString() { public String toString() {
@@ -50,4 +50,10 @@ public @interface ComponentDescriptor {
* move together with it. * move together with it.
*/ */
boolean stretchable() default true; boolean stretchable() default true;
/**
* @return true, if control points may stick to other components' control
* points.
*/
boolean sticky() default false;
} }
@@ -60,6 +60,7 @@ public class ComponentProcessor {
Icon icon; Icon icon;
double zOrder; double zOrder;
boolean stretchable; boolean stretchable;
boolean sticky;
if (clazz.isAnnotationPresent(ComponentDescriptor.class)) { if (clazz.isAnnotationPresent(ComponentDescriptor.class)) {
ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class); ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class);
name = annotation.name(); name = annotation.name();
@@ -69,6 +70,7 @@ public class ComponentProcessor {
author = annotation.author(); author = annotation.author();
zOrder = annotation.zOrder(); zOrder = annotation.zOrder();
stretchable = annotation.stretchable(); stretchable = annotation.stretchable();
sticky = annotation.sticky();
} else { } else {
name = clazz.getSimpleName(); name = clazz.getSimpleName();
description = ""; description = "";
@@ -77,6 +79,7 @@ public class ComponentProcessor {
author = "Unknown"; author = "Unknown";
zOrder = IDIYComponent.COMPONENT; zOrder = IDIYComponent.COMPONENT;
stretchable = true; stretchable = true;
sticky = false;
} }
icon = null; icon = null;
// Draw component icon. // Draw component icon.
@@ -96,7 +99,7 @@ public class ComponentProcessor {
e.printStackTrace(); e.printStackTrace();
} }
ComponentType componentType = new ComponentType(name, description, category, namePrefix, ComponentType componentType = new ComponentType(name, description, category, namePrefix,
author, icon, clazz, zOrder, stretchable); author, icon, clazz, zOrder, stretchable, sticky);
return componentType; return componentType;
} }
@@ -70,8 +70,8 @@ public class Presenter implements IPlugInPort {
private Map<IDIYComponent<?>, Area> componentAreaMap; private Map<IDIYComponent<?>, Area> componentAreaMap;
private Project currentProject; private Project currentProject;
private Map<String, List<ComponentType>> componentTypes; private Map<String, List<ComponentType>> componentTypes;
@SuppressWarnings("unchecked") // Maps component class names to ComponentType objects.
private Map<Class<? extends IDIYComponent>, ComponentType> componentTypeMap; private Map<String, ComponentType> componentTypeMap;
private List<IPlugIn> plugIns; private List<IPlugIn> plugIns;
private ComponentSelection selectedComponents; private ComponentSelection selectedComponents;
@@ -192,14 +192,14 @@ public class Presenter implements IPlugInPort {
if (componentTypes == null) { if (componentTypes == null) {
LOG.info("Loading component types."); LOG.info("Loading component types.");
componentTypes = new HashMap<String, List<ComponentType>>(); componentTypes = new HashMap<String, List<ComponentType>>();
componentTypeMap = new HashMap<Class<? extends IDIYComponent>, ComponentType>(); componentTypeMap = new HashMap<String, ComponentType>();
List<Class<?>> componentTypeClasses = JarScanner.getInstance().scanFolder("library/", List<Class<?>> componentTypeClasses = JarScanner.getInstance().scanFolder("library/",
IDIYComponent.class); IDIYComponent.class);
for (Class<?> clazz : componentTypeClasses) { for (Class<?> clazz : componentTypeClasses) {
if (!Modifier.isAbstract(clazz.getModifiers())) { if (!Modifier.isAbstract(clazz.getModifiers())) {
ComponentType componentType = ComponentProcessor.getInstance() ComponentType componentType = ComponentProcessor.getInstance()
.createComponentTypeFrom((Class<? extends IDIYComponent<?>>) clazz); .createComponentTypeFrom((Class<? extends IDIYComponent<?>>) clazz);
componentTypeMap.put(componentType.getInstanceClass(), componentType); componentTypeMap.put(componentType.getInstanceClass().getName(), componentType);
List<ComponentType> nestedList; List<ComponentType> nestedList;
if (componentTypes.containsKey(componentType.getCategory())) { if (componentTypes.containsKey(componentType.getCategory())) {
nestedList = componentTypes.get(componentType.getCategory()); nestedList = componentTypes.get(componentType.getCategory());
@@ -227,7 +227,7 @@ public class Presenter implements IPlugInPort {
RenderingHints.VALUE_ANTIALIAS_ON); RenderingHints.VALUE_ANTIALIAS_ON);
} }
// AffineTransform initialTx = g2d.getTransform(); // AffineTransform initialTx = g2d.getTransform();
Dimension d = getCanvasDimensions(drawOptions.contains(DrawOption.ZOOM)); Dimension d = getCanvasDimensions(drawOptions.contains(DrawOption.ZOOM));
g2dWrapper.setColor(Constants.CANVAS_COLOR); g2dWrapper.setColor(Constants.CANVAS_COLOR);
@@ -303,10 +303,11 @@ public class Presenter implements IPlugInPort {
// Go back to the original transformation and zoom in to draw the // Go back to the original transformation and zoom in to draw the
// selection rectangle and other similar elements. // selection rectangle and other similar elements.
// g2d.setTransform(initialTx); // g2d.setTransform(initialTx);
// if ((drawOptions.contains(DrawOption.ZOOM)) && (Math.abs(1.0 - zoomLevel) > 1e-4)) { // if ((drawOptions.contains(DrawOption.ZOOM)) && (Math.abs(1.0 -
// g2d.scale(zoomLevel, zoomLevel); // zoomLevel) > 1e-4)) {
// } // g2d.scale(zoomLevel, zoomLevel);
// }
// At the end draw selection rectangle if needed. // At the end draw selection rectangle if needed.
if (drawOptions.contains(DrawOption.SELECTION) && (selectionRect != null)) { if (drawOptions.contains(DrawOption.SELECTION) && (selectionRect != null)) {
@@ -415,8 +416,8 @@ public class Presenter implements IPlugInPort {
try { try {
if (scaledPoint.distance(controlPoint) < CONTROL_POINT_SIZE) { if (scaledPoint.distance(controlPoint) < CONTROL_POINT_SIZE) {
Set<Integer> indices = new HashSet<Integer>(); Set<Integer> indices = new HashSet<Integer>();
ComponentType componentType = componentTypeMap ComponentType componentType = componentTypeMap.get(component.getClass()
.get(component.getClass()); .getName());
if (componentType.isStretchable()) { if (componentType.isStretchable()) {
indices.add(pointIndex); indices.add(pointIndex);
} else { } else {
@@ -521,10 +522,76 @@ public class Presenter implements IPlugInPort {
controlPointMap.put(c, pointIndices); controlPointMap.put(c, pointIndices);
} }
} }
// Expand control points to include all stuck components.
includeStuckComponents(controlPointMap);
LOG.debug(controlPointMap); LOG.debug(controlPointMap);
} }
} }
/**
* Finds any components that are stuck to one of the components already in
* the map.
*
* @param controlPointMap
*/
private void includeStuckComponents(Map<IDIYComponent<?>, Set<Integer>> controlPointMap) {
int oldSize = controlPointMap.size();
LOG.debug("Expanding selected component map");
for (IDIYComponent<?> component : currentProject.getComponents()) {
// Do not process a component if it's already in the map.
ComponentType componentType = componentTypeMap.get(component.getClass().getName());
if (!controlPointMap.containsKey(component) && componentType.isSticky()) {
// Check if there's a control point in the current selection
// that matches with one of its control points.
for (int i = 0; i < component.getControlPointCount(); i++) {
if (controlPointMap.containsKey(component)) {
break;
}
boolean componentMatches = false;
for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap
.entrySet()) {
if (componentMatches) {
break;
}
for (Integer j : entry.getValue()) {
Point firstPoint = component.getControlPoint(i);
Point secondPoint = entry.getKey().getControlPoint(j);
// If they are close enough we can consider them
// matched.
if (firstPoint.distance(secondPoint) < CONTROL_POINT_SIZE) {
componentMatches = true;
break;
}
}
}
if (componentMatches) {
LOG.debug("Including component: " + component);
Set<Integer> indices = new HashSet<Integer>();
// For stretchable components just add the
// matching component.
// Otherwise, add all control points.
if (componentType.isStretchable()) {
indices.add(i);
} else {
for (int k = 0; k < component.getControlPointCount(); k++) {
indices.add(k);
}
}
controlPointMap.put(component, indices);
}
}
}
}
int newSize = controlPointMap.size();
// As long as we're adding new components, do another iteration.
if (newSize > oldSize) {
LOG.debug("Component count changed, trying one more time.");
includeStuckComponents(controlPointMap);
} else {
LOG.debug("Component count didn't change, done with expanding.");
}
}
@Override @Override
public boolean dragOver(Point point) { public boolean dragOver(Point point) {
if (point == null) { if (point == null) {
@@ -612,7 +679,7 @@ public class Presenter implements IPlugInPort {
LOG.debug(String.format("addComponents(%s)", components)); LOG.debug(String.format("addComponents(%s)", components));
Project oldProject = cloner.deepClone(currentProject); Project oldProject = cloner.deepClone(currentProject);
for (IDIYComponent<?> component : components) { for (IDIYComponent<?> component : components) {
addComponent(component, componentTypeMap.get(component.getClass())); addComponent(component, componentTypeMap.get(component.getClass().getName()));
} }
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
.deepClone(currentProject), "Add"); .deepClone(currentProject), "Add");
@@ -784,7 +851,7 @@ public class Presenter implements IPlugInPort {
int index = 0; int index = 0;
while (index < currentProject.getComponents().size() while (index < currentProject.getComponents().size()
&& componentType.getZOrder() >= componentTypeMap.get( && componentType.getZOrder() >= componentTypeMap.get(
currentProject.getComponents().get(index).getClass()).getZOrder()) { currentProject.getComponents().get(index).getClass().getName()).getZOrder()) {
index++; index++;
} }
if (index < currentProject.getComponents().size()) { if (index < currentProject.getComponents().size()) {
@@ -921,7 +988,7 @@ public class Presenter implements IPlugInPort {
* component. * component.
*/ */
private boolean shouldShowControlPointsFor(IDIYComponent<?> component) { private boolean shouldShowControlPointsFor(IDIYComponent<?> component) {
ComponentType componentType = componentTypeMap.get(component.getClass()); ComponentType componentType = componentTypeMap.get(component.getClass().getName());
// Do not show control points for non-stretchable components. // Do not show control points for non-stretchable components.
if (!componentType.isStretchable()) { if (!componentType.isStretchable()) {
return false; return false;
@@ -13,7 +13,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "Trace", description = "", zOrder = IDIYComponent.ABOVE_BOARD) @ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "Trace", description = "", zOrder = IDIYComponent.ABOVE_BOARD, sticky = true)
public class CopperTrace extends AbstractLeadedComponent<Void> { public class CopperTrace extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -13,7 +13,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "Trace", description = "Curved copper trace with two control points", zOrder = IDIYComponent.ABOVE_BOARD) @ComponentDescriptor(name = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "Trace", description = "Curved copper trace with two control points", zOrder = IDIYComponent.ABOVE_BOARD, sticky = true)
public class CurvedTrace extends AbstractCurvedComponent<Void> { public class CurvedTrace extends AbstractCurvedComponent<Void> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -12,7 +12,7 @@ import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty; import org.diylc.core.annotations.EditableProperty;
import org.diylc.utils.Constants; import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.ABOVE_COMPONENT) @ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.ABOVE_COMPONENT, sticky = true)
public class HookupWire extends AbstractCurvedComponent<AWG> { public class HookupWire extends AbstractCurvedComponent<AWG> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -12,7 +12,7 @@ import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty; import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
@ComponentDescriptor(name = "Jumper", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "J", description = "", zOrder = IDIYComponent.ABOVE_BOARD) @ComponentDescriptor(name = "Jumper", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "J", description = "", zOrder = IDIYComponent.ABOVE_BOARD, sticky = true)
public class Jumper extends AbstractLeadedComponent<Void> { public class Jumper extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -14,7 +14,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants; import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Solder Pad", category = "Connectivity", author = "Branislav Stojkovic", description = "test", instanceNamePrefix = "Pad", stretchable = false, zOrder = IDIYComponent.ABOVE_BOARD + 0.1) @ComponentDescriptor(name = "Solder Pad", category = "Connectivity", author = "Branislav Stojkovic", description = "test", instanceNamePrefix = "Pad", stretchable = false, zOrder = IDIYComponent.ABOVE_BOARD + 0.1, sticky = true)
public class SolderPad extends AbstractComponent<Void> { public class SolderPad extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -18,7 +18,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Mini Toggle Switch", category = "Electromechanical", author = "Branislav Stojkovic", description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW") @ComponentDescriptor(name = "Mini Toggle Switch", category = "Electromechanical", author = "Branislav Stojkovic", description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW", sticky = true)
public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchType> { public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchType> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -14,7 +14,7 @@ import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Axial Film Capacitor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT) @ComponentDescriptor(name = "Axial Film Capacitor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT, sticky = true)
public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> { public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -14,7 +14,7 @@ import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Ceramic Capacitor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT) @ComponentDescriptor(name = "Ceramic Capacitor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT, sticky = true)
public class RadialCeramicDiskCapacitor extends AbstractLeadedComponent<Capacitance> { public class RadialCeramicDiskCapacitor extends AbstractLeadedComponent<Capacitance> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -14,7 +14,7 @@ import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Radial Film Capacitor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT) @ComponentDescriptor(name = "Radial Film Capacitor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT, sticky = true)
public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> { public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -14,7 +14,7 @@ import org.diylc.core.measures.ResistanceUnit;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "R", description = "test", zOrder = IDIYComponent.COMPONENT) @ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive", instanceNamePrefix = "R", description = "test", zOrder = IDIYComponent.COMPONENT, sticky = true)
public class Resistor extends AbstractLeadedComponent<Resistance> { public class Resistor extends AbstractLeadedComponent<Resistance> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -23,7 +23,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants; import org.diylc.utils.Constants;
@ComponentDescriptor(name = "DIL IC", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "IC", description = "test", stretchable = false, zOrder = IDIYComponent.COMPONENT) @ComponentDescriptor(name = "DIL IC", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "IC", description = "test", stretchable = false, zOrder = IDIYComponent.COMPONENT, sticky = true)
public class DIL_IC extends AbstractTransparentComponent<String> { public class DIL_IC extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -38,7 +38,6 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in); public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in);
public static Size INDENT_SIZE = new Size(0.15d, SizeUnit.in); public static Size INDENT_SIZE = new Size(0.15d, SizeUnit.in);
private String name = "New Component";
private String value = ""; private String value = "";
private Orientation orientation = Orientation.DEFAULT; private Orientation orientation = Orientation.DEFAULT;
private PinCount pinCount = PinCount._8; private PinCount pinCount = PinCount._8;
@@ -56,15 +55,6 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
updateControlPoints(); updateControlPoints();
} }
@EditableProperty(defaultable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@EditableProperty @EditableProperty
public String getValue() { public String getValue() {
return value; return value;