X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.ui%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2Fmodel%2Fcomponents%2Fsubmodels%2FSimpleRectangularSubmodelComponent.java;fp=net.mograsim.logic.ui%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2Fmodel%2Fcomponents%2Fsubmodels%2FSimpleRectangularSubmodelComponent.java;h=605e020e18ed35d453f682f25c2bc354a0f65f6d;hb=01c5d7035474a5eb58f216b6831b2c0d8c174efa;hp=0000000000000000000000000000000000000000;hpb=4ac977cb31feb34f24e05e9d5e7976951dccf557;p=Mograsim.git diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/submodels/SimpleRectangularSubmodelComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/submodels/SimpleRectangularSubmodelComponent.java new file mode 100644 index 00000000..605e020e --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/submodels/SimpleRectangularSubmodelComponent.java @@ -0,0 +1,168 @@ +package net.mograsim.logic.ui.model.components.submodels; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.eclipse.swt.graphics.Color; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Font; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; +import net.mograsim.logic.ui.model.ViewModelModifiable; +import net.mograsim.logic.ui.model.wires.MovablePin; +import net.mograsim.logic.ui.model.wires.Pin; +import net.mograsim.logic.ui.serializing.SubmodelComponentParams; +import net.mograsim.preferences.Preferences; + +public class SimpleRectangularSubmodelComponent extends SubmodelComponent +{ + public static String kLabel = "label", kInCount = "input_count", kOutCount = "output_count", kLogicWidth = "logic_width"; + + private static final double width = 35; + private static final double pinDistance = 10; + private static final double pinNameMargin = .5; + private static final double labelFontHeight = 5; + private static final double pinNameFontHeight = 3.5; + + private final String label; + protected final int logicWidth; + + private final List inputPinNames; + private final List inputPinNamesUnmodifiable; + private final List outputPinNames; + private final List outputPinNamesUnmodifiable; + + public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label) + { + super(model); + this.label = label; + this.logicWidth = logicWidth; + this.inputPinNames = new ArrayList<>(); + this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames); + this.outputPinNames = new ArrayList<>(); + this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames); + } + + protected void setInputPins(String... pinNames) + { + setIOPins(0, inputPinNames, outputPinNames, pinNames); + } + + protected void setOutputPins(String... pinNames) + { + setIOPins(width, outputPinNames, inputPinNames, pinNames); + } + + private void setIOPins(double relX, List pinNamesListThisSide, List pinNamesListOtherSide, String... newPinNames) + { + int inputCount = newPinNames.length; + List newPinNamesList = Arrays.asList(newPinNames); + if (new HashSet<>(newPinNamesList).size() != inputCount) + throw new IllegalArgumentException("Pin names contain duplicates"); + for (String pinName : newPinNamesList) + if (pinNamesListOtherSide.contains(pinName)) + throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName); + super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance); + for (int i = 0; i < inputCount; i++) + { + String pinName = newPinNames[i]; + int oldPinIndex = pinNamesListThisSide.indexOf(pinName); + if (oldPinIndex == -1) + super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance)); + else + getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance); + } + for (String pinName : pinNamesListThisSide) + if (!newPinNamesList.contains(pinName)) + super.removeSubmodelInterface(pinName); + pinNamesListThisSide.clear(); + pinNamesListThisSide.addAll(newPinNamesList); + } + + public List getInputPinNames() + { + return inputPinNamesUnmodifiable; + } + + public List getOutputPinNames() + { + return outputPinNamesUnmodifiable; + } + + @Override + protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion) + { + Font oldFont = gc.getFont(); + gc.setFont(new Font(oldFont.getName(), labelFontHeight, oldFont.getStyle())); + Point textExtent = gc.textExtent(label); + Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text"); + if (textColor != null) + gc.setForeground(textColor); + gc.drawText(label, getPosX() + (getWidth() - textExtent.x) / 2, getPosY() + (getHeight() - textExtent.y) / 2, true); + gc.setFont(new Font(oldFont.getName(), pinNameFontHeight, oldFont.getStyle())); + for (int i = 0; i < inputPinNames.size(); i++) + { + String pinName = inputPinNames.get(i); + textExtent = gc.textExtent(pinName); + gc.drawText(pinName, getPosX() + pinNameMargin, getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true); + } + for (int i = 0; i < outputPinNames.size(); i++) + { + String pinName = outputPinNames.get(i); + textExtent = gc.textExtent(pinName); + gc.drawText(pinName, getPosX() + width - textExtent.x - pinNameMargin, + getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true); + } + gc.setFont(oldFont); + } + + @Override + protected void renderOutline(GeneralGC gc, Rectangle visibleRegion) + { + Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground"); + if (foreground != null) + gc.setForeground(foreground); + gc.drawRectangle(getBounds()); + } + + @Override + public SubmodelComponentParams calculateParams() + { + SubmodelComponentParams ret = super.calculateParams(); + ret.type = SimpleRectangularSubmodelComponent.class.getSimpleName(); + Map m = new TreeMap<>(); + m.put(kLabel, label); + m.put(kInCount, inputPinNames.toArray()); + m.put(kOutCount, outputPinNames.toArray()); + m.put(kLogicWidth, logicWidth); + ret.specialized = m; + return ret; + } + + @Override + protected Pin addSubmodelInterface(MovablePin supermodelPin) + { + throw new UnsupportedOperationException( + "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead"); + } + + @Override + protected void removeSubmodelInterface(String name) + { + throw new UnsupportedOperationException( + "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead"); + } + + @Override + protected void setSize(double width, double height) + { + throw new UnsupportedOperationException( + "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead"); + } +} \ No newline at end of file