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.JsonObject;
12 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
13 import net.mograsim.logic.model.editor.handles.ComponentHandle;
14 import net.mograsim.logic.model.editor.handles.Handle;
15 import net.mograsim.logic.model.editor.handles.HandleManager;
16 import net.mograsim.logic.model.editor.handles.PinHandle;
17 import net.mograsim.logic.model.editor.states.StateManager;
18 import net.mograsim.logic.model.model.ViewModelModifiable;
19 import net.mograsim.logic.model.model.components.GUIComponent;
20 import net.mograsim.logic.model.model.wires.GUIWire;
21 import net.mograsim.logic.model.serializing.DeserializedSubmodelComponent;
22 import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
24 public final class Editor
26 final Selection selection = new Selection();
27 final Set<ComponentInfo> copyBuffer = new HashSet<>();
28 public final DeserializedSubmodelComponent toBeEdited;
29 public final HandleManager handleManager;
30 final static Map<GUIComponent, String> identifierPerComponent = new HashMap<>();
31 public final EditorGUI gui;
32 public final StateManager stateManager;
33 private final SaveLoadManager saveManager;
34 Snapping snapping = Snapping.ABSOLUTE;
35 private double snapX = 5, snapY = 5;
36 public final DialogManager dialogManager;
38 public Editor(DeserializedSubmodelComponent toBeEdited)
40 this.toBeEdited = toBeEdited;
41 handleManager = new HandleManager(this);
42 gui = new EditorGUI(this);
43 stateManager = new StateManager(this);
45 saveManager = new SaveLoadManager(this);
46 dialogManager = new DialogManager(gui.shell);
48 toBeEdited.submodel.addComponentRemovedListener(c -> identifierPerComponent.remove(c));
53 public ViewModelModifiable getSubmodel()
55 return toBeEdited.getSubmodelModifiable();
58 public Selection getSelection()
63 //TODO: Remove this error prone method: Relative offset may change between multiple moves,
64 //because Handles have different ways of responding to reqMove(...), causing strange behaviour
66 public void moveSelection(double x, double y)
68 Point ref = selection.getTopLeft();
69 Point snapped = new Point(x, y);
70 applySnapping(snapped);
72 for (Handle c : selection)
75 newX = snapped.x + c.getPosX() - ref.x;
76 newY = snapped.y + c.getPosY() - ref.y;
77 c.reqMove(newX, newY);
81 public void moveHandles(double x, double y, Map<Handle, Point> handleOffsetMap)
83 Point snapped = new Point(x, y);
84 applySnapping(snapped);
86 for (Handle c : handleOffsetMap.keySet())
88 Point offset = handleOffsetMap.get(c);
90 newX = snapped.x + offset.x;
91 newY = snapped.y + offset.y;
92 c.reqMove(newX, newY);
96 public void deleteSelection()
98 selection.forEach(h -> h.reqDelete());
105 Point refPoint = selection.getTopLeft();
106 for (Handle h : selection)
108 Optional<ComponentInfo> cInfo = h.reqCopy(refPoint);
109 if(cInfo.isPresent())
110 copyBuffer.add(cInfo.get());
114 public void paste(double x, double y)
117 for (ComponentInfo info : copyBuffer)
119 GUIComponent comp = addComponent(info.identifier, info.params);
120 ComponentHandle h = handleManager.getHandle(comp);
121 h.reqMove(info.relX, info.relY);
132 public void addComponent(double x, double y)
134 GUIComponent c = addComponent(gui.getAddListSelected(), new JsonObject());
136 selection.add(handleManager.getHandle(c));
140 private GUIComponent addComponent(String identifier, JsonElement params)
142 GUIComponent comp = IndirectGUIComponentCreator.createComponent(toBeEdited.getSubmodelModifiable(), identifier,
144 identifierPerComponent.put(comp, identifier);
148 public static String getIdentifier(GUIComponent c)
150 return identifierPerComponent.get(c);
153 public void duplicate()
156 Point origin = selection.getTopLeft();
157 paste(origin.x + 20, origin.y + 20);
160 private void applySnapping(Point newP)
167 newP.x -= newP.x % snapX;
168 newP.y -= newP.y % snapY;
173 public static class ComponentInfo
175 public final double relX, relY;
176 public final String identifier;
177 public final JsonElement params;
179 public ComponentInfo(double relX, double relY, String identifier, JsonElement params)
183 this.identifier = identifier;
184 this.params = params;
188 public Point getCanvasMousePosition()
191 org.eclipse.swt.graphics.Point canvasLoc = gui.logicCanvas.getLocation(),
192 mouseLoc = gui.display.getCursorLocation(), shellLoc = gui.shell.getLocation();
193 return new Point(mouseLoc.x - shellLoc.x - canvasLoc.x, mouseLoc.y - shellLoc.y - canvasLoc.y);
196 public Point getWorldMousePosition()
198 return gui.logicCanvas.canvasToWorldCoords(getCanvasMousePosition());
201 public void addWire(PinHandle a, PinHandle b)
203 new GUIWire(toBeEdited.getSubmodelModifiable(), a.getPin(), b.getPin(), new Point[0]);
206 public static enum Snapping
211 public static void main(String[] args)
213 SaveLoadManager.openLoadDialog();