From f2886cbd57dd08b797921fc2421b41bd92915799 Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Tue, 28 May 2019 11:44:30 +0200 Subject: [PATCH] LogicUICanvas now uses the new listener system; changes in clicked() --- LogicUI/src/era/mi/gui/LogicUICanvas.java | 51 +++++-------------- LogicUI/src/era/mi/gui/LogicUIStandalone.java | 2 +- .../src/era/mi/gui/examples/Playground.java | 7 +-- LogicUI/src/era/mi/gui/model/ViewModel.java | 43 +++++++++++++++- .../mi/gui/model/components/GUIComponent.java | 6 ++- .../src/era/mi/gui/model/wires/GUIWire.java | 5 +- 6 files changed, 66 insertions(+), 48 deletions(-) diff --git a/LogicUI/src/era/mi/gui/LogicUICanvas.java b/LogicUI/src/era/mi/gui/LogicUICanvas.java index 4e619884..da338013 100644 --- a/LogicUI/src/era/mi/gui/LogicUICanvas.java +++ b/LogicUI/src/era/mi/gui/LogicUICanvas.java @@ -1,14 +1,11 @@ package era.mi.gui; -import java.util.HashSet; -import java.util.Set; - import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; +import era.mi.gui.model.ViewModel; import era.mi.gui.model.components.GUIComponent; -import era.mi.gui.model.wires.GUIWire; import era.mi.gui.model.wires.Pin; import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; @@ -22,49 +19,26 @@ import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas; */ public class LogicUICanvas extends ZoomableCanvas { - private final Set components; - private final Set wires; + private final ViewModel model; - public LogicUICanvas(Composite parent, int style) + public LogicUICanvas(Composite parent, int style, ViewModel model) { super(parent, style); - components = new HashSet<>(); - wires = new HashSet<>(); + this.model = model; + + model.addComponentAddedListener(c -> redrawThreadsafe()); + model.addWireAddedListener(c -> redrawThreadsafe()); addZoomedRenderer(gc -> { Rectangle visibleRegion = new Rectangle(offX, offY, gW / zoom, gH / zoom); - components.forEach(c -> drawComponent(gc, c, visibleRegion)); + model.getComponents().forEach(c -> drawComponent(gc, c, visibleRegion)); }); - addZoomedRenderer(gc -> wires.forEach(w -> w.render(gc))); + addZoomedRenderer(gc -> model.getWires().forEach(w -> w.render(gc))); addListener(SWT.MouseDown, this::mouseDown); } - /** - * Add a component to be drawn. Returns the given component for convenience. - * - * @author Daniel Kirschten - */ - // TODO replace with model change listener - public C addComponent(C component) - { - components.add(component); - return component; - } - - /** - * Add a graphical wire between the given connection points of the given components. The given components have to be added and the given - * connection points have to be connected logically first. - * - * @author Daniel Kirschten - */ - // TODO replace with model change listener - public void addWire(Pin pin1, Pin pin2, Point... path) - { - wires.add(new GUIWire(this::redrawThreadsafe, pin1, pin2, path)); - } - private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion) { component.render(gc, visibleRegion); @@ -81,11 +55,10 @@ public class LogicUICanvas extends ZoomableCanvas if (e.button == 1) { Point click = displayToWorldCoords(e.x, e.y); - for (GUIComponent component : components) - if (component.getBounds().contains(click)) + for (GUIComponent component : model.getComponents()) + if (component.getBounds().contains(click) && component.clicked(click.x, click.y)) { - if (component.clicked(click.x, click.y)) - redraw(); + redraw(); break; } } diff --git a/LogicUI/src/era/mi/gui/LogicUIStandalone.java b/LogicUI/src/era/mi/gui/LogicUIStandalone.java index 0bc5d8a7..3079b506 100644 --- a/LogicUI/src/era/mi/gui/LogicUIStandalone.java +++ b/LogicUI/src/era/mi/gui/LogicUIStandalone.java @@ -30,7 +30,7 @@ public class LogicUIStandalone display = new Display(); shell = new Shell(display); shell.setLayout(new FillLayout()); - ui = new LogicUICanvas(shell, SWT.NONE); + ui = new LogicUICanvas(shell, SWT.NONE, model); ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(ui); userInput.buttonDrag = 3; diff --git a/LogicUI/src/era/mi/gui/examples/Playground.java b/LogicUI/src/era/mi/gui/examples/Playground.java index eafa1a58..74da19cc 100644 --- a/LogicUI/src/era/mi/gui/examples/Playground.java +++ b/LogicUI/src/era/mi/gui/examples/Playground.java @@ -5,6 +5,7 @@ import era.mi.gui.LogicUIStandalone; import era.mi.gui.model.ViewModel; import era.mi.gui.model.components.GUIAndGate; import era.mi.gui.model.components.GUINotGate; +import era.mi.gui.model.wires.GUIWire; public class Playground { @@ -22,11 +23,11 @@ public class Playground public static void addComponentsAndWires(LogicUICanvas ui, ViewModel model) { - GUIAndGate andGate = ui.addComponent(new GUIAndGate(model)); + GUIAndGate andGate = new GUIAndGate(model); andGate.moveTo(10, 10); - GUINotGate notGate = ui.addComponent(new GUINotGate(model)); + GUINotGate notGate = new GUINotGate(model); notGate.moveTo(10, 40); - ui.addWire(andGate.getPins().get(0), notGate.getPins().get(1)); + new GUIWire(model, andGate.getPins().get(0), notGate.getPins().get(1)); } } \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/ViewModel.java b/LogicUI/src/era/mi/gui/model/ViewModel.java index 5a41d0ea..4eb81e87 100644 --- a/LogicUI/src/era/mi/gui/model/ViewModel.java +++ b/LogicUI/src/era/mi/gui/model/ViewModel.java @@ -1,6 +1,7 @@ package era.mi.gui.model; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -10,7 +11,9 @@ import era.mi.gui.model.wires.GUIWire; public class ViewModel { private final List components; + private final List componentsUnmodifiable; private final List wires; + private final List wiresUnmodifiable; private final List> componentAddedListeners; private final List> componentRemovedListeners; @@ -20,7 +23,9 @@ public class ViewModel public ViewModel() { components = new ArrayList<>(); + componentsUnmodifiable = Collections.unmodifiableList(components); wires = new ArrayList<>(); + wiresUnmodifiable = Collections.unmodifiableList(wires); componentAddedListeners = new ArrayList<>(); componentRemovedListeners = new ArrayList<>(); @@ -32,7 +37,7 @@ public class ViewModel * Adds the given component to the list of components and calls all componentAddedListeners. Don't call this method from application * code as it is automatically called in GUIComponent::new. */ - public void addComponent(GUIComponent component) + public void componentCreated(GUIComponent component) { if (components.contains(component)) throw new IllegalStateException("Don't add the same component twice!"); @@ -44,7 +49,7 @@ public class ViewModel * Removes the given component from the list of components and calls all componentRemovedListeners. Don't call this method from * application code as it is automatically called in GUIComponent::destroy. */ - public void removeComponent(GUIComponent component) + public void componentDestroyed(GUIComponent component) { if (!components.contains(component)) throw new IllegalStateException("Don't remove the same component twice!"); @@ -52,6 +57,40 @@ public class ViewModel callComponentRemovedListeners(component); } + /** + * Adds the given component to the list of components and calls all componentAddedListeners. Don't call this method from application + * code as it is automatically called in GUIComponent::new. + */ + public void wireCreated(GUIWire wire) + { + if (wires.contains(wire)) + throw new IllegalStateException("Don't add the same wire twice!"); + wires.add(wire); + callWireAddedListeners(wire); + } + + /** + * Removes the given component from the list of components and calls all componentRemovedListeners. Don't call this method from + * application code as it is automatically called in GUIComponent::destroy. + */ + public void wireDestroyed(GUIWire wire) + { + if (!wires.contains(wire)) + throw new IllegalStateException("Don't remove the same wire twice!"); + wires.remove(wire); + callWireRemovedListeners(wire); + } + + public List getComponents() + { + return componentsUnmodifiable; + } + + public List getWires() + { + return wiresUnmodifiable; + } + // @formatter:off public void addComponentAddedListener (Consumer listener){componentAddedListeners .add (listener);} public void addComponentRemovedListener (Consumer listener){componentRemovedListeners.add (listener);} diff --git a/LogicUI/src/era/mi/gui/model/components/GUIComponent.java b/LogicUI/src/era/mi/gui/model/components/GUIComponent.java index 7f4107d7..cf9b23a2 100644 --- a/LogicUI/src/era/mi/gui/model/components/GUIComponent.java +++ b/LogicUI/src/era/mi/gui/model/components/GUIComponent.java @@ -33,6 +33,8 @@ public abstract class GUIComponent this.componentMovedListeners = new ArrayList<>(); this.pinAddedListeners = new ArrayList<>(); this.pinRemovedListeners = new ArrayList<>(); + + model.componentCreated(this); } public void moveTo(double x, double y) @@ -50,9 +52,9 @@ public abstract class GUIComponent return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); } - // TODO /** - * Called when this component is clicked. Relative coordinates of the click are given. Returns true if this component has to be redrawn. + * Called when this component is clicked. Absolute coordinates of the click are given. Returns true if this component consumed this + * click. */ public boolean clicked(double x, double y) { diff --git a/LogicUI/src/era/mi/gui/model/wires/GUIWire.java b/LogicUI/src/era/mi/gui/model/wires/GUIWire.java index d0bd9908..649ddb68 100644 --- a/LogicUI/src/era/mi/gui/model/wires/GUIWire.java +++ b/LogicUI/src/era/mi/gui/model/wires/GUIWire.java @@ -3,6 +3,7 @@ package era.mi.gui.model.wires; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; +import era.mi.gui.model.ViewModel; import era.mi.logic.types.Bit; import era.mi.logic.wires.Wire; import net.haspamelodica.swt.helper.gcs.GeneralGC; @@ -16,7 +17,7 @@ public class GUIWire private Wire wire; - public GUIWire(Runnable redraw, Pin pin1, Pin pin2, Point... path) + public GUIWire(ViewModel model, Pin pin1, Pin pin2, Point... path) { this.path = new double[path.length * 2 + 4]; for (int srcI = 0, dstI = 2; srcI < path.length; srcI++, dstI += 2) @@ -32,6 +33,8 @@ public class GUIWire pos = pin2.getPos(); this.path[this.path.length - 2] = pos.x; this.path[this.path.length - 1] = pos.y; + + model.wireCreated(this); } public void render(GeneralGC gc) -- 2.17.1