From: Fabian Stemmler Date: Sun, 14 Jul 2019 16:08:35 +0000 (+0200) Subject: Added option to switch off snapping in the Editor X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=13e72d4157b071cbb58942d964f3c0bb00c26029;hp=-c;p=Mograsim.git Added option to switch off snapping in the Editor Also moved all UI related classes into their own package --- 13e72d4157b071cbb58942d964f3c0bb00c26029 diff --git a/net.mograsim.logic.model.editor/META-INF/MANIFEST.MF b/net.mograsim.logic.model.editor/META-INF/MANIFEST.MF index 40d06541..a666cdec 100644 --- a/net.mograsim.logic.model.editor/META-INF/MANIFEST.MF +++ b/net.mograsim.logic.model.editor/META-INF/MANIFEST.MF @@ -5,7 +5,8 @@ Bundle-SymbolicName: net.mograsim.logic.model.editor Bundle-Version: 0.1.0.qualifier Export-Package: net.mograsim.logic.model.editor, net.mograsim.logic.model.editor.handles, - net.mograsim.logic.model.editor.states + net.mograsim.logic.model.editor.states, + net.mograsim.logic.model.editor.ui Require-Bundle: net.mograsim.logic.model;bundle-version="0.1.0", net.mograsim.preferences;bundle-version="0.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/DialogManager.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/DialogManager.java deleted file mode 100644 index 347e6222..00000000 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/DialogManager.java +++ /dev/null @@ -1,131 +0,0 @@ -package net.mograsim.logic.model.editor; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -public class DialogManager -{ - private Shell parent; - - public DialogManager(Shell parent) - { - this.parent = parent; - } - - public void openWarningDialog(String title, String message) - { - MessageBox b = new MessageBox(parent, SWT.ICON_WARNING | SWT.OK); - b.setText(title); - b.setMessage(message); - b.open(); - } - - public static class InteractiveDialog - { - private String[] finalInput; - private final Display display; - private final Shell shell; - private final Button b1, b2; - private Text[] textFields; - private InteractiveDialog.InteractiveDialogState state; - - public InteractiveDialog(String title, String acceptLabel, String cancelLabel, String... inputs) - { - display = Display.getDefault(); - shell = new Shell(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.ON_TOP | SWT.APPLICATION_MODAL); - shell.setMinimumSize(500, 150); - shell.setText(title); - GridLayout layout = new GridLayout(); - layout.numColumns = 2; - shell.setLayout(layout); - - this.textFields = new Text[inputs.length]; - for (int i = 0; i < inputs.length; i++) - { - Label textFieldName = new Label(shell, SWT.NONE); - textFieldName.setText(inputs[i].concat(":")); - GridData g = new GridData(); - g.grabExcessHorizontalSpace = true; - g.horizontalAlignment = SWT.FILL; - Text newTextField = new Text(shell, SWT.BORDER); - newTextField.setLayoutData(g); - textFields[i] = newTextField; - } - b1 = new Button(shell, SWT.PUSH); - b1.addListener(SWT.Selection, e -> - { - state = InteractiveDialogState.ACCEPTED; - buildFinalInput(); - dispose(); - }); - b1.setText(acceptLabel); - b2 = new Button(shell, SWT.PUSH); - b2.addListener(SWT.Selection, e -> - { - state = InteractiveDialogState.CANCELLED; - buildFinalInput(); - dispose(); - }); - b2.setText(cancelLabel); - - state = InteractiveDialogState.ACTIVE; - - shell.pack(); - } - - public String getText() - { - return getText(0); - } - - public String getText(int index) - { - if (!shell.isDisposed()) - return textFields[index].getText(); - else - return finalInput[index]; - } - - public void open() - { - shell.open(); - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - } - - public void dispose() - { - shell.dispose(); - } - - public InteractiveDialog.InteractiveDialogState getState() - { - return state; - } - - private void buildFinalInput() - { - finalInput = new String[textFields.length]; - for (int i = 0; i < textFields.length; i++) - finalInput[i] = textFields[i].getText(); - } - - public static enum InteractiveDialogState - { - ACTIVE, ACCEPTED, CANCELLED; - } - } - - public static void openAddPinDialog(Editor editor, double x, double y) - { - - } -} diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Editor.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Editor.java index 36dcbc7f..e285574e 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Editor.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Editor.java @@ -15,6 +15,8 @@ import net.mograsim.logic.model.editor.handles.Handle; import net.mograsim.logic.model.editor.handles.HandleManager; import net.mograsim.logic.model.editor.handles.PinHandle; import net.mograsim.logic.model.editor.states.StateManager; +import net.mograsim.logic.model.editor.ui.DialogManager; +import net.mograsim.logic.model.editor.ui.EditorGUI; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.GUIComponent; import net.mograsim.logic.model.model.wires.GUIWire; @@ -31,15 +33,17 @@ public final class Editor public final EditorGUI gui; public final StateManager stateManager; private final SaveLoadManager saveManager; - Snapping snapping = Snapping.ABSOLUTE; + private Snapping snapping = Snapping.ABSOLUTE; private double snapX = 5, snapY = 5; public final DialogManager dialogManager; + public final EditorUserInput userInput; public Editor(DeserializedSubmodelComponent toBeEdited) { this.toBeEdited = toBeEdited; handleManager = new HandleManager(this); gui = new EditorGUI(this); + userInput = new EditorUserInput(this); stateManager = new StateManager(this); handleManager.init(); saveManager = new SaveLoadManager(this); @@ -185,19 +189,6 @@ public final class Editor } } - public Point getCanvasMousePosition() - { - //TODO - org.eclipse.swt.graphics.Point canvasLoc = gui.logicCanvas.getLocation(), - mouseLoc = gui.display.getCursorLocation(), shellLoc = gui.shell.getLocation(); - return new Point(mouseLoc.x - shellLoc.x - canvasLoc.x, mouseLoc.y - shellLoc.y - canvasLoc.y); - } - - public Point getWorldMousePosition() - { - return gui.logicCanvas.canvasToWorldCoords(getCanvasMousePosition()); - } - public void addWire(PinHandle a, PinHandle b) { new GUIWire(toBeEdited.getSubmodelModifiable(), a.getPin(), b.getPin(), new Point[0]); @@ -206,10 +197,26 @@ public final class Editor public static enum Snapping { OFF, ABSOLUTE; + + @Override + public String toString() + { + return super.toString().toLowerCase(); + } } public static void main(String[] args) { SaveLoadManager.openLoadDialog(); } + + public Snapping getSnapping() + { + return snapping; + } + + public void setSnapping(Snapping snapping) + { + this.snapping = snapping; + } } diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorCanvas.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorCanvas.java deleted file mode 100644 index df6b9137..00000000 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorCanvas.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.mograsim.logic.model.editor; - -import java.util.Collection; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; - -import net.haspamelodica.swt.helper.gcs.TranslatedGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -import net.mograsim.logic.model.LogicUICanvas; -import net.mograsim.logic.model.editor.handles.Handle; -import net.mograsim.preferences.Preferences; - -public class EditorCanvas extends LogicUICanvas -{ - private Collection handles; - - public EditorCanvas(Composite parent, int style, Editor editor) - { - super(parent, style, editor.toBeEdited.submodel); - - handles = editor.handleManager.getHandles(); - editor.handleManager.addHandleAddedListener(h -> - h.addRedrawListener(this::redrawThreadsafe)); - //Is this even necessary? The Handle should be finalized by the gc - editor.handleManager.addHandleRemovedListener(h -> h.removeRedrawListener(this::redrawThreadsafe)); - - addZoomedRenderer(gc -> - { - Rectangle visibleRegion = new Rectangle(-offX / zoom, -offY / zoom, gW / zoom, gH / zoom); - Color background = Preferences.current().getColor("net.mograsim.logic.ui.color.background"); - if (background != null) - setBackground(background);// this.setBackground, not gc.setBackground to have the background fill the - // canvas - - TranslatedGC tgc = new TranslatedGC(gc, 0.0d, 0.0d, 1 / editor.toBeEdited.getSubmodelScale(), false); - editor.toBeEdited.outlineRenderer.render(tgc, new Rectangle(-offX / zoom, -offY / zoom, gW / zoom, gH / zoom)); - - handles.forEach(h -> h.render(gc, visibleRegion)); - }); - } -} diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorGUI.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorGUI.java deleted file mode 100644 index 2627d3c0..00000000 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorGUI.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.mograsim.logic.model.editor; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.List; -import org.eclipse.swt.widgets.Shell; - -import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay; -import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput; -import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; - -public class EditorGUI -{ - final Display display; - final Shell shell; - public final EditorCanvas logicCanvas; - private final List addList; - - public EditorGUI(Editor editor) - { - display = Display.getDefault(); - shell = new Shell(display); - - //Layout - GridLayout layout = new GridLayout(); - shell.setLayout(layout); - layout.numColumns = 2; - - GridData d = new GridData(); - d.grabExcessVerticalSpace = true; - d.verticalAlignment = SWT.FILL; - addList = new List(shell, SWT.FILL); - addList.setLayoutData(d); - refreshAddList(); - - d = new GridData(); - d.grabExcessHorizontalSpace = true; - d.horizontalAlignment = SWT.FILL; - d.grabExcessVerticalSpace = true; - d.verticalAlignment = SWT.FILL; - - logicCanvas = new EditorCanvas(shell, SWT.TRAIL, editor); - logicCanvas.setLayoutData(d); - - - new EditorUserInput(editor, this); - ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(logicCanvas); - userInput.buttonDrag = 3; - userInput.buttonZoom = 2; - userInput.enableUserInput(); - new ZoomableCanvasOverlay(logicCanvas, null).enableScale(); - } - - public void refreshAddList() - { - addList.setItems(IndirectGUIComponentCreator.getStandardComponentIDs().toArray(String[]::new)); - addList.select(0); - } - - public String getAddListSelected() - { - String[] selection = addList.getSelection(); - if(selection.length == 0) - throw new IllegalStateException("Selection in the Add Component List may never be empty!"); - return selection[0]; - } - - public void open() - { - shell.open(); - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - } - -} diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorUserInput.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorUserInput.java index cb66e94f..441360d8 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorUserInput.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/EditorUserInput.java @@ -7,11 +7,15 @@ import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.mograsim.logic.model.editor.ui.EditorGUI; public class EditorUserInput { - public EditorUserInput(Editor editor, EditorGUI gui) + private final EditorGUI gui; + + public EditorUserInput(Editor editor) { + this.gui = editor.gui; gui.logicCanvas.addMouseListener(new MouseListener() { @Override @@ -92,4 +96,14 @@ public class EditorUserInput } }); } + + public Point getCanvasMousePosition() + { + return new Point(gui.logicCanvas.toControl(gui.display.getCursorLocation())); + } + + public Point getWorldMousePosition() + { + return gui.logicCanvas.canvasToWorldCoords(getCanvasMousePosition()); + } } \ No newline at end of file diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java index 848227bc..1ba1d252 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/SaveLoadManager.java @@ -2,7 +2,7 @@ package net.mograsim.logic.model.editor; import java.io.IOException; -import net.mograsim.logic.model.editor.DialogManager.InteractiveDialog; +import net.mograsim.logic.model.editor.ui.DialogManager.InteractiveDialog; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.serializing.DeserializedSubmodelComponent; import net.mograsim.logic.model.serializing.SubmodelComponentDeserializer; diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/states/SelectionState.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/states/SelectionState.java index 446635ee..2a66e476 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/states/SelectionState.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/states/SelectionState.java @@ -7,12 +7,12 @@ import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas.ZoomedRenderer; import net.mograsim.logic.model.editor.Editor; import net.mograsim.logic.model.editor.Selection; -import net.mograsim.logic.model.editor.DialogManager.InteractiveDialog; import net.mograsim.logic.model.editor.handles.Handle; import net.mograsim.logic.model.editor.handles.PinHandle; import net.mograsim.logic.model.editor.handles.WireHandle; import net.mograsim.logic.model.editor.handles.Handle.HandleClickInfo; import net.mograsim.logic.model.editor.handles.WireHandle.WireHandleClickInfo; +import net.mograsim.logic.model.editor.ui.DialogManager.InteractiveDialog; import net.mograsim.logic.model.model.wires.MovablePin; import net.mograsim.logic.model.model.wires.Pin; @@ -36,7 +36,7 @@ public class SelectionState extends EditorState @Override public void add() { - Point curserPos = editor.getWorldMousePosition(); + Point curserPos = editor.userInput.getWorldMousePosition(); editor.addComponent(curserPos.x, curserPos.y); } @@ -55,7 +55,7 @@ public class SelectionState extends EditorState @Override public void paste() { - Point curserPos = editor.getWorldMousePosition(); + Point curserPos = editor.userInput.getWorldMousePosition(); editor.paste(curserPos.x, curserPos.y); } diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/DialogManager.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/DialogManager.java new file mode 100644 index 00000000..7d982e01 --- /dev/null +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/DialogManager.java @@ -0,0 +1,133 @@ +package net.mograsim.logic.model.editor.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import net.mograsim.logic.model.editor.Editor; + +public class DialogManager +{ + private Shell parent; + + public DialogManager(Shell parent) + { + this.parent = parent; + } + + public void openWarningDialog(String title, String message) + { + MessageBox b = new MessageBox(parent, SWT.ICON_WARNING | SWT.OK); + b.setText(title); + b.setMessage(message); + b.open(); + } + + public static class InteractiveDialog + { + private String[] finalInput; + private final Display display; + private final Shell shell; + private final Button b1, b2; + private Text[] textFields; + private InteractiveDialog.InteractiveDialogState state; + + public InteractiveDialog(String title, String acceptLabel, String cancelLabel, String... inputs) + { + display = Display.getDefault(); + shell = new Shell(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.ON_TOP | SWT.APPLICATION_MODAL); + shell.setMinimumSize(500, 150); + shell.setText(title); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + shell.setLayout(layout); + + this.textFields = new Text[inputs.length]; + for (int i = 0; i < inputs.length; i++) + { + Label textFieldName = new Label(shell, SWT.NONE); + textFieldName.setText(inputs[i].concat(":")); + GridData g = new GridData(); + g.grabExcessHorizontalSpace = true; + g.horizontalAlignment = SWT.FILL; + Text newTextField = new Text(shell, SWT.BORDER); + newTextField.setLayoutData(g); + textFields[i] = newTextField; + } + b1 = new Button(shell, SWT.PUSH); + b1.addListener(SWT.Selection, e -> + { + state = InteractiveDialogState.ACCEPTED; + buildFinalInput(); + dispose(); + }); + b1.setText(acceptLabel); + b2 = new Button(shell, SWT.PUSH); + b2.addListener(SWT.Selection, e -> + { + state = InteractiveDialogState.CANCELLED; + buildFinalInput(); + dispose(); + }); + b2.setText(cancelLabel); + + state = InteractiveDialogState.ACTIVE; + + shell.pack(); + } + + public String getText() + { + return getText(0); + } + + public String getText(int index) + { + if (!shell.isDisposed()) + return textFields[index].getText(); + else + return finalInput[index]; + } + + public void open() + { + shell.open(); + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + } + + public void dispose() + { + shell.dispose(); + } + + public InteractiveDialog.InteractiveDialogState getState() + { + return state; + } + + private void buildFinalInput() + { + finalInput = new String[textFields.length]; + for (int i = 0; i < textFields.length; i++) + finalInput[i] = textFields[i].getText(); + } + + public static enum InteractiveDialogState + { + ACTIVE, ACCEPTED, CANCELLED; + } + } + + public static void openAddPinDialog(Editor editor, double x, double y) + { + + } +} diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/EditorCanvas.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/EditorCanvas.java new file mode 100644 index 00000000..357e88ff --- /dev/null +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/EditorCanvas.java @@ -0,0 +1,44 @@ +package net.mograsim.logic.model.editor.ui; + +import java.util.Collection; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; + +import net.haspamelodica.swt.helper.gcs.TranslatedGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; +import net.mograsim.logic.model.LogicUICanvas; +import net.mograsim.logic.model.editor.Editor; +import net.mograsim.logic.model.editor.handles.Handle; +import net.mograsim.preferences.Preferences; + +//TODO: Remove Inheritance +public class EditorCanvas extends LogicUICanvas +{ + private Collection handles; + + public EditorCanvas(Composite parent, int style, Editor editor) + { + super(parent, style, editor.toBeEdited.submodel); + + handles = editor.handleManager.getHandles(); + editor.handleManager.addHandleAddedListener(h -> + h.addRedrawListener(this::redrawThreadsafe)); + //TODO: Is this even necessary? The Handle should be finalized by the gc + editor.handleManager.addHandleRemovedListener(h -> h.removeRedrawListener(this::redrawThreadsafe)); + + addZoomedRenderer(gc -> + { + Rectangle visibleRegion = new Rectangle(-offX / zoom, -offY / zoom, gW / zoom, gH / zoom); + Color background = Preferences.current().getColor("net.mograsim.logic.ui.color.background"); + if (background != null) + setBackground(background);// this.setBackground, not gc.setBackground to have the background fill the + // canvas + + TranslatedGC tgc = new TranslatedGC(gc, 0.0d, 0.0d, 1 / editor.toBeEdited.getSubmodelScale(), false); + editor.toBeEdited.outlineRenderer.render(tgc, new Rectangle(-offX / zoom, -offY / zoom, gW / zoom, gH / zoom)); + + handles.forEach(h -> h.render(gc, visibleRegion)); + }); + } +} diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/EditorGUI.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/EditorGUI.java new file mode 100644 index 00000000..4d5236f6 --- /dev/null +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/ui/EditorGUI.java @@ -0,0 +1,147 @@ +package net.mograsim.logic.model.editor.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay; +import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput; +import net.mograsim.logic.model.editor.Editor; +import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; + +public class EditorGUI +{ + public final Display display; + public final Shell shell; + public final EditorCanvas logicCanvas; + private final List addList; + private final Editor editor; + + public EditorGUI(Editor editor) + { + this.editor = editor; + display = Display.getDefault(); + shell = new Shell(display); + + // Layout + GridLayout layout = new GridLayout(); + shell.setLayout(layout); + layout.numColumns = 2; + + GridData d = new GridData(); + d.grabExcessVerticalSpace = true; + d.verticalAlignment = SWT.FILL; + d.verticalSpan = 2; + addList = new List(shell, SWT.FILL); + addList.setLayoutData(d); + refreshAddList(); + + d = new GridData(); + d.grabExcessHorizontalSpace = true; + d.horizontalAlignment = SWT.FILL; + d.grabExcessVerticalSpace = true; + d.verticalAlignment = SWT.FILL; + + logicCanvas = new EditorCanvas(shell, SWT.TRAIL, editor); + logicCanvas.setLayoutData(d); + + setupToolBar(); + + ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(logicCanvas); + userInput.buttonDrag = 3; + userInput.buttonZoom = 2; + userInput.enableUserInput(); + new ZoomableCanvasOverlay(logicCanvas, null).enableScale(); + } + + private ToolBar setupToolBar() + { + GridData d = new GridData(); + d.grabExcessHorizontalSpace = true; + d.horizontalAlignment = SWT.FILL; + + ToolBar toolBar = new ToolBar(shell, SWT.BORDER); + toolBar.setLayoutData(d); + + ToolItem snappingLabel = new ToolItem(toolBar, SWT.NONE); + snappingLabel.setText("Snapping:"); + + Menu menu = new Menu(shell, SWT.POP_UP); + ToolItem snappSelect = new ToolItem(toolBar, SWT.DROP_DOWN); + for (Editor.Snapping sn : Editor.Snapping.values()) + { + MenuItem item = new MenuItem(menu, SWT.PUSH); + item.addSelectionListener(new SelectionListener() + { + @Override + public void widgetSelected(SelectionEvent arg0) + { + editor.setSnapping(sn); + snappSelect.setText(sn.toString()); + } + + @Override + public void widgetDefaultSelected(SelectionEvent arg0) {} + }); + item.setText(sn.toString()); + } + + snappSelect.setText(editor.getSnapping().toString()); + snappSelect.addListener(SWT.Selection, new Listener() + { + public void handleEvent(Event event) + { + if (event.detail == SWT.ARROW) + { + Rectangle rect = snappSelect.getBounds(); + Point pt = new Point(rect.x, rect.y + rect.height); + pt = toolBar.toDisplay(pt); + menu.setLocation(pt.x, pt.y); + menu.setVisible(true); + } + } + }); + + new ToolItem(toolBar, SWT.SEPARATOR); + + toolBar.pack(); + + return toolBar; + } + + public void refreshAddList() + { + addList.setItems(IndirectGUIComponentCreator.getStandardComponentIDs().toArray(String[]::new)); + addList.select(0); + } + + public String getAddListSelected() + { + String[] selection = addList.getSelection(); + if (selection.length == 0) + throw new IllegalStateException("Selection in the Add Component List may never be empty!"); + return selection[0]; + } + + public void open() + { + shell.open(); + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + } + +}