Z-order component handling

This commit is contained in:
bancika
2011-01-08 09:34:21 +00:00
parent 5b0753c42c
commit b9fe3d84e2
4 changed files with 64 additions and 22 deletions
@@ -8,7 +8,6 @@ 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;
/** /**
* Entity class that defines a project. Contains project properties and a * Entity class that defines a project. Contains project properties and a
* collection of components.This class is serialized to file. Some filed getters * collection of components.This class is serialized to file. Some filed getters
@@ -95,6 +94,11 @@ public class Project implements Serializable {
this.height = height; this.height = height;
} }
/**
* List of components sorted by z-order ascending.
*
* @return
*/
public List<IDIYComponent<?>> getComponents() { public List<IDIYComponent<?>> getComponents() {
return components; return components;
} }
@@ -1,7 +1,9 @@
package org.diylc.presenter; package org.diylc.presenter;
import java.util.Comparator; import java.util.Comparator;
import java.util.Map;
import org.diylc.common.ComponentType;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
public class ComparatorFactory { public class ComparatorFactory {
@@ -9,6 +11,7 @@ public class ComparatorFactory {
private static ComparatorFactory instance; private static ComparatorFactory instance;
private Comparator<IDIYComponent<?>> componentNameComparator; private Comparator<IDIYComponent<?>> componentNameComparator;
private Comparator<IDIYComponent<?>> componentZOrderComparator;
public static ComparatorFactory getInstance() { public static ComparatorFactory getInstance() {
if (instance == null) { if (instance == null) {
@@ -34,4 +37,20 @@ public class ComparatorFactory {
} }
return componentNameComparator; return componentNameComparator;
} }
public Comparator<IDIYComponent<?>> getComponentZOrderComparator(
final Map<Class<? extends IDIYComponent>, ComponentType> componentTypeMap) {
if (componentZOrderComparator == null) {
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
@Override
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
int zIndex1 = componentTypeMap.get(o1.getClass()).getLayer().ordinal();
int zIndex2 = componentTypeMap.get(o2.getClass()).getLayer().ordinal();
return new Integer(zIndex1).compareTo(zIndex2);
}
};
}
return componentZOrderComparator;
}
} }
@@ -17,6 +17,7 @@ import java.awt.geom.Point2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -401,6 +402,9 @@ public class Presenter implements IPlugInPort {
components.add(entry.getKey()); components.add(entry.getKey());
} }
} }
// Sort by z-order.
Collections.sort(components, ComparatorFactory.getInstance().getComponentZOrderComparator(
componentTypeMap));
return components; return components;
} }
@@ -411,11 +415,10 @@ public class Presenter implements IPlugInPort {
Point scaledPoint = scalePoint(point); Point scaledPoint = scalePoint(point);
if (componentSlot != null) { if (componentSlot != null) {
try { try {
instantiateComponent(componentSlot.getInstanceClass(), componentSlot.getName(), instantiateComponent(componentSlot, scaledPoint);
componentSlot.getNamePrefix(), scaledPoint);
} catch (Exception e) { } catch (Exception e) {
LOG.error("Error instatiating component of type: " LOG.error("Error instatiating component of type: "
+ componentSlot.getInstanceClass().getName()); + componentSlot.getInstanceClass().getName(), e);
} }
setNewComponentSlot(null); setNewComponentSlot(null);
} else { } else {
@@ -449,7 +452,8 @@ public class Presenter implements IPlugInPort {
Map<IDIYComponent<?>, Set<Integer>> components = new HashMap<IDIYComponent<?>, Set<Integer>>(); Map<IDIYComponent<?>, Set<Integer>> components = new HashMap<IDIYComponent<?>, Set<Integer>>();
Point scaledPoint = scalePoint(point); Point scaledPoint = scalePoint(point);
for (IDIYComponent<?> component : currentProject.getComponents()) { for (IDIYComponent<?> component : currentProject.getComponents()) {
for (int i = 0; i < component.getControlPointCount(); i++) { // Go backwards so we take the highest z-order components first.
for (int i = component.getControlPointCount() - 1; i >= 0; i--) {
Point controlPoint = component.getControlPoint(i); Point controlPoint = component.getControlPoint(i);
if (shouldShowControlPointsFor(component)) { if (shouldShowControlPointsFor(component)) {
try { try {
@@ -537,6 +541,7 @@ public class Presenter implements IPlugInPort {
return false; return false;
} }
Point scaledPoint = scalePoint(point); Point scaledPoint = scalePoint(point);
boolean repaint = false;
if (!controlPointMap.isEmpty()) { if (!controlPointMap.isEmpty()) {
// We're dragging control point(s). // We're dragging control point(s).
// IDIYComponent<?> firstComponent = // IDIYComponent<?> firstComponent =
@@ -559,6 +564,8 @@ public class Presenter implements IPlugInPort {
dx = (int) (Math.round(dx / Constants.GRID) * Constants.GRID); dx = (int) (Math.round(dx / Constants.GRID) * Constants.GRID);
dy = (int) (Math.round(dy / Constants.GRID) * Constants.GRID); dy = (int) (Math.round(dy / Constants.GRID) * Constants.GRID);
} }
// Only repaint if there's an actual change.
repaint = dx != 0 && dy != 0;
previousDragPoint.translate(dx, dy); previousDragPoint.translate(dx, dy);
@@ -566,7 +573,7 @@ public class Presenter implements IPlugInPort {
for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap.entrySet()) { for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap.entrySet()) {
IDIYComponent<?> c = entry.getKey(); IDIYComponent<?> c = entry.getKey();
for (Integer index : entry.getValue()) { for (Integer index : entry.getValue()) {
Point p = c.getControlPoint(index); Point p = new Point(c.getControlPoint(index));
p.translate(dx, dy); p.translate(dx, dy);
c.setControlPoint(p, index); c.setControlPoint(p, index);
} }
@@ -576,11 +583,12 @@ public class Presenter implements IPlugInPort {
// If there's no selection, the only thing to do is update the // If there's no selection, the only thing to do is update the
// selection rectangle and refresh. // selection rectangle and refresh.
this.selectionRect = Utils.createRectangle(scaledPoint, previousDragPoint); this.selectionRect = Utils.createRectangle(scaledPoint, previousDragPoint);
repaint = true;
// messageDispatcher.dispatchMessage(EventType.SELECTION_RECT_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_RECT_CHANGED,
// selectionRect); // selectionRect);
} else { } else {
// If there are components selected translate their control points. // If there are components selected translate their control points.
translateSelectedComponents(previousDragPoint, scaledPoint); repaint = translateSelectedComponents(previousDragPoint, scaledPoint);
// dragStartPoint = point; // dragStartPoint = point;
} }
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
@@ -621,21 +629,22 @@ public class Presenter implements IPlugInPort {
dragInProgress = false; dragInProgress = false;
} }
private void translateSelectedComponents(Point fromPoint, Point toPoint) { private boolean translateSelectedComponents(Point fromPoint, Point toPoint) {
if (toPoint == null) { if (toPoint == null) {
LOG.debug("Drag ended outside the drawing area."); LOG.debug("Drag ended outside the drawing area.");
return; return false;
} }
int dx = (int) (Math.round((toPoint.x - fromPoint.x) / zoomLevel / Constants.GRID) * Constants.GRID); int dx = (int) (Math.round((toPoint.x - fromPoint.x) / zoomLevel / Constants.GRID) * Constants.GRID);
int dy = (int) (Math.round((toPoint.y - fromPoint.y) / zoomLevel / Constants.GRID) * Constants.GRID); int dy = (int) (Math.round((toPoint.y - fromPoint.y) / zoomLevel / Constants.GRID) * Constants.GRID);
fromPoint.translate(dx, dy); fromPoint.translate(dx, dy);
for (IDIYComponent<?> component : selectedComponents) { for (IDIYComponent<?> component : selectedComponents) {
for (int i = 0; i < component.getControlPointCount(); i++) { for (int i = 0; i < component.getControlPointCount(); i++) {
Point controlPoint = component.getControlPoint(i); Point controlPoint = new Point(component.getControlPoint(i));
translateControlPoint(controlPoint, dx, dy); translateControlPoint(controlPoint, dx, dy);
component.setControlPoint(controlPoint, i); component.setControlPoint(controlPoint, i);
} }
} }
return dx != 0 && dy != 0;
} }
private void translateControlPoint(Point controlPoint, int dx, int dy) { private void translateControlPoint(Point controlPoint, int dx, int dy) {
@@ -705,21 +714,20 @@ public class Presenter implements IPlugInPort {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void instantiateComponent(Class<? extends IDIYComponent> componentClass, private void instantiateComponent(ComponentType componentType, Point point) throws Exception {
String componentTypeName, String namePrefix, Point point) throws Exception { LOG.info("Instatiating component of type: " + componentType.getInstanceClass().getName());
LOG.info("Instatiating component of type: " + componentClass.getName());
Project oldProject = cloner.deepClone(currentProject); Project oldProject = cloner.deepClone(currentProject);
// Instantiate the component. // Instantiate the component.
IDIYComponent component = componentClass.newInstance(); IDIYComponent component = componentType.getInstanceClass().newInstance();
// Find the next available componentName for the component. // Find the next available componentName for the component.
int i = 0; int i = 0;
boolean exists = true; boolean exists = true;
while (exists) { while (exists) {
i++; i++;
String name = namePrefix + i; String name = componentType.getNamePrefix() + i;
exists = false; exists = false;
for (IDIYComponent c : currentProject.getComponents()) { for (IDIYComponent c : currentProject.getComponents()) {
if (c.getName().equals(name)) { if (c.getName().equals(name)) {
@@ -728,15 +736,25 @@ public class Presenter implements IPlugInPort {
} }
} }
} }
component.setName(namePrefix + i); component.setName(componentType.getNamePrefix() + i);
// Add it to the project. // Add it to the project taking z-order into account.
currentProject.getComponents().add(component); int index = 0;
while (index < currentProject.getComponents().size()
&& componentType.getLayer().ordinal() >= componentTypeMap.get(
currentProject.getComponents().get(index).getClass()).getLayer().ordinal()) {
index++;
}
if (index < currentProject.getComponents().size()) {
currentProject.getComponents().add(index, component);
} else {
currentProject.getComponents().add(component);
}
// Translate them to the desired location. // Translate them to the desired location.
if (point != null) { if (point != null) {
for (int j = 0; j < component.getControlPointCount(); j++) { for (int j = 0; j < component.getControlPointCount(); j++) {
Point controlPoint = component.getControlPoint(j); Point controlPoint = new Point(component.getControlPoint(j));
int x = controlPoint.x + point.x; int x = controlPoint.x + point.x;
int y = controlPoint.y + point.y; int y = controlPoint.y + point.y;
if (snapToGrid) { if (snapToGrid) {
@@ -750,14 +768,15 @@ public class Presenter implements IPlugInPort {
// Extract properties. // Extract properties.
List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties( List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties(
componentClass); componentType.getInstanceClass());
// Override with default values if available. // Override with default values if available.
for (PropertyWrapper property : properties) { for (PropertyWrapper property : properties) {
Object defaultValue = null; Object defaultValue = null;
Map<String, Object> defaultMap = (Map<String, Object>) ConfigurationManager Map<String, Object> defaultMap = (Map<String, Object>) ConfigurationManager
.getInstance().getConfigurationItem(DEFAULTS_KEY); .getInstance().getConfigurationItem(DEFAULTS_KEY);
if (defaultMap != null) { if (defaultMap != null) {
defaultValue = defaultMap.get(componentClass.getName() + ":" + property.getName()); defaultValue = defaultMap.get(componentType.getInstanceClass().getName() + ":"
+ property.getName());
} }
if (defaultValue != null) { if (defaultValue != null) {
property.setValue(cloner.deepClone(defaultValue)); property.setValue(cloner.deepClone(defaultValue));
@@ -768,7 +787,7 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
.deepClone(currentProject), "Add " + componentTypeName); .deepClone(currentProject), "Add " + componentType.getName());
} }
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }