|
@@ -1,6 +1,8 @@
|
|
|
package holeg.ui.view.main;
|
|
|
|
|
|
-import holeg.model.*;
|
|
|
+import holeg.model.AbstractCanvasObject;
|
|
|
+import holeg.model.GroupNode;
|
|
|
+import holeg.model.Model;
|
|
|
import holeg.preferences.ImagePreference;
|
|
|
import holeg.preferences.PreferenceKeys;
|
|
|
import holeg.ui.controller.Control;
|
|
@@ -8,7 +10,9 @@ import holeg.ui.model.GuiSettings;
|
|
|
import holeg.ui.view.canvas.Canvas;
|
|
|
import holeg.ui.view.canvas.CanvasCollectionPanel;
|
|
|
import holeg.ui.view.category.CategoryPanel;
|
|
|
-import holeg.ui.view.dialog.*;
|
|
|
+import holeg.ui.view.dialog.AboutUsPopUp;
|
|
|
+import holeg.ui.view.dialog.CanvasResizePopUp;
|
|
|
+import holeg.ui.view.dialog.EditEdgesPopUp;
|
|
|
import holeg.ui.view.image.Import;
|
|
|
import holeg.ui.view.information.HolonInformationPanel;
|
|
|
import holeg.ui.view.inspector.Inspector;
|
|
@@ -16,18 +20,24 @@ import holeg.ui.view.window.AddOnWindow;
|
|
|
import holeg.ui.view.window.FlexWindow;
|
|
|
import holeg.ui.view.window.Outliner;
|
|
|
import holeg.utility.listener.WindowClosingListener;
|
|
|
+import holeg.utility.math.vector.Vec2i;
|
|
|
|
|
|
import javax.swing.*;
|
|
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
|
|
import javax.swing.filechooser.FileSystemView;
|
|
|
import java.awt.*;
|
|
|
-import java.awt.event.*;
|
|
|
+import java.awt.event.ActionEvent;
|
|
|
+import java.awt.event.InputEvent;
|
|
|
+import java.awt.event.KeyEvent;
|
|
|
import java.io.File;
|
|
|
import java.net.URI;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.Set;
|
|
|
import java.util.logging.Logger;
|
|
|
import java.util.prefs.Preferences;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
-public class Gui extends JFrame{
|
|
|
+public class Gui extends JFrame {
|
|
|
private static final Logger log = Logger.getLogger(Model.class.getName());
|
|
|
private static final Preferences prefs = Preferences.userNodeForPackage(Gui.class);
|
|
|
private final Control control;
|
|
@@ -40,6 +50,7 @@ public class Gui extends JFrame{
|
|
|
|
|
|
/**
|
|
|
* Create the application.
|
|
|
+ *
|
|
|
* @param control the Controller
|
|
|
*/
|
|
|
public Gui(Control control) {
|
|
@@ -61,9 +72,9 @@ public class Gui extends JFrame{
|
|
|
private void initFrame() {
|
|
|
this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30));
|
|
|
this.setBounds(new Rectangle(prefs.getInt(PreferenceKeys.Gui.Width, 1200), prefs.getInt(PreferenceKeys.Gui.Height, 800)));
|
|
|
- if(prefs.get(PreferenceKeys.Gui.Width, null) != null){
|
|
|
+ if (prefs.get(PreferenceKeys.Gui.Width, null) != null) {
|
|
|
this.setLocation(prefs.getInt(PreferenceKeys.Gui.XPos, 1200), prefs.getInt(PreferenceKeys.Gui.YPos, 800));
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
this.setLocationRelativeTo(null);
|
|
|
}
|
|
|
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
|
@@ -81,13 +92,15 @@ public class Gui extends JFrame{
|
|
|
}
|
|
|
|
|
|
private void initLayout() {
|
|
|
+ this.setJMenuBar(new GuiMenuBar());
|
|
|
+
|
|
|
final JSplitPane categorySplit = new JSplitPane();
|
|
|
final JSplitPane canvasSplit = new JSplitPane();
|
|
|
final JSplitPane elementSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
|
|
|
final JScrollPane informationPanelScrollPane = new JScrollPane();
|
|
|
- this.setJMenuBar(new GuiMenuBar());
|
|
|
- this.getContentPane().setLayout(new BorderLayout(0, 0));
|
|
|
- this.getContentPane().add(categorySplit);
|
|
|
+ Container contentPanel = this.getContentPane();
|
|
|
+ contentPanel.setLayout(new BorderLayout(0, 0));
|
|
|
+ contentPanel.add(categorySplit);
|
|
|
categorySplit.setLeftComponent(categoryPanel);
|
|
|
categorySplit.setRightComponent(canvasSplit);
|
|
|
categorySplit.setDividerLocation(200);
|
|
@@ -110,7 +123,7 @@ public class Gui extends JFrame{
|
|
|
informationPanelScrollPane.getVerticalScrollBar().setUnitIncrement(16);
|
|
|
informationPanelScrollPane.setBorder(null);
|
|
|
|
|
|
- this.getContentPane().add(timePanel, BorderLayout.SOUTH);
|
|
|
+ contentPanel.add(timePanel, BorderLayout.SOUTH);
|
|
|
}
|
|
|
|
|
|
public Canvas getActualCanvas() {
|
|
@@ -141,6 +154,10 @@ public class Gui extends JFrame{
|
|
|
private final JMenuItem selectAllButton = new JMenuItem("All");
|
|
|
private final JMenuItem clearSelectionButton = new JMenuItem("Clear");
|
|
|
private final JMenuItem invertSelectionButton = new JMenuItem("Invert");
|
|
|
+ private final JMenuItem groupButton = new JMenuItem("Group");
|
|
|
+ private final JMenuItem ungroupButton = new JMenuItem("Ungroup");
|
|
|
+ private final JMenuItem removeButton = new JMenuItem("Remove");
|
|
|
+
|
|
|
|
|
|
private final JMenuItem edgePropertiesButton = new JMenuItem("Edge Properties");
|
|
|
private final JMenuItem alignAllButton = new JMenuItem("Align All");
|
|
@@ -161,7 +178,7 @@ public class Gui extends JFrame{
|
|
|
private final JCheckBoxMenuItem showSupplyBarsCheckBox = new JCheckBoxMenuItem("Show supply bars.", true);
|
|
|
private final JFileChooser fileChooser = initFileChooser();
|
|
|
|
|
|
- private final int IconSize = 15;
|
|
|
+ private final static int IconSize = 15;
|
|
|
//WindowMenu
|
|
|
JMenuItem algorithmButton = new JMenuItem("Algorithm Panel", new ImageIcon(Import
|
|
|
.loadImage(ImagePreference.Button.Menu.Algo).getScaledInstance(IconSize, IconSize, java.awt.Image.SCALE_SMOOTH)));
|
|
@@ -170,6 +187,8 @@ public class Gui extends JFrame{
|
|
|
JMenuItem flexMenuButton = new JMenuItem("Flexibility Panel", new ImageIcon(Import
|
|
|
.loadImage(ImagePreference.Button.Menu.Algo).getScaledInstance(IconSize, IconSize, java.awt.Image.SCALE_SMOOTH)));
|
|
|
|
|
|
+ private final static Vec2i DefaultOffset = new Vec2i(20,20);
|
|
|
+
|
|
|
GuiMenuBar() {
|
|
|
initMenuLayout();
|
|
|
initButtonActions();
|
|
@@ -209,6 +228,11 @@ public class Gui extends JFrame{
|
|
|
selectionMenu.add(clearSelectionButton);
|
|
|
selectionMenu.add(invertSelectionButton);
|
|
|
editMenu.addSeparator();
|
|
|
+ editMenu.add(groupButton);
|
|
|
+ editMenu.add(ungroupButton);
|
|
|
+ editMenu.addSeparator();
|
|
|
+ editMenu.add(removeButton);
|
|
|
+ editMenu.addSeparator();
|
|
|
editMenu.add(edgePropertiesButton);
|
|
|
editMenu.add(alignAllButton);
|
|
|
editMenu.add(resetMenu);
|
|
@@ -235,6 +259,9 @@ public class Gui extends JFrame{
|
|
|
openMenuButton.addActionListener(clicked -> openFile());
|
|
|
saveMenuButton.addActionListener(clicked -> saveFile());
|
|
|
saveAsMenuButton.addActionListener(clicked -> saveNewFile());
|
|
|
+ groupButton.addActionListener(clicked -> control.group());
|
|
|
+ ungroupButton.addActionListener(clicked -> control.ungroup());
|
|
|
+
|
|
|
edgePropertiesButton.addActionListener(actionEvent -> new EditEdgesPopUp(Gui.this, control));
|
|
|
alignAllButton.addActionListener(clicked -> {
|
|
|
//TODO(Tom2022-01-14): recreateTryToAlignObjects
|
|
@@ -248,6 +275,15 @@ public class Gui extends JFrame{
|
|
|
outlinerButton.addActionListener(clicked -> new Outliner(Gui.this, control));
|
|
|
flexMenuButton.addActionListener(clicked -> new FlexWindow(Gui.this, control));
|
|
|
|
|
|
+ selectAllButton.addActionListener(clicked -> selectAll());
|
|
|
+ clearSelectionButton.addActionListener(clicked -> control.clearSelection());
|
|
|
+ invertSelectionButton.addActionListener(clicked -> invertSelection());
|
|
|
+
|
|
|
+ copyButton.addActionListener(clicked -> control.copy());
|
|
|
+ cutButton.addActionListener(clicked -> control.cut());
|
|
|
+ pasteButton.addActionListener(clicked -> paste());
|
|
|
+
|
|
|
+ removeButton.addActionListener(clicked -> removeSelectedObjects());
|
|
|
|
|
|
String tkWikiWebpage = "https://git.tk.informatik.tu-darmstadt.de/carlos.garcia/praktikum-holons/wiki/";
|
|
|
introductionButton.addActionListener(clicked -> openWebpage(tkWikiWebpage + "Introduction+V2.1"));
|
|
@@ -257,6 +293,7 @@ public class Gui extends JFrame{
|
|
|
aboutUsButton.addActionListener(clicked -> new AboutUsPopUp(Gui.this));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
private void openWebpage(String URL) {
|
|
|
try {
|
|
|
java.awt.Desktop.getDesktop().browse(new URI(URL));
|
|
@@ -267,8 +304,9 @@ public class Gui extends JFrame{
|
|
|
|
|
|
private void initButtonShortCuts() {
|
|
|
int defaultModifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
|
|
|
+ int defaultShiftModifier = defaultModifier + InputEvent.SHIFT_DOWN_MASK;
|
|
|
saveMenuButton.setAccelerator(KeyStroke.getKeyStroke('S', defaultModifier));
|
|
|
- saveAsMenuButton.setAccelerator(KeyStroke.getKeyStroke('S', defaultModifier + InputEvent.SHIFT_DOWN_MASK));
|
|
|
+ saveAsMenuButton.setAccelerator(KeyStroke.getKeyStroke('S', defaultShiftModifier));
|
|
|
openMenuButton.setAccelerator(KeyStroke.getKeyStroke('O', defaultModifier));
|
|
|
newMenuButton.setAccelerator(KeyStroke.getKeyStroke('N', defaultModifier));
|
|
|
undoButton.setAccelerator(KeyStroke.getKeyStroke('Z', defaultModifier));
|
|
@@ -277,21 +315,25 @@ public class Gui extends JFrame{
|
|
|
pasteButton.setAccelerator(KeyStroke.getKeyStroke('V', defaultModifier));
|
|
|
cutButton.setAccelerator(KeyStroke.getKeyStroke('X', defaultModifier));
|
|
|
selectAllButton.setAccelerator(KeyStroke.getKeyStroke('A', defaultModifier));
|
|
|
- clearSelectionButton.setAccelerator(KeyStroke.getKeyStroke('A', defaultModifier + InputEvent.SHIFT_DOWN_MASK));
|
|
|
+ clearSelectionButton.setAccelerator(KeyStroke.getKeyStroke('A', defaultShiftModifier));
|
|
|
invertSelectionButton.setAccelerator(KeyStroke.getKeyStroke('I', defaultModifier));
|
|
|
+ groupButton.setAccelerator(KeyStroke.getKeyStroke('G', defaultModifier));
|
|
|
+ ungroupButton.setAccelerator(KeyStroke.getKeyStroke('U', defaultModifier));
|
|
|
+ removeButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
private void toggleSupplyBarAppearance() {
|
|
|
GuiSettings.showSupplyBars = showSupplyBarsCheckBox.isSelected();
|
|
|
- log.info("canvas.repaint4");
|
|
|
}
|
|
|
|
|
|
- private void saveFile(){
|
|
|
+ private void saveFile() {
|
|
|
GuiSettings.getActualSaveFile().ifPresentOrElse(control::saveFile, this::saveNewFile);
|
|
|
}
|
|
|
|
|
|
private void saveNewFile() {
|
|
|
- if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
|
|
|
+ if (fileChooser.showSaveDialog(Gui.this) == JFileChooser.APPROVE_OPTION) {
|
|
|
String path = fileChooser.getSelectedFile().getPath();
|
|
|
if (!path.endsWith(".json")) {
|
|
|
path += ".json";
|
|
@@ -302,16 +344,15 @@ public class Gui extends JFrame{
|
|
|
}
|
|
|
|
|
|
private void openFile() {
|
|
|
- if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
|
|
|
+ if (fileChooser.showOpenDialog(Gui.this) == JFileChooser.APPROVE_OPTION) {
|
|
|
prefs.put(PreferenceKeys.Gui.DefaultFolder, fileChooser.getCurrentDirectory().getPath());
|
|
|
control.loadFile(fileChooser.getSelectedFile());
|
|
|
- //TODO(Tom2022-01-27): make better
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void newFile() {
|
|
|
if (control.getModel().getCanvas().getObjectsInThisLayer().findAny().isPresent()) {
|
|
|
- int selectedOption = JOptionPane.showConfirmDialog(this, "Do you want to save your current model?",
|
|
|
+ int selectedOption = JOptionPane.showConfirmDialog(Gui.this, "Do you want to save your current model?",
|
|
|
"Warning", JOptionPane.YES_NO_OPTION);
|
|
|
if (selectedOption == JOptionPane.YES_OPTION) {
|
|
|
saveNewFile();
|
|
@@ -319,5 +360,27 @@ public class Gui extends JFrame{
|
|
|
}
|
|
|
control.clearModel();
|
|
|
}
|
|
|
+
|
|
|
+ private void selectAll(){
|
|
|
+ control.setSelection(getActualCanvas().getGroupNode()
|
|
|
+ .getObjectsInThisLayer().collect(Collectors.toSet()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void invertSelection() {
|
|
|
+ control.toggleSelectedObjects(getActualCanvas().getGroupNode()
|
|
|
+ .getObjectsInThisLayer().collect(Collectors.toSet()));
|
|
|
+ }
|
|
|
+ private void removeSelectedObjects() {
|
|
|
+ control.deleteCanvasObjects(GuiSettings.getSelectedObjects());
|
|
|
+ control.clearSelection();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void paste() {
|
|
|
+ Vec2i middlePosition = GroupNode.calculateMiddlePosition(GuiSettings.getClipboardObjects());
|
|
|
+ Optional<Vec2i> offset = Optional.ofNullable(getActualCanvas().getMousePosition())
|
|
|
+ .map(point -> new Vec2i(point).subtract(middlePosition));
|
|
|
+ control.paste(getActualCanvas().getGroupNode(), offset.orElse(DefaultOffset));
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|