diff --git a/qt/aqt/browser/table/table.py b/qt/aqt/browser/table/table.py index 56de065a2..6ca9b256a 100644 --- a/qt/aqt/browser/table/table.py +++ b/qt/aqt/browser/table/table.py @@ -12,7 +12,7 @@ from anki.collection import Collection, Config, OpChanges from anki.consts import * from anki.notes import Note, NoteId from anki.utils import is_win -from aqt import colors, gui_hooks +from aqt import gui_hooks from aqt.browser.table import Columns, ItemId, SearchContext from aqt.browser.table.model import DataModel from aqt.browser.table.state import CardState, ItemState, NoteState @@ -61,7 +61,6 @@ class Table: def cleanup(self) -> None: self._save_header() - gui_hooks.theme_did_change.remove(self._setup_style) # Public Methods ###################################################################### @@ -351,10 +350,8 @@ class Table: self._view.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) self._view.horizontalScrollBar().setSingleStep(10) self._update_font() - self._setup_style() self._view.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) qconnect(self._view.customContextMenuRequested, self._on_context_menu) - gui_hooks.theme_did_change.append(self._setup_style) def _update_font(self) -> None: # we can't choose different line heights efficiently, so we need @@ -367,19 +364,6 @@ class Table: curmax = bsize self._view.verticalHeader().setDefaultSectionSize(curmax + 6) - def _setup_style(self) -> None: - if not theme_manager.night_mode: - self._view.setStyleSheet( - "QTableView{ selection-background-color: rgba(150, 150, 150, 50); " - "selection-color: black; }" - ) - elif theme_manager.macos_dark_mode(): - self._view.setStyleSheet( - f"QTableView {{ gridline-color: {colors.CANVAS_INSET} }}" - ) - else: - self._view.setStyleSheet("") - def _setup_headers(self) -> None: vh = self._view.verticalHeader() hh = self._view.horizontalHeader() diff --git a/qt/aqt/data/qt/icons/BUILD.bazel b/qt/aqt/data/qt/icons/BUILD.bazel index 1043ca7d3..9692fe8d5 100644 --- a/qt/aqt/data/qt/icons/BUILD.bazel +++ b/qt/aqt/data/qt/icons/BUILD.bazel @@ -37,6 +37,10 @@ copy_mdi_icons( # QHeaderView arrows "menu-up.svg", "menu-down.svg", + + # drag handle + "drag-vertical.svg", + "drag-horizontal.svg", ], ) diff --git a/qt/aqt/forms/browser.ui b/qt/aqt/forms/browser.ui index 6e1da64eb..a43a9257d 100644 --- a/qt/aqt/forms/browser.ui +++ b/qt/aqt/forms/browser.ui @@ -26,13 +26,13 @@ 12 - 12 + 0 6 - 12 + 6 12 diff --git a/qt/aqt/stylesheets.py b/qt/aqt/stylesheets.py index 960b9015d..025f52229 100644 --- a/qt/aqt/stylesheets.py +++ b/qt/aqt/stylesheets.py @@ -4,6 +4,28 @@ from aqt import colors, props from aqt.theme import ThemeManager +def button_gradient(start: str, end: str) -> str: + return f""" +qlineargradient( + spread:pad, x1:0.5, y1:0, x2:0.5, y2:1.25, + stop:0 {start}, + stop:1 {end} +); + """ + + +def button_pressed_gradient(start: str, end: str, shadow: str) -> str: + return f""" +qlineargradient( + spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, + stop:0 {shadow}, + stop:0.1 {start}, + stop:0.9 {end}, + stop:1 {shadow} +); + """ + + def general_styles(tm: ThemeManager, buf: str) -> str: buf += f""" QFrame {{ @@ -45,37 +67,56 @@ def button_styles(tm: ThemeManager, buf: str) -> str: QPushButton, QTabBar::tab:!selected, QComboBox:!editable {{ - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_GRADIENT_END)} - ); - + background: { + button_gradient( + tm.var(colors.BUTTON_GRADIENT_START), + tm.var(colors.BUTTON_GRADIENT_END) + ) + }; }} QPushButton:hover, QTabBar::tab:hover, QComboBox:!editable:hover {{ - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1.25, - stop:0 {tm.var(colors.BUTTON_HOVER_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_HOVER_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_HOVER_GRADIENT_START), + tm.var(colors.BUTTON_HOVER_GRADIENT_END) + ) + }; }} QPushButton:pressed, QComboBox:!editable:pressed {{ border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)}; - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_PRESSED_SHADOW)}, - stop:0.1 {tm.var(colors.BUTTON_GRADIENT_START)}, - stop:0.9 {tm.var(colors.BUTTON_GRADIENT_END)}, - stop:1 {tm.var(colors.BUTTON_PRESSED_SHADOW)}, - ); + background: { + button_pressed_gradient( + tm.var(colors.BUTTON_GRADIENT_START), + tm.var(colors.BUTTON_GRADIENT_END), + tm.var(colors.BUTTON_PRESSED_SHADOW) + ) + }; }} """ return buf +def splitter_styles(tm: ThemeManager, buf: str) -> str: + buf += """ +QSplitter::handle, +QMainWindow::separator { + height: 16px; +} +QSplitter::handle:vertical, +QMainWindow::separator:horizontal { + image: url(icons:drag-horizontal.svg); +} +QSplitter::handle:horizontal, +QMainWindow::separator:vertical { + image: url(icons:drag-vertical.svg); +} +""" + return buf + + def combobox_styles(tm: ThemeManager, buf: str) -> str: buf += f""" QComboBox {{ @@ -118,18 +159,20 @@ QComboBox::down-arrow {{ image: url(icons:chevron-down.svg); }} QComboBox::drop-down {{ - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_PRIMARY_GRADIENT_START), + tm.var(colors.BUTTON_PRIMARY_GRADIENT_END) + ) + }; }} QComboBox::drop-down:hover {{ - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1.25, - stop:0 {tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_START), + tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_END) + ) + }; }} """ return buf @@ -145,7 +188,7 @@ QTabWidget::pane {{ top: -15px; padding-top: 1em; background: {tm.var(colors.CANVAS_ELEVATED)}; - border: 1px solid {tm.var(colors.BORDER_SUBTLE)}; + border: 1px solid {tm.var(colors.BORDER)}; border-radius: {tm.var(props.BORDER_RADIUS)}; }} QTabWidget::tab-bar {{ @@ -157,7 +200,7 @@ QTabBar::tab {{ min-width: 8ex; }} QTabBar::tab {{ - border: 1px solid {tm.var(colors.BORDER_SUBTLE)}; + border: 1px solid {tm.var(colors.BORDER)}; }} QTabBar::tab:first {{ border-top-left-radius: {tm.var(props.BORDER_RADIUS)}; @@ -172,11 +215,12 @@ QTabBar::tab:last {{ }} QTabBar::tab:selected {{ color: white; - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_PRIMARY_GRADIENT_START), + tm.var(colors.BUTTON_PRIMARY_GRADIENT_END) + ) + }; }} """ return buf @@ -185,43 +229,43 @@ QTabBar::tab:selected {{ def table_styles(tm: ThemeManager, buf: str) -> str: buf += f""" QTableView {{ - background: none; - top: 2px; - border-left: 1px solid {tm.var(colors.BORDER_SUBTLE)}; border-radius: {tm.var(props.BORDER_RADIUS)}; - gridline-color: {tm.var(colors.BORDER_SUBTLE)}; + gridline-color: {tm.var(colors.BORDER)}; + selection-background-color: {tm.var(colors.SELECTION_BG)}; + selection-color: {tm.var(colors.SELECTION_FG)}; }} QHeaderView {{ background: {tm.var(colors.CANVAS)}; }} QHeaderView::section {{ border: 1px solid {tm.var(colors.BORDER_SUBTLE)}; - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_GRADIENT_START), + tm.var(colors.BUTTON_GRADIENT_END) + ) + }; }} -QHeaderView::section:pressed {{ +QHeaderView::section:pressed, +QHeaderView::section:pressed:!first {{ border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)}; - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_PRESSED_SHADOW)}, - stop:0.1 {tm.var(colors.BUTTON_GRADIENT_START)}, - stop:0.9 {tm.var(colors.BUTTON_GRADIENT_END)}, - stop:1 {tm.var(colors.BUTTON_PRESSED_SHADOW)}, - ); + background: { + button_pressed_gradient( + tm.var(colors.BUTTON_GRADIENT_START), + tm.var(colors.BUTTON_GRADIENT_END), + tm.var(colors.BUTTON_PRESSED_SHADOW) + ) + } }} QHeaderView::section:hover {{ - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1.25, - stop:0 {tm.var(colors.BUTTON_HOVER_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_HOVER_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_HOVER_GRADIENT_START), + tm.var(colors.BUTTON_HOVER_GRADIENT_END) + ) + }; }} QHeaderView::section:first {{ - margin-left: -1px; - border-top: 1px solid {tm.var(colors.BORDER_SUBTLE)}; border-left: 1px solid {tm.var(colors.BORDER_SUBTLE)}; border-top-left-radius: {tm.var(props.BORDER_RADIUS)}; }} @@ -229,20 +273,12 @@ QHeaderView::section:!first {{ border-left: none; }} QHeaderView::section:last {{ - border-top: 1px solid {tm.var(colors.BORDER_SUBTLE)}; border-right: 1px solid {tm.var(colors.BORDER_SUBTLE)}; border-top-right-radius: {tm.var(props.BORDER_RADIUS)}; }} -QHeaderView::section:next-selected {{ - border-right: none; -}} -QHeaderView::section:previous-selected {{ - border-left: none; -}} QHeaderView::section:only-one {{ border-left: 1px solid {tm.var(colors.BORDER_SUBTLE)}; - border-top: 1px solid {tm.var(colors.BORDER_SUBTLE)}; - border-right: 1px solid {tm.var(colors.CANVAS)}; + border-right: 1px solid {tm.var(colors.BORDER_SUBTLE)}; border-top-left-radius: {tm.var(props.BORDER_RADIUS)}; border-top-right-radius: {tm.var(props.BORDER_RADIUS)}; }} @@ -268,30 +304,32 @@ QSpinBox::down-button {{ subcontrol-origin: border; width: 16px; border: 1px solid {tm.var(colors.BUTTON_BORDER)}; - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_PRIMARY_GRADIENT_START), + tm.var(colors.BUTTON_PRIMARY_GRADIENT_END) + ) + }; }} QSpinBox::up-button:pressed, QSpinBox::down-button:pressed {{ border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)}; - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 {tm.var(colors.BUTTON_PRESSED_SHADOW)}, - stop:0.1 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_START)}, - stop:0.9 {tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)}, - stop:1 {tm.var(colors.BUTTON_PRESSED_SHADOW)}, - ); + background: { + button_pressed_gradient( + tm.var(colors.BUTTON_PRIMARY_GRADIENT_START), + tm.var(colors.BUTTON_PRIMARY_GRADIENT_END), + tm.var(colors.BUTTON_PRESSED_SHADOW) + ) + } }} QSpinBox::up-button:hover, QSpinBox::down-button:hover {{ - background: qlineargradient( - spread:pad, x1:0.5, y1:0, x2:0.5, y2:1.25, - stop:0 {tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_START)}, - stop:1 {tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_END)} - ); + background: { + button_gradient( + tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_START), + tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_END) + ) + }; }} QSpinBox::up-button {{ margin-bottom: -1px; @@ -338,7 +376,8 @@ QAbstractScrollArea::corner {{ border: none; }} QScrollBar {{ - background-color: {tm.var(colors.CANVAS)}; + subcontrol-origin: content; + background-color: transparent; }} QScrollBar::handle {{ border-radius: {tm.var(props.BORDER_RADIUS)}; @@ -354,13 +393,13 @@ QScrollBar:horizontal {{ height: 12px; }} QScrollBar::handle:horizontal {{ - min-width: 50px; + min-width: 60px; }} QScrollBar:vertical {{ width: 12px; }} QScrollBar::handle:vertical {{ - min-height: 50px; + min-height: 60px; }} QScrollBar::add-line {{ border: none; diff --git a/qt/aqt/theme.py b/qt/aqt/theme.py index 713ffee72..c2e83b546 100644 --- a/qt/aqt/theme.py +++ b/qt/aqt/theme.py @@ -186,7 +186,9 @@ class ThemeManager: gui_hooks.theme_did_change() def _apply_style(self, app: QApplication) -> None: - buf = "" + from aqt.stylesheets import splitter_styles + + buf = splitter_styles(self, "") if not is_mac: from aqt.stylesheets import ( diff --git a/sass/_vars.scss b/sass/_vars.scss index 982a70cd5..0cd59a402 100644 --- a/sass/_vars.scss +++ b/sass/_vars.scss @@ -60,8 +60,8 @@ $vars: ( ), border: ( default: ( - light: palette(lightgray, 7), - dark: palette(darkgray, 7), + light: palette(lightgray, 6), + dark: palette(darkgray, 6), ), subtle: ( light: palette(lightgray, 5), @@ -108,7 +108,7 @@ $vars: ( dark: palette(darkgray, 2), ), end: ( - light: palette(lightgray, 3), + light: palette(lightgray, 4), dark: palette(darkgray, 3), ), ), @@ -149,15 +149,15 @@ $vars: ( scrollbar: ( bg: ( default: ( - light: palette(lightgray, 6), + light: palette(lightgray, 5), dark: palette(darkgray, 4), ), hover: ( - light: palette(lightgray, 7), + light: palette(lightgray, 6), dark: palette(darkgray, 3), ), active: ( - light: palette(lightgray, 8), + light: palette(lightgray, 7), dark: palette(darkgray, 1), ), ), @@ -263,6 +263,16 @@ $vars: ( dark: white, ), ), + selection: ( + bg: ( + light: color.scale(palette(lightgray, 5), $alpha: -50%), + dark: color.scale(palette(blue, 3), $alpha: -50%), + ), + fg: ( + light: black, + dark: white, + ), + ), ), );