Skip to content

Commit

Permalink
Added several different color schemes to ZXLive and the ability to sw…
Browse files Browse the repository at this point in the history
…itch between them
  • Loading branch information
jvdwetering committed Nov 8, 2023
1 parent ad5fce5 commit c26a89f
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 36 deletions.
61 changes: 61 additions & 0 deletions zxlive/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing_extensions import TypeAlias

from PySide6.QtCore import QSettings
from PySide6.QtGui import QColor

import pyzx

Expand Down Expand Up @@ -56,6 +57,66 @@ def view_to_length(width:float,height:float)-> tuple[float, float]:
return (width / SCALE, height / SCALE)


class Colors(object):
z_spider: QColor = QColor("#ccffcc")
z_spider_pressed: QColor = QColor("#64BC90")
x_spider: QColor = QColor("#ff8888")
x_spider_pressed: QColor = QColor("#bb0f0f")
hadamard: QColor = QColor("#ffff00")
hadamard_pressed: QColor = QColor("#f1c232")
boundary: QColor = QColor("#000000")
boundary_pressed: QColor = QColor("#444444")
w_input: QColor = QColor("#000000")
w_input_pressed: QColor = QColor("#444444")
w_output: QColor = QColor("#000000")
w_output_pressed: QColor = QColor("#444444")
outline: QColor = QColor("#000000")

def __init__(self, color_scheme:str='modern-red-green'):
self.set_color_scheme(color_scheme)

def set_color_scheme(self,color_scheme):
if color_scheme == 'modern-red-green':
self.z_spider = QColor("#ccffcc")
self.z_spider_pressed = QColor("#64BC90")
self.x_spider = QColor("#ff8888")
self.x_spider_pressed = QColor("#bb0f0f")
self.hadamard = QColor("#ffff00")
self.hadamard_pressed = QColor("#f1c232")
self.boundary = QColor("#000000")
elif color_scheme == 'classic-red-green':
self.z_spider = QColor("#00ff00")
self.z_spider_pressed = QColor("#00dd00")
self.x_spider = QColor("#ff0d00")
self.x_spider_pressed = QColor("#dd0b00")
self.hadamard = QColor("#ffff00")
self.hadamard_pressed = QColor("#f1c232")
self.boundary = QColor("#000000")
elif color_scheme == 'white-grey':
self.z_spider = QColor("#ffffff")
self.z_spider_pressed = QColor("#eeeeee")
self.x_spider = QColor("#b4b4b4")
self.x_spider_pressed = QColor("#a0a0a0")
self.hadamard = QColor("#ffffff")
self.hadamard_pressed = QColor("#dddddd")
self.boundary = QColor("#000000")
elif color_scheme == 'gidney':
self.z_spider = QColor("#000000")
self.z_spider_pressed = QColor("#222222")
self.x_spider = QColor("#ffffff")
self.x_spider_pressed = QColor("#dddddd")
self.hadamard = QColor("#ffffff")
self.hadamard_pressed = QColor("#dddddd")
self.boundary = QColor("#000000")
else:
raise ValueError(f"Unknown colour scheme {color_scheme}")

settings = QSettings("zxlive", "zxlive")
color_scheme = settings.value("color-scheme")
if color_scheme is None: color_scheme = 'modern-red-green'
else: color_scheme = str(color_scheme)
colors = Colors(color_scheme)

