X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=LogicUI%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2FLogicUICanvas.java;fp=LogicUI%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2FLogicUICanvas.java;h=3a080973212ad59c3f4dcb56f73c8a1b9cd31828;hb=0009789a8df6b8d4562b6e1cbfa75102a7516ea8;hp=0000000000000000000000000000000000000000;hpb=a28f7aa0dab4248e99159c5a647676170cb17a4e;p=Mograsim.git diff --git a/LogicUI/src/net/mograsim/logic/ui/LogicUICanvas.java b/LogicUI/src/net/mograsim/logic/ui/LogicUICanvas.java new file mode 100644 index 00000000..3a080973 --- /dev/null +++ b/LogicUI/src/net/mograsim/logic/ui/LogicUICanvas.java @@ -0,0 +1,114 @@ +package net.mograsim.logic.ui; + +import java.util.function.Consumer; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; +import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas; +import net.mograsim.logic.ui.model.ViewModel; +import net.mograsim.logic.ui.model.components.GUIComponent; +import net.mograsim.logic.ui.model.wires.GUIWire; +import net.mograsim.logic.ui.model.wires.Pin; + +/** + * Simulation visualizer canvas. + * + * @author Daniel Kirschten + */ +public class LogicUICanvas extends ZoomableCanvas +{ + private static final boolean DRAW_PINS = false; + + private final ViewModel model; + + public LogicUICanvas(Composite parent, int style, ViewModel model) + { + super(parent, style); + + this.model = model; + + Consumer redrawConsumer = o -> redrawThreadsafe(); + Consumer pinAddedListener = p -> + { + p.addPinMovedListener(redrawConsumer); + redrawThreadsafe(); + }; + Consumer pinRemovedListener = p -> + { + p.removePinMovedListener(redrawConsumer); + redrawThreadsafe(); + }; + Consumer componentAddedListener = c -> + { + c.addComponentLookChangedListener(redrawConsumer); + c.addComponentMovedListener(redrawConsumer); + c.addPinAddedListener(pinAddedListener); + c.addPinRemovedListener(pinRemovedListener); + redrawThreadsafe(); + }; + model.addComponentAddedListener(componentAddedListener); + model.getComponents().forEach(componentAddedListener); + model.addComponentRemovedListener(c -> + { + c.removeComponentLookChangedListener(redrawConsumer); + c.removeComponentMovedListener(redrawConsumer); + c.removePinAddedListener(pinAddedListener); + c.removePinRemovedListener(pinRemovedListener); + redrawThreadsafe(); + }); + Consumer wireAddedListener = w -> + { + w.addWireLookChangedListener(redrawConsumer); + redrawThreadsafe(); + }; + model.addWireAddedListener(wireAddedListener); + model.getWires().forEach(wireAddedListener); + model.addWireRemovedListener(w -> + { + w.removeWireLookChangedListener(redrawConsumer); + redrawThreadsafe(); + }); + + addZoomedRenderer(gc -> + { + gc.setLineWidth(.5); + model.getWires().forEach(w -> w.render(gc)); + Rectangle visibleRegion = new Rectangle(offX, offY, gW / zoom, gH / zoom); + model.getComponents().forEach(c -> drawComponent(gc, c, visibleRegion)); + }); + addListener(SWT.MouseDown, this::mouseDown); + } + + private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion) + { + component.render(gc, visibleRegion); + if (DRAW_PINS) + { + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_DARK_CYAN)); + for (Pin p : component.getPins()) + { + Point pos = p.getPos(); + gc.fillOval(pos.x - 1, pos.y - 1, 2, 2); + } + } + } + + private void mouseDown(Event e) + { + if (e.button == 1) + { + Point click = displayToWorldCoords(e.x, e.y); + for (GUIComponent component : model.getComponents()) + if (component.getBounds().contains(click) && component.clicked(click.x, click.y)) + { + redraw(); + break; + } + } + } +} \ No newline at end of file