Add right-click actions to componentTree

This commit is contained in:
SiboVG 2022-05-30 20:39:39 +02:00
parent 5d80a3a167
commit b4c56163e5
8 changed files with 133 additions and 14 deletions

View File

@ -33,6 +33,8 @@ RocketActions.CopyAct.Copy = Copy
RocketActions.CopyAct.ttip.Copy = Copy this component (and subcomponents) to the clipboard.
RocketActions.PasteAct.Paste = Paste
RocketActions.PasteAct.ttip.Paste = Paste the component or simulation on the clipboard to the design.
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.NewStageAct.Newstage = New stage

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -60,7 +60,7 @@ import com.google.inject.Module;
@SuppressWarnings("serial")
public class PhotoFrame extends JFrame {
private static final Logger log = LoggerFactory.getLogger(PhotoFrame.class);
private final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
private final Translator trans = Application.getTranslator();
private final PhotoPanel photoPanel;

View File

@ -87,6 +87,8 @@ import net.sf.openrocket.utils.ComponentPresetEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
public class BasicFrame extends JFrame {
private static final long serialVersionUID = 948877655223365313L;
@ -98,7 +100,10 @@ public class BasicFrame extends JFrame {
private static final Translator trans = Application.getTranslator();
private static final Preferences prefs = Application.getPreferences();
private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
private static final int SHIFT_SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() |
SHIFT_DOWN_MASK;
public static final int COMPONENT_TAB = 0;
public static final int CONFIGURATION_TAB = 1;
@ -124,6 +129,7 @@ public class BasicFrame extends JFrame {
private JTabbedPane tabbedPane;
private RocketPanel rocketpanel;
private ComponentTree tree = null;
private final JPopupMenu popupMenu;
private final DocumentSelectionModel selectionModel;
private final TreeSelectionModel componentSelectionModel;
@ -163,6 +169,15 @@ public class BasicFrame extends JFrame {
actions = new RocketActions(document, selectionModel, this);
// Populate the popup menu
popupMenu = new JPopupMenu();
popupMenu.add(actions.getEditAction());
popupMenu.add(actions.getCutAction());
popupMenu.add(actions.getCopyAction());
popupMenu.add(actions.getPasteAction());
popupMenu.add(actions.getDuplicateAction());
popupMenu.add(actions.getDeleteAction());
log.debug("Constructing the BasicFrame UI");
// The main vertical split pane
@ -278,15 +293,17 @@ public class BasicFrame extends JFrame {
// Double-click opens config dialog
MouseListener ml = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
public void mouseClicked(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if (selRow != -1) {
if ((e.getClickCount() == 2) && !ComponentConfigDialog.isDialogVisible()) {
if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2) && !ComponentConfigDialog.isDialogVisible()) {
// Double-click
RocketComponent c = (RocketComponent) selPath.getLastPathComponent();
ComponentConfigDialog.showDialog(BasicFrame.this,
BasicFrame.this.document, c);
} else if ((e.getButton() == MouseEvent.BUTTON3) && (e.getClickCount() == 1)) {
doComponentTreePopup(e);
}
}
}
@ -333,7 +350,7 @@ public class BasicFrame extends JFrame {
button = new SelectColorButton(actions.getMoveDownAction());
panel.add(button, "sizegroup buttons, aligny 0%");
button = new SelectColorButton(actions.getEditAction());
button = new SelectColorButton(actions.getEditActionNoIcon());
panel.add(button, "sizegroup buttons");
button = new SelectColorButton(actions.getDeleteAction());
@ -698,6 +715,9 @@ public class BasicFrame extends JFrame {
item = new JMenuItem(actions.getPasteAction());
menu.add(item);
item = new JMenuItem(actions.getDuplicateAction());
menu.add(item);
item = new JMenuItem(actions.getDeleteAction());
menu.add(item);
@ -856,7 +876,7 @@ public class BasicFrame extends JFrame {
//// Debug log
item = new JMenuItem(trans.get("main.menu.help.debugLog"), KeyEvent.VK_D);
item.setIcon(Icons.HELP_DEBUG_LOG);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, SHORTCUT_KEY));
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, SHIFT_SHORTCUT_KEY));
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.help.debugLog.desc"));
item.addActionListener(new ActionListener() {
@Override
@ -898,6 +918,10 @@ public class BasicFrame extends JFrame {
this.setJMenuBar(menubar);
}
protected void doComponentTreePopup(MouseEvent e) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
private JMenu makeDebugMenu() {
JMenu menu;
JMenuItem item;

View File

@ -44,11 +44,14 @@ import net.sf.openrocket.util.Pair;
public class RocketActions {
public static final KeyStroke CUT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_X,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke COPY_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_C,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke PASTE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_V,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke DUPLICATE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_D,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
private final OpenRocketDocument document;
private final Rocket rocket;
@ -62,7 +65,9 @@ public class RocketActions {
private final RocketAction cutAction;
private final RocketAction copyAction;
private final RocketAction pasteAction;
private final RocketAction duplicateAction;
private final RocketAction editAction;
private final RocketAction editActionNoIcon;
private final RocketAction newStageAction;
private final RocketAction moveUpAction;
private final RocketAction moveDownAction;
@ -83,7 +88,10 @@ public class RocketActions {
this.cutAction = new CutAction();
this.copyAction = new CopyAction();
this.pasteAction = new PasteAction();
this.duplicateAction = new DuplicateAction();
this.editAction = new EditAction();
this.editActionNoIcon = new EditAction();
this.editActionNoIcon.putValue(Action.SMALL_ICON, null);
this.newStageAction = new NewStageAction();
this.moveUpAction = new MoveUpAction();
this.moveDownAction = new MoveDownAction();
@ -115,7 +123,9 @@ public class RocketActions {
cutAction.clipboardChanged();
copyAction.clipboardChanged();
pasteAction.clipboardChanged();
duplicateAction.clipboardChanged();
editAction.clipboardChanged();
editActionNoIcon.clipboardChanged();
newStageAction.clipboardChanged();
moveUpAction.clipboardChanged();
moveDownAction.clipboardChanged();
@ -147,10 +157,18 @@ public class RocketActions {
public Action getPasteAction() {
return pasteAction;
}
public Action getDuplicateAction() {
return duplicateAction;
}
public Action getEditAction() {
return editAction;
}
public Action getEditActionNoIcon() {
return editActionNoIcon;
}
public Action getNewStageAction() {
return newStageAction;
@ -667,12 +685,12 @@ public class RocketActions {
OpenRocketClipboard.setClipboard(copiedComponents);
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
} else if (sims.length > 0) {
} else if (sims != null && sims.length > 0) {
Simulation[] simsCopy = new Simulation[sims.length];
for (int i=0; i < sims.length; i++) {
simsCopy[i] = sims[i].copy();
}
OpenRocketClipboard.setClipboard(simsCopy);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
}
@ -765,9 +783,81 @@ public class RocketActions {
(OpenRocketClipboard.getClipboardSimulations() != null));
}
}
/**
* Action that duplicates the selected component.
*/
private class DuplicateAction extends RocketAction {
private static final long serialVersionUID = 1L;
public DuplicateAction() {
//// Copy
this.putValue(NAME, trans.get("RocketActions.DuplicateAct.Duplicate"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
this.putValue(ACCELERATOR_KEY, DUPLICATE_KEY_STROKE);
//// Copy this component (and subcomponents) to the clipboard.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DuplicateAct.ttip.Duplicate"));
this.putValue(SMALL_ICON, Icons.EDIT_DUPLICATE);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components != null) {
components = new ArrayList<>(components);
fillInMissingSelections(components);
components.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
}
Simulation[] sims = selectionModel.getSelectedSimulations();
if (isCopyable(components)) {
List<RocketComponent> duplicateComponents = new LinkedList<>(copyComponentsMaintainParent(components));
List<Pair<RocketComponent, Integer>> positions = new LinkedList<>();
for (RocketComponent component : duplicateComponents) {
positions.add(getPastePosition(component));
}
if (duplicateComponents.size() == 1) {
document.addUndoPosition("Duplicate " + duplicateComponents.get(0).getComponentName());
} else {
document.addUndoPosition("Duplicate components");
}
for (int i = 0; i < duplicateComponents.size(); i++) {
positions.get(i).getU().addChild(duplicateComponents.get(i), positions.get(i).getV());
}
selectionModel.setSelectedComponents(duplicateComponents);
} else if (sims != null && sims.length > 0) {
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
for (Simulation s: sims) {
Simulation copy = s.duplicateSimulation(rocket);
String name = copy.getName();
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
copy.setName(document.getNextSimulationName());
}
document.addSimulation(copy);
copySims.add(copy);
}
// TODO: undo
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
}
}
@Override
public void clipboardChanged() {
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
isSimulationSelected());
}
}
@ -782,6 +872,7 @@ public class RocketActions {
this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
//// Edit the selected component.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
clipboardChanged();
}

View File

@ -58,9 +58,11 @@ public class Icons {
public static final Icon FILE_QUIT = loadImageIcon("pix/icons/application-exit.png", "Quit OpenRocket");
public static final Icon EDIT_UNDO = loadImageIcon("pix/icons/edit-undo.png", trans.get("Icons.Undo"));
public static final Icon EDIT_REDO = loadImageIcon("pix/icons/edit-redo.png", trans.get("Icons.Redo"));
public static final Icon EDIT_EDIT = loadImageIcon("pix/icons/edit-edit.png", "Edit");
public static final Icon EDIT_CUT = loadImageIcon("pix/icons/edit-cut.png", "Cut");
public static final Icon EDIT_COPY = loadImageIcon("pix/icons/edit-copy.png", "Copy");
public static final Icon EDIT_PASTE = loadImageIcon("pix/icons/edit-paste.png", "Paste");
public static final Icon EDIT_DUPLICATE = loadImageIcon("pix/icons/edit-duplicate.png", "Duplicate");
public static final Icon EDIT_DELETE = loadImageIcon("pix/icons/edit-delete.png", "Delete");
public static final Icon EDIT_SCALE = loadImageIcon("pix/icons/edit-scale.png", "Scale");