Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update graph and sidebar colours after a color-scheme settings change. #176

Merged
merged 4 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions zxlive/base_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,6 @@ def copy_selection(self) -> GraphT:
copied_graph = self.graph.subgraph_from_vertices(selection)
assert isinstance(copied_graph, GraphT)
return copied_graph

def update_colors(self) -> None:
self.graph_scene.update_colors()
2 changes: 1 addition & 1 deletion zxlive/edit_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, graph: GraphT, *actions: QAction) -> None:
self.splitter.addWidget(self.graph_view)
self.graph_view.set_graph(graph)

self.sidebar = self.create_side_bar()
self.create_side_bar()
self.splitter.addWidget(self.sidebar)


Expand Down
77 changes: 51 additions & 26 deletions zxlive/editor_base_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,21 @@ class DrawPanelNodeType(TypedDict):
icon: tuple[ShapeType, str]


VERTICES: dict[VertexType.Type, DrawPanelNodeType] = {
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] = {
EdgeType.SIMPLE: {"text": "Simple", "icon": (ShapeType.LINE, BLACK)},
EdgeType.HADAMARD: {"text": "Hadamard", "icon": (ShapeType.DASHED_LINE, HAD_EDGE_BLUE)},
}
def vertices_data() -> dict[VertexType.Type, DrawPanelNodeType]:
return {
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)},
}

def edges_data() -> dict[EdgeType.Type, DrawPanelNodeType]:
return {
EdgeType.SIMPLE: {"text": "Simple", "icon": (ShapeType.LINE, BLACK)},
EdgeType.HADAMARD: {"text": "Hadamard", "icon": (ShapeType.DASHED_LINE, HAD_EDGE_BLUE)},
}


class EditorBasePanel(BasePanel):
Expand All @@ -63,6 +65,7 @@ class EditorBasePanel(BasePanel):

graph_scene: EditGraphScene
start_derivation_signal = Signal(object)
sidebar: QSplitter

_curr_ety: EdgeType.Type
_curr_vty: VertexType.Type
Expand All @@ -76,17 +79,27 @@ def _toolbar_sections(self) -> Iterator[ToolbarSection]:
yield toolbar_select_node_edge(self)
yield ToolbarSection(*self.actions())

def create_side_bar(self) -> QSplitter:
sidebar = QSplitter(self)
sidebar.setOrientation(Qt.Orientation.Vertical)
vertex_list = create_list_widget(self, VERTICES, self._vty_clicked)
edge_list = create_list_widget(self, EDGES, self._ety_clicked)
def create_side_bar(self) -> None:
self.sidebar = QSplitter(self)
self.sidebar.setOrientation(Qt.Orientation.Vertical)
self.vertex_list = create_list_widget(self, vertices_data(), self._vty_clicked)
self.edge_list = create_list_widget(self, edges_data(), self._ety_clicked)
self._populate_variables()
self.variable_viewer = VariableViewer(self.variable_types)
sidebar.addWidget(vertex_list)
sidebar.addWidget(edge_list)
sidebar.addWidget(self.variable_viewer)
return sidebar
self.sidebar.addWidget(self.vertex_list)
self.sidebar.addWidget(self.edge_list)
self.sidebar.addWidget(self.variable_viewer)

def update_side_bar(self) -> None:
populate_list_widget(self.vertex_list, vertices_data(), self._vty_clicked)
populate_list_widget(self.edge_list, edges_data(), self._ety_clicked)

def update_colors(self) -> None:
super().update_colors()
self.update_side_bar()

def update_variable_viewer(self) -> None:
self.update_side_bar()

def _populate_variables(self) -> None:
self.variable_types = {}
Expand Down Expand Up @@ -309,9 +322,10 @@ def toolbar_select_node_edge(parent: EditorBasePanel) -> ToolbarSection:
edge.clicked.connect(lambda: parent._tool_clicked(ToolType.EDGE))
return ToolbarSection(select, vertex, edge, exclusive=True)


def create_list_widget(parent: EditorBasePanel,
data: dict[VertexType.Type, DrawPanelNodeType] | dict[EdgeType.Type, DrawPanelNodeType],
onclick: Callable[[VertexType.Type], None] | Callable[[EdgeType.Type], None]) -> QListWidget:
data: dict[VertexType.Type, DrawPanelNodeType] | dict[EdgeType.Type, DrawPanelNodeType],
onclick: Callable[[VertexType.Type], None] | Callable[[EdgeType.Type], None]) -> QListWidget:
list_widget = QListWidget(parent)
list_widget.setResizeMode(QListView.ResizeMode.Adjust)
list_widget.setViewMode(QListView.ViewMode.IconMode)
Expand All @@ -320,14 +334,25 @@ def create_list_widget(parent: EditorBasePanel,
list_widget.setGridSize(QSize(60, 64))
list_widget.setWordWrap(True)
list_widget.setIconSize(QSize(24, 24))
populate_list_widget(list_widget, data, onclick)
list_widget.setCurrentItem(list_widget.item(0))
return list_widget


def populate_list_widget(list_widget: QListWidget,
data: dict[VertexType.Type, DrawPanelNodeType] | dict[EdgeType.Type, DrawPanelNodeType],
onclick: Callable[[VertexType.Type], None] | Callable[[EdgeType.Type], None]) \
-> None:
row = list_widget.currentRow()
list_widget.clear()
for typ, value in data.items():
icon = create_icon(*value["icon"])
item = QListWidgetItem(icon, value["text"])
item.setData(Qt.ItemDataRole.UserRole, typ)
list_widget.addItem(item)
list_widget.itemClicked.connect(lambda x: onclick(x.data(Qt.ItemDataRole.UserRole)))
list_widget.setCurrentItem(list_widget.item(0))
return list_widget
list_widget.setCurrentRow(row)


def create_icon(shape: ShapeType, color: str) -> QIcon:
icon = QIcon()
Expand Down
6 changes: 6 additions & 0 deletions zxlive/graphscene.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ def update_graph(self, new: GraphT, select_new: bool = False) -> None:

self.select_vertices(selected_vertices)

def update_colors(self) -> None:
for v in self.vertex_map.values():
v.refresh()
for e in self.edge_map.values():
e.refresh()

def add_items(self) -> None:
"""Add QGraphicsItem's for all vertices and edges in the graph"""
self.vertex_map = {}
Expand Down
9 changes: 8 additions & 1 deletion zxlive/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import_diagram_dialog, import_diagram_from_file, show_error_msg)
from zxlive.settings_dialog import open_settings_dialog

