From 7069cacd0a08e8005a120a853f9b36d5d19f3ed9 Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Thu, 3 Sep 2026 16:41:22 +0200 Subject: [PATCH] add alpha to composite --- .../composite/CompositeComponent.java | 17 ++++++------ .../composite/CompositeComponentTest.java | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/diylc/diylc-core/src/main/java/org/diylc/components/composite/CompositeComponent.java b/diylc/diylc-core/src/main/java/org/diylc/components/composite/CompositeComponent.java index 20f007d3..d3d6328e 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/components/composite/CompositeComponent.java +++ b/diylc/diylc-core/src/main/java/org/diylc/components/composite/CompositeComponent.java @@ -22,6 +22,7 @@ package org.diylc.components.composite; import java.awt.Color; +import java.awt.Composite; import java.awt.Graphics2D; import java.awt.Stroke; import java.awt.geom.Point2D; @@ -31,6 +32,7 @@ import java.util.List; import java.util.Objects; import org.diylc.components.AbstractComponent; +import org.diylc.components.AbstractTransparentComponent; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; @@ -47,12 +49,6 @@ import org.diylc.utils.Constants; * so it can be placed, moved, rotated and wired up like any other component while the netlist, * BOM and AI project description still see its individual terminals (see * {@link #getControlPointNodeName(int)}). - *

- * The composite is intentionally a footprint, not a circuit model: it does not implement - * {@code IContinuity} or {@code ISwitch}, so internal point-to-point connectivity and internal - * switching are not represented (internal copper still conducts, since children draw through the - * same drawing observer). Its own properties are the only ones exposed for editing; children are - * frozen exactly as they were when the block was saved. * * @author Branislav Stojkovic */ @@ -69,7 +65,7 @@ import org.diylc.utils.Constants; enableCache = false, transformer = CompositeComponentTransformer.class, hiddenInPalette = true) -public class CompositeComponent extends AbstractComponent { +public class CompositeComponent extends AbstractTransparentComponent { private static final long serialVersionUID = 1L; @@ -212,11 +208,13 @@ public class CompositeComponent extends AbstractComponent { @Override public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, IDrawingObserver drawingObserver) { + Composite oldComposite = applyAlpha(g2d, componentState); for (IDIYComponent c : getChildComponents()) { // Children always draw in their normal state - the composite draws its own selection // outline below instead of letting every child paint its own highlight. c.draw(g2d, ComponentState.NORMAL, outlineMode, project, drawingObserver); } + g2d.setComposite(oldComposite); if (componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING) { Rectangle2D bounds = getControlPointBounds(); @@ -288,6 +286,8 @@ public class CompositeComponent extends AbstractComponent { clone.setId(getId()); clone.setName(getName()); clone.blockName = this.blockName; + // matches AbstractComponent.clone(), which shallow-copies the Percentage reference + clone.setAlpha(getAlpha()); List> clonedComponents = new ArrayList>(getChildComponents().size()); for (IDIYComponent c : getChildComponents()) { clonedComponents.add(c.clone()); @@ -310,7 +310,8 @@ public class CompositeComponent extends AbstractComponent { return false; } CompositeComponent o = (CompositeComponent) other; - if (!Objects.equals(getName(), o.getName()) || !Objects.equals(blockName, o.blockName)) { + if (!Objects.equals(getName(), o.getName()) || !Objects.equals(blockName, o.blockName) + || !Objects.equals(getAlpha(), o.getAlpha())) { return false; } List> otherComponents = o.getChildComponents(); diff --git a/diylc/diylc-core/src/test/java/org/diylc/components/composite/CompositeComponentTest.java b/diylc/diylc-core/src/test/java/org/diylc/components/composite/CompositeComponentTest.java index 38739446..83199499 100644 --- a/diylc/diylc-core/src/test/java/org/diylc/components/composite/CompositeComponentTest.java +++ b/diylc/diylc-core/src/test/java/org/diylc/components/composite/CompositeComponentTest.java @@ -31,6 +31,7 @@ import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.UUID; +import org.diylc.common.Percentage; import org.diylc.core.IDIYComponent; import org.diylc.netlist.Node; import org.diylc.serialization.ProjectFileManager; @@ -163,6 +164,31 @@ public class CompositeComponentTest { assertFalse(a.equalsTo(b)); } + @Test + public void defaultsToFullyOpaque() { + assertEquals(new Percentage(100), twoChildComposite().getAlpha()); + } + + @Test + public void cloneCopiesAlpha() throws Exception { + CompositeComponent original = twoChildComposite(); + original.setAlpha(new Percentage(40)); + + CompositeComponent clone = (CompositeComponent) original.clone(); + + assertEquals(new Percentage(40), clone.getAlpha()); + } + + @Test + public void equalsToRejectsDifferentAlpha() throws Exception { + CompositeComponent original = twoChildComposite(); + CompositeComponent clone = (CompositeComponent) original.clone(); + assertTrue(original.equalsTo(clone)); + + clone.setAlpha(new Percentage(50)); + assertFalse(original.equalsTo(clone)); + } + @Test public void survivesAnXStreamRoundTripAndRebuildsItsIndexLazily() { CompositeComponent original = twoChildComposite();