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