*/
public class LogicUICanvas extends ZoomableCanvas
{
+ private static final boolean DRAW_PINS = false;
+
private final ViewModel model;
public LogicUICanvas(Composite parent, int style, ViewModel model)
private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion)
{
component.render(gc, visibleRegion);
- gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_CYAN));
- for (Pin p : component.getPins())
+ if (DRAW_PINS)
{
- Point pos = p.getPos();
- gc.fillOval(pos.x - 1, pos.y - 1, 2, 2);
+ 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);
+ }
}
}
package era.mi.gui.examples;
-import org.eclipse.swt.SWT;
-
import era.mi.gui.LogicUIStandalone;
import era.mi.gui.model.ViewModel;
import era.mi.gui.model.components.GUIAndGate;
+import era.mi.gui.model.components.GUIManualSwitch;
import era.mi.gui.model.components.GUINotGate;
+import era.mi.gui.model.components.GUIOrGate;
import era.mi.gui.model.wires.GUIWire;
+import era.mi.gui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
public class Playground
public static void main(String[] args)
{
ViewModel model = new ViewModel();
- GUIAndGate andGate = new GUIAndGate(model, 1);
- andGate.moveTo(10, 10);
- GUINotGate notGate = new GUINotGate(model, 1);
- notGate.moveTo(10, 40);
+ createRSLatchExample(model);
+ LogicUIStandalone ui = new LogicUIStandalone(model);
+ ui.run();
+ }
- new GUIWire(model, andGate.getPins().get(0), notGate.getPins().get(1), new Point(20, 50));
+ private static void createRSLatchExample(ViewModel model)
+ {
+ GUIManualSwitch rIn = new GUIManualSwitch(model);
+ rIn.moveTo(100, 100);
+ GUIManualSwitch sIn = new GUIManualSwitch(model);
+ sIn.moveTo(100, 200);
- LogicUIStandalone ui = new LogicUIStandalone(model);
+ GUIOrGate or1 = new GUIOrGate(model, 1);
+ or1.moveTo(160, 102.5);
+ new GUIWire(model, rIn.getOutputPin(), or1.getInputPins().get(0));
- ui.getLogicUICanvas().addListener(SWT.KeyDown, e -> notGate.moveTo(150, 10));
- ui.run();
+ GUIOrGate or2 = new GUIOrGate(model, 1);
+ or2.moveTo(160, 192.5);
+ new GUIWire(model, sIn.getOutputPin(), or2.getInputPins().get(1));
+
+ GUINotGate not1 = new GUINotGate(model, 1);
+ not1.moveTo(200, 107.5);
+ new GUIWire(model, or1.getOutputPin(), not1.getInputPins().get(0));
+
+ GUINotGate not2 = new GUINotGate(model, 1);
+ not2.moveTo(200, 197.5);
+ new GUIWire(model, or2.getOutputPin(), not2.getInputPins().get(0));
+
+ WireCrossPoint p1 = new WireCrossPoint(model, 1);
+ p1.moveTo(250, 112.5);
+ new GUIWire(model, not1.getOutputPin(), p1.getPin());
+ new GUIWire(model, p1.getPin(), or2.getInputPins().get(0), new Point(250, 130), new Point(140, 185), new Point(140, 197.5));
+
+ WireCrossPoint p2 = new WireCrossPoint(model, 1);
+ p2.moveTo(250, 202.5);
+ new GUIWire(model, not2.getOutputPin(), p2.getPin());
+ new GUIWire(model, p2.getPin(), or1.getInputPins().get(1), new Point(250, 185), new Point(140, 130), new Point(140, 117.5));
+
+ WireCrossPoint o1 = new WireCrossPoint(model, 1);
+ o1.moveTo(270, 112.5);
+ new GUIWire(model, p1.getPin(), o1.getPin());
+
+ WireCrossPoint o2 = new WireCrossPoint(model, 1);
+ o2.moveTo(270, 202.5);
+ new GUIWire(model, p2.getPin(), o2.getPin());
}
- public static void addComponentsAndWires(LogicUIStandalone ui, ViewModel model)
+ @SuppressWarnings("unused")
+ private static void createBasicExample(ViewModel model)
{
GUIAndGate andGate = new GUIAndGate(model, 1);
andGate.moveTo(10, 10);
GUINotGate notGate = new GUINotGate(model, 1);
notGate.moveTo(10, 40);
- new GUIWire(model, andGate.getPins().get(0), notGate.getPins().get(1), new Point(20, 50));
+ WireCrossPoint wcp1 = new WireCrossPoint(model, 1);
+ wcp1.moveTo(150, 10);
+
+ new GUIWire(model, andGate.getOutputPin(), notGate.getInputPins().get(0), new Point(60, 50));
+ new GUIWire(model, notGate.getOutputPin(), wcp1.getPin());
+
+ GUIManualSwitch sw1 = new GUIManualSwitch(model);
+ sw1.moveTo(-20, 0);
+ GUIManualSwitch sw2 = new GUIManualSwitch(model);
+ sw2.moveTo(-20, 50);
- ui.getLogicUICanvas().addListener(SWT.KeyDown, e -> notGate.moveTo(150, 10));
+ new GUIWire(model, sw1.getOutputPin(), andGate.getInputPins().get(0));
+ new GUIWire(model, sw2.getOutputPin(), andGate.getInputPins().get(1));
}
}
\ No newline at end of file
private static final double height = 15;
private static final double fontHeight = 5;
+ private final Pin outputPin;
+
private ManualSwitch logicSwitch;
private ReadEnd end;
{
super(model);
setSize(width, height);
- addPin(new Pin(this, 1, width, height / 2));
+ addPin(this.outputPin = new Pin(this, 1, width, height / 2));
}
@Override
public void render(GeneralGC gc, Rectangle visibleRegion)
{
- gc.drawRectangle(0, 0, width, height);
+ double posX = getBounds().x;
+ double posY = getBounds().y;
+
+ gc.drawRectangle(posX, posY, width, height);
String label = BitVectorFormatter.formatValueAsString(end);
Font oldFont = gc.getFont();
Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
gc.setFont(labelFont);
Point textExtent = gc.textExtent(label);
- gc.drawText(label, (width - textExtent.x) / 2, (height - textExtent.y) / 2, true);
+ gc.drawText(label, posX + (width - textExtent.x) / 2, posY + (height - textExtent.y) / 2, true);
gc.setFont(oldFont);
}
logicSwitch.toggle();
return true;
}
+
+ public Pin getOutputPin()
+ {
+ return outputPin;
+ }
}
\ No newline at end of file
public class WireCrossPoint extends GUIComponent
{
+ private final Pin pin;
+
private ReadEnd end;
private final int logicWidth;
super(model);
this.logicWidth = logicWidth;
setSize(0, 0);
- addPin(new Pin(this, logicWidth, 0, 0));
+ addPin(this.pin = new Pin(this, logicWidth, 0, 0));
}
@Override
public void render(GeneralGC gc, Rectangle visibleRegion)
{
- ColorHelper.executeWithDifferentBackground(gc, BitVectorFormatter.formatAsColor(end), () -> gc.fillOval(-1, -1, 2, 2));
+ Rectangle bounds = getBounds();
+ ColorHelper.executeWithDifferentBackground(gc, BitVectorFormatter.formatAsColor(end),
+ () -> gc.fillOval(bounds.x - 1, bounds.y - 1, 2, 2));
}
public void setLogicModelBinding(ReadEnd end)
{
return logicWidth;
}
+
+ public Pin getPin()
+ {
+ return pin;
+ }
}
\ No newline at end of file
import era.mi.gui.model.wires.Pin;
import era.mi.gui.model.wires.WireCrossPoint;
import era.mi.gui.modeladapter.componentadapters.ComponentAdapter;
+import era.mi.gui.modeladapter.componentadapters.ManualSwitchAdapter;
import era.mi.gui.modeladapter.componentadapters.SimpleGateAdapter;
import era.mi.logic.components.Component;
import era.mi.logic.components.gates.AndGate;
private final static Map<Class<? extends GUIComponent>, ComponentAdapter<? extends GUIComponent>> componentAdapters;
static
{
- Map<Class<? extends GUIComponent>, ComponentAdapter<? extends GUIComponent>> componentAdaptersModifiable = new HashMap<>();
- componentAdaptersModifiable.put(GUIOrGate.class, new SimpleGateAdapter(OrGate::new));
- componentAdaptersModifiable.put(GUIAndGate.class, new SimpleGateAdapter(AndGate::new));
- componentAdaptersModifiable.put(GUINotGate.class, new SimpleGateAdapter((t, p, o, i) -> new NotGate(t, p, i[0], o)));
+ Set<ComponentAdapter<? extends GUIComponent>> componentAdaptersModifiable = new HashSet<>();
+ componentAdaptersModifiable.add(new SimpleGateAdapter<>(GUIOrGate.class, OrGate::new));
+ componentAdaptersModifiable.add(new SimpleGateAdapter<>(GUIAndGate.class, AndGate::new));
+ componentAdaptersModifiable.add(new SimpleGateAdapter<>(GUINotGate.class, (t, p, o, i) -> new NotGate(t, p, i[0], o)));
+ componentAdaptersModifiable.add(new ManualSwitchAdapter());
// TODO list all "primitive" adapters here
- componentAdapters = Collections.unmodifiableMap(componentAdaptersModifiable);
+ componentAdapters = Collections.unmodifiableMap(
+ componentAdaptersModifiable.stream().collect(Collectors.toMap(ComponentAdapter::getSupportedClass, Function.identity())));
}
public static Timeline convert(ViewModel viewModel, LogicModelParameters params)
Map<GUIComponent, Component> oneToOneComponents = new HashMap<>();
for (GUIComponent guiComp : viewModel.getComponents())
{
- // WireCrossPoints just vanish
if (!(guiComp instanceof WireCrossPoint))
oneToOneComponents.put(guiComp, createAndLinkComponent(timeline, params, guiComp, logicWiresPerPinUnmodifiable,
componentAdapters.get(guiComp.getClass())));
+ else
+ {
+ WireCrossPoint guiCompCasted = (WireCrossPoint) guiComp;
+ guiCompCasted.setLogicModelBinding(logicWiresPerPin.get(guiCompCasted.getPin()).createReadOnlyEnd());
+ }
}
// TODO handle complex components
public interface ComponentAdapter<G extends GUIComponent>
{
+ public Class<G> getSupportedClass();
+
public Component createAndLinkComponent(Timeline timeline, LogicModelParameters params, G guiComponent,
Map<Pin, Wire> logicWiresPerPin);
}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.modeladapter.componentadapters;
+
+import java.util.Map;
+
+import era.mi.gui.model.components.GUIManualSwitch;
+import era.mi.gui.model.wires.Pin;
+import era.mi.gui.modeladapter.LogicModelParameters;
+import era.mi.logic.components.Component;
+import era.mi.logic.components.ManualSwitch;
+import era.mi.logic.timeline.Timeline;
+import era.mi.logic.wires.Wire;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
+
+public class ManualSwitchAdapter implements ComponentAdapter<GUIManualSwitch>
+{
+ @Override
+ public Class<GUIManualSwitch> getSupportedClass()
+ {
+ return GUIManualSwitch.class;
+ }
+
+ @Override
+ public Component createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIManualSwitch guiComponent,
+ Map<Pin, Wire> logicWiresPerPin)
+ {
+ ReadWriteEnd end = logicWiresPerPin.get(guiComponent.getOutputPin()).createReadWriteEnd();
+ ManualSwitch manualSwitch = new ManualSwitch(timeline, end);
+ guiComponent.setLogicModelBinding(manualSwitch, end);
+ return manualSwitch;
+ }
+}
\ No newline at end of file
import era.mi.logic.wires.Wire.ReadEnd;
import era.mi.logic.wires.Wire.ReadWriteEnd;
-public class SimpleGateAdapter implements ComponentAdapter<SimpleRectangularGUIGate>
+public class SimpleGateAdapter<G extends SimpleRectangularGUIGate> implements ComponentAdapter<G>
{
+ private final Class<G> supportedClass;
private final ComponentConstructor constructor;
- public SimpleGateAdapter(ComponentConstructor constructor)
+ public SimpleGateAdapter(Class<G> supportedClass, ComponentConstructor constructor)
{
+ this.supportedClass = supportedClass;
this.constructor = constructor;
}
@Override
- public Component createAndLinkComponent(Timeline timeline, LogicModelParameters params, SimpleRectangularGUIGate guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ public Class<G> getSupportedClass()
+ {
+ return supportedClass;
+ }
+
+ @Override
+ public Component createAndLinkComponent(Timeline timeline, LogicModelParameters params, G guiComponent, Map<Pin, Wire> logicWiresPerPin)
{
ReadWriteEnd out = logicWiresPerPin.get(guiComponent.getOutputPin()).createReadWriteEnd();
List<Pin> inputPins = guiComponent.getInputPins();
{
public Component newComponent(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd[] ins);
}
+
}
\ No newline at end of file