1 package net.mograsim.logic.ui.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;
8 import java.util.Iterator;
12 import java.util.function.Consumer;
13 import java.util.stream.Collectors;
15 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
16 import net.mograsim.logic.ui.editor.Editor;
17 import net.mograsim.logic.ui.editor.states.EditorState;
18 import net.mograsim.logic.ui.model.ViewModelModifiable;
19 import net.mograsim.logic.ui.model.components.GUIComponent;
20 import net.mograsim.logic.ui.model.wires.GUIWire;
21 import net.mograsim.logic.ui.model.wires.MovablePin;
22 import net.mograsim.logic.ui.model.wires.Pin;
24 public class HandleManager
26 private final Map<Pin, StaticPinHandle> handlePerPin;
27 private final Map<Pin, InterfacePinHandle> handlePerInterfacePin;
28 private final Map<GUIWire, List<WirePointHandle>> pointHandlesPerWire;
29 private final Map<GUIWire, WireHandle> handlePerWire;
30 private final Set<Handle> handles;
31 private final Set<WirePointHandle> wirePointHandles;
32 private final Map<GUIComponent, ComponentHandle> handlePerComp;
34 private final Collection<Consumer<Handle>> handleAddedListeners;
35 private final Collection<Consumer<Handle>> handleRemovedListeners;
36 private final Editor editor;
37 private boolean initialized = false;
39 private CornerHandle cornerHandle;
41 public HandleManager(Editor editor)
44 handlePerPin = new HashMap<>();
45 handlePerInterfacePin = new HashMap<>();
46 pointHandlesPerWire = new HashMap<>();
47 handlePerComp = new HashMap<>();
48 handles = new HashSet<>();
49 wirePointHandles = new HashSet<>();
50 handlePerWire = new HashMap<>();
52 handleAddedListeners = new ArrayList<>();
53 handleRemovedListeners = new ArrayList<>();
55 ViewModelModifiable model = editor.getSubmodel();
57 model.addComponentAddedListener(c -> registerComponent(c));
59 model.addComponentRemovedListener(c ->
61 removeComponentHandle(c);
64 model.addWireAddedListener(w ->
69 model.addWireRemovedListener(w ->
72 removeWirePointHandles(w);
76 ////////////////////////////////////////
77 // -- Setting up initial handles -- ///
78 //////////////////////////////////////
83 System.err.println("Warning! HandleManager was already initialized.");
86 ViewModelModifiable model = editor.getSubmodel();
88 Iterator<GUIComponent> cIt = model.getComponents().iterator();
89 // First GUIComponent is the Submodel Interface
90 registerInterfaceComponent(cIt.next());
91 cIt.forEachRemaining(c -> registerComponent(c));
92 model.getWires().forEach(w -> registerWire(w));
93 addHandle(cornerHandle = new CornerHandle(editor.toBeEdited));
97 private void registerInterfaceComponent(GUIComponent c)
99 c.getPins().values().forEach(p -> addInterfacePinHandle(p));
100 c.addPinAddedListener(p -> addInterfacePinHandle(p));
101 c.addPinRemovedListener(p -> removeInterfacePinHandle(p));
104 private void registerComponent(GUIComponent c)
106 addComponentHandle(c);
108 c.getPins().values().forEach(p -> addPinHandle(p));
110 c.addPinAddedListener(p -> addPinHandle(p));
111 c.addPinRemovedListener(p -> removePinHandle(p));
114 private void registerWire(GUIWire wire)
116 wire.addPathChangedListener((w, diff) ->
122 for(int i = 0; i < diff; i++)
123 addWirePointHandle(w);
127 for(int i = 0; i > diff; i--)
129 removeLastWirePointHandle(wire);
133 List<WirePointHandle> wpHandles = pointHandlesPerWire.get(w);
134 int size = wpHandles.size();
135 for(int i = 0; i < size; i++)
137 wpHandles.get(i).setIndex(i);
140 pointHandlesPerWire.get(w).forEach(h -> h.updatePos());
143 if (wire.getPath() == null)
145 for (int i = 0; i < wire.getPath().length; i++)
147 addWirePointHandle(wire);
151 /////////////////////////////////////
152 // -- Adding/Removing handles -- ///
153 ///////////////////////////////////
155 private void addComponentHandle(GUIComponent c)
157 ComponentHandle h = new ComponentHandle(c);
158 handlePerComp.put(c, h);
162 private void removeComponentHandle(GUIComponent c)
164 ComponentHandle h = handlePerComp.get(c);
165 handlePerComp.remove(c);
169 private void addPinHandle(Pin owner)
171 StaticPinHandle h = new StaticPinHandle(owner);
172 handlePerPin.put(owner, h);
176 private void removePinHandle(Pin owner)
178 StaticPinHandle h = handlePerPin.get(owner);
179 handlePerPin.remove(owner);
183 private void addInterfacePinHandle(Pin p)
185 //The following is not an alternative to the cast, because the new pin is not yet in the map, when the listener is called
186 //editor.toBeEdited.getSubmodelMovablePins().get(p.name);
187 MovablePin pM = (MovablePin) p;
188 InterfacePinHandle h = new InterfacePinHandle(pM, editor.toBeEdited);
189 handlePerInterfacePin.put(pM, h);
193 private void removeInterfacePinHandle(Pin p)
195 InterfacePinHandle h = handlePerInterfacePin.get(p);
196 handlePerInterfacePin.remove(p);
200 private void addWirePointHandle(GUIWire w)
202 List<WirePointHandle> wireHandles = pointHandlesPerWire.get(w);
204 if (wireHandles != null)
205 wireHandles.add(h = new WirePointHandle(w, wireHandles.size()));
208 wireHandles = new ArrayList<>();
209 h = new WirePointHandle(w, 0);
211 pointHandlesPerWire.put(h.parent, wireHandles);
213 this.wirePointHandles.add(h);
217 private void removeLastWirePointHandle(GUIWire owner)
219 Handle h = pointHandlesPerWire.get(owner).remove(0);
220 wirePointHandles.remove(h);
224 private void removeWirePointHandles(GUIWire owner)
226 if(!pointHandlesPerWire.containsKey(owner))
228 pointHandlesPerWire.get(owner).forEach(h ->
230 wirePointHandles.remove(h);
233 pointHandlesPerWire.remove(owner);
236 private void addWireHandle(GUIWire w)
238 WireHandle h = new WireHandle(w);
239 handlePerWire.put(w, h);
243 private void removeWireHandle(GUIWire w)
245 WireHandle h = handlePerWire.get(w);
246 handlePerWire.remove(w);
250 private void addHandle(Handle h)
253 callHandleAddedListeners(h);
256 private void removeHandle(Handle h)
259 callHandleRemovedListeners(h);
263 public StaticPinHandle getHandle(Pin parent)
265 return handlePerPin.get(parent);
268 public ComponentHandle getHandle(GUIComponent parent)
270 return handlePerComp.get(parent);
273 public WireHandle getHandle(GUIWire parent)
275 return handlePerWire.get(parent);
278 public Handle getInterfacePinHandle(Pin p)
280 return handlePerInterfacePin.get(p);
284 * @return A Collection of the registered {@link WirePointHandle}s of the specified wire
286 public Collection<WirePointHandle> getWirePointHandles(GUIWire parent)
288 return pointHandlesPerWire.get(parent).stream().collect(Collectors.toSet());
292 * @return An unmodifiable view of all registered {@link Handle}s
294 public Collection<Handle> getHandles()
296 return Collections.unmodifiableCollection(handles);
300 * @return An unmodifiable view of all registered {@link StaticPinHandle}s
302 public Collection<StaticPinHandle> getPinHandles()
304 return Collections.unmodifiableCollection(handlePerPin.values());
308 * @return An unmodifiable view of all registered {@link InterfacePinHandle}s
310 public Collection<InterfacePinHandle> getInterfacePinHandles()
312 return Collections.unmodifiableCollection(handlePerInterfacePin.values());
316 * @return An unmodifiable view of all registered {@link ComponentHandle}s
318 public Collection<ComponentHandle> getComponentHandles()
320 return Collections.unmodifiableCollection(handlePerComp.values());
324 * @return An unmodifiable view of all registered {@link WireHandle}s
326 public Collection<WireHandle> getWireHandles()
328 return Collections.unmodifiableCollection(handlePerWire.values());
332 * @return An unmodifiable view of all registered {@link WirePointHandle}s
334 public Collection<WirePointHandle> getWirePointHandles()
336 return Collections.unmodifiableSet(wirePointHandles);
339 public void click(Point clicked, int stateMask)
341 EditorState entryState = editor.stateManager.getState();
343 if (!cornerHandle.click(clicked.x, clicked.y, stateMask, entryState))
344 if (!click(handlePerPin.values(), clicked, entryState, stateMask))
345 if (!click(handlePerInterfacePin.values(), clicked, entryState, stateMask))
346 if (!click(getWirePointHandles(), clicked, entryState, stateMask))
347 if (!click(handlePerComp.values(), clicked, entryState, stateMask))
348 if (!click(getWireHandles(), clicked, entryState, stateMask))
349 entryState.clickedEmpty(clicked, stateMask);
350 entryState.clicked(clicked, stateMask);
353 private boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
355 for (Handle h : handles)
356 if (h.click(clicked.x, clicked.y, stateMask, state))
361 public void addHandleAddedListener(Consumer<Handle> c)
363 handleAddedListeners.add(c);
366 private void callHandleAddedListeners(Handle added)
368 handleAddedListeners.forEach(l -> l.accept(added));
371 public void removeHandleAddedListener(Consumer<Handle> c)
373 handleAddedListeners.remove(c);
376 public void addHandleRemovedListener(Consumer<Handle> c)
378 handleRemovedListeners.add(c);
381 private void callHandleRemovedListeners(Handle removed)
383 handleRemovedListeners.forEach(l -> l.accept(removed));
386 public void removeHandleRemovedListener(Consumer<Handle> c)
388 handleRemovedListeners.remove(c);