mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
Z-order component handling
This commit is contained in:
Binary file not shown.
+5
-1
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-21
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user