mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 17:04:42 -04:00
parent
6c8bc65d7c
commit
dadc335178
@ -23,6 +23,7 @@ public class Key<VALUE> {
|
||||
private CheckEnabled checkEnabled;
|
||||
private boolean isSecondary;
|
||||
private boolean requiresRestart = false;
|
||||
private boolean requiresRepaint = false;
|
||||
private String panelId;
|
||||
|
||||
// Both values are always null in digital.
|
||||
@ -235,6 +236,23 @@ public class Key<VALUE> {
|
||||
return requiresRestart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called if this setting needs a repaint.
|
||||
*
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Key<VALUE> setRequiresRepaint() {
|
||||
requiresRepaint = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if changing this value needs a repaint
|
||||
*/
|
||||
public boolean getRequiresRepaint() {
|
||||
return requiresRepaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves this key to the panel with the given id
|
||||
*
|
||||
|
@ -466,7 +466,7 @@ public final class Keys {
|
||||
* enables the grid
|
||||
*/
|
||||
public static final Key<Boolean> SETTINGS_GRID
|
||||
= new Key<>("grid", true);
|
||||
= new Key<>("grid", true).setRequiresRepaint();
|
||||
|
||||
/**
|
||||
* enables the wire bits view
|
||||
|
153
src/main/java/de/neemann/digital/draw/graphics/ColorMap.java
Normal file
153
src/main/java/de/neemann/digital/draw/graphics/ColorMap.java
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.draw.graphics;
|
||||
|
||||
import de.neemann.digital.core.element.Key;
|
||||
import de.neemann.digital.gui.Settings;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Color map.
|
||||
* Used to define the different color schemes.
|
||||
*/
|
||||
public final class ColorMap {
|
||||
|
||||
private static final ColorMap DEFAULT_MAP = new ColorMap()
|
||||
.set(ColorKey.BACKGROUND, Color.WHITE)
|
||||
.set(ColorKey.MAIN, Color.BLACK)
|
||||
.set(ColorKey.WIRE, Color.BLUE.darker())
|
||||
.set(ColorKey.WIRE_LOW, new Color(0, 142, 0))
|
||||
.set(ColorKey.WIRE_HIGH, new Color(102, 255, 102))
|
||||
.set(ColorKey.WIRE_OUT, Color.RED.darker())
|
||||
.set(ColorKey.WIRE_VALUE, new Color(50, 162, 50))
|
||||
.set(ColorKey.WIRE_Z, Color.GRAY)
|
||||
.set(ColorKey.PINS, Color.GRAY)
|
||||
.set(ColorKey.HIGHLIGHT, Color.CYAN)
|
||||
.set(ColorKey.GRID, new Color(210, 210, 210))
|
||||
.set(ColorKey.PASSED, Color.GREEN)
|
||||
.set(ColorKey.ERROR, Color.RED);
|
||||
|
||||
private static final ColorMap DARK_MAP = new ColorMap()
|
||||
.set(ColorKey.BACKGROUND, Color.BLACK)
|
||||
.set(ColorKey.MAIN, Color.GRAY)
|
||||
.set(ColorKey.WIRE, Color.BLUE.darker())
|
||||
.set(ColorKey.WIRE_LOW, new Color(0, 142, 0))
|
||||
.set(ColorKey.WIRE_HIGH, new Color(102, 255, 102))
|
||||
.set(ColorKey.WIRE_OUT, Color.RED.darker())
|
||||
.set(ColorKey.WIRE_VALUE, new Color(50, 162, 50))
|
||||
.set(ColorKey.WIRE_Z, Color.GRAY)
|
||||
.set(ColorKey.PINS, Color.GRAY)
|
||||
.set(ColorKey.HIGHLIGHT, Color.CYAN)
|
||||
.set(ColorKey.GRID, new Color(50, 50, 50))
|
||||
.set(ColorKey.PASSED, Color.GREEN)
|
||||
.set(ColorKey.ERROR, Color.RED);
|
||||
|
||||
private static final ColorMap COLOR_BLIND_MAP = new ColorMap()
|
||||
.set(ColorKey.BACKGROUND, Color.WHITE)
|
||||
.set(ColorKey.MAIN, Color.BLACK)
|
||||
.set(ColorKey.WIRE, Color.BLUE.darker())
|
||||
.set(ColorKey.WIRE_LOW, new Color(32, 59, 232))
|
||||
.set(ColorKey.WIRE_HIGH, new Color(244, 235, 66))
|
||||
.set(ColorKey.WIRE_OUT, Color.RED.darker())
|
||||
.set(ColorKey.WIRE_VALUE, new Color(50, 162, 50))
|
||||
.set(ColorKey.WIRE_Z, new Color(1, 188, 157))
|
||||
.set(ColorKey.PINS, Color.GRAY)
|
||||
.set(ColorKey.HIGHLIGHT, Color.CYAN)
|
||||
.set(ColorKey.GRID, new Color(210, 210, 210))
|
||||
.set(ColorKey.PASSED, Color.GREEN)
|
||||
.set(ColorKey.ERROR, Color.RED);
|
||||
|
||||
private enum ColorSchemes {
|
||||
DEFAULT(DEFAULT_MAP), DARK(DARK_MAP), COLOR_BLIND(COLOR_BLIND_MAP);
|
||||
|
||||
private final ColorMap map;
|
||||
|
||||
ColorSchemes(ColorMap map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
private ColorMap getMap() {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The key used to select the color map
|
||||
*/
|
||||
public static final Key<ColorSchemes> COLOR_SCHEME =
|
||||
new Key.KeyEnum<>("colorScheme", ColorSchemes.DEFAULT, ColorSchemes.values())
|
||||
.setRequiresRepaint();
|
||||
|
||||
private static ColorMap instance = null;
|
||||
|
||||
/**
|
||||
* @return the selected color map
|
||||
*/
|
||||
public static ColorMap getInstance() {
|
||||
if (instance == null) {
|
||||
Settings.getInstance().getAttributes().addListener(ColorMap::updateInstance);
|
||||
updateInstance();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static void updateInstance() {
|
||||
instance = Settings.getInstance().get(COLOR_SCHEME).getMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifiers for the different colors
|
||||
*/
|
||||
public enum ColorKey {BACKGROUND, MAIN, WIRE, WIRE_HIGH, WIRE_LOW, WIRE_VALUE, WIRE_OUT, WIRE_Z, ERROR, PASSED, PINS, GRID, HIGHLIGHT}
|
||||
|
||||
private final Color[] colors;
|
||||
|
||||
private ColorMap() {
|
||||
colors = new Color[ColorKey.HIGHLIGHT.ordinal() + 1];
|
||||
}
|
||||
|
||||
private ColorMap set(ColorKey key, Color color) {
|
||||
colors[key.ordinal()] = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected color
|
||||
*
|
||||
* @param key te color key
|
||||
* @return the color
|
||||
*/
|
||||
public Color getColor(ColorKey key) {
|
||||
Color color = colors[key.ordinal()];
|
||||
if (color == null)
|
||||
return colors[ColorKey.MAIN.ordinal()];
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a color
|
||||
*/
|
||||
public interface ColorProvider {
|
||||
/**
|
||||
* @return the color
|
||||
*/
|
||||
Color getColor();
|
||||
}
|
||||
|
||||
static final class ColorByKey implements ColorProvider {
|
||||
private final ColorKey key;
|
||||
|
||||
ColorByKey(ColorKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return getInstance().getColor(key);
|
||||
}
|
||||
}
|
||||
}
|
@ -37,11 +37,11 @@ public final class Style {
|
||||
/**
|
||||
* used to draw the failed state lines in the measurement graph
|
||||
*/
|
||||
public static final Style FAILED = new Builder(NORMAL).setColor(Color.RED).build();
|
||||
public static final Style FAILED = new Builder(NORMAL).setColor(ColorMap.ColorKey.ERROR).build();
|
||||
/**
|
||||
* used to draw the passed state lines in the measurement graph
|
||||
*/
|
||||
public static final Style PASS = new Builder(NORMAL).setColor(Color.GREEN).build();
|
||||
public static final Style PASS = new Builder(NORMAL).setColor(ColorMap.ColorKey.PASSED).build();
|
||||
/**
|
||||
* Used for text which is integral part of the shape.
|
||||
* Text which uses this style is always included in sizing!
|
||||
@ -66,25 +66,25 @@ public final class Style {
|
||||
public static final Style WIRE = new Builder()
|
||||
.setThickness(WIRETHICK)
|
||||
.setFilled(true)
|
||||
.setColor(Color.BLUE.darker())
|
||||
.setColor(ColorMap.ColorKey.WIRE)
|
||||
.setEndCap(BasicStroke.CAP_ROUND)
|
||||
.build();
|
||||
/**
|
||||
* Used for low wires in running mode
|
||||
*/
|
||||
public static final Style WIRE_LOW = new Builder(WIRE).setColor(new Color(0, 142, 0)).build();
|
||||
public static final Style WIRE_LOW = new Builder(WIRE).setColor(ColorMap.ColorKey.WIRE_LOW).build();
|
||||
/**
|
||||
* Used for high wires in running mode
|
||||
*/
|
||||
public static final Style WIRE_HIGH = new Builder(WIRE).setColor(new Color(102, 255, 102)).build();
|
||||
public static final Style WIRE_HIGH = new Builder(WIRE).setColor(ColorMap.ColorKey.WIRE_HIGH).build();
|
||||
/**
|
||||
* Used for wires in high Z state
|
||||
*/
|
||||
public static final Style WIRE_HIGHZ = new Builder(WIRE).setColor(Color.GRAY).build();
|
||||
public static final Style WIRE_HIGHZ = new Builder(WIRE).setColor(ColorMap.ColorKey.WIRE_Z).build();
|
||||
/**
|
||||
* used to draw the output dots
|
||||
*/
|
||||
public static final Style WIRE_OUT = new Builder(WIRE).setColor(Color.RED.darker()).build();
|
||||
public static final Style WIRE_OUT = new Builder(WIRE).setColor(ColorMap.ColorKey.WIRE_OUT).build();
|
||||
|
||||
/**
|
||||
* used to draw the bus wires
|
||||
@ -107,7 +107,7 @@ public final class Style {
|
||||
*/
|
||||
public static final Style SHAPE_PIN = new Builder()
|
||||
.setThickness(LINETHIN)
|
||||
.setColor(Color.GRAY)
|
||||
.setColor(ColorMap.ColorKey.PINS)
|
||||
.setFontSize(18)
|
||||
.build();
|
||||
/**
|
||||
@ -118,19 +118,19 @@ public final class Style {
|
||||
* Used to draw the pin description text
|
||||
*/
|
||||
public static final Style WIRE_VALUE = new Builder(SHAPE_SPLITTER)
|
||||
.setColor(new Color(50, 162, 50))
|
||||
.setColor(ColorMap.ColorKey.WIRE_VALUE)
|
||||
.build();
|
||||
/**
|
||||
* Used to draw the wire bit number
|
||||
*/
|
||||
public static final Style WIRE_BITS = new Builder(SHAPE_SPLITTER)
|
||||
.setColor(WIRE.color)
|
||||
.setColor(ColorMap.ColorKey.WIRE)
|
||||
.build();
|
||||
/**
|
||||
* highlight color used for the circles to mark an element
|
||||
*/
|
||||
public static final Style HIGHLIGHT = new Builder(NORMAL)
|
||||
.setColor(Color.CYAN)
|
||||
.setColor(ColorMap.ColorKey.HIGHLIGHT)
|
||||
.setEndCap(BasicStroke.CAP_ROUND)
|
||||
.build();
|
||||
|
||||
@ -138,13 +138,13 @@ public final class Style {
|
||||
* error color used for the circles to mark an element
|
||||
*/
|
||||
public static final Style ERROR = new Builder(NORMAL)
|
||||
.setColor(Color.RED)
|
||||
.setColor(ColorMap.ColorKey.ERROR)
|
||||
.setEndCap(BasicStroke.CAP_ROUND)
|
||||
.build();
|
||||
|
||||
private final int thickness;
|
||||
private final boolean filled;
|
||||
private final Color color;
|
||||
private final ColorMap.ColorProvider color;
|
||||
private final int fontSize;
|
||||
private final float[] dash;
|
||||
private final BasicStroke stroke;
|
||||
@ -188,7 +188,7 @@ public final class Style {
|
||||
* @return the color
|
||||
*/
|
||||
public Color getColor() {
|
||||
return color;
|
||||
return color.getColor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,7 +309,7 @@ public final class Style {
|
||||
private static final class Builder {
|
||||
private int thickness = LINETHICK;
|
||||
private boolean filled = false;
|
||||
private Color color = Color.BLACK;
|
||||
private ColorMap.ColorProvider color = new ColorMap.ColorByKey(ColorMap.ColorKey.MAIN);
|
||||
private int fontSize = 24;
|
||||
private float[] dash = null;
|
||||
private boolean mattersForSize = false;
|
||||
@ -339,8 +339,13 @@ public final class Style {
|
||||
return this;
|
||||
}
|
||||
|
||||
private Builder setColor(ColorMap.ColorKey key) {
|
||||
this.color = new ColorMap.ColorByKey(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
private Builder setColor(Color color) {
|
||||
this.color = color;
|
||||
this.color = () -> color;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,6 @@ package de.neemann.digital.draw.shapes;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.draw.graphics.*;
|
||||
import de.neemann.digital.draw.graphics.Polygon;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* The shape to show a seven seg display.
|
||||
@ -46,7 +43,7 @@ public abstract class SevenShape implements Shape {
|
||||
*/
|
||||
public SevenShape(ElementAttributes attr) {
|
||||
onStyle = Style.NORMAL.deriveFillStyle(attr.get(Keys.COLOR));
|
||||
offStyle = Style.NORMAL.deriveFillStyle(new Color(230, 230, 230));
|
||||
offStyle = Style.NORMAL.deriveFillStyle(ColorMap.getInstance().getColor(ColorMap.ColorKey.GRID));
|
||||
size = attr.get(Keys.SEVEN_SEG_SIZE);
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,6 @@ import de.neemann.digital.draw.elements.IOState;
|
||||
import de.neemann.digital.draw.elements.Pin;
|
||||
import de.neemann.digital.draw.elements.Pins;
|
||||
import de.neemann.digital.draw.graphics.*;
|
||||
import de.neemann.digital.draw.graphics.Polygon;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
|
||||
|
||||
@ -67,7 +64,7 @@ public class SixteenShape implements Shape {
|
||||
public SixteenShape(ElementAttributes attr, PinDescriptions inputs, PinDescriptions outputs) {
|
||||
pins = inputs;
|
||||
onStyle = Style.NORMAL.deriveFillStyle(attr.get(Keys.COLOR));
|
||||
offStyle = Style.NORMAL.deriveFillStyle(new Color(230, 230, 230));
|
||||
offStyle = Style.NORMAL.deriveFillStyle(ColorMap.getInstance().getColor(ColorMap.ColorKey.GRID));
|
||||
size = attr.get(Keys.SEVEN_SEG_SIZE);
|
||||
}
|
||||
|
||||
|
@ -745,7 +745,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
Lang.setLanguage(modified.get(Keys.SETTINGS_LANGUAGE));
|
||||
JOptionPane.showMessageDialog(Main.this, Lang.get("msg_restartNeeded"));
|
||||
}
|
||||
if (!Settings.getInstance().getAttributes().equalsKey(Keys.SETTINGS_GRID, modified))
|
||||
if (Settings.getInstance().requiresRepaint(modified))
|
||||
circuitComponent.graphicHasChanged();
|
||||
|
||||
Settings.getInstance().getAttributes().getValuesFrom(modified);
|
||||
|
@ -8,6 +8,7 @@ package de.neemann.digital.gui;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Key;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.draw.graphics.ColorMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -42,6 +43,7 @@ public final class Settings extends SettingsBase {
|
||||
intList.add(Keys.SETTINGS_IEEE_SHAPES);
|
||||
intList.add(Keys.SETTINGS_LANGUAGE);
|
||||
intList.add(Keys.SETTINGS_EXPRESSION_FORMAT);
|
||||
intList.add(ColorMap.COLOR_SCHEME);
|
||||
intList.add(Keys.SETTINGS_DEFAULT_TREESELECT);
|
||||
intList.add(Keys.SETTINGS_GRID);
|
||||
intList.add(Keys.SETTINGS_SHOW_WIRE_BITS);
|
||||
@ -76,4 +78,18 @@ public final class Settings extends SettingsBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given modification requires a repaint.
|
||||
*
|
||||
* @param modified the modified settings
|
||||
* @return true if the modification requires a repaint
|
||||
*/
|
||||
public boolean requiresRepaint(ElementAttributes modified) {
|
||||
for (Key<?> key : getKeys())
|
||||
if (key.getRequiresRepaint() && !getAttributes().equalsKey(key, modified))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static de.neemann.digital.draw.graphics.ColorMap.*;
|
||||
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
|
||||
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
|
||||
|
||||
@ -92,8 +93,6 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
||||
|
||||
private static final int DRAG_DISTANCE = (int) (SIZE2 * Screen.getInstance().getScaling());
|
||||
|
||||
private static final Color GRID_COLOR = new Color(210, 210, 210);
|
||||
|
||||
private final Main parent;
|
||||
private final ElementLibrary library;
|
||||
private final HashSet<Drawable> highLighted;
|
||||
@ -859,7 +858,7 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
||||
|
||||
Graphics2D gr2 = buffer.createGraphics();
|
||||
enableAntiAlias(gr2);
|
||||
gr2.setColor(Color.WHITE);
|
||||
gr2.setColor(getInstance().getColor(ColorKey.BACKGROUND));
|
||||
gr2.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
if (scaleX > 0.3 && Settings.getInstance().get(Keys.SETTINGS_GRID))
|
||||
@ -917,7 +916,7 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
||||
if (delta > max) delta = max;
|
||||
double sub = delta / 2.0;
|
||||
|
||||
gr2.setColor(GRID_COLOR);
|
||||
gr2.setColor(getInstance().getColor(ColorKey.GRID));
|
||||
for (int x = 0; x <= cx; x++) {
|
||||
double xx = p1.getX() + (p2.getX() - p1.getX()) * x / cx - sub;
|
||||
for (int y = 0; y <= cy; y++) {
|
||||
|
@ -1506,6 +1506,11 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
||||
<string name="key_layoutShapeDelta_tt">Wird vom Layout-Shape verwendet. Legt den Abstand zum vorherigen Pin fest.
|
||||
</string>
|
||||
|
||||
<string name="key_colorScheme">Farbschema</string>
|
||||
<string name="key_colorScheme_DEFAULT">Normal</string>
|
||||
<string name="key_colorScheme_DARK">Dunkel</string>
|
||||
<string name="key_colorScheme_COLOR_BLIND">Rot-Grün-Sehschwäche</string>
|
||||
|
||||
<string name="mod_insertWire">Leitung eingefügt.</string>
|
||||
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>
|
||||
<string name="mod_setKey_N0_in_element_N1">Wert ''{0}'' in Element ''{1}'' verändert.</string>
|
||||
|
@ -1470,6 +1470,11 @@
|
||||
<string name="key_layoutShapeDelta_tt">Used by the layout shape type. Sets the distance to the previous pin.
|
||||
</string>
|
||||
|
||||
<string name="key_colorScheme">Color-Scheme</string>
|
||||
<string name="key_colorScheme_DEFAULT">Normal</string>
|
||||
<string name="key_colorScheme_DARK">Dark</string>
|
||||
<string name="key_colorScheme_COLOR_BLIND">red/green colorblind</string>
|
||||
|
||||
<string name="mod_insertWire">Inserted wire.</string>
|
||||
<string name="mod_insertCopied">Insert from clipboard.</string>
|
||||
<string name="mod_setKey_N0_in_element_N1">Value ''{0}'' in component ''{1}'' modified.</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user