Merge pull request #2129 from SiboVG/issue-2102

[#2102] Add "Select components of same color" and "Select none" option
This commit is contained in:
Sibo Van Gool 2023-03-24 11:38:28 +01:00 committed by GitHub
commit 52988bf31e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 145 additions and 0 deletions

View File

@ -39,6 +39,11 @@ 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 of same color
RocketActions.Select.SelectSameColorAct.ttip = Select all components of the same color as this component.
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

View File

@ -238,6 +238,13 @@ 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());
selectMenu.add(actions.getDeselectAllAction());
popupMenu.add(selectMenu);
popupMenu.addSeparator();
popupMenu.add(actions.getScaleAction());
}
@ -557,6 +564,15 @@ public class BasicFrame extends JFrame {
fileMenu.addSeparator();
JMenu subMenu = new JMenu(trans.get("RocketActions.Select"));
menu.add(subMenu);
item = new JMenuItem(actions.getSelectSameColorAction());
subMenu.add(item);
item = new JMenuItem(actions.getDeselectAllAction());
subMenu.add(item);
menu.addSeparator();
item = new JMenuItem(actions.getScaleAction());
fileMenu.add(item);

View File

@ -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,8 @@ public class RocketActions {
private final RocketAction pasteAction;
private final RocketAction duplicateAction;
private final RocketAction editAction;
private final RocketAction selectSameColorAction;
private final RocketAction deselectAllAction;
private final RocketAction scaleAction;
private final RocketAction moveUpAction;
private final RocketAction moveDownAction;
@ -98,6 +101,8 @@ public class RocketActions {
this.pasteAction = new PasteAction();
this.duplicateAction = new DuplicateAction();
this.editAction = new EditAction();
this.selectSameColorAction = new SelectSameColorAction();
this.deselectAllAction = new DeselectAllAction();
this.scaleAction = new ScaleAction();
this.moveUpAction = new MoveUpAction();
this.moveDownAction = new MoveDownAction();
@ -131,6 +136,8 @@ public class RocketActions {
pasteAction.clipboardChanged();
duplicateAction.clipboardChanged();
editAction.clipboardChanged();
selectSameColorAction.clipboardChanged();
deselectAllAction.clipboardChanged();
scaleAction.clipboardChanged();
moveUpAction.clipboardChanged();
moveDownAction.clipboardChanged();
@ -171,6 +178,14 @@ public class RocketActions {
return editAction;
}
public Action getSelectSameColorAction() {
return selectSameColorAction;
}
public Action getDeselectAllAction() {
return deselectAllAction;
}
public Action getScaleAction() {
return scaleAction;
}
@ -1006,6 +1021,115 @@ public class RocketActions {
}
}
/**
* Action to select all components with the same color as the currently selected component.
*/
private class SelectSameColorAction extends RocketAction {
private static final long serialVersionUID = 1L;
public SelectSameColorAction() {
//// 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<RocketComponent> components = selectionModel.getSelectedComponents();
if (components.size() == 0) {
return;
}
RocketComponent component = components.get(0);
List<RocketComponent> 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<RocketComponent> getComponentsCustomColor(RocketComponent component) {
Color targetColor = component.getAppearance().getPaint();
List<RocketComponent> 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<RocketComponent> getComponentsDefaultColor(RocketComponent component) {
List<RocketComponent> 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<RocketComponent> components = selectionModel.getSelectedComponents();
this.setEnabled(components.size() == 1 && components.get(0).isMassive());
}
}
/**
* Action to deselect all currently selected components.
*/
private class DeselectAllAction extends RocketAction {
private static final long serialVersionUID = 1L;
public DeselectAllAction() {
//// Deselect all
this.putValue(NAME, trans.get("RocketActions.Select.DeselectAllAct"));
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.Select.DeselectAllAct.ttip"));
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
selectionModel.clearComponentSelection();
}
@Override
public void clipboardChanged() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
this.setEnabled(components.size() > 0);
}
}
/**
* Action to scale the currently selected component.
*/