Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / atomic / ModelSplitter.java
index 1bf22b0..962f2ac 100644 (file)
@@ -6,14 +6,17 @@ import net.haspamelodica.swt.helper.gcs.GeneralGC;
 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
 import net.mograsim.logic.core.types.BitVectorFormatter;
 import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
-import net.mograsim.logic.model.model.ViewModelModifiable;
+import net.mograsim.logic.model.model.LogicModelModifiable;
 import net.mograsim.logic.model.model.components.ModelComponent;
+import net.mograsim.logic.model.model.components.Orientation;
+import net.mograsim.logic.model.model.components.OrientationCalculator;
 import net.mograsim.logic.model.model.wires.Pin;
 import net.mograsim.logic.model.model.wires.PinUsage;
 import net.mograsim.logic.model.modeladapter.LogicCoreAdapter;
 import net.mograsim.logic.model.modeladapter.componentadapters.SplitterAdapter;
 import net.mograsim.logic.model.serializing.IdentifyParams;
 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
+import net.mograsim.logic.model.util.JsonHandler;
 import net.mograsim.preferences.ColorDefinition;
 import net.mograsim.preferences.ColorManager;
 import net.mograsim.preferences.Preferences;
@@ -23,27 +26,34 @@ public class ModelSplitter extends ModelComponent
        private static final double width = 10;
        private static final double heightPerPin = 10;
 
+       private final double heightWithoutOC;
        public final int logicWidth;
+       private final OrientationCalculator oc;
        private final Pin inputPin;
 
        private ReadEnd inputEnd;
        private final ReadEnd[] outputEnds;
 
-       public ModelSplitter(ViewModelModifiable model, int logicWidth)
+       public ModelSplitter(LogicModelModifiable model, SplitterParams params)
        {
-               this(model, logicWidth, null);
+               this(model, params, null);
        }
 
-       public ModelSplitter(ViewModelModifiable model, int logicWidth, String name)
+       public ModelSplitter(LogicModelModifiable model, SplitterParams params, String name)
        {
-               super(model, name);
-               this.logicWidth = logicWidth;
-               setSize(width, (logicWidth - 1) * heightPerPin);
-               addPin(this.inputPin = new Pin(this, "I", logicWidth, PinUsage.TRISTATE, 0, (logicWidth - 1) * heightPerPin / 2));
+               super(model, name, false);
+               this.logicWidth = params.logicWidth;
+               this.oc = new OrientationCalculator(toggleLeftDownAlt(params.orientation), width,
+                               this.heightWithoutOC = (logicWidth - 1) * heightPerPin);
+               setSize(oc.width(), oc.height());
+               double inLineY = (logicWidth - 1) * heightPerPin / 2;
+               addPin(this.inputPin = new Pin(model, this, "I", logicWidth, PinUsage.TRISTATE, oc.newX(0, inLineY), oc.newY(0, inLineY)));
                double outputHeight = (logicWidth - 1) * heightPerPin;
                for (int i = 0; i < logicWidth; i++, outputHeight -= 10)
-                       addPin(new Pin(this, "O" + i, 1, PinUsage.TRISTATE, width, outputHeight));
+                       addPin(new Pin(model, this, "O" + i, 1, PinUsage.TRISTATE, oc.newX(width, outputHeight), oc.newY(width, outputHeight)));
                outputEnds = new ReadEnd[logicWidth];
+
+               init();
        }
 
        @Override
@@ -57,16 +67,18 @@ public class ModelSplitter extends ModelComponent
                        gc.setForeground(ColorManager.current().toColor(c));
                gc.setLineWidth(
                                Preferences.current().getDouble("net.mograsim.logic.model.linewidth.wire." + (logicWidth == 1 ? "singlebit" : "multibit")));
-               double inLineY = posY + (logicWidth - 1) * heightPerPin / 2;
-               gc.drawLine(posX, inLineY, posX + width / 2, inLineY);
+               double inLineY = heightWithoutOC / 2;
+               gc.drawLine(posX + oc.newX(0, inLineY), posY + oc.newY(0, inLineY), posX + oc.newX(width / 2, inLineY),
+                               posY + oc.newY(width / 2, inLineY));
                gc.setLineWidth(Preferences.current().getDouble("net.mograsim.logic.model.linewidth.wire.singlebit"));
