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