From daf6189c8f31f1a0feb3f812494b8d9a8ff6ee02 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 20 Mar 2023 22:44:23 +0100 Subject: [PATCH 1/6] [#2102] Add "Select components of same color" option --- core/resources/l10n/messages.properties | 3 + .../sf/openrocket/gui/main/BasicFrame.java | 13 +++ .../sf/openrocket/gui/main/RocketActions.java | 92 +++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 6d70535fc..0aaca5e6c 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -39,6 +39,9 @@ RocketActions.DuplicateAct.Duplicate = Duplicate RocketActions.DuplicateAct.ttip.Duplicate = Duplicate this component (and subcomponents). RocketActions.EditAct.Edit = Edit RocketActions.EditAct.ttip.Edit = Edit the selected component. +RocketActions.Select = Select +RocketActions.Select.SelectSameColorAct = Components with same color +RocketActions.Select.SelectSameColorAct.ttip = Select all components with the same color as this component. RocketActions.ScaleAct.Scale = Scale RocketActions.ScaleAct.ttip.Scale = Scale parts of the rocket design RocketActions.NewStageAct.Newstage = New stage diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 260f27d7d..7a19f6a01 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -236,6 +236,12 @@ public class BasicFrame extends JFrame { popupMenu.add(actions.getPasteAction()); popupMenu.add(actions.getDuplicateAction()); popupMenu.add(actions.getDeleteAction()); + + popupMenu.addSeparator(); + JMenu selectMenu = new JMenu(trans.get("RocketActions.Select")); + selectMenu.add(actions.getSelectSameColorAction()); + popupMenu.add(selectMenu); + popupMenu.addSeparator(); popupMenu.add(actions.getScaleAction()); } @@ -656,6 +662,13 @@ public class BasicFrame extends JFrame { menu.addSeparator(); + JMenu subMenu = new JMenu(trans.get("RocketActions.Select")); + item = new JMenuItem(actions.getSelectSameColorAction()); + subMenu.add(item); + menu.add(subMenu); + + menu.addSeparator(); + item = new JMenuItem(actions.getScaleAction()); menu.add(item); diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 497f30bcb..d4f1dd9b9 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -35,6 +35,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.AxialStage; import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Preferences; +import net.sf.openrocket.util.Color; import net.sf.openrocket.util.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,6 +75,7 @@ public class RocketActions { private final RocketAction pasteAction; private final RocketAction duplicateAction; private final RocketAction editAction; + private final RocketAction selectSameColorAction; private final RocketAction scaleAction; private final RocketAction moveUpAction; private final RocketAction moveDownAction; @@ -98,6 +100,7 @@ public class RocketActions { this.pasteAction = new PasteAction(); this.duplicateAction = new DuplicateAction(); this.editAction = new EditAction(); + this.selectSameColorAction = new SelectSameColor(); this.scaleAction = new ScaleAction(); this.moveUpAction = new MoveUpAction(); this.moveDownAction = new MoveDownAction(); @@ -131,6 +134,7 @@ public class RocketActions { pasteAction.clipboardChanged(); duplicateAction.clipboardChanged(); editAction.clipboardChanged(); + selectSameColorAction.clipboardChanged(); scaleAction.clipboardChanged(); moveUpAction.clipboardChanged(); moveDownAction.clipboardChanged(); @@ -171,6 +175,10 @@ public class RocketActions { return editAction; } + public Action getSelectSameColorAction() { + return selectSameColorAction; + } + public Action getScaleAction() { return scaleAction; } @@ -1006,6 +1014,90 @@ public class RocketActions { } } + /** + * Action to select all components with the same color as the currently selected component. + */ + private class SelectSameColor extends RocketAction { + private static final long serialVersionUID = 1L; + + public SelectSameColor() { + //// Select same color + this.putValue(NAME, trans.get("RocketActions.Select.SelectSameColorAct")); + this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.Select.SelectSameColorAct.ttip")); + clipboardChanged(); + } + + @Override + public void actionPerformed(ActionEvent e) { + List components = selectionModel.getSelectedComponents(); + if (components.size() == 0) { + return; + } + + RocketComponent component = components.get(0); + List sameColorComponents; + + // Case 1: component has a default appearance (null) + if (component.getAppearance() == null) { + sameColorComponents = getComponentsDefaultColor(component); + } + // Case 2: component has a custom appearance + else { + sameColorComponents = getComponentsCustomColor(component); + } + + selectionModel.setSelectedComponents(sameColorComponents); + } + + private List getComponentsCustomColor(RocketComponent component) { + Color targetColor = component.getAppearance().getPaint(); + List components = new ArrayList<>(); + components.add(component); + + for (RocketComponent c : rocket) { + if (c == component || c.getAppearance() == null || c.getAppearance().getPaint() == null) { + continue; + } + Color color = c.getAppearance().getPaint(); + // Add components with the same RGB values (ignore alpha) + if (color.getRed() == targetColor.getRed() && + color.getGreen() == targetColor.getGreen() && + color.getBlue() == targetColor.getBlue()) { + components.add(c); + } + } + + return components; + } + + private List getComponentsDefaultColor(RocketComponent component) { + List components = new ArrayList<>(); + components.add(component); + + for (RocketComponent c : rocket) { + if (c == component) { + continue; + } + + // Only add same components & components that also have the default color + if (c.getClass().equals(component.getClass()) && c.getAppearance() == null) { + components.add(c); + } + } + + return components; + } + + @Override + public void clipboardChanged() { + List components = selectionModel.getSelectedComponents(); + this.setEnabled(components.size() > 0); + } + } + + + + /** * Action to scale the currently selected component. */ From 84689df28359c37cba90af5c0f37e1d8c2286000 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 20 Mar 2023 22:52:42 +0100 Subject: [PATCH 2/6] Add select None action --- core/resources/l10n/messages.properties | 2 + .../sf/openrocket/gui/main/BasicFrame.java | 5 ++- .../sf/openrocket/gui/main/RocketActions.java | 38 +++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 0aaca5e6c..057634612 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -42,6 +42,8 @@ RocketActions.EditAct.ttip.Edit = Edit the selected component. RocketActions.Select = Select RocketActions.Select.SelectSameColorAct = Components with same color RocketActions.Select.SelectSameColorAct.ttip = Select all components with the same color as this component. +RocketActions.Select.SelectNoneAct = None +RocketActions.Select.SelectNoneAct.ttip = Deselect all components. RocketActions.ScaleAct.Scale = Scale RocketActions.ScaleAct.ttip.Scale = Scale parts of the rocket design RocketActions.NewStageAct.Newstage = New stage diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 7a19f6a01..44a381457 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -240,6 +240,7 @@ public class BasicFrame extends JFrame { popupMenu.addSeparator(); JMenu selectMenu = new JMenu(trans.get("RocketActions.Select")); selectMenu.add(actions.getSelectSameColorAction()); + selectMenu.add(actions.getSelectNoneAction()); popupMenu.add(selectMenu); popupMenu.addSeparator(); @@ -663,9 +664,11 @@ public class BasicFrame extends JFrame { menu.addSeparator(); JMenu subMenu = new JMenu(trans.get("RocketActions.Select")); + menu.add(subMenu); item = new JMenuItem(actions.getSelectSameColorAction()); subMenu.add(item); - menu.add(subMenu); + item = new JMenuItem(actions.getSelectNoneAction()); + subMenu.add(item); menu.addSeparator(); diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index d4f1dd9b9..8d52e5901 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -76,6 +76,7 @@ public class RocketActions { private final RocketAction duplicateAction; private final RocketAction editAction; private final RocketAction selectSameColorAction; + private final RocketAction selectNoneAction; private final RocketAction scaleAction; private final RocketAction moveUpAction; private final RocketAction moveDownAction; @@ -100,7 +101,8 @@ public class RocketActions { this.pasteAction = new PasteAction(); this.duplicateAction = new DuplicateAction(); this.editAction = new EditAction(); - this.selectSameColorAction = new SelectSameColor(); + this.selectSameColorAction = new SelectSameColorAction(); + this.selectNoneAction = new SelectNoneAction(); this.scaleAction = new ScaleAction(); this.moveUpAction = new MoveUpAction(); this.moveDownAction = new MoveDownAction(); @@ -135,6 +137,7 @@ public class RocketActions { duplicateAction.clipboardChanged(); editAction.clipboardChanged(); selectSameColorAction.clipboardChanged(); + selectNoneAction.clipboardChanged(); scaleAction.clipboardChanged(); moveUpAction.clipboardChanged(); moveDownAction.clipboardChanged(); @@ -179,6 +182,10 @@ public class RocketActions { return selectSameColorAction; } + public Action getSelectNoneAction() { + return selectNoneAction; + } + public Action getScaleAction() { return scaleAction; } @@ -1014,13 +1021,14 @@ public class RocketActions { } } + /** * Action to select all components with the same color as the currently selected component. */ - private class SelectSameColor extends RocketAction { + private class SelectSameColorAction extends RocketAction { private static final long serialVersionUID = 1L; - public SelectSameColor() { + public SelectSameColorAction() { //// Select same color this.putValue(NAME, trans.get("RocketActions.Select.SelectSameColorAct")); this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.Select.SelectSameColorAct.ttip")); @@ -1095,6 +1103,30 @@ public class RocketActions { } } + /** + * Action to select all components with the same color as the currently selected component. + */ + private class SelectNoneAction extends RocketAction { + private static final long serialVersionUID = 1L; + + public SelectNoneAction() { + //// Select none + this.putValue(NAME, trans.get("RocketActions.Select.SelectNoneAct")); + this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.Select.SelectNoneAct.ttip")); + clipboardChanged(); + } + + @Override + public void actionPerformed(ActionEvent e) { + selectionModel.clearComponentSelection(); + } + + @Override + public void clipboardChanged() { + List components = selectionModel.getSelectedComponents(); + this.setEnabled(components.size() > 0); + } + } From fd4e357e3bcc698db8eab9a6ca3a159d535d027e Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 20 Mar 2023 23:02:44 +0100 Subject: [PATCH 3/6] Fix translation --- core/resources/l10n/messages.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 057634612..0ad43a056 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -40,8 +40,8 @@ RocketActions.DuplicateAct.ttip.Duplicate = Duplicate this component (and subcom RocketActions.EditAct.Edit = Edit RocketActions.EditAct.ttip.Edit = Edit the selected component. RocketActions.Select = Select -RocketActions.Select.SelectSameColorAct = Components with same color -RocketActions.Select.SelectSameColorAct.ttip = Select all components with the same color as this component. +RocketActions.Select.SelectSameColorAct = Components of same color +RocketActions.Select.SelectSameColorAct.ttip = Select all components of the same color as this component. RocketActions.Select.SelectNoneAct = None RocketActions.Select.SelectNoneAct.ttip = Deselect all components. RocketActions.ScaleAct.Scale = Scale From e3d83eafb752f06da6eb69bfebc2e9b1eea8f929 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 23 Mar 2023 01:54:32 +0100 Subject: [PATCH 4/6] Only activate same color selection when one component selected --- swing/src/net/sf/openrocket/gui/main/RocketActions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 8d52e5901..e4cb06238 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -1099,7 +1099,7 @@ public class RocketActions { @Override public void clipboardChanged() { List components = selectionModel.getSelectedComponents(); - this.setEnabled(components.size() > 0); + this.setEnabled(components.size() == 1); } } From 805ea919dc68df6915130baf1d37390a1d284cbd Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 23 Mar 2023 03:04:41 +0100 Subject: [PATCH 5/6] Only enable select color for components that have an appearance --- swing/src/net/sf/openrocket/gui/main/RocketActions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index e4cb06238..61bd565cb 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -1099,7 +1099,7 @@ public class RocketActions { @Override public void clipboardChanged() { List components = selectionModel.getSelectedComponents(); - this.setEnabled(components.size() == 1); + this.setEnabled(components.size() == 1 && components.get(0).isMassive()); } } From ea05bc5001070b712ed2746a07a87f9c9a9ee6bc Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 23 Mar 2023 03:16:37 +0100 Subject: [PATCH 6/6] Rename "Select none" to "Deselect all" --- core/resources/l10n/messages.properties | 4 ++-- .../sf/openrocket/gui/main/BasicFrame.java | 4 ++-- .../sf/openrocket/gui/main/RocketActions.java | 22 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 0ad43a056..ae11973ad 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -42,8 +42,8 @@ RocketActions.EditAct.ttip.Edit = Edit the selected component. RocketActions.Select = Select RocketActions.Select.SelectSameColorAct = Components of same color RocketActions.Select.SelectSameColorAct.ttip = Select all components of the same color as this component. -RocketActions.Select.SelectNoneAct = None -RocketActions.Select.SelectNoneAct.ttip = Deselect all components. +RocketActions.Select.DeselectAllAct = Deselect all +RocketActions.Select.DeselectAllAct.ttip = Deselect all currently selected components. RocketActions.ScaleAct.Scale = Scale RocketActions.ScaleAct.ttip.Scale = Scale parts of the rocket design RocketActions.NewStageAct.Newstage = New stage diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 44a381457..df08145c6 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -240,7 +240,7 @@ public class BasicFrame extends JFrame { popupMenu.addSeparator(); JMenu selectMenu = new JMenu(trans.get("RocketActions.Select")); selectMenu.add(actions.getSelectSameColorAction()); - selectMenu.add(actions.getSelectNoneAction()); + selectMenu.add(actions.getDeselectAllAction()); popupMenu.add(selectMenu); popupMenu.addSeparator(); @@ -667,7 +667,7 @@ public class BasicFrame extends JFrame { menu.add(subMenu); item = new JMenuItem(actions.getSelectSameColorAction()); subMenu.add(item); - item = new JMenuItem(actions.getSelectNoneAction()); + item = new JMenuItem(actions.getDeselectAllAction()); subMenu.add(item); menu.addSeparator(); diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 61bd565cb..200244723 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -76,7 +76,7 @@ public class RocketActions { private final RocketAction duplicateAction; private final RocketAction editAction; private final RocketAction selectSameColorAction; - private final RocketAction selectNoneAction; + private final RocketAction deselectAllAction; private final RocketAction scaleAction; private final RocketAction moveUpAction; private final RocketAction moveDownAction; @@ -102,7 +102,7 @@ public class RocketActions { this.duplicateAction = new DuplicateAction(); this.editAction = new EditAction(); this.selectSameColorAction = new SelectSameColorAction(); - this.selectNoneAction = new SelectNoneAction(); + this.deselectAllAction = new DeselectAllAction(); this.scaleAction = new ScaleAction(); this.moveUpAction = new MoveUpAction(); this.moveDownAction = new MoveDownAction(); @@ -137,7 +137,7 @@ public class RocketActions { duplicateAction.clipboardChanged(); editAction.clipboardChanged(); selectSameColorAction.clipboardChanged(); - selectNoneAction.clipboardChanged(); + deselectAllAction.clipboardChanged(); scaleAction.clipboardChanged(); moveUpAction.clipboardChanged(); moveDownAction.clipboardChanged(); @@ -182,8 +182,8 @@ public class RocketActions { return selectSameColorAction; } - public Action getSelectNoneAction() { - return selectNoneAction; + public Action getDeselectAllAction() { + return deselectAllAction; } public Action getScaleAction() { @@ -1104,15 +1104,15 @@ public class RocketActions { } /** - * Action to select all components with the same color as the currently selected component. + * Action to deselect all currently selected components. */ - private class SelectNoneAction extends RocketAction { + private class DeselectAllAction extends RocketAction { private static final long serialVersionUID = 1L; - public SelectNoneAction() { - //// Select none - this.putValue(NAME, trans.get("RocketActions.Select.SelectNoneAct")); - this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.Select.SelectNoneAct.ttip")); + public DeselectAllAction() { + //// Deselect all + this.putValue(NAME, trans.get("RocketActions.Select.DeselectAllAct")); + this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.Select.DeselectAllAct.ttip")); clipboardChanged(); }