switch position display

This commit is contained in:
Bane Stojkovic
2025-03-15 23:29:47 +01:00
parent 74f43159c4
commit 9d8555c4b7
15 changed files with 686 additions and 56 deletions
@@ -24,6 +24,7 @@ package org.diylc.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.diylc.core.IDynamicPropertySource;
import org.diylc.core.IPropertyValidator;
/**
@@ -45,9 +46,10 @@ public class PropertyWrapper implements Cloneable {
private boolean changed = false;
private int sortOrder;
private Object ownerObject;
private IDynamicPropertySource dynamicPropertySource;
public PropertyWrapper(String name, Class<?> type, String getter, String setter, boolean defaultable,
IPropertyValidator validator, int sortOrder) {
IPropertyValidator validator, int sortOrder, IDynamicPropertySource dynamicPropertySource) {
super();
this.name = name;
this.type = type;
@@ -56,6 +58,7 @@ public class PropertyWrapper implements Cloneable {
this.defaultable = defaultable;
this.validator = validator;
this.sortOrder = sortOrder;
this.dynamicPropertySource = dynamicPropertySource;
this.ownerObject = null;
}
@@ -138,6 +141,10 @@ public class PropertyWrapper implements Cloneable {
return sortOrder;
}
public IDynamicPropertySource getDynamicPropertySource() {
return dynamicPropertySource;
}
// @Override
// public Object clone() throws CloneNotSupportedException {
// // Try to invoke clone method on value if possible.
@@ -152,7 +159,7 @@ public class PropertyWrapper implements Cloneable {
public Object clone() throws CloneNotSupportedException {
PropertyWrapper clone =
new PropertyWrapper(this.name, this.type, this.getter, this.setter, this.defaultable, this.validator,
this.sortOrder);
this.sortOrder, this.dynamicPropertySource);
clone.value = this.value;
clone.changed = this.changed;
clone.unique = this.unique;
@@ -0,0 +1,34 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.core;
import java.util.List;
import java.util.Map;
public interface IDynamicPropertySource {
void setComponent(IDIYComponent<?> component);
List<Object> getAvailableValues();
String getDisplayValue(Object value);
}
@@ -21,6 +21,8 @@
*/
package org.diylc.core;
import java.awt.*;
/**
* Interface for all component that can act as switches. They must have at least one position.
*
@@ -28,6 +30,13 @@ package org.diylc.core;
*/
public interface ISwitch {
Color[] POLE_COLORS = new Color[] { Color.decode("#FFD1DC"),
Color.decode("#FFE5B4"),
Color.decode("#FFFACD"),
Color.decode("#B8F2E6"),
Color.decode("#AEC6CF"),
Color.decode("#E6E6FA")};
/**
* @return a positive number of positions.
*/
@@ -48,4 +57,15 @@ public interface ISwitch {
* @return true if the two points are connected in the given switch position, false otherwise.
*/
boolean arePointsConnected(int index1, int index2, int position);
/**
* @return currently selected switch position, or null if none
*/
default Integer getSelectedPosition() {
return null;
}
default Boolean getRenderConnectedTerminals() {
return false;
}
}
@@ -0,0 +1,38 @@
package org.diylc.core;
import java.util.*;
public class SwitchPositionPropertyValueSource implements IDynamicPropertySource {
private IDIYComponent<?> component;
@Override
public void setComponent(IDIYComponent<?> component) {
this.component = component;
}
@Override
public List<Object> getAvailableValues() {
if (component == null) {
throw new RuntimeException("Component not set");
}
if (!(component instanceof ISwitch sw)) {
return List.of();
}
int positionCount = sw.getPositionCount();
List<Object> res = new ArrayList<>();
res.add(null);
for (int i = 0; i < positionCount; i++) {
res.add(i);
}
return res;
}
@Override
public String getDisplayValue(Object value) {
if (value == null) {
return "";
}
return "#" + (((Integer)value) + 1);
}
}
@@ -0,0 +1,42 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.core.annotations;
import org.diylc.core.IDynamicPropertySource;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/***
* Used for properties having dynamic set of possible values. Only to be used in addition to
* EditableProperty annotation.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamicEditableProperty {
/**
* Optional parameter for dynamic values
*
* @return
*/
Class<? extends IDynamicPropertySource> source() ;
}
@@ -25,6 +25,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.diylc.core.AllowAllValidator;
import org.diylc.core.IDynamicPropertySource;
import org.diylc.core.IPropertyValidator;
/**
@@ -41,11 +41,9 @@ import org.diylc.common.IComponentTransformer;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDynamicPropertySource;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.annotations.*;
import org.diylc.lang.LangUtil;
/**
@@ -189,10 +187,16 @@ public class ComponentProcessor {
LangUtil.translate(o.toString());
}
}
IDynamicPropertySource dynamicPropertySource = null;
if (getter.isAnnotationPresent(DynamicEditableProperty.class)) {
DynamicEditableProperty dynamicAnnotation = getter.getAnnotation(DynamicEditableProperty.class);
dynamicPropertySource = getDynamicPropertySource(dynamicAnnotation.source());
}
PropertyWrapper property =
new PropertyWrapper(name, getter.getReturnType(), getter.getName(), setterName,
annotation.defaultable(), validator, annotation.sortOrder());
annotation.defaultable(), validator, annotation.sortOrder(), dynamicPropertySource);
properties.add(property);
}
}
@@ -278,6 +282,17 @@ public class ComponentProcessor {
return validator;
}
private IDynamicPropertySource getDynamicPropertySource(Class<? extends IDynamicPropertySource> clazz) {
IDynamicPropertySource source;
try {
source = clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
LOG.error("Could not instantiate source for " + clazz.getName(), e);
return null;
}
return source;
}
private IComponentTransformer getComponentTransformer(Class<? extends IComponentTransformer> clazz) {
if (clazz == null)
return null;
@@ -1,3 +1,24 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.utils;
import org.apache.log4j.Logger;
@@ -1,3 +1,24 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.utils;
import java.awt.Graphics2D;
@@ -0,0 +1,89 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.utils;
import org.diylc.core.ISwitch;
import java.util.*;
public class SwitchUtils {
public static List<Set<Integer>> getConnectedTerminals(ISwitch switchComponent, int numPoints) {
List<Set<Integer>> connectedGroups = new ArrayList<>();
// Only process if we have a selected position and should render connections
if (switchComponent.getSelectedPosition() == null || !Boolean.TRUE.equals(switchComponent.getRenderConnectedTerminals())) {
return connectedGroups;
}
// First, collect all direct connections
List<int[]> connections = new ArrayList<>();
for (int i = 0; i < numPoints; i++) {
for (int j = i + 1; j < numPoints; j++) {
if (switchComponent.arePointsConnected(i, j, switchComponent.getSelectedPosition())) {
connections.add(new int[]{i, j});
}
}
}
// Create a map to track which points are in which group
Map<Integer, Set<Integer>> pointToGroup = new HashMap<>();
// Process each connection
for (int[] connection : connections) {
int p1 = connection[0];
int p2 = connection[1];
Set<Integer> group1 = pointToGroup.get(p1);
Set<Integer> group2 = pointToGroup.get(p2);
if (group1 == null && group2 == null) {
// Create new group
Set<Integer> newGroup = new HashSet<>();
newGroup.add(p1);
newGroup.add(p2);
pointToGroup.put(p1, newGroup);
pointToGroup.put(p2, newGroup);
} else if (group1 == null) {
// Add p1 to p2's group
group2.add(p1);
pointToGroup.put(p1, group2);
} else if (group2 == null) {
// Add p2 to p1's group
group1.add(p2);
pointToGroup.put(p2, group1);
} else if (group1 != group2) {
// Merge groups
group1.addAll(group2);
for (Integer p : group2) {
pointToGroup.put(p, group1);
}
}
}
// Collect unique groups
Set<Set<Integer>> uniqueGroups = new HashSet<>(pointToGroup.values());
connectedGroups.addAll(uniqueGroups);
return connectedGroups;
}
}