From 65ebf9de721f7138350f5ee7ee5b54c7736a74a4 Mon Sep 17 00:00:00 2001 From: "neil.weinstock@gmail.com" Date: Tue, 8 Oct 2024 20:57:49 -0400 Subject: [PATCH 1/7] Implement angle constraints in fin editor --- .../main/resources/l10n/messages.properties | 6 +- .../configdialog/FreeformFinSetConfig.java | 56 ++++++++++++++++++- .../swing/gui/scalefigure/FinPointFigure.java | 23 ++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/core/src/main/resources/l10n/messages.properties b/core/src/main/resources/l10n/messages.properties index 58c287ad2..68c17d295 100644 --- a/core/src/main/resources/l10n/messages.properties +++ b/core/src/main/resources/l10n/messages.properties @@ -1260,9 +1260,11 @@ FreeformFinSetCfg.lbl.ttip.Fincant = The angle that the fins are canted with res FreeformFinSetCfg.lbl.FincrossSection = Fin cross section: FreeformFinSetCfg.lbl.Thickness = Thickness: FreeformFinSetConfig.lbl.doubleClick1 = Double-click -FreeformFinSetConfig.lbl.doubleClick2 = to edit -FreeformFinSetConfig.lbl.clickDrag = Click+drag: Add and move points +FreeformFinSetConfig.lbl.doubleClick2 = to edit table entry FreeformFinSetConfig.lbl.ctrlClick = Ctrl+click: Delete point +FreeformFinSetConfig.lbl.clickDrag = Click+drag: Add and move points +FreeformFinSetConfig.lbl.shiftClickDrag = Shift+click+drag: Lock angle to previous point +FreeformFinSetConfig.lbl.ctrlShiftClickDrag = Ctrl+shift+click+drag: Lock angle to following point FreeformFinSetConfig.lbl.scaleFin = Scale Fin FreeformFinSetConfig.lbl.exportCSV = Export CSV FreeformFinSetConfig.lbl.deletePoint = Delete point diff --git a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java index b43cc420b..0e3c4f778 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java @@ -337,9 +337,11 @@ public class FreeformFinSetConfig extends FinSetConfig { order.add(table); // row of text directly below figure - panel.add(new StyledLabel(trans.get("lbl.doubleClick1")+" "+trans.get("FreeformFinSetConfig.lbl.doubleClick2"), -2), "spanx 3"); - panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.clickDrag"), -2), "spanx 3"); - panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 3, wrap"); + panel.add(new StyledLabel(trans.get("lbl.doubleClick1")+" "+trans.get("FreeformFinSetConfig.lbl.doubleClick2"), -2), "spanx 2"); + panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 2, wrap"); + panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.clickDrag"), -2), "spanx 2"); + panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.shiftClickDrag"), -2), "spanx 2"); + panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlShiftClickDrag"), -2), "spanx 2, wrap"); // row of controls at the bottom of the tab: panel.add(selector.getAsPanel(), "aligny bottom, gap unrel"); @@ -534,13 +536,58 @@ public class FreeformFinSetConfig extends FinSetConfig { @Override public void mouseDragged(MouseEvent event) { int mods = event.getModifiersEx(); + /*XXX if (dragIndex < 0 || (mods & (ANY_MASK | MouseEvent.BUTTON1_DOWN_MASK)) != MouseEvent.BUTTON1_DOWN_MASK) { super.mouseDragged(event); return; } + */ Point2D.Double point = getCoordinates(event); final FreeformFinSet finset = (FreeformFinSet) component; + + // If shift is held down and a point is being dragged, constrain angle relative to previous or following point + int lockIndex = -1; + int highlightIndex = -1; + if (dragIndex >= 0 && (mods & MouseEvent.SHIFT_DOWN_MASK) != 0) { + if ((mods & MouseEvent.CTRL_DOWN_MASK) != 0) { + if (dragIndex < finset.getFinPoints().length-1) { + lockIndex = dragIndex + 1; + highlightIndex = dragIndex; + } + } + else if (dragIndex > 0) { + lockIndex = dragIndex - 1; + highlightIndex = dragIndex - 1; + } + + if (lockIndex >= 0) { + // Fetch point to lock to + final Coordinate lockPoint = finset.getFinPoints()[lockIndex]; + // Distances to vertical and horizontal lines + final double diffX = point.x - lockPoint.x; + final double diffY = point.y - lockPoint.y; + final double distanceX = Math.abs(diffX); + final double distanceY = Math.abs(diffY); + // Calculate distance to 45 or 135 degree line, as appropriate + final double a = 1; // always + final double b = (Math.signum(diffX) == Math.signum(diffY)) ? -1 : 1; + final double c = -(a*lockPoint.x + b*lockPoint.y); + final double distanceDiag = Math.abs(a*point.x + b*point.y + c) / Math.sqrt(2); + + // Snap in the appropriate direction + if (distanceX <= distanceY && distanceX <= distanceDiag) // snap horizontal + point.x = lockPoint.x; + else if (distanceY <= distanceX && distanceY <= distanceDiag) // snap vertical + point.y = lockPoint.y; + else { // snap diagonal + point.x = (b*( b*point.x - a*point.y) - a*c) / 2; + point.y = (a*(-b*point.x + a*point.y) - b*c) / 2; + } + } + } + figure.setHighlightIndex(highlightIndex); + try { finset.setPoint(dragIndex, point.x, point.y); } catch (IllegalFinPointException e) { @@ -627,6 +674,9 @@ public class FreeformFinSetConfig extends FinSetConfig { public void mouseReleased(MouseEvent event) { dragIndex = -1; dragPoint = null; + figure.setHighlightIndex(-1); + figure.updateFigure(); + super.mouseReleased(event); } diff --git a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java index 11b7a214f..4f3911ab7 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java +++ b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java @@ -39,6 +39,7 @@ public class FinPointFigure extends AbstractScaleFigure { private static final int LINE_WIDTH_FIN_PIXELS = 1; private static final int LINE_WIDTH_BODY_PIXELS = 2; + private static final int LINE_WIDTH_HIGHLIGHT_PIXELS = 3; // the size of the boxes around each fin point vertex private static final int LINE_WIDTH_BOX_PIXELS = 1; @@ -59,6 +60,7 @@ public class FinPointFigure extends AbstractScaleFigure { private Rectangle2D.Double[] finPointHandles = null; private int selectedIndex = -1; + private int highlightIndex = -1; private static Color backgroundColor; private static Color finPointBodyLineColor; @@ -124,6 +126,7 @@ public class FinPointFigure extends AbstractScaleFigure { paintRocketBody(g2); paintFinShape(g2); + paintHighlight(g2); paintFinHandles(g2); } @@ -261,6 +264,22 @@ public class FinPointFigure extends AbstractScaleFigure { g2.setColor(finPointBodyLineColor); g2.draw(shape); } + + private void paintHighlight(final Graphics2D g2) { + final Coordinate[] points = finset.getFinPointsWithRoot(); + + if (highlightIndex < 0 || highlightIndex > points.length - 1) { + return; + } + + Coordinate start = points[highlightIndex]; + Coordinate end = points[highlightIndex+1]; + + final float highlightWidth_m = (float) (LINE_WIDTH_HIGHLIGHT_PIXELS / scale ); + g2.setStroke(new BasicStroke(highlightWidth_m)); + g2.setColor(Color.RED); + g2.draw(new Line2D.Double(start.x, start.y, end.x, end.y)); + } private void paintFinHandles(final Graphics2D g2) { // Excludes fin tab points @@ -438,4 +457,8 @@ public class FinPointFigure extends AbstractScaleFigure { this.selectedIndex = newIndex; } + public void setHighlightIndex(final int newIndex) { + this.highlightIndex = newIndex; + } + } From efc043d2b4e902b96bfac8ab5e02e02db6eb7bc4 Mon Sep 17 00:00:00 2001 From: "neil.weinstock@gmail.com" Date: Tue, 8 Oct 2024 21:54:56 -0400 Subject: [PATCH 2/7] Small fix --- .../swing/gui/configdialog/FreeformFinSetConfig.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java index 0e3c4f778..c3f24acf0 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java @@ -536,12 +536,11 @@ public class FreeformFinSetConfig extends FinSetConfig { @Override public void mouseDragged(MouseEvent event) { int mods = event.getModifiersEx(); - /*XXX - if (dragIndex < 0 || (mods & (ANY_MASK | MouseEvent.BUTTON1_DOWN_MASK)) != MouseEvent.BUTTON1_DOWN_MASK) { + + if (dragIndex < 0) { super.mouseDragged(event); return; } - */ Point2D.Double point = getCoordinates(event); final FreeformFinSet finset = (FreeformFinSet) component; @@ -549,7 +548,7 @@ public class FreeformFinSetConfig extends FinSetConfig { // If shift is held down and a point is being dragged, constrain angle relative to previous or following point int lockIndex = -1; int highlightIndex = -1; - if (dragIndex >= 0 && (mods & MouseEvent.SHIFT_DOWN_MASK) != 0) { + if ((mods & MouseEvent.SHIFT_DOWN_MASK) != 0) { if ((mods & MouseEvent.CTRL_DOWN_MASK) != 0) { if (dragIndex < finset.getFinPoints().length-1) { lockIndex = dragIndex + 1; From f4b4e3ccc07daa6e864c184ef8c8ad858065a8ba Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 12 Oct 2024 13:02:29 +0200 Subject: [PATCH 3/7] Allow table editing with single click + fix tab traversal in table --- .../main/resources/l10n/messages.properties | 2 - .../resources/l10n/messages_ar.properties | 3 - .../resources/l10n/messages_cs.properties | 3 - .../resources/l10n/messages_de.properties | 3 - .../resources/l10n/messages_es.properties | 3 - .../resources/l10n/messages_fr.properties | 3 - .../resources/l10n/messages_it.properties | 3 - .../resources/l10n/messages_ja.properties | 3 - .../resources/l10n/messages_nl.properties | 3 - .../resources/l10n/messages_pl.properties | 3 - .../resources/l10n/messages_pt.properties | 3 - .../resources/l10n/messages_ru.properties | 3 - .../resources/l10n/messages_uk_UA.properties | 2 - .../resources/l10n/messages_zh_CN.properties | 3 - .../configdialog/FreeformFinSetConfig.java | 60 ++++++++++++++++--- 15 files changed, 52 insertions(+), 48 deletions(-) diff --git a/core/src/main/resources/l10n/messages.properties b/core/src/main/resources/l10n/messages.properties index 840d1e5c2..3cb057103 100644 --- a/core/src/main/resources/l10n/messages.properties +++ b/core/src/main/resources/l10n/messages.properties @@ -1342,8 +1342,6 @@ FreeformFinSetCfg.lbl.Fincant = Fin cant: FreeformFinSetCfg.lbl.ttip.Fincant = The angle that the fins are canted with respect to the rocket body. FreeformFinSetCfg.lbl.FincrossSection = Fin cross section: FreeformFinSetCfg.lbl.Thickness = Thickness: -FreeformFinSetConfig.lbl.doubleClick1 = Double-click -FreeformFinSetConfig.lbl.doubleClick2 = to edit table entry FreeformFinSetConfig.lbl.ctrlClick = Ctrl+click: Delete point FreeformFinSetConfig.lbl.clickDrag = Click+drag: Add and move points FreeformFinSetConfig.lbl.shiftClickDrag = Shift+click+drag: Lock angle to previous point diff --git a/core/src/main/resources/l10n/messages_ar.properties b/core/src/main/resources/l10n/messages_ar.properties index 609c91090..92a7eee9a 100644 --- a/core/src/main/resources/l10n/messages_ar.properties +++ b/core/src/main/resources/l10n/messages_ar.properties @@ -1033,9 +1033,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = :الموقع بالنسبة إلى FreeformFinSetCfg.lbl.plus = plus FreeformFinSetCfg.lbl.FincrossSection = :المقطع العرضي للزعنفة FreeformFinSetCfg.lbl.Thickness = :السماكة -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = نقرتين -FreeformFinSetConfig.lbl.doubleClick2 = للتعديل FreeformFinSetConfig.lbl.clickDrag = أنقر وإسحب: لإضافة وتحريك نقاط FreeformFinSetConfig.lbl.ctrlClick = مفتاح التحكم مع النقر: لحذف نقطة FreeformFinSetConfig.lbl.scaleFin = حَجِّمْ الزعنفة diff --git a/core/src/main/resources/l10n/messages_cs.properties b/core/src/main/resources/l10n/messages_cs.properties index 28b602379..af6f08cbe 100644 --- a/core/src/main/resources/l10n/messages_cs.properties +++ b/core/src/main/resources/l10n/messages_cs.properties @@ -715,9 +715,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = Pozice vzhledem k: FreeformFinSetCfg.lbl.plus = plus FreeformFinSetCfg.lbl.FincrossSection = Hrany stabiliztoru: FreeformFinSetCfg.lbl.Thickness = Tlou\u0161tka: -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = Dvoj klik -FreeformFinSetConfig.lbl.doubleClick2 = k editaci FreeformFinSetConfig.lbl.clickDrag = Klik a thnout: Pridej a presun body FreeformFinSetConfig.lbl.ctrlClick = Ctrl+klik: Odstran bod FreeformFinSetConfig.lbl.scaleFin = Mertko stabiliztoru diff --git a/core/src/main/resources/l10n/messages_de.properties b/core/src/main/resources/l10n/messages_de.properties index 9544e29a4..446f9f52b 100644 --- a/core/src/main/resources/l10n/messages_de.properties +++ b/core/src/main/resources/l10n/messages_de.properties @@ -772,9 +772,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = Position relativ zu: FreeformFinSetCfg.lbl.plus = plus FreeformFinSetCfg.lbl.FincrossSection = Querschnitt: FreeformFinSetCfg.lbl.Thickness = Wandstrke: -! doubleClick1 + 2 form the message "Doppelklick zum Bearbeiten", ungefhr in der Mitte teilen -FreeformFinSetConfig.lbl.doubleClick1 = Doppelklick -FreeformFinSetConfig.lbl.doubleClick2 = zum Bearbeiten FreeformFinSetConfig.lbl.clickDrag = Klicken+Ziehen: Punkte bewegen und hinzufgen FreeformFinSetConfig.lbl.ctrlClick = Strg+Klick: Punkt lschen FreeformFinSetConfig.lbl.scaleFin = Leitwerk skalieren diff --git a/core/src/main/resources/l10n/messages_es.properties b/core/src/main/resources/l10n/messages_es.properties index 154d5a816..f4197626e 100644 --- a/core/src/main/resources/l10n/messages_es.properties +++ b/core/src/main/resources/l10n/messages_es.properties @@ -374,9 +374,6 @@ FreeformFinSetCfg.tab.ttip.General = Propiedades generales FreeformFinSetConfig.lbl.clickDrag = Click (sobre l\u00ednea)+arrastrar: Agregar punto FreeformFinSetConfig.lbl.ctrlClick = Control+Click (sobre punto): Eliminar punto -!DobleClic 1 + 2 en el mensaje "Doble-Click para editar", corta aproximadamente por la mitad -FreeformFinSetConfig.lbl.doubleClick1 = Doble Click en la lista -FreeformFinSetConfig.lbl.doubleClick2 = para editar FreeformFinSetConfig.lbl.scaleFin = Dimensionar GeneralOptimizationDialog.basicSimulationName = Simulaci\u00f3n b\u00e1sica diff --git a/core/src/main/resources/l10n/messages_fr.properties b/core/src/main/resources/l10n/messages_fr.properties index 98ca53516..fbe18ed00 100644 --- a/core/src/main/resources/l10n/messages_fr.properties +++ b/core/src/main/resources/l10n/messages_fr.properties @@ -365,9 +365,6 @@ FreeformFinSetCfg.tab.ttip.General = Propri\u00E9t\u00E9s g\u00E9n\u00E9rales FreeformFinSetConfig.lbl.clickDrag = Cliquer+d\u00E9placer: Ajouter et d\u00E9placer des points FreeformFinSetConfig.lbl.ctrlClick = Ctrl+cliquer: Enlever un point -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = Double-cliquer -FreeformFinSetConfig.lbl.doubleClick2 = pour modifier FreeformFinSetConfig.lbl.scaleFin = Redimensionner les ailerons GeneralOptimizationDialog.basicSimulationName = Simulation simple diff --git a/core/src/main/resources/l10n/messages_it.properties b/core/src/main/resources/l10n/messages_it.properties index 19f4f4715..3e6786b2b 100644 --- a/core/src/main/resources/l10n/messages_it.properties +++ b/core/src/main/resources/l10n/messages_it.properties @@ -774,9 +774,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = Posizione relativa a : FreeformFinSetCfg.lbl.plus = pi\u00f9 FreeformFinSetCfg.lbl.FincrossSection = Sezione delle pinne FreeformFinSetCfg.lbl.Thickness = Spessore: -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = Doppio-click -FreeformFinSetConfig.lbl.doubleClick2 = per modificare FreeformFinSetConfig.lbl.clickDrag = Click+muovi: aggiunge e muove punti FreeformFinSetConfig.lbl.ctrlClick = Ctrl+click: rimuove punti FreeformFinSetConfig.lbl.scaleFin = Scala pinna diff --git a/core/src/main/resources/l10n/messages_ja.properties b/core/src/main/resources/l10n/messages_ja.properties index 86e9a7789..7671fa434 100644 --- a/core/src/main/resources/l10n/messages_ja.properties +++ b/core/src/main/resources/l10n/messages_ja.properties @@ -804,9 +804,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = \u4F4D\u7F6E\uFF1A FreeformFinSetCfg.lbl.plus = \u30D7\u30E9\u30B9 FreeformFinSetCfg.lbl.FincrossSection = \u30D5\u30A3\u30F3\u65AD\u9762\u7A4D\uFF1A FreeformFinSetCfg.lbl.Thickness = \u539A\u3055\uFF1A -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = \u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF\u3067 -FreeformFinSetConfig.lbl.doubleClick2 = \u7DE8\u96C6 FreeformFinSetConfig.lbl.clickDrag = Click+drag: \u30DD\u30A4\u30F3\u30C8\u306E\u8FFD\u52A0\u3068\u79FB\u52D5 FreeformFinSetConfig.lbl.ctrlClick = Ctrl+click: \u30DD\u30A4\u30F3\u30C8\u306E\u524A\u9664 FreeformFinSetConfig.lbl.scaleFin = Scale Fin diff --git a/core/src/main/resources/l10n/messages_nl.properties b/core/src/main/resources/l10n/messages_nl.properties index ecd1496c5..06bb2d5d6 100644 --- a/core/src/main/resources/l10n/messages_nl.properties +++ b/core/src/main/resources/l10n/messages_nl.properties @@ -984,9 +984,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = Positie relatief t.o.v.: FreeformFinSetCfg.lbl.plus = plus FreeformFinSetCfg.lbl.FincrossSection = Vindoorsnede: FreeformFinSetCfg.lbl.Thickness = Dikte: -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = Dubbelklik op -FreeformFinSetConfig.lbl.doubleClick2 = om te bewerken FreeformFinSetConfig.lbl.clickDrag = Klik+sleep: Punten toevoegen en verplaatsen FreeformFinSetConfig.lbl.ctrlClick = Ctrl+klik: Verwijder punt FreeformFinSetConfig.lbl.scaleFin = Schaal vin diff --git a/core/src/main/resources/l10n/messages_pl.properties b/core/src/main/resources/l10n/messages_pl.properties index d46226ee5..69c80af8e 100644 --- a/core/src/main/resources/l10n/messages_pl.properties +++ b/core/src/main/resources/l10n/messages_pl.properties @@ -719,9 +719,6 @@ ComponentInfo.EngineBlock = Blokada silnika unieruchamia silnik wewn\u01 FreeformFinSetCfg.lbl.plus = plus FreeformFinSetCfg.lbl.FincrossSection = Przekrj statecznika: FreeformFinSetCfg.lbl.Thickness = Grubo\u015B\u0107: - ! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle - FreeformFinSetConfig.lbl.doubleClick1 = Kliknij dwukrotnie - FreeformFinSetConfig.lbl.doubleClick2 = aby edytowa\u0107 FreeformFinSetConfig.lbl.clickDrag = Kliknij i przeci\u0105gnij: Dodaj i przesuwaj punkty FreeformFinSetConfig.lbl.ctrlClick = Ctrl+klik: Usu\u0144 punkt FreeformFinSetConfig.lbl.scaleFin = Skaluj statecznik diff --git a/core/src/main/resources/l10n/messages_pt.properties b/core/src/main/resources/l10n/messages_pt.properties index c71236ce9..7dd1875d4 100644 --- a/core/src/main/resources/l10n/messages_pt.properties +++ b/core/src/main/resources/l10n/messages_pt.properties @@ -354,9 +354,6 @@ FreeformFinSetCfg.tab.ttip.General = Propriedades gerais FreeformFinSetConfig.lbl.clickDrag = Clique+arraste: Adicionar e mover pontos FreeformFinSetConfig.lbl.ctrlClick = Ctrl+clique em: Remover ponto -# doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = Duplo clique -FreeformFinSetConfig.lbl.doubleClick2 = editar FreeformFinSetConfig.lbl.scaleFin = Escala da aleta GeneralOptimizationDialog.basicSimulationName = Simula\u00e7\u00e3o b\u00e1sica diff --git a/core/src/main/resources/l10n/messages_ru.properties b/core/src/main/resources/l10n/messages_ru.properties index 03e9250f1..a90dac2cb 100644 --- a/core/src/main/resources/l10n/messages_ru.properties +++ b/core/src/main/resources/l10n/messages_ru.properties @@ -1013,9 +1013,6 @@ FreeformFinSetCfg.lbl.Posrelativeto = \u041F\u043E\u043B\u043E\u0436\u0435\u043D FreeformFinSetCfg.lbl.plus = \u043F\u043B\u044E\u0441 FreeformFinSetCfg.lbl.FincrossSection = \u041F\u0440\u043E\u0444\u0438\u043B\u044C \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430: FreeformFinSetCfg.lbl.Thickness = \u0422\u043E\u043B\u0449\u0438\u043D\u0430: -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = \u0414\u0432\u043E\u0439\u043D\u043E\u0439 \u043A\u043B\u0438\u043A -FreeformFinSetConfig.lbl.doubleClick2 = \u0434\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F FreeformFinSetConfig.lbl.clickDrag = \u041A\u043B\u0438\u043A+\u0442\u0430\u0449\u0438\u0442\u044C: \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438 \u0434\u0432\u0438\u0433\u0430\u0442\u044C \u0442\u043E\u0447\u043A\u0438 FreeformFinSetConfig.lbl.ctrlClick = Ctrl+\u043A\u043B\u0438\u043A: \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0442\u043E\u0447\u043A\u0443 FreeformFinSetConfig.lbl.scaleFin = \u041C\u0430\u0441\u0448\u0442\u0430\u0431 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 diff --git a/core/src/main/resources/l10n/messages_uk_UA.properties b/core/src/main/resources/l10n/messages_uk_UA.properties index c3e5770ec..9038f46ae 100644 --- a/core/src/main/resources/l10n/messages_uk_UA.properties +++ b/core/src/main/resources/l10n/messages_uk_UA.properties @@ -1225,8 +1225,6 @@ FreeformFinSetCfg.lbl.Fincant = \u041d\u0430\u0445\u0438\u043b \u043a\u0456\u043 FreeformFinSetCfg.lbl.ttip.Fincant = \u041a\u0443\u0442, \u043f\u0456\u0434 \u044f\u043a\u0438\u043c \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043d\u0430\u0445\u0438\u043b\u0435\u043d\u043e \u0432\u0456\u0434\u043d\u043e\u0441\u043d\u043e \u043a\u043e\u0440\u043f\u0443\u0441\u0443 \u0440\u0430\u043a\u0435\u0442\u0438. FreeformFinSetCfg.lbl.FincrossSection = \u041f\u0435\u0440\u0435\u0440\u0456\u0437 \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456: FreeformFinSetCfg.lbl.Thickness = \u0422\u043e\u0432\u0449\u0438\u043d\u0430: -FreeformFinSetConfig.lbl.doubleClick1 = \u0414\u0432\u0456\u0447\u0456 \u043a\u043b\u0456\u043a\u043d\u0456\u0442\u044c -FreeformFinSetConfig.lbl.doubleClick2 = \u0449\u043e\u0431 \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 FreeformFinSetConfig.lbl.clickDrag = \u041a\u043b\u0456\u043a+\u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0443\u0432\u0430\u043d\u043d\u044f: \u0414\u043e\u0434\u0430\u0442\u0438 \u0442\u0430 \u043f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 FreeformFinSetConfig.lbl.ctrlClick = Ctrl+\u043a\u043b\u0456\u043a: \u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438 \u0442\u043e\u0447\u043a\u0443 FreeformFinSetConfig.lbl.scaleFin = \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0443\u0432\u0430\u0442\u0438 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c diff --git a/core/src/main/resources/l10n/messages_zh_CN.properties b/core/src/main/resources/l10n/messages_zh_CN.properties index f9903be6f..8275be969 100644 --- a/core/src/main/resources/l10n/messages_zh_CN.properties +++ b/core/src/main/resources/l10n/messages_zh_CN.properties @@ -391,9 +391,6 @@ FreeformFinSetCfg.tab.ttip.General = \u5E38\u89C4\u5C5E\u6027 FreeformFinSetConfig.lbl.clickDrag = \u5355\u51FB+\u62D6\u62FD: \u6DFB\u52A0,\u79FB\u52A8\u70B9 FreeformFinSetConfig.lbl.ctrlClick = Ctrl+\u5355\u51FB: \u5220\u9664\u70B9 -! doubleClick1 + 2 form the message "Double-click to edit", split approximately at the middle -FreeformFinSetConfig.lbl.doubleClick1 = \u53CC\u51FB -FreeformFinSetConfig.lbl.doubleClick2 = \u7F16\u8F91 FreeformFinSetConfig.lbl.scaleFin = \u7F29\u653E\u7A33\u5B9A\u7FFC GeneralOptimizationDialog.basicSimulationName = \u57FA\u672C\u4EFF\u771F diff --git a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java index c3f24acf0..96ad6d734 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java @@ -1,10 +1,13 @@ package info.openrocket.swing.gui.configdialog; +import java.awt.Component; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Point2D; @@ -19,6 +22,7 @@ import java.util.ArrayList; import java.util.List; import javax.swing.AbstractAction; +import javax.swing.DefaultCellEditor; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; @@ -31,6 +35,7 @@ import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JSplitPane; import javax.swing.JTable; +import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; @@ -230,11 +235,40 @@ public class FreeformFinSetConfig extends FinSetConfig { // Create the table tableModel = new FinPointTableModel(); - table = new JTable(tableModel); + table = new JTable(tableModel) { + @Override + public void changeSelection(int row, int column, boolean toggle, boolean extend) { + super.changeSelection(row, column, toggle, extend); + + if (isCellEditable(row, column)) { + editCellAt(row, column); + Component editor = getEditorComponent(); + if (editor != null) { + editor.requestFocus(); + } + } + } + }; table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); for (int i = 0; i < Columns.values().length; i++) { table.getColumnModel().getColumn(i).setPreferredWidth(Columns.values()[i].getWidth()); } + + // Set custom editor for highlighting all text + DefaultCellEditor editor = new DefaultCellEditor(new JTextField()) { + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + JTextField textField = (JTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column); + SwingUtilities.invokeLater(textField::selectAll); + return textField; + } + }; + + // Apply the editor to all columns + for (int i = 0; i < table.getColumnCount(); i++) { + table.getColumnModel().getColumn(i).setCellEditor(editor); + } + table.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { @@ -264,6 +298,17 @@ public class FreeformFinSetConfig extends FinSetConfig { } }); JScrollPane tablePane = new JScrollPane(table); + + // Remove focus from table when interacting on the figure + figurePane.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + if (table.isEditing()) { + table.getCellEditor().stopCellEditing(); + } + table.clearSelection(); + } + }); JButton scaleButton = new JButton(trans.get("FreeformFinSetConfig.lbl.scaleFin")); scaleButton.addActionListener(new ActionListener() { @@ -337,9 +382,8 @@ public class FreeformFinSetConfig extends FinSetConfig { order.add(table); // row of text directly below figure - panel.add(new StyledLabel(trans.get("lbl.doubleClick1")+" "+trans.get("FreeformFinSetConfig.lbl.doubleClick2"), -2), "spanx 2"); - panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 2, wrap"); - panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.clickDrag"), -2), "spanx 2"); + panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlClick"), -2), "spanx 2"); + panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.clickDrag"), -2), "spanx 2, wrap"); panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.shiftClickDrag"), -2), "spanx 2"); panel.add(new StyledLabel(trans.get("FreeformFinSetConfig.lbl.ctrlShiftClickDrag"), -2), "spanx 2, wrap"); @@ -503,6 +547,7 @@ public class FreeformFinSetConfig extends FinSetConfig { @Override public void mousePressed(MouseEvent event) { + requestFocusInWindow(); final FreeformFinSet finset = (FreeformFinSet) component; final int pressIndex = getPoint(event); @@ -681,8 +726,8 @@ public class FreeformFinSetConfig extends FinSetConfig { @Override public void mouseClicked(MouseEvent event) { - int mods = event.getModifiersEx(); - if(( event.getButton() == MouseEvent.BUTTON1) && (0 < (MouseEvent.CTRL_DOWN_MASK & mods))) { + int mods = event.getModifiersEx(); + if ((event.getButton() == MouseEvent.BUTTON1) && (0 < (MouseEvent.CTRL_DOWN_MASK & mods))) { int clickIndex = getPoint(event); if ( 0 < clickIndex) { // if ctrl+click, delete point @@ -695,8 +740,7 @@ public class FreeformFinSetConfig extends FinSetConfig { return; } } - - super.mouseClicked(event); + super.mouseClicked(event); } private int getPoint(MouseEvent event) { From 1ee09f285043ab36629ff827546263e25c575526 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 12 Oct 2024 16:22:15 +0200 Subject: [PATCH 4/7] Use proper snap highlight colors for different themes --- .../swing/gui/scalefigure/FinPointFigure.java | 4 +++- .../openrocket/swing/gui/theme/UITheme.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java index 4f3911ab7..656bde9ee 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java +++ b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java @@ -68,6 +68,7 @@ public class FinPointFigure extends AbstractScaleFigure { private static Color finPointGridMinorLineColor; private static Color finPointPointColor; private static Color finPointSelectedPointColor; + private static Color finPointSnapHighlightColor; static { initColors(); @@ -94,6 +95,7 @@ public class FinPointFigure extends AbstractScaleFigure { finPointGridMinorLineColor = GUIUtil.getUITheme().getFinPointGridMinorLineColor(); finPointPointColor = GUIUtil.getUITheme().getFinPointPointColor(); finPointSelectedPointColor = GUIUtil.getUITheme().getFinPointSelectedPointColor(); + finPointSnapHighlightColor = GUIUtil.getUITheme().getFinPointSnapHighlightColor(); } @Override @@ -277,7 +279,7 @@ public class FinPointFigure extends AbstractScaleFigure { final float highlightWidth_m = (float) (LINE_WIDTH_HIGHLIGHT_PIXELS / scale ); g2.setStroke(new BasicStroke(highlightWidth_m)); - g2.setColor(Color.RED); + g2.setColor(finPointSnapHighlightColor); g2.draw(new Line2D.Double(start.x, start.y, end.x, end.y)); } diff --git a/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java b/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java index a64bd1865..5706a0273 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java +++ b/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java @@ -93,6 +93,7 @@ public class UITheme { Color getFinPointPointColor(); Color getFinPointSelectedPointColor(); Color getFinPointBodyLineColor(); + Color getFinPointSnapHighlightColor(); Icon getMassOverrideIcon(); Icon getMassOverrideSubcomponentIcon(); @@ -404,6 +405,11 @@ public class UITheme { return Color.BLACK; } + @Override + public Color getFinPointSnapHighlightColor() { + return Color.RED; + } + @Override public Icon getMassOverrideIcon() { return Icons.MASS_OVERRIDE_LIGHT; @@ -805,6 +811,11 @@ public class UITheme { return Color.WHITE; } + @Override + public Color getFinPointSnapHighlightColor() { + return new Color(255, 58, 58, 255); + } + @Override public Icon getMassOverrideIcon() { return Icons.MASS_OVERRIDE_DARK; @@ -1206,6 +1217,11 @@ public class UITheme { return Color.WHITE; } + @Override + public Color getFinPointSnapHighlightColor() { + return new Color(241, 77, 77, 255); + } + @Override public Icon getMassOverrideIcon() { return Icons.MASS_OVERRIDE_DARK; @@ -1626,6 +1642,11 @@ public class UITheme { return getCurrentTheme().getFinPointBodyLineColor(); } + @Override + public Color getFinPointSnapHighlightColor() { + return getCurrentTheme().getFinPointBodyLineColor(); + } + @Override public Icon getMassOverrideIcon() { return getCurrentTheme().getMassOverrideIcon(); From 3ac5953b94baeb609fcbc58fc1e2f96f516f6bfa Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 12 Oct 2024 16:25:18 +0200 Subject: [PATCH 5/7] Code cleanup --- .../configdialog/FreeformFinSetConfig.java | 166 ++++++++---------- 1 file changed, 77 insertions(+), 89 deletions(-) diff --git a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java index 96ad6d734..f29dc4e48 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java @@ -590,44 +590,14 @@ public class FreeformFinSetConfig extends FinSetConfig { Point2D.Double point = getCoordinates(event); final FreeformFinSet finset = (FreeformFinSet) component; - // If shift is held down and a point is being dragged, constrain angle relative to previous or following point - int lockIndex = -1; + // If shift is held down, apply snapping int highlightIndex = -1; if ((mods & MouseEvent.SHIFT_DOWN_MASK) != 0) { - if ((mods & MouseEvent.CTRL_DOWN_MASK) != 0) { - if (dragIndex < finset.getFinPoints().length-1) { - lockIndex = dragIndex + 1; - highlightIndex = dragIndex; - } - } - else if (dragIndex > 0) { - lockIndex = dragIndex - 1; - highlightIndex = dragIndex - 1; - } + int lockIndex = getLockIndex(mods); + highlightIndex = getHighlightIndex(lockIndex); if (lockIndex >= 0) { - // Fetch point to lock to - final Coordinate lockPoint = finset.getFinPoints()[lockIndex]; - // Distances to vertical and horizontal lines - final double diffX = point.x - lockPoint.x; - final double diffY = point.y - lockPoint.y; - final double distanceX = Math.abs(diffX); - final double distanceY = Math.abs(diffY); - // Calculate distance to 45 or 135 degree line, as appropriate - final double a = 1; // always - final double b = (Math.signum(diffX) == Math.signum(diffY)) ? -1 : 1; - final double c = -(a*lockPoint.x + b*lockPoint.y); - final double distanceDiag = Math.abs(a*point.x + b*point.y + c) / Math.sqrt(2); - - // Snap in the appropriate direction - if (distanceX <= distanceY && distanceX <= distanceDiag) // snap horizontal - point.x = lockPoint.x; - else if (distanceY <= distanceX && distanceY <= distanceDiag) // snap vertical - point.y = lockPoint.y; - else { // snap diagonal - point.x = (b*( b*point.x - a*point.y) - a*c) / 2; - point.y = (a*(-b*point.x + a*point.y) - b*c) / 2; - } + point = snapPoint(point, finset.getFinPoints()[lockIndex]); } } figure.setHighlightIndex(highlightIndex); @@ -643,29 +613,59 @@ public class FreeformFinSetConfig extends FinSetConfig { updateFields(); - // if point is within borders of figure _AND_ outside borders of the ScrollPane's view: - final Rectangle dragRectangle = viewport.getViewRect(); - final Point canvasPoint = new Point( dragPoint.x + dragRectangle.x, dragPoint.y + dragRectangle.y); - if( (figure.getBorderWidth() < canvasPoint.x) && (canvasPoint.x < (figure.getWidth() - figure.getBorderWidth())) - && (figure.getBorderHeight() < canvasPoint.y) && (canvasPoint.y < (figure.getHeight() - figure.getBorderHeight()))) - { - boolean hitBorder = false; - if(dragPoint.x < figure.getBorderWidth()){ - hitBorder = true; - dragRectangle.x += dragPoint.x - figure.getBorderWidth(); - } else if(dragPoint.x >(dragRectangle.width -figure.getBorderWidth())) { - hitBorder = true; - dragRectangle.x += dragPoint.x - (dragRectangle.width - figure.getBorderWidth()); - } + // Handle scrolling if point is dragged out of view + handleScrolling(); + } - if (dragPoint.y(dragRectangle.height -figure.getBorderHeight())) { - hitBorder = true; - dragRectangle.y += dragPoint.y - (dragRectangle.height - figure.getBorderHeight()); - } + private int getLockIndex(int mods) { + if ((mods & MouseEvent.CTRL_DOWN_MASK) != 0) { + return (dragIndex < ((FreeformFinSet) component).getFinPoints().length - 1) ? dragIndex + 1 : -1; + } else { + return (dragIndex > 0) ? dragIndex - 1 : -1; + } + } + private int getHighlightIndex(int lockIndex) { + return (lockIndex == dragIndex + 1) ? dragIndex : lockIndex; + } + + private Point2D.Double snapPoint(Point2D.Double point, Coordinate lockPoint) { + Point2D.Double snappedPoint = new Point2D.Double(point.x, point.y); + + double diffX = point.x - lockPoint.x; + double diffY = point.y - lockPoint.y; + double distanceX = Math.abs(diffX); + double distanceY = Math.abs(diffY); + + // Calculate distance to 45 or 135 degree line + double a = 1; + double b = (Math.signum(diffX) == Math.signum(diffY)) ? -1 : 1; + double c = -(a * lockPoint.x + b * lockPoint.y); + double distanceDiag = Math.abs(a * point.x + b * point.y + c) / Math.sqrt(2); + + // Snap to the closest constraint + if (distanceX <= distanceY && distanceX <= distanceDiag) { + // Snap horizontal + snappedPoint.x = lockPoint.x; + } else if (distanceY <= distanceX && distanceY <= distanceDiag) { + // Snap vertical + snappedPoint.y = lockPoint.y; + } else { + // Snap diagonal (45 degrees) + double avgDist = (Math.abs(diffX) + Math.abs(diffY)) / 2; + snappedPoint.x = lockPoint.x + Math.signum(diffX) * avgDist; + snappedPoint.y = lockPoint.y + Math.signum(diffY) * avgDist; + } + + return snappedPoint; + } + + private void handleScrolling() { + Rectangle dragRectangle = viewport.getViewRect(); + Point canvasPoint = new Point(dragPoint.x + dragRectangle.x, dragPoint.y + dragRectangle.y); + + if (isPointWithinFigureBounds(canvasPoint)) { + boolean hitBorder = updateScrollPosition(dragRectangle); if (hitBorder) { super.setFitting(false); selector.update(); @@ -675,43 +675,31 @@ public class FreeformFinSetConfig extends FinSetConfig { } } - @Override - public void componentResized(ComponentEvent e) { - if (fit) { - // if we're fitting the whole figure in the ScrollPane, the parent behavior is fine - super.componentResized(e); - } else if (0 > dragIndex) { - // if we're not _currently_ dragging a point, the parent behavior is fine - super.componentResized(e); - } else { - // currently dragging a point. - // ... and if we drag out-of-bounds, we want to move the viewport to keep up - boolean hitBorder = false; - final Rectangle dragRectangle = viewport.getViewRect(); + private boolean isPointWithinFigureBounds(Point point) { + return figure.getBorderWidth() < point.x && point.x < (figure.getWidth() - figure.getBorderWidth()) + && figure.getBorderHeight() < point.y && point.y < (figure.getHeight() - figure.getBorderHeight()); + } - if(dragPoint.x(dragRectangle.width -figure.getBorderWidth())) { - hitBorder = true; - dragRectangle.x += dragPoint.x - (dragRectangle.width - figure.getBorderWidth()); - } + private boolean updateScrollPosition(Rectangle dragRectangle) { + boolean hitBorder = false; - if (dragPoint.y(dragRectangle.height -figure.getBorderHeight())) { - hitBorder = true; - dragRectangle.y += dragPoint.y - (dragRectangle.height - figure.getBorderHeight()); - } - - if (hitBorder) { - super.setFitting(false); - selector.update(); - figure.scrollRectToVisible(dragRectangle); - revalidate(); - } + if (dragPoint.x < figure.getBorderWidth()) { + hitBorder = true; + dragRectangle.x += dragPoint.x - figure.getBorderWidth(); + } else if (dragPoint.x > (dragRectangle.width - figure.getBorderWidth())) { + hitBorder = true; + dragRectangle.x += dragPoint.x - (dragRectangle.width - figure.getBorderWidth()); } + + if (dragPoint.y < figure.getBorderHeight()) { + hitBorder = true; + dragRectangle.y += dragPoint.y - figure.getBorderHeight(); + } else if (dragPoint.y > (dragRectangle.height - figure.getBorderHeight())) { + hitBorder = true; + dragRectangle.y += dragPoint.y - (dragRectangle.height - figure.getBorderHeight()); + } + + return hitBorder; } @Override From aeeddcd921c02a81d4af8159cb3b57e077155e86 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sun, 13 Oct 2024 11:23:07 +0200 Subject: [PATCH 6/7] Improve documentation --- .../openrocket/swing/gui/scalefigure/FinPointFigure.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java index 656bde9ee..0325a9406 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java +++ b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/FinPointFigure.java @@ -60,7 +60,7 @@ public class FinPointFigure extends AbstractScaleFigure { private Rectangle2D.Double[] finPointHandles = null; private int selectedIndex = -1; - private int highlightIndex = -1; + private int highlightIndex = -1; // The first index of the segment to highlight when snapping to a fin point private static Color backgroundColor; private static Color finPointBodyLineColor; @@ -267,6 +267,10 @@ public class FinPointFigure extends AbstractScaleFigure { g2.draw(shape); } + /** + * Paints the highlight line between the two points when snapping to a fin point. + * @param g2 The graphics context to paint to. + */ private void paintHighlight(final Graphics2D g2) { final Coordinate[] points = finset.getFinPointsWithRoot(); From 9288b93383b9cf99c19a7d7ae5e47e85b0aa94f3 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sun, 13 Oct 2024 11:23:17 +0200 Subject: [PATCH 7/7] Disable snapping for root points --- .../gui/configdialog/FreeformFinSetConfig.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java index f29dc4e48..59e41b4a3 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/main/java/info/openrocket/swing/gui/configdialog/FreeformFinSetConfig.java @@ -591,16 +591,15 @@ public class FreeformFinSetConfig extends FinSetConfig { final FreeformFinSet finset = (FreeformFinSet) component; // If shift is held down, apply snapping - int highlightIndex = -1; if ((mods & MouseEvent.SHIFT_DOWN_MASK) != 0) { int lockIndex = getLockIndex(mods); - highlightIndex = getHighlightIndex(lockIndex); - if (lockIndex >= 0) { + if (lockIndex != -1) { point = snapPoint(point, finset.getFinPoints()[lockIndex]); + int highlightIndex = getHighlightIndex(lockIndex); + figure.setHighlightIndex(highlightIndex); } } - figure.setHighlightIndex(highlightIndex); try { finset.setPoint(dragIndex, point.x, point.y); @@ -617,11 +616,17 @@ public class FreeformFinSetConfig extends FinSetConfig { handleScrolling(); } + /** + * Get the index of the point that the current point should lock to. + * @param mods The modifiers of the mouse event + * @return The index of the point to lock to, or -1 if no point should be locked to + */ private int getLockIndex(int mods) { + int length = ((FreeformFinSet) component).getFinPoints().length; if ((mods & MouseEvent.CTRL_DOWN_MASK) != 0) { - return (dragIndex < ((FreeformFinSet) component).getFinPoints().length - 1) ? dragIndex + 1 : -1; + return (dragIndex > 0 && dragIndex < length - 1) ? dragIndex + 1 : -1; } else { - return (dragIndex > 0) ? dragIndex - 1 : -1; + return (dragIndex < length - 1 && dragIndex > 0) ? dragIndex - 1 : -1; } }