Skip to content

Commit

Permalink
Have a tri-state when a group is partially shown
Browse files Browse the repository at this point in the history
  • Loading branch information
mmouchous-ledger committed Nov 25, 2024
1 parent 6f23aa9 commit 1691789
Showing 1 changed file with 50 additions and 11 deletions.
61 changes: 50 additions & 11 deletions laserstudio/widgets/toolbars/markerslistdialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,43 @@
from ..viewer import Viewer
from ..marker import Marker

class MarkerGroupListItem(QTreeWidgetItem):
def __init__(self, parent: QTreeWidget):
super().__init__(parent)
self._number_of_checked = 0

@property
def number_of_checked(self):
return self._number_of_checked

@number_of_checked.setter
def number_of_checked(self, value):
self._number_of_checked = value

def update_checked_state(self):
self.treeWidget().blockSignals(True)
self.setToolTip(0, f"{self._number_of_checked} shown over {self.childCount()}")
self.treeWidget().blockSignals(False)
if self._number_of_checked == 0:
self.setCheckState(0, Qt.CheckState.Unchecked)
elif self._number_of_checked == self.childCount():
self.setCheckState(0, Qt.CheckState.Checked)
else:
self.setCheckState(0, Qt.CheckState.PartiallyChecked)


class MarkerListItem(QTreeWidgetItem):
def __init__(self, group: QTreeWidgetItem, marker: Marker):
def __init__(self, group: MarkerGroupListItem, marker: Marker):
super().__init__(group)
self.group = group
x, y = marker.pos().x(), marker.pos().y()
self.marker = marker
self.setCheckState(0, Qt.CheckState.Checked if marker.isVisible() else Qt.CheckState.Unchecked)
visible = marker.isVisible()
self.setCheckState(0, Qt.CheckState.Checked if visible else Qt.CheckState.Unchecked)
self.setText(0, f"{x:.02f}µm {y:.02f}µm")
self.setForeground(0, marker.fillcolor)
if visible:
group.number_of_checked += 1

class MarkerListDialog(QDialog):
def open(self):
Expand Down Expand Up @@ -40,14 +69,17 @@ def refresh_list(self):
else:
markers_by_colors[name].append(marker)
for color in sorted(markers_by_colors.keys()):
markers = markers_by_colors[color]
group = QTreeWidgetItem(self.list)
markers: list[Marker] = markers_by_colors[color]
group = MarkerGroupListItem(self.list)
group.setForeground(0, markers[0].fillcolor)
group.setText(0, f"{len(markers)} marker(s)")
group.setCheckState(0, Qt.CheckState.Checked)
group.setText(0, f"{len(markers)} marker" + ("" if len(markers) == 1 else "s"))

self.list.itemChanged.disconnect(self.item_changed)
for marker in markers:
MarkerListItem(group, marker)
group.update_checked_state()
self.list.itemChanged.connect(self.item_changed)


def __init__(self, viewer: Viewer):
super().__init__()
Expand All @@ -72,9 +104,7 @@ def __init__(self, viewer: Viewer):
w.clicked.connect(self.hide_selected)
hbox.addWidget(w)
vbox.addLayout(hbox)

vbox.addWidget(self.list)

self.list.itemDoubleClicked.connect(self.show_marker)

def show_marker(self, item: QTreeWidgetItem):
Expand All @@ -84,10 +114,19 @@ def show_marker(self, item: QTreeWidgetItem):

def item_changed(self, item: QTreeWidgetItem):
if isinstance(item, MarkerListItem):
item.marker.setVisible(item.checkState(0) == Qt.CheckState.Checked)
else:
visible = item.checkState(0) == Qt.CheckState.Checked
was_visible = item.marker.isVisible()
if not was_visible and visible:
item.group.number_of_checked += 1
elif was_visible and not visible:
item.group.number_of_checked -= 1
item.marker.setVisible(visible)
item.group.update_checked_state()
if isinstance(item, MarkerGroupListItem):
new_state = item.checkState(0)
if new_state == Qt.CheckState.PartiallyChecked: return
for i in range(item.childCount()):
child = item.child(i)
if child is None: continue
child.setCheckState(0, item.checkState(0))
child.setCheckState(0, new_state)

0 comments on commit 1691789

Please sign in to comment.