1 package net.mograsim.logic.model.editor.handles;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.HashSet;
11 import java.util.function.Consumer;
12 import java.util.stream.Collectors;
14 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
15 import net.mograsim.logic.model.editor.Editor;
16 import net.mograsim.logic.model.editor.states.EditorState;
17 import net.mograsim.logic.model.model.ViewModelModifiable;
18 import net.mograsim.logic.model.model.components.GUIComponent;
19 import net.mograsim.logic.model.model.wires.GUIWire;
20 import net.mograsim.logic.model.model.wires.MovablePin;
21 import net.mograsim.logic.model.model.wires.Pin;
23 public class HandleManager
25 private final Map<Pin, StaticPinHandle> handlePerPin;
26 private final Map<Pin, InterfacePinHandle> handlePerInterfacePin;
27 private final Map<GUIWire, List<WirePointHandle>> pointHandlesPerWire;
28 private final Map<GUIWire, WireHandle> handlePerWire;
29 private final Set<Handle> handles;
30 private final Set<WirePointHandle> wirePointHandles;
31 private final Map<GUIComponent, ComponentHandle> handlePerComp;
33 private final Collection<Consumer<Handle>> handleAddedListeners;
34 private final Collection<Consumer<Handle>> handleRemovedListeners;
35 private final Editor editor;
36 private boolean initialized = false;
38 private CornerHandle cornerHandle;
40 public HandleManager(Editor editor)
43 handlePerPin = new HashMap<>();
44 handlePerInterfacePin = new HashMap<>();
45 pointHandlesPerWire = new HashMap<>();
46 handlePerComp = new HashMap<>();
47 handles = new HashSet<>();
48 wirePointHandles = new HashSet<>();
49 handlePerWire = new HashMap<>();
51 handleAddedListeners = new ArrayList<>();
52 handleRemovedListeners = new ArrayList<>();
54 ViewModelModifiable model = editor.getSubmodel();
56 model.addComponentAddedListener(c -> registerComponent(c));
58 model.addComponentRemovedListener(c ->
60 removeComponentHandle(c);
63 model.addWireAddedListener(w ->
68 model.addWireRemovedListener(w ->
71 removeWirePointHandles(w);
75 ////////////////////////////////////////
76 // -- Setting up initial handles -- ///
77 //////////////////////////////////////
82 System.err.println("Warning! HandleManager was already initialized.");
85 ViewModelModifiable model = editor.getSubmodel();
86 Map<String, GUIComponent> compsByName = model.getComponentsByName();
87 Set<GUIComponent> comps = new HashSet<>(compsByName.values());
88 GUIComponent interfaceComp = compsByName.get("_submodelinterface");
89 comps.remove(interfaceComp);
90 registerInterfaceComponent(interfaceComp);
91 comps.forEach(c -> registerComponent(c));
93 model.getWires().forEach(w -> registerWire(w));
94 addHandle(cornerHandle = new CornerHandle(editor.toBeEdited));
98 private void registerInterfaceComponent(GUIComponent c)
100 c.getPins().values().forEach(p -> addInterfacePinHandle(p));
101 c.addPinAddedListener(p -> addInterfacePinHandle(p));
102 c.addPinRemovedListener(p -> removeInterfacePinHandle(p));
105 private void registerComponent(GUIComponent c)
107 addComponentHandle(c);
109 c.getPins().values().forEach(p -> addPinHandle(p));
111 c.addPinAddedListener(p -> addPinHandle(p));
112 c.addPinRemovedListener(p -> removePinHandle(p));
115 private void registerWire(GUIWire wire)
117 wire.addPathChangedListener((w, diff) ->
123 for(int i = 0; i < diff; i++)
124 addWirePointHandle(w);
128 for(int i = 0; i > diff; i--)
130 removeLastWirePointHandle(wire);
134 List<WirePointHandle> wpHandles = pointHandlesPerWire.get(w);
135 int size = wpHandles.size();
136 for(int i = 0; i < size; i++)
138 wpHandles.get(i).setIndex(i);
141 pointHandlesPerWire.get(w).forEach(h -> h.updatePos());
144 if (wire.getPath() == null)
146 for (int i = 0; i < wire.getPath().length; i++)
148 addWirePointHandle(wire);
152 /////////////////////////////////////
153 // -- Adding/Removing handles -- ///
154 ///////////////////////////////////
156 private void addComponentHandle(GUIComponent c)
158 ComponentHandle h = new ComponentHandle(c);
159 handlePerComp.put(c, h);
163 private void removeComponentHandle(GUIComponent c)
165 ComponentHandle h = handlePerComp.get(c);
166 handlePerComp.remove(c);
170 private void addPinHandle(Pin owner)
172 StaticPinHandle h = new StaticPinHandle(owner);
173 handlePerPin.put(owner, h);
177 private void removePinHandle(Pin owner)
179 StaticPinHandle h = handlePerPin.get(owner);
180 handlePerPin.remove(owner);
184 private void addInterfacePinHandle(Pin p)
186 //The following is not an alternative to the cast, because the new pin is not yet in the map, when the listener is called
187 //editor.toBeEdited.getSubmodelMovablePins().get(p.name);
188 MovablePin pM = (MovablePin) p;
189 InterfacePinHandle h = new InterfacePinHandle(pM, editor.toBeEdited);
190 handlePerInterfacePin.put(pM, h);
194 private void removeInterfacePinHandle(Pin p)
196 InterfacePinHandle h = handlePerInterfacePin.get(p);
197 handlePerInterfacePin.remove(p);
201 private void addWirePointHandle(GUIWire w)
203 List<WirePointHandle> wireHandles = pointHandlesPerWire.get(w);
205 if (wireHandles != null)
206 wireHandles.add(h = new WirePointHandle(w, wireHandles.size()));
209 wireHandles = new ArrayList<>();
210 h = new WirePointHandle(w, 0);
212 pointHandlesPerWire.put(h.parent, wireHandles);
214 this.wirePointHandles.add(h);
218 private void removeLastWirePointHandle(GUIWire owner)
220 Handle h = pointHandlesPerWire.get(owner).remove(0);
221 wirePointHandles.remove(h);
225 private void removeWirePointHandles(GUIWire owner)
227 if(!pointHandlesPerWire.containsKey(owner))
229 pointHandlesPerWire.get(owner).forEach(h ->
231 wirePointHandles.remove(h);
234 pointHandlesPerWire.remove(owner);
237 private void addWireHandle(GUIWire w)
239 WireHandle h = new WireHandle(w);
240 handlePerWire.put(w, h);
244 private void removeWireHandle(GUIWire w)
246 WireHandle h = handlePerWire.get(w);
247 handlePerWire.remove(w);
251 private void addHandle(Handle h)
254 callHandleAddedListeners(h);
257 private void removeHandle(Handle h)
260 callHandleRemovedListeners(h);
264 public StaticPinHandle getHandle(Pin parent)
266 return handlePerPin.get(parent);
269 public ComponentHandle getHandle(GUIComponent parent)
271 return handlePerComp.get(parent);
274 public WireHandle getHandle(GUIWire parent)
276 return handlePerWire.get(parent);
279 public Handle getInterfacePinHandle(Pin p)
281 return handlePerInterfacePin.get(p);
285 * @return A Collection of the registered {@link WirePointHandle}s of the specified wire
287 public Collection<WirePointHandle> getWirePointHandles(GUIWire parent)
289 return pointHandlesPerWire.get(parent).stream().collect(Collectors.toSet());
293 * @return An unmodifiable view of all registered {@link Handle}s
295 public Collection<Handle> getHandles()
297 return Collections.unmodifiableCollection(handles);
301 * @return An unmodifiable view of all registered {@link StaticPinHandle}s
303 public Collection<StaticPinHandle> getPinHandles()
305 return Collections.unmodifiableCollection(handlePerPin.values());
309 * @return An unmodifiable view of all registered {@link InterfacePinHandle}s
311 public Collection<InterfacePinHandle> getInterfacePinHandles()
313 return Collections.unmodifiableCollection(handlePerInterfacePin.values());
317 * @return An unmodifiable view of all registered {@link ComponentHandle}s
319 public Collection<ComponentHandle> getComponentHandles()
321 return Collections.unmodifiableCollection(handlePerComp.values());
325 * @return An unmodifiable view of all registered {@link WireHandle}s
327 public Collection<WireHandle> getWireHandles()
329 return Collections.unmodifiableCollection(handlePerWire.values());
333 * @return An unmodifiable view of all registered {@link WirePointHandle}s
335 public Collection<WirePointHandle> getWirePointHandles()
337 return Collections.unmodifiableSet(wirePointHandles);
340 public void click(Point clicked, int stateMask)
342 EditorState entryState = editor.stateManager.getState();
344 if (!cornerHandle.click(clicked.x, clicked.y, stateMask, entryState))
345 if (!click(handlePerPin.values(), clicked, entryState, stateMask))
346 if (!click(handlePerInterfacePin.values(), clicked, entryState, stateMask))
347 if (!click(getWirePointHandles(), clicked, entryState, stateMask))
348 if (!click(handlePerComp.values(), clicked, entryState, stateMask))
349 if (!click(getWireHandles(), clicked, entryState, stateMask))
350 entryState.clickedEmpty(clicked, stateMask);
351 entryState.clicked(clicked, stateMask);
354 private boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
356 for (Handle h : handles)
357 if (h.click(clicked.x, clicked.y, stateMask, state))
362 public void addHandleAddedListener(Consumer<Handle> c)
364 handleAddedListeners.add(c);
367 private void callHandleAddedListeners(Handle added)
369 handleAddedListeners.forEach(l -> l.accept(added));
372 public void removeHandleAddedListener(Consumer<Handle> c)
374 handleAddedListeners.remove(c);
377 public void addHandleRemovedListener(Consumer<Handle> c)
379 handleRemovedListeners.add(c);
382 private void callHandleRemovedListeners(Handle removed)
384 handleRemovedListeners.forEach(l -> l.accept(removed));
387 public void removeHandleRemovedListener(Consumer<Handle> c)
389 handleRemovedListeners.remove(c);