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.editor.ui.DialogManager;
19 import net.mograsim.logic.model.editor.ui.EditorGUI;
20 import net.mograsim.logic.model.model.ViewModelModifiable;
21 import net.mograsim.logic.model.model.components.GUIComponent;
22 import net.mograsim.logic.model.model.wires.GUIWire;
23 import net.mograsim.logic.model.serializing.DeserializedSubmodelComponent;
24 import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
26 public final class Editor
28 final Selection selection = new Selection();
29 final Set<ComponentInfo> copyBuffer = new HashSet<>();
30 public final DeserializedSubmodelComponent toBeEdited;
31 public final HandleManager handleManager;
32 final static Map<GUIComponent, String> identifierPerComponent = new HashMap<>();
33 public final EditorGUI gui;
34 public final StateManager stateManager;
35 private final SaveLoadManager saveManager;
36 private Snapping snapping = Snapping.ABSOLUTE;
37 private double snapX = 5, snapY = 5;
38 public final DialogManager dialogManager;
39 public final EditorUserInput userInput;
41 public Editor(DeserializedSubmodelComponent toBeEdited)
43 this.toBeEdited = toBeEdited;
44 handleManager = new HandleManager(this);
45 gui = new EditorGUI(this);
46 userInput = new EditorUserInput(this);
47 stateManager = new StateManager(this);
49 saveManager = new SaveLoadManager(this);
50 dialogManager = new DialogManager(gui.shell);
52 toBeEdited.submodel.addComponentRemovedListener(c -> identifierPerComponent.remove(c));
57 public ViewModelModifiable getSubmodel()
59 return toBeEdited.getSubmodelModifiable();
62 public Selection getSelection()
67 //TODO: Remove this error prone method: Relative offset may change between multiple moves,
68 //because Handles have different ways of responding to reqMove(...), causing strange behaviour
70 public void moveSelection(double x, double y)
72 Point ref = selection.getTopLeft();
73 Point snapped = new Point(x, y);
74 applySnapping(snapped);
76 for (Handle c : selection)
79 newX = snapped.x + c.getPosX() - ref.x;
80 newY = snapped.y + c.getPosY() - ref.y;
81 c.reqMove(newX, newY);
85 public void moveHandles(double x, double y, Map<Handle, Point> handleOffsetMap)
87 Point snapped = new Point(x, y);
88 applySnapping(snapped);
90 for (Handle c : handleOffsetMap.keySet())
92 Point offset = handleOffsetMap.get(c);
94 newX = snapped.x + offset.x;
95 newY = snapped.y + offset.y;
96 c.reqMove(newX, newY);
100 public void deleteSelection()
102 selection.forEach(h -> h.reqDelete());
109 Point refPoint = selection.getTopLeft();
110 for (Handle h : selection)
112 Optional<ComponentInfo> cInfo = h.reqCopy(refPoint);
113 if(cInfo.isPresent())
114 copyBuffer.add(cInfo.get());
118 public void paste(double x, double y)
121 for (ComponentInfo info : copyBuffer)
123 GUIComponent comp = addComponent(info.identifier, info.params);
124 ComponentHandle h = handleManager.getHandle(comp);
125 h.reqMove(info.relX, info.relY);
136 public void addComponent(double x, double y)
138 GUIComponent c = addComponent(gui.getAddListSelected(), new JsonObject());
140 selection.add(handleManager.getHandle(c));
144 private GUIComponent addComponent(String identifier, JsonElement params)
146 GUIComponent comp = IndirectGUIComponentCreator.createComponent(toBeEdited.getSubmodelModifiable(), identifier,
148 identifierPerComponent.put(comp, identifier);
152 public static String getIdentifier(GUIComponent c)
154 return identifierPerComponent.get(c);
157 public void duplicate()
160 Point origin = selection.getTopLeft();
161 paste(origin.x + 20, origin.y + 20);
164 private void applySnapping(Point newP)
171 newP.x -= newP.x % snapX;
172 newP.y -= newP.y % snapY;
177 public static class ComponentInfo
179 public final double relX, relY;
180 public final String identifier;
181 public final JsonElement params;
183 public ComponentInfo(double relX, double relY, String identifier, JsonElement params)
187 this.identifier = identifier;
188 this.params = params;
192 public void addWire(PinHandle a, PinHandle b)
194 new GUIWire(toBeEdited.getSubmodelModifiable(), a.getPin(), b.getPin(), new Point[0]);
197 public static enum Snapping
202 public String toString()
204 return super.toString().toLowerCase();
208 public static void main(String[] args)
210 SaveLoadManager.openLoadDialog();
213 public Snapping getSnapping()
218 public void setSnapping(Snapping snapping)
220 this.snapping = snapping;