Review fixes: a drag in the Underside Display picks the part a click would, the part being placed there is drawn like the parts already there, a bottom Dot no longer adds an empty silkscreen page; one helper decides a part's board side and copper layers share an interface

This commit is contained in:
Bane Stojkovic
2026-11-11 17:32:46 +01:00
parent 5ef6952ef4
commit 13b31e6dd5
43 changed files with 345 additions and 170 deletions
@@ -24,7 +24,7 @@ package org.diylc.swing.plugins.file;
import org.diylc.common.DrawOption;
import org.diylc.common.IPlugInPort;
import org.diylc.common.PCBLayer;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IBoard;
import org.diylc.core.IDIYComponent;
import org.diylc.filter.PCBLayerFilter;
import org.diylc.filter.SilkScreenFilter;
@@ -59,11 +59,12 @@ public class SilkScreenDrawingProvider implements IDrawingProvider {
new SilkScreenFilter(page == 0 ? PCBLayer._2 : PCBLayer._1), zoomFactor, null, null);
}
// the top side, followed by the bottom side when a part is mounted there
// the top side, followed by the bottom side when it has silkscreen other than board outlines
@Override
public int getPageCount() {
SilkScreenFilter bottom = new SilkScreenFilter(PCBLayer._1);
for (IDIYComponent<?> c : plugInPort.getCurrentProject().getComponents()) {
if (c instanceof IBoardSideComponent && ((IBoardSideComponent) c).getBoardSide() == PCBLayer._1) {
if (!(c instanceof IBoard) && bottom.testComponent(c)) {
return 2;
}
}
@@ -24,7 +24,6 @@ package org.diylc.swing.plugins.file;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
@@ -37,6 +36,7 @@ import org.diylc.common.DrawOption;
import org.diylc.common.IPlugInPort;
import org.diylc.common.PCBLayer;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IPCBLayerComponent;
import org.diylc.filter.PCBLayerFilter;
/**
@@ -72,12 +72,8 @@ public class TraceMaskDrawingProvider implements IDrawingProvider {
private PCBLayer[] getUsedLayers() {
Set<PCBLayer> layers = EnumSet.noneOf(PCBLayer.class);
for (IDIYComponent<?> c : plugInPort.getCurrentProject().getComponents()) {
Class<?> clazz = c.getClass();
try {
Method m = clazz.getMethod("getLayer");
PCBLayer l = (PCBLayer) m.invoke(c);
layers.add(l);
} catch (Exception e) {
if (c instanceof IPCBLayerComponent copper) {
layers.add(copper.getLayer());
}
}
List<PCBLayer> sorted = new ArrayList<PCBLayer>(layers);
@@ -27,6 +27,7 @@ import org.diylc.common.IPlugInPort;
import org.diylc.common.PCBLayer;
import org.diylc.components.boards.BlankBoard;
import org.diylc.components.chassis.ChassisPanel;
import org.diylc.components.connectivity.Jumper;
import org.diylc.components.passive.Resistor;
import org.diylc.components.composite.CompositeComponent;
import org.diylc.core.BoardUndersideDisplay;
@@ -296,7 +297,8 @@ public class PresenterTests extends TestBase {
instantiateTwoClick("Passive", "Resistor", new Point(1000, 1000), new Point(1200, 1000));
IDIYComponent<?> resistor = presenter.getCurrentProject().getComponents().get(0);
IBoard board = boardUnder(resistor);
Point2D start = new Point2D.Double(resistor.getControlPoint(1).getX(), resistor.getControlPoint(1).getY());
Point2D start = new Point2D.Double(resistor.getControlPoint(1).getX(),
resistor.getControlPoint(1).getY());
Point inMirror = toScreen(UndersideMirror.createTransform(board).transform(start, null));
presenter.mouseMoved(inMirror, false, false, false);
@@ -314,8 +316,10 @@ public class PresenterTests extends TestBase {
instantiateTwoClick("Passive", "Resistor", new Point(1000, 1000), new Point(1200, 1000));
IDIYComponent<?> resistor = presenter.getCurrentProject().getComponents().get(0);
IBoard board = boardUnder(resistor);
Point2D start0 = new Point2D.Double(resistor.getControlPoint(0).getX(), resistor.getControlPoint(0).getY());
Point2D start1 = new Point2D.Double(resistor.getControlPoint(1).getX(), resistor.getControlPoint(1).getY());
Point2D start0 = new Point2D.Double(resistor.getControlPoint(0).getX(),
resistor.getControlPoint(0).getY());
Point2D start1 = new Point2D.Double(resistor.getControlPoint(1).getX(),
resistor.getControlPoint(1).getY());
// the hit test reads the areas recorded while drawing
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
@@ -399,6 +403,39 @@ public class PresenterTests extends TestBase {
// a board reaching 200px past the component on every side, with its underside mirror below it;
// the component stays selected
@Test
public void testDragThroughUndersideMirrorIgnoresPartsTheMirrorDoesNotShow() {
instantiateTwoClick("Passive", "Resistor", new Point(1000, 1000), new Point(1200, 1000));
IDIYComponent<?> resistor = presenter.getCurrentProject().getComponents().get(0);
IBoard board = boardUnder(resistor);
// a jumper drawn over the resistor with both ends off the board, so the mirror does not show it
double y = resistor.getControlPoint(0).getY();
Jumper jumper = new Jumper();
jumper.setControlPoint(new Point2D.Double(board.getBoardRectangle().getMinX() - 100, y), 0);
jumper.setControlPoint(new Point2D.Double(board.getBoardRectangle().getMaxX() + 100, y), 1);
presenter.getCurrentProject().getComponents().add(jumper);
Point2D jumperStart =
new Point2D.Double(jumper.getControlPoint(0).getX(), jumper.getControlPoint(0).getY());
Point2D resistorStart =
new Point2D.Double(resistor.getControlPoint(0).getX(), resistor.getControlPoint(0).getY());
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
presenter.draw(g2d, EnumSet.of(DrawOption.ZOOM), null, null, null, null);
g2d.dispose();
Point2D middle = new Point2D.Double(
(resistor.getControlPoint(0).getX() + resistor.getControlPoint(1).getX()) / 2,
resistor.getControlPoint(0).getY());
Point inMirror = toScreen(UndersideMirror.createTransform(board).transform(middle, null));
presenter.mouseMoved(inMirror, false, false, false);
presenter.dragStarted(inMirror, java.awt.dnd.DnDConstants.ACTION_MOVE, false, false);
presenter.dragOver(new Point(inMirror.x + 100, inMirror.y + 100));
presenter.dragEnded(new Point(inMirror.x + 100, inMirror.y + 100));
Assert.assertTrue(resistor.getControlPoint(0).getX() > resistorStart.getX());
Assert.assertEquals(jumperStart, jumper.getControlPoint(0));
}
private IBoard boardUnder(IDIYComponent<?> component) {
Point2D first = component.getControlPoint(0);
Point2D last = component.getControlPoint(component.getControlPointCount() - 1);
@@ -27,6 +27,7 @@ import java.awt.Point;
import org.diylc.TestBase;
import org.diylc.common.PCBLayer;
import org.diylc.components.connectivity.Dot;
import org.diylc.components.passive.Resistor;
import org.junit.Test;
@@ -47,4 +48,14 @@ public class SilkScreenDrawingProviderTest extends TestBase {
assertEquals(2, new SilkScreenDrawingProvider(presenter).getPageCount());
}
// a dot has no silkscreen, so a bottom page would show nothing but the board outline
@Test
public void testNoBottomPageForBottomDot() {
Dot dot = new Dot();
dot.setBoardSide(PCBLayer._1);
presenter.getCurrentProject().getComponents().add(dot);
assertEquals(1, new SilkScreenDrawingProvider(presenter).getPageCount());
}
}