diff --git a/src/main/java/de/neemann/digital/core/IntFormat.java b/src/main/java/de/neemann/digital/core/IntFormat.java index fc87c0a69..4cf195f98 100644 --- a/src/main/java/de/neemann/digital/core/IntFormat.java +++ b/src/main/java/de/neemann/digital/core/IntFormat.java @@ -138,6 +138,11 @@ public enum IntFormat { public long dragValue(long initial, int bits, double inc) { return dragValueSigned(initial, bits, inc, false); } + + @Override + public IsSeparator getSeparators(int bits) { + return bit -> bit % 4 == 0; + } } private static long dragValueSigned(long initial, int bits, double inc, boolean signed) { @@ -224,6 +229,11 @@ public enum IntFormat { public int strLen(int bits) { return (bits - 1) / 4 + 3; } + + @Override + public IsSeparator getSeparators(int bits) { + return bit -> bit % 4 == 0; + } } /** @@ -289,6 +299,11 @@ public enum IntFormat { } return sb.toString(); } + + @Override + public IsSeparator getSeparators(int bits) { + return bit -> bit % 3 == 0; + } } /** @@ -448,6 +463,11 @@ public enum IntFormat { public long dragValue(long initial, int bits, double inc) { return dragValueSigned(initial, bits, inc, signed); } + + @Override + public IsSeparator getSeparators(int bits) { + return bit -> bit == fixedPoint; + } } /** @@ -527,6 +547,18 @@ public enum IntFormat { else return Double.doubleToLongBits(val); } + + @Override + public IsSeparator getSeparators(int bits) { + switch (bits) { + case 32: + return bit -> bit == 31 || bit == 23; + case 64: + return bit -> bit == 63 || bit == 52; + default: + return HEX_FORMATTER.getSeparators(bits); + } + } } } diff --git a/src/main/java/de/neemann/digital/core/ValueFormatter.java b/src/main/java/de/neemann/digital/core/ValueFormatter.java index 5a7339d35..10584c76d 100644 --- a/src/main/java/de/neemann/digital/core/ValueFormatter.java +++ b/src/main/java/de/neemann/digital/core/ValueFormatter.java @@ -54,4 +54,28 @@ public interface ValueFormatter { * @return the modified value */ long dragValue(long initial, int bits, double inc); + + /** + * Returns the {@link IsSeparator} interface to place separators in the {@link de.neemann.digital.gui.components.SingleValueDialog} + * Defaults to no separator at all. + * + * @param bits the number of bits used + * @return the IsSeparator instance + */ + default IsSeparator getSeparators(int bits) { + return bit -> false; + } + + /** + * Interface to define separators + */ + interface IsSeparator { + /** + * Returns true if there should be a separator in front of the given bit. + * + * @param bit the bit in question + * @return true if there should be a separator in front of the given bit. + */ + boolean isSeparatorInFrontOf(int bit); + } } diff --git a/src/main/java/de/neemann/digital/gui/components/SingleValueDialog.java b/src/main/java/de/neemann/digital/gui/components/SingleValueDialog.java index 5c4dd8dc1..5ef5f2a13 100644 --- a/src/main/java/de/neemann/digital/gui/components/SingleValueDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/SingleValueDialog.java @@ -11,6 +11,7 @@ import de.neemann.digital.lang.Lang; import de.neemann.gui.Screen; import javax.swing.*; +import javax.swing.border.Border; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -28,6 +29,7 @@ import java.util.ArrayList; public final class SingleValueDialog extends JDialog implements ModelStateObserverTyped { private static final Format[] FORMATS; + private static final Border SEPARATOR = BorderFactory.createEmptyBorder(0, 0, 0, 5); static { ArrayList f = new ArrayList<>(); @@ -98,8 +100,10 @@ public final class SingleValueDialog extends JDialog implements ModelStateObserv formatComboBox = new JComboBox<>(FORMATS); formatComboBox.addActionListener(actionEvent -> { Format selectedItem = (Format) formatComboBox.getSelectedItem(); - if (selectedItem != null) + if (selectedItem != null) { valueFormatter = selectedItem.intFormat.createFormatter(null); + updateSeparators(); + } setLongToDialog(editValue); }); @@ -205,6 +209,7 @@ public final class SingleValueDialog extends JDialog implements ModelStateObserv checkBoxes[bit].addActionListener(actionEvent -> setBit(bit, checkBoxes[bit].isSelected())); p.add(checkBoxes[bit]); } + updateSeparators(); return p; } @@ -234,10 +239,22 @@ public final class SingleValueDialog extends JDialog implements ModelStateObserv valueFormatter = format; formatComboBox.setSelectedItem(findFormat(valueFormatter)); setLongToDialog(editValue); + updateSeparators(); requestFocus(); return this; } + private void updateSeparators() { + ValueFormatter.IsSeparator s = valueFormatter.getSeparators(editValue.getBits()); + for (int i = 1; i < checkBoxes.length; i++) { + if (s.isSeparatorInFrontOf(i)) + checkBoxes[i].setBorder(SEPARATOR); + else + checkBoxes[i].setBorder(null); + } + pack(); + } + private void setStringToDialog(String text) { text = text.trim(); if (text.equalsIgnoreCase("z") && supportsHighZ)