1 package net.mograsim.logic.model.editor;
3 import java.util.HashMap;
4 import java.util.HashSet;
6 import java.util.Optional;
9 import com.google.gson.JsonElement;
10 import com.google.gson.JsonNull;
11 import com.google.gson.JsonParser;
12 import com.google.gson.JsonSyntaxException;
14 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
15 import net.mograsim.logic.model.editor.handles.ComponentHandle;
16 import net.mograsim.logic.model.editor.handles.Handle;
17 import net.mograsim.logic.model.editor.handles.HandleManager;
18 import net.mograsim.logic.model.editor.handles.PinHandle;
19 import net.mograsim.logic.model.editor.states.StateManager;
20 import net.mograsim.logic.model.editor.ui.DialogManager;
21 import net.mograsim.logic.model.editor.ui.EditorGUI;
22 import net.mograsim.logic.model.model.ViewModelModifiable;
23 import net.mograsim.logic.model.model.components.GUIComponent;
24 import net.mograsim.logic.model.model.wires.GUIWire;
25 import net.mograsim.logic.model.serializing.DeserializedSubmodelComponent;
26 import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
28 public final class Editor
30 final Selection selection = new Selection();
31 final Set<ComponentInfo> copyBuffer = new HashSet<>();
32 public final DeserializedSubmodelComponent toBeEdited;
33 public final HandleManager handleManager;
34 final static Map<GUIComponent, String> identifierPerComponent = new HashMap<>();
35 public final EditorGUI gui;
36 public final StateManager stateManager;
37 private final SaveLoadManager saveManager;
38 private Snapping snapping = Snapping.ABSOLUTE;
39 private double snapX = 5, snapY = 5;
40 public final DialogManager dialogManager;
41 public final EditorUserInput userInput;
43 public Editor(DeserializedSubmodelComponent toBeEdited)
45 this.toBeEdited = toBeEdited;
46 handleManager = new HandleManager(this);
47 gui = new EditorGUI(this);
48 userInput = new EditorUserInput(this);
49 stateManager = new StateManager(this);
51 saveManager = new SaveLoadManager(this);
52 dialogManager = new DialogManager(gui.shell);
54 toBeEdited.submodel.addComponentRemovedListener(c -> identifierPerComponent.remove(c));
59 public ViewModelModifiable getSubmodel()
61 return toBeEdited.getSubmodelModifiable();
64 public Selection getSelection()
69 //TODO: Remove this error prone method: Relative offset may change between multiple moves,
70 //because Handles have different ways of responding to reqMove(...), causing strange behaviour
72 public void moveSelection(double x, double y)
74 Point ref = selection.getTopLeft();
75 Point snapped = new Point(x, y);
76 applySnapping(snapped);
78 for (Handle c : selection)
81 newX = snapped.x + c.getPosX() - ref.x;
82 newY = snapped.y + c.getPosY() - ref.y;
83 c.reqMove(newX, newY);
87 public void moveHandles(double x, double y, Map<Handle, Point> handleOffsetMap)
89 Point snapped = new Point(x, y);
90 applySnapping(snapped);
92 for (Handle c : handleOffsetMap.keySet())
94 Point offset = handleOffsetMap.get(c);
96 newX = snapped.x + offset.x;
97 newY = snapped.y + offset.y;
98 c.reqMove(newX, newY);
102 public void deleteSelection()
104 selection.forEach(h -> h.reqDelete());
111 Point refPoint = selection.getTopLeft();
112 for (Handle h : selection)
114 Optional<ComponentInfo> cInfo = h.reqCopy(refPoint);
115 if(cInfo.isPresent())
116 copyBuffer.add(cInfo.get());
120 public void paste(double x, double y)
123 for (ComponentInfo info : copyBuffer)
125 GUIComponent comp = addComponent(info.identifier, info.params);
126 ComponentHandle h = handleManager.getHandle(comp);
127 h.reqMove(info.relX, info.relY);
138 public void addComponent(double x, double y)
140 boolean successful = false;
141 JsonElement params = JsonNull.INSTANCE;
145 String selected = gui.getAddListSelected();
148 GUIComponent c = addComponent(selected, params);
150 selection.add(handleManager.getHandle(c));
154 catch(UnsupportedOperationException | JsonSyntaxException | NumberFormatException e)
156 String result = DialogManager.openMultiLineTextDialog("Add component", "Create", "Cancel", "Parameters:");
159 params = new JsonParser().parse(result);
164 private GUIComponent addComponent(String identifier, JsonElement params)
166 GUIComponent comp = IndirectGUIComponentCreator.createComponent(toBeEdited.getSubmodelModifiable(), identifier,
168 identifierPerComponent.put(comp, identifier);
172 public static String getIdentifier(GUIComponent c)
174 return identifierPerComponent.get(c);
177 public void duplicate()
180 Point origin = selection.getTopLeft();
181 paste(origin.x + 20, origin.y + 20);
184 private void applySnapping(Point newP)
191 newP.x -= newP.x % snapX;
192 newP.y -= newP.y % snapY;
197 public static class ComponentInfo
199 public final double relX, relY;
200 public final String identifier;
201 public final JsonElement params;
203 public ComponentInfo(double relX, double relY, String identifier, JsonElement params)
207 this.identifier = identifier;
208 this.params = params;
212 public void addWire(PinHandle a, PinHandle b)
214 new GUIWire(toBeEdited.getSubmodelModifiable(), a.getPin(), b.getPin(), new Point[0]);
217 public static enum Snapping
222 public String toString()
224 return super.toString().toLowerCase();
228 public static void main(String[] args)
230 SaveLoadManager.openLoadDialog();
233 public Snapping getSnapping()
238 public void setSnapping(Snapping snapping)
240 this.snapping = snapping;