def set_pyzx_tikz_settings() -> None:
settings = QSettings("zxlive", "zxlive")
tikz_classes = {
Expand Down
16 changes: 8 additions & 8 deletions zxlive/editor_base_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
from .commands import (AddEdge, AddNode, AddWNode, ChangeEdgeColor,
ChangeNodeType, ChangePhase, MoveNode, SetGraph,
UpdateGraph)
from .common import VT, GraphT, ToolType, get_data
from .common import VT, GraphT, ToolType, get_data, colors
from .dialogs import show_error_msg
from .eitem import HAD_EDGE_BLUE
from .graphscene import EditGraphScene
from .parse_poly import parse
from .poly import Poly, new_var
from .vitem import BLACK, H_YELLOW, ZX_GREEN, ZX_RED
from .vitem import BLACK


class ShapeType(Enum):
Expand All @@ -43,12 +43,12 @@ class DrawPanelNodeType(TypedDict):


VERTICES: dict[VertexType.Type, DrawPanelNodeType] = {
VertexType.Z: {"text": "Z spider", "icon": (ShapeType.CIRCLE, ZX_GREEN)},
VertexType.X: {"text": "X spider", "icon": (ShapeType.CIRCLE, ZX_RED)},
VertexType.H_BOX: {"text": "H box", "icon": (ShapeType.SQUARE, H_YELLOW)},
VertexType.Z_BOX: {"text": "Z box", "icon": (ShapeType.SQUARE, ZX_GREEN)},
VertexType.W_OUTPUT: {"text": "W node", "icon": (ShapeType.TRIANGLE, BLACK)},
VertexType.BOUNDARY: {"text": "boundary", "icon": (ShapeType.CIRCLE, BLACK)},
VertexType.Z: {"text": "Z spider", "icon": (ShapeType.CIRCLE, colors.z_spider)},
VertexType.X: {"text": "X spider", "icon": (ShapeType.CIRCLE, colors.x_spider)},
VertexType.H_BOX: {"text": "H box", "icon": (ShapeType.SQUARE, colors.hadamard)},
VertexType.Z_BOX: {"text": "Z box", "icon": (ShapeType.SQUARE, colors.z_spider)},
VertexType.W_OUTPUT: {"text": "W node", "icon": (ShapeType.TRIANGLE, colors.w_output)},
VertexType.BOUNDARY: {"text": "boundary", "icon": (ShapeType.CIRCLE, colors.w_input)},
}

EDGES: dict[EdgeType.Type, DrawPanelNodeType] = {
Expand Down
6 changes: 3 additions & 3 deletions zxlive/proof_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
from .base_panel import BasePanel, ToolbarSection
from .commands import AddRewriteStep, GoToRewriteStep, MoveNodeInStep
from .common import (get_custom_rules_path, ET, SCALE, VT, GraphT, get_data,
pos_from_view, pos_to_view)
pos_from_view, pos_to_view, colors)
from .custom_rule import CustomRule
from .eitem import EItem
from .graphscene import GraphScene
from .graphview import GraphTool, GraphView, WandTrace
from .proof import ProofModel
from .vitem import ZX_GREEN, DragState, VItem
from .vitem import DragState, VItem


class ProofPanel(BasePanel):
Expand Down Expand Up @@ -368,7 +368,7 @@ def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: Union[QM

# Draw circle
painter.setPen(QPen(Qt.GlobalColor.black, self.circle_outline_width))
painter.setBrush(QColor(ZX_GREEN))
painter.setBrush(colors.z_spider)
circle_radius = self.circle_radius_selected if option.state & QStyle.StateFlag.State_Selected else self.circle_radius
painter.drawEllipse(
QPointF(self.line_padding + self.line_width / 2, option.rect.y() + option.rect.height() / 2),
Expand Down
29 changes: 26 additions & 3 deletions zxlive/settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@
QFormLayout, QLineEdit, QMessageBox,
QPushButton, QTextEdit, QWidget,
QVBoxLayout, QSpinBox, QDoubleSpinBox,
QLabel, QHBoxLayout, QTabWidget)
QLabel, QHBoxLayout, QTabWidget,
QComboBox)

import pyzx

from .common import set_pyzx_tikz_settings
from .common import set_pyzx_tikz_settings, colors

if TYPE_CHECKING:
from .mainwindow import MainWindow

defaults: Dict[str,Any] = {
"path/custom-rules": "lemmas/",
"color-scheme": "modern-red-green",

"tikz/Z-spider-export": "Z dot",
"tikz/Z-phase-export": "Z phase dot",
Expand Down Expand Up @@ -60,6 +62,12 @@
"tikz/edge-W-import": ", ".join(pyzx.tikz.synonyms_wedge),
}

color_schemes = {
'modern-red-green': "Modern Red & Green",
'classic-red-green': "Classic Red & Green",
'white-grey': "Dodo book White & Grey",
'gidney': "Gidney's Black & White",
}

class SettingsDialog(QDialog):
def __init__(self, parent: Optional[QWidget] = None) -> None:
Expand Down Expand Up @@ -87,6 +95,7 @@ def __init__(self, parent: Optional[QWidget] = None) -> None:
w.setLayout(form_general)
vlayout.addWidget(w)
self.add_setting(form_general, "path/custom-rules", "Custom rules path", 'folder')
self.add_setting(form_general, "color-scheme", "Color scheme", 'combo',data=color_schemes)
vlayout.addStretch()

##### Tikz Export settings #####
Expand Down Expand Up @@ -161,7 +170,7 @@ def __init__(self, parent: Optional[QWidget] = None) -> None:
hlayout.addWidget(cancel_button)


def add_setting(self,form:QFormLayout, name:str, label:str, ty:str) -> None:
def add_setting(self,form:QFormLayout, name:str, label:str, ty:str, data:Any=None) -> None:
val = self.settings.value(name)
if val is None: val = defaults[name]
if ty == 'str':
Expand Down Expand Up @@ -192,6 +201,14 @@ def browse() -> None:
button = QPushButton("Browse")
button.clicked.connect(browse)
hlayout.addWidget(button)
elif ty == 'combo':
widget = QComboBox()
val = str(val)
assert isinstance(data, dict)
widget.addItems(data.values())
widget.setCurrentText(data[val])
widget.data = data


form.addRow(label, widget)
self.value_dict[name] = widget
Expand All @@ -204,9 +221,15 @@ def okay(self) -> None:
self.settings.setValue(name, widget.value())
elif isinstance(widget, QDoubleSpinBox):
self.settings.setValue(name, widget.value())
elif isinstance(widget, QComboBox):
s = widget.currentText()
assert hasattr(widget, "data")
val = next(k for k in widget.data if widget.data[k] == s)
self.settings.setValue(name, val)
elif isinstance(widget, QWidget) and hasattr(widget, "text_value"):
self.settings.setValue(name, widget.text_value)
set_pyzx_tikz_settings()
colors.set_color_scheme(self.settings.value("color-scheme"))
self.accept()

def cancel(self) -> None:
Expand Down
38 changes: 16 additions & 22 deletions zxlive/vitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,13 @@

from pyzx.utils import VertexType, phase_to_s, get_w_partner, vertex_is_w, get_z_box_label

from .common import VT, W_INPUT_OFFSET, GraphT, SCALE, pos_to_view, pos_from_view
from .common import VT, W_INPUT_OFFSET, GraphT, SCALE, pos_to_view, pos_from_view, colors

if TYPE_CHECKING:
from .eitem import EItem
from .graphscene import GraphScene


ZX_GREEN = "#ccffcc"
ZX_GREEN_PRESSED = "#64BC90"
ZX_RED = "#ff8888"
ZX_RED_PRESSED = "#bb0f0f"
H_YELLOW = "#ffff00"
H_YELLOW_PRESSED = "#f1c232"
BLACK = "#000000"

# Z values for different items. We use those to make sure that edges
Expand Down Expand Up @@ -129,51 +123,51 @@ def refresh(self) -> None:
if not self.isSelected():
t = self.ty
if t == VertexType.Z or t == VertexType.Z_BOX:
self.setBrush(QBrush(QColor(ZX_GREEN)))
self.setBrush(QBrush(colors.z_spider))
elif t == VertexType.X:
self.setBrush(QBrush(QColor(ZX_RED)))
self.setBrush(QBrush(colors.x_spider))
elif t == VertexType.H_BOX:
self.setBrush(QBrush(QColor(H_YELLOW)))
self.setBrush(QBrush(colors.hadamard))
elif t == VertexType.W_INPUT:
self.setBrush(QBrush(QColor(BLACK)))
self.setBrush(QBrush(colors.w_input))
elif t == VertexType.W_OUTPUT:
self.setBrush(QBrush(QColor(BLACK)))
self.setBrush(QBrush(colors.w_output))
else:
self.setBrush(QBrush(QColor(BLACK)))
self.setBrush(QBrush(colors.boundary))
pen = QPen()
pen.setWidthF(3)
pen.setColor(QColor(BLACK))
pen.setColor(colors.outline)
self.setPen(pen)

if self.isSelected():
pen = QPen()
pen.setWidthF(5)
t = self.ty
if t == VertexType.Z or t == VertexType.Z_BOX:
brush = QBrush(QColor(ZX_GREEN_PRESSED))
brush = QBrush(colors.z_spider_pressed)
brush.setStyle(Qt.BrushStyle.Dense1Pattern)
self.setBrush(brush)
elif t == VertexType.X:
brush = QBrush(QColor(ZX_RED_PRESSED))
brush = QBrush(colors.x_spider_pressed)
brush.setStyle(Qt.BrushStyle.Dense1Pattern)
self.setBrush(brush)
elif t == VertexType.H_BOX:
brush = QBrush(QColor(H_YELLOW_PRESSED))
brush = QBrush(colors.hadamard_pressed)
brush.setStyle(Qt.BrushStyle.Dense1Pattern)
self.setBrush(brush)
elif t == VertexType.W_INPUT:
brush = QBrush(QColor(BLACK))
brush = QBrush(colors.w_input_pressed)
brush.setStyle(Qt.BrushStyle.Dense1Pattern)
self.setBrush(brush)
elif t == VertexType.W_OUTPUT:
brush = QBrush(QColor(BLACK))
brush = QBrush(colors.w_output_pressed)
brush.setStyle(Qt.BrushStyle.Dense1Pattern)
self.setBrush(brush)
else:
brush = QBrush(QColor("#444444"))
brush = QBrush(colors.boundary_pressed)
brush.setStyle(Qt.BrushStyle.Dense1Pattern)
self.setBrush(brush)
pen.setColor(QColor("#444444"))
pen.setColor(colors.boundary_pressed)
self.setPen(pen)

if self.phase_item:
Expand All @@ -189,7 +183,7 @@ def refresh(self) -> None:
def update_shape(self) -> None:
pen = QPen()
pen.setWidthF(3)
pen.setColor(QColor(BLACK))
pen.setColor(colors.outline)
self.setPen(pen)

path = QPainterPath()
Expand Down

0 comments on commit c26a89f

Please sign in to comment.