Cleaned up Editor: removed warnings; cleaned listener system
[Mograsim.git] / plugins / net.mograsim.logic.model.editor / src / net / mograsim / logic / model / editor / ui / EditorGUI.java
1 package net.mograsim.logic.model.editor.ui;
2
3 import java.io.IOException;
4
5 import org.eclipse.swt.SWT;
6 import org.eclipse.swt.graphics.Point;
7 import org.eclipse.swt.graphics.Rectangle;
8 import org.eclipse.swt.layout.GridData;
9 import org.eclipse.swt.layout.GridLayout;
10 import org.eclipse.swt.widgets.Composite;
11 import org.eclipse.swt.widgets.Display;
12 import org.eclipse.swt.widgets.List;
13 import org.eclipse.swt.widgets.Menu;
14 import org.eclipse.swt.widgets.MenuItem;
15 import org.eclipse.swt.widgets.Shell;
16 import org.eclipse.swt.widgets.ToolBar;
17 import org.eclipse.swt.widgets.ToolItem;
18
19 import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay;
20 import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;
21 import net.mograsim.logic.model.editor.Editor;
22 import net.mograsim.logic.model.editor.SaveLoadManager;
23 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
24
25 public class EditorGUI
26 {
27         public final Display display;
28         public final Shell shell;
29         public final EditorCanvas logicCanvas;
30         private final List addList;
31         private final Editor editor;
32
33         public EditorGUI(Editor editor)
34         {
35                 this.editor = editor;
36                 display = Display.getDefault();
37                 shell = new Shell(display);
38
39                 GridLayout layout = new GridLayout();
40                 layout.numColumns = 1;
41                 shell.setLayout(layout);
42
43                 setupTopToolBar(shell);
44                 Composite innerComp = new Composite(shell, SWT.NONE);
45                 GridData innerCompData = new GridData();
46                 innerCompData.grabExcessHorizontalSpace = true;
47                 innerCompData.grabExcessVerticalSpace = true;
48                 innerCompData.horizontalAlignment = SWT.FILL;
49                 innerCompData.verticalAlignment = SWT.FILL;
50                 innerComp.setLayoutData(innerCompData);
51
52                 GridLayout innerLayout = new GridLayout();
53                 innerComp.setLayout(innerLayout);
54                 innerLayout.numColumns = 2;
55
56                 GridData d = new GridData();
57                 d.grabExcessHorizontalSpace = true;
58                 d.horizontalAlignment = SWT.FILL;
59                 d.grabExcessVerticalSpace = true;
60                 d.verticalAlignment = SWT.FILL;
61
62                 logicCanvas = new EditorCanvas(innerComp, SWT.TRAIL, editor);
63                 logicCanvas.setLayoutData(d);
64
65                 d = new GridData();
66                 d.grabExcessVerticalSpace = true;
67                 d.verticalAlignment = SWT.FILL;
68                 d.verticalSpan = 2;
69                 addList = new List(innerComp, SWT.V_SCROLL);
70                 addList.setLayoutData(d);
71                 refreshAddList();
72
73                 setupBottomToolBar(innerComp);
74
75                 ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(logicCanvas);
76                 userInput.buttonDrag = 3;
77                 userInput.buttonZoom = 2;
78                 userInput.enableUserInput();
79                 new ZoomableCanvasOverlay(logicCanvas, null).enableScale();
80         }
81
82         private ToolBar setupTopToolBar(Composite parent)
83         {
84                 GridData d = new GridData();
85                 d.grabExcessHorizontalSpace = true;
86                 d.horizontalAlignment = SWT.FILL;
87
88                 ToolBar toolBar = new ToolBar(parent, SWT.BORDER);
89                 toolBar.setLayoutData(d);
90
91                 ToolItem file = new ToolItem(toolBar, SWT.DROP_DOWN);
92
93                 // TODO
94                 DropDownEntry newEntry = new DropDownEntry("New", Editor::openNewEditor);
95                 DropDownEntry loadEntry = new DropDownEntry("Load", () ->
96                 {
97                         try
98                         {
99                                 SaveLoadManager.openLoadDialog();
100                         }
101                         catch (IOException e)
102                         {
103                                 editor.dialogManager.openWarningDialog("Failed to load Component!", e.getMessage());
104                         }
105                 });
106                 DropDownEntry saveEntry = new DropDownEntry("Save", editor::save);
107                 DropDownEntry saveAsEntry = new DropDownEntry("Save as...", editor::saveAs);
108
109                 DropDownEntry[] entries = new DropDownEntry[] { newEntry, loadEntry, saveEntry, saveAsEntry };
110
111                 setupDrowpDownMenu(file, entries);
112
113                 file.setText("File");
114                 return toolBar;
115         }
116
117         @SuppressWarnings("unused") // ToolItem
118         private ToolBar setupBottomToolBar(Composite parent)
119         {
120                 GridData d = new GridData();
121                 d.grabExcessHorizontalSpace = true;
122                 d.horizontalAlignment = SWT.FILL;
123
124                 ToolBar toolBar = new ToolBar(parent, SWT.BORDER);
125                 toolBar.setLayoutData(d);
126
127                 ToolItem snappingLabel = new ToolItem(toolBar, SWT.NONE);
128                 snappingLabel.setText("Snapping:");
129
130                 ToolItem snappSelect = new ToolItem(toolBar, SWT.DROP_DOWN);
131                 DropDownEntry[] entries = new DropDownEntry[Editor.Snapping.values().length];
132                 int index = 0;
133                 for (Editor.Snapping sn : Editor.Snapping.values())
134                 {
135                         entries[index++] = new DropDownEntry(sn.toString(), () ->
136                         {
137                                 editor.setSnapping(sn);
138                                 snappSelect.setText(sn.toString());
139                         });
140                 }
141                 snappSelect.setText(editor.getSnapping().toString());
142                 setupDrowpDownMenu(snappSelect, entries);
143
144                 new ToolItem(toolBar, SWT.SEPARATOR);
145
146                 toolBar.pack();
147
148                 return toolBar;
149         }
150
151         private void setupDrowpDownMenu(ToolItem parent, DropDownEntry[] entries)
152         {
153                 Menu menu = new Menu(shell, SWT.POP_UP);
154                 for (DropDownEntry entry : entries)
155                 {
156                         MenuItem item = new MenuItem(menu, SWT.PUSH);
157                         item.addListener(SWT.Selection, e -> entry.onSelected.run());
158                         item.setText(entry.title);
159                 }
160
161                 parent.addListener(SWT.Selection, e ->
162                 {
163                         Rectangle rect = parent.getBounds();
164                         Point pt = new Point(rect.x, rect.y + rect.height);
165                         pt = parent.getParent().toDisplay(pt);
166                         menu.setLocation(pt.x, pt.y);
167                         menu.setVisible(true);
168                 });
169         }
170
171         private static class DropDownEntry
172         {
173                 public final String title;
174                 public final Runnable onSelected;
175
176                 public DropDownEntry(String title, Runnable onSelected)
177                 {
178                         super();
179                         this.title = title;
180                         this.onSelected = onSelected;
181                 }
182         }
183
184         public void refreshAddList()
185         {
186                 addList.setItems(IndirectModelComponentCreator.getStandardComponentIDs().keySet().stream().sorted().toArray(String[]::new));
187                 addList.select(0);
188         }
189
190         public String getAddListSelected()
191         {
192                 String[] selection = addList.getSelection();
193                 if (selection.length == 0)
194                         throw new IllegalStateException("Selection in the Add Component List may never be empty!");
195                 return selection[0];
196         }
197
198         public void open()
199         {
200                 shell.open();
201                 while (!shell.isDisposed())
202                         if (!display.readAndDispatch())
203                                 display.sleep();
204         }
205 }