Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values

This commit is contained in:
Bane Stojkovic
2026-04-06 21:04:55 +02:00
parent 124d1ab577
commit 194c8e0606
98 changed files with 12813 additions and 13008 deletions
@@ -0,0 +1,75 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2025 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.common;
import java.io.Serializable;
public class Percentage implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
private int value;
public Percentage(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + value;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Percentage other = (Percentage) obj;
if (value != other.value)
return false;
return true;
}
@Override
public String toString() {
return value + "%";
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@@ -149,10 +149,7 @@ public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComp
path.curveTo(p[4].getX(), p[4].getY(), p[5].getX(), p[5].getY(), p[6].getX(), p[6].getY());
}
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Composite oldComposite = applyAlpha(g2d, componentState);
drawCurve(path, g2d, componentState, drawingObserver);
@@ -22,24 +22,46 @@
package org.diylc.components;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.ComponentState;
import org.diylc.common.Percentage;
import java.awt.*;
public abstract class AbstractTransparentComponent<T> extends AbstractComponent<T> {
private static final long serialVersionUID = 1L;
public static byte MAX_ALPHA = 127;
public static byte MAX_ALPHA_LEGACY = Byte.MAX_VALUE;
public static int MAX_ALPHA = 100;
protected Byte alpha = MAX_ALPHA;
@Deprecated
protected Byte alpha;
@EditableProperty
public Byte getAlpha() {
if (alpha == null) {
alpha = MAX_ALPHA;
protected Percentage alphaPercent = new Percentage(100);
@EditableProperty(name = "Alpha")
public Percentage getAlpha() {
if (alphaPercent == null) {
if (alpha != null) {
alphaPercent = new Percentage(Math.round(100f * alpha / MAX_ALPHA_LEGACY));
alpha = null;
} else {
alphaPercent = new Percentage(100);
}
}
return alpha;
return alphaPercent;
}
public void setAlpha(Byte alpha) {
this.alpha = alpha;
public void setAlpha(Percentage alphaPercent) {
this.alphaPercent = alphaPercent;
}
public Composite applyAlpha(Graphics2D g2d, ComponentState componentState) {
Composite oldComposite = g2d.getComposite();
int alpha = componentState == ComponentState.DRAGGING ? 0 : getAlpha().getValue();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha / 100f));
}
return oldComposite;
}
}
@@ -27,5 +27,7 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface PercentEditor {
public byte _100PercentValue();
public int minValue() default 0;
public int maxValue() default 100;
}
@@ -68,7 +68,7 @@ import org.diylc.utils.Constants;
public class DrawingManager {
private static final Logger LOG = Logger.getLogger(DrawingManager.class);
public static final byte MIRROR_ALPHA = 64;
public static final Percentage MIRROR_ALPHA = new Percentage(50);
public static int CONTROL_POINT_SIZE = 7;
public static double EXTRA_SPACE = 0.25;
@@ -317,6 +317,10 @@
<changeType>NEW_FEATURE</changeType>
<description>Added more ceramic resistor variants to 'Resistor' component</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Improved editing experience of integer properties (e.g. number of terminals on a tag strip) by using the spinner text field</description>
@@ -235,7 +235,7 @@ public class CalcUtilsTest {
assertEquals(Color.BLACK.getRed(), result.getRed());
assertEquals(Color.BLACK.getGreen(), result.getGreen());
assertEquals(Color.BLACK.getBlue(), result.getBlue());
assertEquals(128, result.getAlpha());
assertEquals(128, result.getAlpha().getValue());
// Test light color with alpha - should become WHITE
Color transparentLight = new Color(255, 255, 200, 128);
@@ -243,16 +243,16 @@ public class CalcUtilsTest {
assertEquals(Color.WHITE.getRed(), result.getRed());
assertEquals(Color.WHITE.getGreen(), result.getGreen());
assertEquals(Color.WHITE.getBlue(), result.getBlue());
assertEquals(128, result.getAlpha());
assertEquals(128, result.getAlpha().getValue());
// Test fully transparent color
Color transparent = new Color(100, 150, 200, 0);
result = CalcUtils.convertToMonochrome(transparent);
assertEquals(0, result.getAlpha());
assertEquals(0, result.getAlpha().getValue());
// Test opaque color - alpha should remain 255
Color opaque = new Color(50, 50, 50);
result = CalcUtils.convertToMonochrome(opaque);
assertEquals(255, result.getAlpha());
assertEquals(255, result.getAlpha().getValue());
}
}