from .editor_base_panel import EditorBasePanel
from .edit_panel import GraphEditPanel
from .proof_panel import ProofPanel
from .rule_panel import RulePanel
Expand Down Expand Up @@ -130,7 +131,7 @@ def __init__(self) -> None:
self.select_all_action = self._new_action("Select &All", self.select_all, QKeySequence.StandardKey.SelectAll, "Select all")
self.deselect_all_action = self._new_action("&Deselect All", self.deselect_all, QKeySequence.StandardKey.Deselect,
"Deselect all", alt_shortcut = QKeySequence("Ctrl+D"))
self.preferences_action = self._new_action("&Preferences...", open_settings_dialog, None, "Open the preferences dialog")
self.preferences_action = self._new_action("&Preferences...", lambda: open_settings_dialog(self), None, "Open the preferences dialog")

edit_menu = menu.addMenu("&Edit")
edit_menu.addAction(self.undo_action)
Expand Down Expand Up @@ -257,6 +258,8 @@ def tab_changed(self, i: int) -> None:
self.proof_as_rewrite_action.setEnabled(False)
self._undo_changed()
self._redo_changed()
if self.active_panel:
self.active_panel.update_colors()

def _undo_changed(self) -> None:
if self.active_panel:
Expand Down Expand Up @@ -515,3 +518,7 @@ def proof_as_lemma(self) -> None:
rhs_graph = self.active_panel.proof_model.graphs[-1]
rule = CustomRule(lhs_graph, rhs_graph, name, description)
export_rule_dialog(rule, self)

def update_colors(self) -> None:
if self.active_panel is not None:
self.active_panel.update_colors()
2 changes: 1 addition & 1 deletion zxlive/rule_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, graph1: GraphT, graph2: GraphT, name: str, description: str,
self.graph_scene_right.vertex_added.connect(self.add_vert)
self.graph_scene_right.edge_added.connect(self.add_edge)

self.sidebar = self.create_side_bar()
self.create_side_bar()
self.splitter.addWidget(self.sidebar)

def _toolbar_sections(self) -> Iterator[ToolbarSection]:
Expand Down
18 changes: 11 additions & 7 deletions zxlive/settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@
}

class SettingsDialog(QDialog):
def __init__(self, parent: Optional[QWidget] = None) -> None:
def __init__(self, parent: MainWindow) -> None:
super().__init__(parent)
self.parent = parent
self.setWindowTitle("Settings")
self.settings = QSettings("zxlive", "zxlive")
self.value_dict: Dict[str,QWidget] = {}
Expand All @@ -95,6 +96,7 @@ def __init__(self, parent: Optional[QWidget] = None) -> None:
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)
self.prev_color_scheme = self.settings.value("color-scheme")
vlayout.addStretch()

##### Tikz Export settings #####
Expand Down Expand Up @@ -148,7 +150,7 @@ def __init__(self, parent: Optional[QWidget] = None) -> None:
self.add_setting(form_import, "tikz/boundary-import", "Boundary", 'str')
self.add_setting(form_import, "tikz/edge-import", "Regular Edge", 'str')
self.add_setting(form_import, "tikz/edge-H-import", "Hadamard edge", 'str')

self.add_setting(form_import, "tikz/w-input-import", "W input", 'str')
self.add_setting(form_import, "tikz/w-output-import", "W output", 'str')
self.add_setting(form_import, "tikz/z-box-import", "Z box", 'str')
Expand All @@ -168,7 +170,7 @@ def __init__(self, parent: Optional[QWidget] = None) -> None:
cancel_button.clicked.connect(self.cancel)
hlayout.addWidget(cancel_button)


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]
Expand Down Expand Up @@ -208,7 +210,7 @@ def browse() -> None:
widget.setCurrentText(data[val])
widget.data = data


form.addRow(label, widget)
self.value_dict[name] = widget

Expand All @@ -228,7 +230,9 @@ def okay(self) -> None:
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"))
if self.settings.value("color-scheme") != self.prev_color_scheme:
colors.set_color_scheme(self.settings.value("color-scheme"))
self.parent.update_colors()
self.accept()

def cancel(self) -> None:
Expand All @@ -237,6 +241,6 @@ def cancel(self) -> None:



def open_settings_dialog() -> None:
dialog = SettingsDialog()
def open_settings_dialog(parent: MainWindow) -> None:
dialog = SettingsDialog(parent)
dialog.exec()
Loading