-               double outputHeight = posY;
+               double outputHeight = 0;
                for (int i = 0; i < logicWidth; i++, outputHeight += 10)
                {
                        c = BitVectorFormatter.formatAsColor(outputEnds[i]);
                        if (c != null)
                                gc.setForeground(ColorManager.current().toColor(c));
-                       gc.drawLine(posX + width / 2, outputHeight, posX + width, outputHeight);
+                       gc.drawLine(posX + oc.newX(width / 2, outputHeight), posY + oc.newY(width / 2, outputHeight),
+                                       posX + oc.newX(width, outputHeight), posY + oc.newY(width, outputHeight));
                }
                gc.setForeground(Preferences.current().getColor("net.mograsim.logic.model.color.foreground"));
                int oldLineCap = gc.getLineCap();
@@ -74,7 +86,8 @@ public class ModelSplitter extends ModelComponent
                // TODO find better "replacement" for JOIN_BEVEL
                // TODO it looks weird that the vertical line is thinner than the single multibit wire.
                gc.setLineCap(lineJoin == SWT.JOIN_MITER ? SWT.CAP_SQUARE : lineJoin == SWT.JOIN_ROUND ? SWT.CAP_ROUND : SWT.CAP_SQUARE);
-               gc.drawLine(posX + width / 2, posY, posX + width / 2, posY + heightPerPin * (logicWidth - 1));
+               gc.drawLine(posX + oc.newX(width / 2, 0), posY + oc.newY(width / 2, 0), posX + oc.newX(width / 2, heightWithoutOC),
+                               posY + oc.newY(width / 2, heightWithoutOC));
                gc.setLineWidth(Preferences.current().getDouble("net.mograsim.logic.model.linewidth.default"));
                gc.setLineCap(oldLineCap);
        }
@@ -86,9 +99,12 @@ public class ModelSplitter extends ModelComponent
        }
 
        @Override
-       public Integer getParamsForSerializing(IdentifyParams idParams)
+       public SplitterParams getParamsForSerializing(IdentifyParams idParams)
        {
-               return logicWidth;
+               SplitterParams splitterParams = new SplitterParams();
+               splitterParams.logicWidth = logicWidth;
+               splitterParams.orientation = toggleLeftDownAlt(oc.getOrientation());
+               return splitterParams;
        }
 
        public void setCoreModelBinding(ReadEnd inputEnd, ReadEnd[] outputEnds)
@@ -102,10 +118,48 @@ public class ModelSplitter extends ModelComponent
                return inputPin;
        }
 
+       /**
+        * Used to leave bit order intuitive (MSB left or on top)
+        */
+       private static Orientation toggleLeftDownAlt(Orientation orientation)
+       {
+               // TODO if we upgrade to Java 12, replace with switch-expression
+               switch (orientation)
+               {
+               case LEFT:
+                       return Orientation.LEFT_ALT;
+               case LEFT_ALT:
+                       return Orientation.LEFT;
+               case DOWN:
+                       return Orientation.DOWN_ALT;
+               case DOWN_ALT:
+                       return Orientation.DOWN;
+               default:
+                       return orientation;
+               }
+       }
+
+       public static class SplitterParams
+       {
+               public int logicWidth;
+               public Orientation orientation;
+       }
+
        static
        {
                LogicCoreAdapter.addComponentAdapter(new SplitterAdapter());
-               IndirectModelComponentCreator.setComponentSupplier(ModelSplitter.class.getCanonicalName(),
-                               (m, p, n) -> new ModelSplitter(m, p.getAsInt(), n));
+               IndirectModelComponentCreator.setComponentSupplier(ModelSplitter.class.getCanonicalName(), (m, p, n) ->
+               {
+                       // TODO remove legacy params parsing
+                       SplitterParams params;
+                       if (p.isJsonPrimitive())
+                       {
+                               params = new SplitterParams();
+                               params.logicWidth = p.getAsInt();
+                               params.orientation = Orientation.RIGHT;
+                       } else
+                               params = JsonHandler.fromJsonTree(p, SplitterParams.class);
+                       return new ModelSplitter(m, params, n);
+               });
        }
 }
\ No newline at end of file