mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 02:32:09 +10:00
Derive the z-order of a building blocks placed as a single component based on its child components
This commit is contained in:
@@ -118,16 +118,10 @@ public class ComparatorFactory {
|
||||
if (componentZOrderComparator == null) {
|
||||
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
ComponentType type1 =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o1.getClass());
|
||||
ComponentType type2 =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o2.getClass());
|
||||
return Double.valueOf(type1.getZOrder()).compareTo(type2.getZOrder());
|
||||
return Double.compare(ComponentProcessor.getInstance().getZOrder(o1),
|
||||
ComponentProcessor.getInstance().getZOrder(o2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -409,6 +409,31 @@ public class ComponentProcessor {
|
||||
return type.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the z-order (layer) of the component. A {@link CompositeComponent} sits on the lowest
|
||||
* layer among its children rather than the one its class declares: it is drawn as a
|
||||
* single unit, so it takes one place in the stack, and that place has to be under
|
||||
* whatever is later put on top of it. A block of chassis panels therefore stays on the
|
||||
* chassis layer, and a block built from a board, pads and silkscreen text on the board
|
||||
* layer.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public double getZOrder(IDIYComponent<?> component) {
|
||||
if (component instanceof CompositeComponent) {
|
||||
double zOrder = Double.MAX_VALUE;
|
||||
for (IDIYComponent<?> child : ((CompositeComponent) component).getChildComponents()) {
|
||||
zOrder = Math.min(zOrder, getZOrder(child));
|
||||
}
|
||||
if (zOrder < Double.MAX_VALUE) {
|
||||
return zOrder;
|
||||
}
|
||||
}
|
||||
ComponentType type =
|
||||
extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
// internal types without a descriptor do not take part in layering
|
||||
return type == null ? Double.MAX_VALUE : type.getZOrder();
|
||||
}
|
||||
|
||||
public static boolean hasStickyPoint(IDIYComponent<?> c) {
|
||||
for (int i = 0; i < c.getControlPointCount(); i++)
|
||||
if (c.isControlPointSticky(0))
|
||||
|
||||
@@ -94,7 +94,8 @@ public class GroupAndLockIndex {
|
||||
if (componentType == null) {
|
||||
return false;
|
||||
}
|
||||
return project.getLockedLayers().contains((int) Math.round(componentType.getZOrder()))
|
||||
return project.getLockedLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)))
|
||||
|| project.getLockedComponents().contains(component);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,7 +494,8 @@ public class Presenter implements IPlugInPort {
|
||||
// for internal types
|
||||
if (componentType == null)
|
||||
return true;
|
||||
return !currentProject.getHiddenLayers().contains((int) Math.round(componentType.getZOrder()));
|
||||
return !currentProject.getHiddenLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1076,10 +1077,9 @@ public class Presenter implements IPlugInPort {
|
||||
Iterator<IDIYComponent<?>> i = newSelection.iterator();
|
||||
while (i.hasNext()) {
|
||||
IDIYComponent<?> c = i.next();
|
||||
ComponentType type =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
if ((int) type.getZOrder() != layer)
|
||||
if ((int) ComponentProcessor.getInstance().getZOrder(c) != layer) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSelection(newSelection);
|
||||
@@ -2229,6 +2229,7 @@ public class Presenter implements IPlugInPort {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
long layer = Math.round(ComponentProcessor.getInstance().getZOrder(component));
|
||||
int index = currentProject.getComponents().indexOf(component);
|
||||
if (index < 0) {
|
||||
LOG.warn("Component not found in the project: " + component.getName());
|
||||
@@ -2236,11 +2237,8 @@ public class Presenter implements IPlugInPort {
|
||||
while (index > 0) {
|
||||
IDIYComponent<?> componentBefore = currentProject.getComponents().get(index - 1);
|
||||
if (!selectedComponents.contains(componentBefore)) {
|
||||
ComponentType componentBeforeType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) componentBefore.getClass());
|
||||
if (!componentType.isFlexibleZOrder()
|
||||
&& Math.round(componentBeforeType.getZOrder()) < Math.round(componentType.getZOrder())
|
||||
&& Math.round(ComponentProcessor.getInstance().getZOrder(componentBefore)) < layer
|
||||
&& forceConfirmation != IView.YES_OPTION
|
||||
&& (forceConfirmation =
|
||||
this.view
|
||||
@@ -2278,6 +2276,7 @@ public class Presenter implements IPlugInPort {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
long layer = Math.round(ComponentProcessor.getInstance().getZOrder(component));
|
||||
int index = currentProject.getComponents().indexOf(component);
|
||||
if (index < 0) {
|
||||
LOG.warn("Component not found in the project: " + component.getName());
|
||||
@@ -2285,11 +2284,8 @@ public class Presenter implements IPlugInPort {
|
||||
while (index < currentProject.getComponents().size() - 1) {
|
||||
IDIYComponent<?> componentAfter = currentProject.getComponents().get(index + 1);
|
||||
if (!selectedComponents.contains(componentAfter)) {
|
||||
ComponentType componentAfterType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) componentAfter.getClass());
|
||||
if (!componentType.isFlexibleZOrder()
|
||||
&& Math.round(componentAfterType.getZOrder()) > Math.round(componentType.getZOrder())
|
||||
&& Math.round(ComponentProcessor.getInstance().getZOrder(componentAfter)) > layer
|
||||
&& forceConfirmation != IView.YES_OPTION
|
||||
&& (forceConfirmation =
|
||||
this.view
|
||||
@@ -2684,13 +2680,9 @@ public class Presenter implements IPlugInPort {
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addComponent(IDIYComponent<?> component, boolean allowAutoCreate) {
|
||||
int index = currentProject.getComponents().size();
|
||||
while (index > 0
|
||||
&& ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass()).getZOrder() < ComponentProcessor
|
||||
.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) currentProject.getComponents().get(index - 1).getClass())
|
||||
.getZOrder()) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
while (index > 0 && zOrder < ComponentProcessor.getInstance()
|
||||
.getZOrder(currentProject.getComponents().get(index - 1))) {
|
||||
index--;
|
||||
}
|
||||
if (index < currentProject.getComponents().size()) {
|
||||
@@ -2724,12 +2716,9 @@ public class Presenter implements IPlugInPort {
|
||||
int maxIndex = 0;
|
||||
for (IDIYComponent<?> component : components) {
|
||||
int index = currentProject.getComponents().size();
|
||||
while (index > maxIndex && ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass())
|
||||
.getZOrder() < ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) currentProject
|
||||
.getComponents().get(index - 1).getClass())
|
||||
.getZOrder()) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
while (index > maxIndex && zOrder < ComponentProcessor.getInstance()
|
||||
.getZOrder(currentProject.getComponents().get(index - 1))) {
|
||||
index--;
|
||||
}
|
||||
|
||||
@@ -3132,12 +3121,9 @@ public class Presenter implements IPlugInPort {
|
||||
return GroupAndLockIndex.isLocked(currentProject, component);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean isComponentLayerLocked(IDIYComponent<?> component) {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
return currentProject.getLockedLayers().contains((int) Math.round(componentType.getZOrder()));
|
||||
return currentProject.getLockedLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -517,6 +517,10 @@
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Re-modeled factory variants of Resistor component type as datasheet in order to make them available to the AI; this will produce more accurate AI-driven edits</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Derive the z-order of a building blocks placed as a single component based on its child components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added datasheets to 'DIP IC', 'SIP IC' and 'Multiwatt IC' - pick a part by its number from the component's submenu to set its pin count, spacing and pin names at once; the AI Assistant can place these parts by part number too</description>
|
||||
|
||||
+78
@@ -35,7 +35,12 @@ import java.util.UUID;
|
||||
|
||||
import org.diylc.common.Percentage;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.presenter.ComparatorFactory;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.presenter.GroupAndLockIndex;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.testcomponents.OnePointTestComponent;
|
||||
import org.diylc.testcomponents.TwoPointTestComponent;
|
||||
@@ -326,4 +331,77 @@ public class CompositeComponentTest {
|
||||
assertNotNull(blank.getChildComponents());
|
||||
assertTrue(blank.getChildComponents().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAChassisOnlyCompositeIsTheChassisLayer() {
|
||||
CompositeComponent composite = customBoard(new ChassisTestComponent(),
|
||||
new ChassisTestComponent());
|
||||
|
||||
assertEquals(IDIYComponent.CHASSIS, ComponentProcessor.getInstance().getZOrder(composite), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAMixedCompositeIsItsLowestChildLayer() {
|
||||
CompositeComponent composite = customBoard(new TextTestComponent(), twoPoint("R1"),
|
||||
new BoardTestComponent());
|
||||
|
||||
assertEquals(IDIYComponent.BOARD, ComponentProcessor.getInstance().getZOrder(composite), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfANestedCompositeLooksThroughTheInnerComposite() {
|
||||
CompositeComponent inner = customBoard(new ChassisTestComponent());
|
||||
CompositeComponent outer = customBoard(twoPoint("R1"), inner);
|
||||
|
||||
assertEquals(IDIYComponent.CHASSIS, ComponentProcessor.getInstance().getZOrder(outer), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAChildlessCompositeIsTheDeclaredOne() {
|
||||
assertEquals(IDIYComponent.COMPONENT,
|
||||
ComponentProcessor.getInstance().getZOrder(new CompositeComponent()), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lockingTheChildLayerLocksTheComposite() {
|
||||
Project project = new Project();
|
||||
CompositeComponent chassis = customBoard(new ChassisTestComponent());
|
||||
project.getComponents().add(chassis);
|
||||
|
||||
project.getLockedLayers().add(IDIYComponent.COMPONENT);
|
||||
assertFalse(GroupAndLockIndex.isLocked(project, chassis));
|
||||
|
||||
project.getLockedLayers().add(IDIYComponent.CHASSIS);
|
||||
assertTrue(GroupAndLockIndex.isLocked(project, chassis));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compositeSortsByItsChildLayer() {
|
||||
CompositeComponent chassis = customBoard(new ChassisTestComponent());
|
||||
BoardTestComponent board = new BoardTestComponent();
|
||||
|
||||
assertTrue(ComparatorFactory.getInstance().getComponentZOrderComparator().compare(chassis,
|
||||
board) < 0);
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Chassis Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "CT", zOrder = IDIYComponent.CHASSIS)
|
||||
public static class ChassisTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Board Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "BT", zOrder = IDIYComponent.BOARD)
|
||||
public static class BoardTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Text Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "TT", zOrder = IDIYComponent.TEXT)
|
||||
public static class TextTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user