mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-22 15:44:59 +00:00
Merge pull request #1034 from phw/PICARD-1060-fix-collection-menu-layout
PICARD-1060: Fix collections menu not looking and behaving like a normal menu
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# Picard, the next-generation MusicBrainz tagger
|
||||
# Copyright (C) 2013 Michael Wiencek
|
||||
# Copyright (C) 2018 Philipp Wolfer
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@@ -21,6 +22,7 @@ import locale
|
||||
|
||||
from PyQt5 import (
|
||||
QtCore,
|
||||
QtGui,
|
||||
QtWidgets,
|
||||
)
|
||||
|
||||
@@ -35,18 +37,24 @@ class CollectionMenu(QtWidgets.QMenu):
|
||||
def __init__(self, albums, *args):
|
||||
super().__init__(*args)
|
||||
self.ids = set(a.id for a in albums)
|
||||
self._ignore_update = False
|
||||
self.update_collections()
|
||||
|
||||
def update_collections(self):
|
||||
self._ignore_update = True
|
||||
self.clear()
|
||||
self.actions = []
|
||||
for id_, collection in sorted(user_collections.items(),
|
||||
key=lambda k_v:
|
||||
(locale.strxfrm(str(k_v[1])), k_v[0])):
|
||||
action = QtWidgets.QWidgetAction(self)
|
||||
action.setDefaultWidget(CollectionCheckBox(self, collection))
|
||||
action.setDefaultWidget(CollectionMenuItem(self, collection))
|
||||
self.addAction(action)
|
||||
self.actions.append(action)
|
||||
self._ignore_update = False
|
||||
self.addSeparator()
|
||||
self.refresh_action = self.addAction(_("Refresh List"))
|
||||
self.hovered.connect(self.update_highlight)
|
||||
|
||||
def refresh_list(self):
|
||||
self.refresh_action.setEnabled(False)
|
||||
@@ -57,13 +65,81 @@ class CollectionMenu(QtWidgets.QMenu):
|
||||
if self.actionAt(event.pos()) == self.refresh_action and self.refresh_action.isEnabled():
|
||||
self.refresh_list()
|
||||
|
||||
def update_highlight(self, action):
|
||||
if self._ignore_update:
|
||||
return
|
||||
for a in self.actions:
|
||||
a.defaultWidget().set_active(a == action)
|
||||
|
||||
def update_active_action_for_widget(self, widget):
|
||||
if self._ignore_update:
|
||||
return
|
||||
for action in self.actions:
|
||||
action_widget = action.defaultWidget()
|
||||
is_active = action_widget == widget
|
||||
if is_active:
|
||||
self._ignore_hover = True
|
||||
self.setActiveAction(action)
|
||||
self._ignore_hover = False
|
||||
action_widget.set_active(is_active)
|
||||
|
||||
|
||||
class CollectionMenuItem(QtWidgets.QWidget):
|
||||
|
||||
def __init__(self, menu, collection):
|
||||
super().__init__()
|
||||
self.menu = menu
|
||||
self.active = False
|
||||
self._setup_layout(menu, collection)
|
||||
self._setup_colors()
|
||||
|
||||
def _setup_layout(self, menu, collection):
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
style = self.style()
|
||||
layout.setContentsMargins(
|
||||
style.pixelMetric(QtWidgets.QStyle.PM_LayoutLeftMargin),
|
||||
style.pixelMetric(QtWidgets.QStyle.PM_FocusFrameVMargin),
|
||||
style.pixelMetric(QtWidgets.QStyle.PM_LayoutRightMargin),
|
||||
style.pixelMetric(QtWidgets.QStyle.PM_FocusFrameVMargin))
|
||||
self.checkbox = CollectionCheckBox(self, menu, collection)
|
||||
layout.addWidget(self.checkbox)
|
||||
|
||||
def _setup_colors(self):
|
||||
palette = self.palette()
|
||||
self.text_color = palette.text().color()
|
||||
self.highlight_color = palette.highlightedText().color()
|
||||
|
||||
def set_active(self, active):
|
||||
self.active = active
|
||||
palette = self.palette()
|
||||
textcolor = self.highlight_color if active else self.text_color
|
||||
palette.setColor(QtGui.QPalette.WindowText, textcolor)
|
||||
self.checkbox.setPalette(palette)
|
||||
|
||||
def enterEvent(self, e):
|
||||
self.menu.update_active_action_for_widget(self)
|
||||
|
||||
def leaveEvent(self, e):
|
||||
self.set_active(False)
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QtWidgets.QStylePainter(self)
|
||||
option = QtWidgets.QStyleOptionMenuItem()
|
||||
option.initFrom(self)
|
||||
option.state = QtWidgets.QStyle.State_None
|
||||
if self.isEnabled():
|
||||
option.state |= QtWidgets.QStyle.State_Enabled
|
||||
if self.active:
|
||||
option.state |= QtWidgets.QStyle.State_Selected
|
||||
painter.drawControl(QtWidgets.QStyle.CE_MenuItem, option)
|
||||
|
||||
|
||||
class CollectionCheckBox(QtWidgets.QCheckBox):
|
||||
|
||||
def __init__(self, menu, collection):
|
||||
def __init__(self, parent, menu, collection):
|
||||
self.menu = menu
|
||||
self.collection = collection
|
||||
super().__init__(self.label())
|
||||
super().__init__(self.label(), parent)
|
||||
|
||||
releases = collection.releases & menu.ids
|
||||
if len(releases) == len(menu.ids):
|
||||
|
||||
Reference in New Issue
Block a user