From a266985795927128a1d812ccca1e759afb7e3d13 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Mon, 28 Dec 2020 22:59:41 -0500 Subject: [PATCH 01/46] Make headless napari usable without qt (#2039) * move resources to qt folder * tests working * move init to proper spot * fix tests * broaden include * absolute import * make window file * rename _qt.resources to _qt.qt_resources * user ViewerModel instead of test_viewer to test plugins * move window module --- napari/_qt/qt_resources/styles/02_custom.qss | 591 +++++++++++++++++++ 1 file changed, 591 insertions(+) create mode 100644 napari/_qt/qt_resources/styles/02_custom.qss diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss new file mode 100644 index 0000000..e70cbfd --- /dev/null +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -0,0 +1,591 @@ +QLabel#h1 { + font-size: 28px; +} + +QLabel#h2 { + font-size: 22px; + color: {{ secondary }}; +} + +QLabel#h3 { + font-size: 18px; + color: {{ secondary }}; +} + +QtViewer { + padding-top: 0px; +} + +QtLayerButtons, QtViewerButtons, QtLayerList { + min-width: 242px; + max-width: 242px; +} + +/* ------------- QMainWindow --------- */ +/* QDockWidgets will use the MainWindow styles +as long as they are docked (though they use the +style of QDockWidget when undocked) */ + + +QMainWindow::separator { + background: {{ foreground }}; + width: 2px; /* when vertical */ + height: 2px; /* when horizontal */ +} + +QMainWindow::separator:hover { + background: {{ highlight }}; +} + +/* ------------- DockWidgets --------- */ + +#QtCustomTitleBar { + padding-top:3px; +} + +#QtCustomTitleBar:hover { + background-color: {{ darken(background, 10) }}; +} + +#QtCustomTitleBarLine { + background-color: {{ foreground }}; +} + +#QtCustomTitleBar > QPushButton { + background-color: none; + max-width: 12px; + max-height: 12px; +} + +#QtCustomTitleBar > QPushButton:hover { + background-color: {{ foreground }}; +} + +#QTitleBarCloseButton{ + width: 12px; + height: 12px; + padding: 0; + image: url(":/themes/{{ folder }}/delete_shape.svg"); +} + + +#QTitleBarFloatButton{ + image: url(":/themes/{{ folder }}/pop_out.svg"); + width: 10px; + height: 8px; + padding: 2 1 2 1; +} + +/* ----------------- Console ------------------ */ + +QtConsole { + min-height: 100px; +} + +QtConsole > QTextEdit { + background-color: {{ console }}; + background-clip: padding; + color: {{ text }}; + selection-background-color: {{ highlight }}; + margin: 10px; +} +.inverted { + background-color: {{ background }}; + color: {{ foreground }}; +} +.error { color: #b72121; } +.in-prompt-number { font-weight: bold; } +.out-prompt-number { font-weight: bold; } +.in-prompt { color: #6ab825; } +.out-prompt { color: #b72121; } + +/* ------------- Narrow scrollbar for qtlayer list --------- */ + +QtLayerList QScrollBar:vertical { + max-width: 8px; + margin: 12px 0px; +} + +QtLayerList QScrollBar::add-line:vertical, +QtLayerList QScrollBar::sub-line:vertical { + height: 10px; + width: 8px; +} + + +QtLayerList QScrollBar:up-arrow, +QtLayerList QScrollBar:down-arrow { + min-height: 6px; + min-width: 6px; + max-height: 6px; + max-width: 6px; +} + + +/* controls the area around the canvas */ +QSplitter { + spacing: 0px; + padding: 0px; + margin: 0px; +} + +QtDivider { + spacing: 0px; + padding: 0px; + border: 0px; + margin: 0px 3px 0px 3px; + min-width: 214px; + max-width: 214px; + min-height: 1px; + max-height: 1px; +} + +QtDivider[selected=true] { + background-color: {{ text }}; +} + +QtDivider[selected=false] { + background-color: {{ background }}; +} + + +/* --------------- QtLayerWidget -------------------- */ + +QtLayerWidget { + padding: 0px; + background-color: {{ foreground }}; + border-radius: 2px; + min-height: 32px; + max-height: 32px; + min-width: 228px; + max-width: 228px; +} + +QtLayerWidget[selected="true"] { + background-color: {{ current }}; +} + + +QtLayerWidget > QLabel { + background-color: transparent; + padding: 0px; + qproperty-alignment: AlignCenter; +} + + +/* The name of the layer*/ +QtLayerWidget > QLineEdit { + background-color: transparent; + border: none; + border-radius: 2px; + padding: 2px; + font-size: 14px; + qproperty-alignment: right; +} + +QtLayerWidget > QLineEdit:disabled { + background-color: transparent; + border-color: transparent; + border-radius: 3px; +} + +QtLayerWidget > QLineEdit:focus { + background-color: {{ darken(current, 20) }}; + selection-background-color: {{ lighten(current, 20) }}; +} + +QtLayerWidget QCheckBox::indicator { + background-color: transparent; +} + +QtLayerWidget QCheckBox::indicator:hover { + background-color: transparent; +} + +QtLayerWidget > QCheckBox#visibility { + spacing: 0px; + margin: 0px 0px 0px 4px; +} + +QtLayerWidget > QCheckBox#visibility::indicator{ + width: 18px; + height: 18px; +} + +QtLayerWidget > QCheckBox#visibility::indicator:unchecked { + image: url(":/themes/{{ folder }}/visibility_off.svg"); +} + +QtLayerWidget > QCheckBox#visibility::indicator:checked { + image: url(":/themes/{{ folder }}/visibility.svg"); +} + + +QLabel[layer_type_label="true"] { + max-width: 20px; + min-width: 20px; + min-height: 20px; + max-height: 20px; + margin-right: 4px; +} + +QLabel#Shapes { + image: url(":/themes/{{ folder }}/new_shapes.svg"); +} + +QLabel#Points { + image: url(":/themes/{{ folder }}/new_points.svg"); +} + +QLabel#Labels { + image: url(":/themes/{{ folder }}/new_labels.svg"); +} + +QLabel#Image { + image: url(":/themes/{{ folder }}/new_image.svg"); +} + +QLabel#Multiscale { + image: url(":/themes/{{ folder }}/new_image.svg"); +} + +QLabel#Surface { + image: url(":/themes/{{ folder }}/new_surface.svg"); +} + +QLabel#Vectors { + image: url(":/themes/{{ folder }}/new_vectors.svg"); +} + + +/* ------------------------------------------------------ */ + +QtLayerControlsContainer { + border-radius: 2px; + padding: 0px; + margin: 10px; + min-height: 245px; + max-height: 245px; + min-width: 240px; + max-width: 240px; + margin-left: 10px; + margin-right: 8px; + margin-bottom: 4px; +} + +QtLayerControlsContainer > QFrame { + padding: 5px; + padding-right: 8px; + border-radius: 2px; +} + +/* the box that shows the current Label color */ +QtColorBox { + padding: 0px; + border: 0px; + margin: -1px 0 0 -1px; + border-radius: 2px; + min-height: 20px; + max-height: 20px; + min-width: 20px; + max-width: 20px; +} + +/* ----------------- QtLayerControls -------------------- */ + +QtLayerControls > QLabel { + font-size: 11pt; + font-color: {{ text}}; +} + +/* ------------- DimsSliders --------- */ + +QtDimSliderWidget > QScrollBar::handle[last_used=false]:horizontal { + background: {{ highlight }}; +} + +QtDimSliderWidget > QScrollBar::handle[last_used=true]:horizontal { + background: {{ secondary }}; +} + +QtDimSliderWidget > QScrollBar:left-arrow:horizontal { + image: url(":/themes/{{ folder }}/step_left.svg"); +} + +QtDimSliderWidget > QScrollBar::right-arrow:horizontal { + image: url(":/themes/{{ folder }}/step_right.svg"); +} + +QtDimSliderWidget > QLineEdit { + background-color: {{ background }}; +} + + +#QtModalPopup { + /* required for rounded corners to not have background color */ + background: transparent; +} + +#QtPopupFrame { + border: 1px solid {{ secondary }}; + border-radius: 5px; +} + +#QtPopupFrame > QLabel { + color: {{ darken(text, 35) }}; + font-size: 12px; +} + +#playDirectionCheckBox::indicator { + image: url(":/themes/{{ folder }}/long_right_arrow.svg"); + width: 22px; + height: 22px; + padding: 0 6px; + border: 0px; +} + +#fpsSpinBox { + min-width: 60px; +} + +#playDirectionCheckBox::indicator:checked { + image: url(":/themes/{{ folder }}/long_left_arrow.svg"); +} + +#playDirectionCheckBox::indicator:pressed { + background-color: {{ highlight }}; +} + + +#colorSwatch { + border-radius: 1px; + min-height: 22px; + max-height: 22px; + min-width: 22px; + max-width: 22px; +} + +#QtColorPopup{ + background-color: transparent; +} + +#CustomColorDialog QPushButton { + padding: 4px 10px; +} + +#CustomColorDialog QLabel { + background-color: {{ background }}; + color: {{ secondary }}; +} + + +/* editable slice label and axis name */ +QtDimSliderWidget > QLineEdit { + padding: 0 0 1px 2px; + max-height: 14px; + min-height: 12px; + min-width: 16px; + color: {{ text }}; +} + +#slice_label { + font-size: 11pt; + color: {{ secondary }}; + background: transparent; +} + +#slice_label_sep{ + background-color: {{ background }}; + border: 1px solid {{ primary }}; +} + + +/* ------------ Special Dialogs ------------ */ + +QtAboutKeybindings { + min-width: 600px; + min-height: 605px; +} + +QtAbout > QTextEdit{ + margin: 0px; + border: 0px; + padding: 2px; +} + +/* ------------ Plugin Sorter ------------ */ + +ImplementationListItem { + background-color: {{ background }}; + border-radius: 2px; +} + +QtHookImplementationListWidget::item { + background: transparent; +} + +QtHookImplementationListWidget { + background-color: {{ console }}; +} + +/* for the error reporter */ +#pluginInfo { + color: text; +} + +QtPluginErrReporter > QTextEdit { + background-color: {{ console }}; + background-clip: padding; + color: {{ text }}; + selection-background-color: {{ highlight }}; + margin: 10px; +} + +/* ------------ Notifications ------------ */ + +NapariNotification > QWidget { + background: none; +} + +NapariNotification::hover{ + background: {{ lighten(background, 5) }}; +} + +MultilineElidedLabel{ + background: none; + color: {{ icon }}; + font-size: 12px; +} + +NapariNotification #expand_button { + background: none; + padding: 0px; + margin: 0px; + max-width: 20px; +} + +NapariNotification[expanded="false"] #expand_button { + image: url(":/themes/{{ folder }}/chevron_up.svg"); +} + +NapariNotification[expanded="true"] #expand_button { + image: url(":/themes/{{ folder }}/chevron_down.svg"); +} + + +NapariNotification #close_button { + background: none; + image: url(":/themes/{{ folder }}/delete_shape.svg"); + padding: 0px; + margin: 0px; + max-width: 20px; +} + +NapariNotification #source_label { + color: {{ primary }}; + font-size: 11px; +} + +NapariNotification #severity_icon { + padding: 0; + margin: 0 0 -3px 0; + min-width: 20px; + min-height: 18px; + font-size: 15px; + color: {{ icon }}; +} + + +/* ------------ Plugin Dialog ------------ */ + +QPluginList { + background: {{ console }}; +} + +PluginListItem { + background: {{ darken(foreground, 20) }}; + padding: 0; + margin: 2px 4px; + border-radius: 3px; +} + +PluginListItem > QPushButton { + background-color: {{ current }} +} + +PluginListItem > QPushButton:hover { + background-color: {{ lighten(current, 10) }} +} + +PluginListItem > QPushButton:pressed { + background-color: {{ darken(current, 10) }} +} + +PluginListItem > QPushButton#remove_button { + background-color: {{ warning }} +} + +PluginListItem > QPushButton#remove_button:hover { + background-color: {{ lighten(warning, 10) }} +} + +PluginListItem > QPushButton#remove_button:pressed { + background-color: {{ darken(warning, 10) }} +} + +#small_text { + color: {{ opacity(text, 150) }}; + font-size: 10px; +} + +#pip_install_status{ + background: {{ background }}; + color: {{ opacity(text, 200) }}; +} + +#info_icon { + image: url(":/themes/{{ folder }}/info.svg"); + min-width: 18px; + min-height: 18px; + margin: 2px; +} + +#warning_icon { + image: url(":/themes/{{ folder }}/warning.svg"); + max-width: 14px; + max-height: 14px; + min-width: 14px; + min-height: 14px; + margin: 0px; + margin-left: 1px; + padding: 2px; + background: darken(foreground, 20); +} + +#warning_icon:hover{ + background: {{ foreground }}; +} + +#warning_icon:pressed{ + background: {{ primary }}; +} + +#error_label { + image: url(":/themes/{{ folder }}/warning.svg"); + max-width: 18px; + max-height: 18px; + min-width: 18px; + min-height: 18px; + margin: 0px; + margin-left: 1px; + padding: 2px; +} + +QtPluginDialog QSplitter{ + padding-right: 2; +} + + +QtPluginSorter { + padding: 20px; +} \ No newline at end of file From bdc60e003668730fcbe842618dd64d2b22ff49c4 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Mon, 15 Feb 2021 11:42:24 -0500 Subject: [PATCH 02/46] Add `theme` parameter to `get_stylesheet` (#2263) * add theme option to get_stylesheet * add deprecation warnings * undo changes to canvas --- napari/_qt/qt_resources/styles/02_custom.qss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index e70cbfd..dae4dff 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -37,6 +37,11 @@ QMainWindow::separator:hover { background: {{ highlight }}; } +QStatusBar { + background: {{ background }}; + color: {{ text }}; +} + /* ------------- DockWidgets --------- */ #QtCustomTitleBar { From f56f860bdbbb8947f01da4962a0b0f0be01b68a2 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Tue, 23 Feb 2021 00:59:22 -0500 Subject: [PATCH 03/46] Refactor icon build process (#2285) * QColoredSVGIcon class * docstrings * add tests * add note * reorg * fix lru_cache for 3.7 * only get .svg icons * wip * typing and staticmethod * encode * remove build resources * rename some things * trim tests * improve persistence * remove __main__ * minor * move regex check * fix order * undo future annotations * fix for older pyside2 * windows version * another windows fix * custom example * refactor * restore Env var control * fix glob * docs * rename function * make a couple things private * more docs * move custom icon example * Update napari/_qt/qt_resources/_icons.py Co-authored-by: Matthias Bussonnier * Update napari/_qt/qt_resources/_icons.py Co-authored-by: Matthias Bussonnier * Update napari/_qt/qt_resources/_icons.py Co-authored-by: Matthias Bussonnier * Update napari/_qt/qt_resources/_icons.py Co-authored-by: Matthias Bussonnier Co-authored-by: Matthias Bussonnier --- napari/_qt/qt_resources/styles/02_custom.qss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index dae4dff..58879a1 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -218,7 +218,7 @@ QtLayerWidget > QCheckBox#visibility::indicator{ } QtLayerWidget > QCheckBox#visibility::indicator:unchecked { - image: url(":/themes/{{ folder }}/visibility_off.svg"); + image: url(":/themes/{{ folder }}/visibility_off_50.svg"); } QtLayerWidget > QCheckBox#visibility::indicator:checked { From 6bb18b3004c8080ce5d0dde379eaa23369d6decc Mon Sep 17 00:00:00 2001 From: kir0ul <6053592+kir0ul@users.noreply.github.com> Date: Tue, 23 Feb 2021 06:12:51 +0000 Subject: [PATCH 04/46] Contour toggle (#2168) * feat: countour toggle draft #1858 * fix: typo * feat: compute contour on the view of the data * test: changing contour * test: restore contour's previous state * fix: stylecheet issue * feat: keep labels colors in contour Co-authored-by: Nicholas Sofroniew * fix: useless calls from review comments * test: Check data_view changed after contour is set * feat: find boundaries for each labels * refactor: apply `low_discrepancy_image` Apply `low_discrepancy_image` function to get the right color for the labels * refactor: remove loop to make contour faster * fix: always refresh Co-authored-by: Nicholas Sofroniew --- napari/_qt/qt_resources/styles/02_custom.qss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 58879a1..d4d9f10 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -269,8 +269,8 @@ QtLayerControlsContainer { border-radius: 2px; padding: 0px; margin: 10px; - min-height: 245px; - max-height: 245px; + min-height: 265px; + max-height: 265px; min-width: 240px; max-width: 240px; margin-left: 10px; @@ -593,4 +593,4 @@ QtPluginDialog QSplitter{ QtPluginSorter { padding: 20px; -} \ No newline at end of file +} From 980f04ff1e5ee3a69497ad3b6a1dba81d3c09387 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 8 Mar 2021 08:07:26 -0800 Subject: [PATCH 05/46] Notification Manager (#2205) * Separate notification to not need qt. Be stricter about singleton usage, and install hooks explicitely. Also store datetime when notification is created for later usage Move notifications into utils * Update to increase coverage * remove gc debug * static show notif * Reviews 1 * Reviews 2 * Update napari/utils/notifications.py Co-authored-by: Talley Lambert * move notifications manager test outside of qt subtree * remove need for singleton * Update napari/_tests/test_notification_manager.py Co-authored-by: Juan Nunez-Iglesias * add assertions to test_notification * move test, add exit assertion * assert notification types * add NapariQtNotification tests * add lambda for 3.7 * remove old exception handler * remove line * add example to dev for testing Co-authored-by: Talley Lambert Co-authored-by: Juan Nunez-Iglesias --- napari/_qt/qt_resources/styles/02_custom.qss | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index d4d9f10..c669c6a 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -448,11 +448,11 @@ QtPluginErrReporter > QTextEdit { /* ------------ Notifications ------------ */ -NapariNotification > QWidget { +NapariQtNotification > QWidget { background: none; } -NapariNotification::hover{ +NapariQtNotification::hover{ background: {{ lighten(background, 5) }}; } @@ -462,23 +462,23 @@ MultilineElidedLabel{ font-size: 12px; } -NapariNotification #expand_button { +NapariQtNotification #expand_button { background: none; padding: 0px; margin: 0px; max-width: 20px; } -NapariNotification[expanded="false"] #expand_button { +NapariQtNotification[expanded="false"] #expand_button { image: url(":/themes/{{ folder }}/chevron_up.svg"); } -NapariNotification[expanded="true"] #expand_button { +NapariQtNotification[expanded="true"] #expand_button { image: url(":/themes/{{ folder }}/chevron_down.svg"); } -NapariNotification #close_button { +NapariQtNotification #close_button { background: none; image: url(":/themes/{{ folder }}/delete_shape.svg"); padding: 0px; @@ -486,12 +486,12 @@ NapariNotification #close_button { max-width: 20px; } -NapariNotification #source_label { +NapariQtNotification #source_label { color: {{ primary }}; font-size: 11px; } -NapariNotification #severity_icon { +NapariQtNotification #severity_icon { padding: 0; margin: 0 0 -3px 0; min-width: 20px; From 7ec0d9d1e914a658ba212a3d2906362522c94052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Tue, 9 Mar 2021 22:48:43 -0500 Subject: [PATCH 06/46] PR: Add a font size preview slider widget (#2318) * Add a size preview slider widget * Add tests * Fix precommit style --- napari/_qt/qt_resources/styles/02_custom.qss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index c669c6a..99fe854 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -594,3 +594,9 @@ QtPluginDialog QSplitter{ QtPluginSorter { padding: 20px; } + + +QtFontSizePreview { + border: 1px solid {{ foreground }}; + border-radius: 5px; +} From d72a0b4d0697d4011c960bc4946e8195ed91ee38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Tue, 23 Mar 2021 15:31:02 -0500 Subject: [PATCH 07/46] PR: Update preferences dialog style to match Designs (#2456) * Update preferences dialog style * Update manager and preferences options * Fix tests * Add localization to settings titles * Add appearance settings and update attributes on manager for IDE access * Fix conflicts and update defaults --- napari/_qt/qt_resources/styles/02_custom.qss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 99fe854..1b17765 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -600,3 +600,8 @@ QtFontSizePreview { border: 1px solid {{ foreground }}; border-radius: 5px; } + + +QListWidget#Preferences { + background: {{ background }}; +} From e41e6e88b7d7a3cd50ce7e91f7a0566fd053383c Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Fri, 26 Mar 2021 19:10:34 -0400 Subject: [PATCH 08/46] add name to dock widget titlebar (#2471) --- napari/_qt/qt_resources/styles/02_custom.qss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 1b17765..48f0517 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -66,6 +66,10 @@ QStatusBar { background-color: {{ foreground }}; } +#QtCustomTitleBar > QLabel { + color: {{ primary }}; +} + #QTitleBarCloseButton{ width: 12px; height: 12px; From 907e5efe4831dfebf0a6a2f35656ad8866f2b8fd Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Tue, 13 Apr 2021 19:53:47 -0400 Subject: [PATCH 09/46] New new qt layerlist (#2493) Co-authored-by: Juan Nunez-Iglesias Co-authored-by: Matthias Bussonnier --- napari/_qt/qt_resources/styles/02_custom.qss | 104 +++++++++++++++---- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 48f0517..13311a3 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -68,6 +68,7 @@ QStatusBar { #QtCustomTitleBar > QLabel { color: {{ primary }}; + font-size: 11pt; } #QTitleBarCloseButton{ @@ -108,28 +109,6 @@ QtConsole > QTextEdit { .in-prompt { color: #6ab825; } .out-prompt { color: #b72121; } -/* ------------- Narrow scrollbar for qtlayer list --------- */ - -QtLayerList QScrollBar:vertical { - max-width: 8px; - margin: 12px 0px; -} - -QtLayerList QScrollBar::add-line:vertical, -QtLayerList QScrollBar::sub-line:vertical { - height: 10px; - width: 8px; -} - - -QtLayerList QScrollBar:up-arrow, -QtLayerList QScrollBar:down-arrow { - min-height: 6px; - min-width: 6px; - max-height: 6px; - max-width: 6px; -} - /* controls the area around the canvas */ QSplitter { @@ -605,7 +584,86 @@ QtFontSizePreview { border-radius: 5px; } - QListWidget#Preferences { background: {{ background }}; } + + +/* ------------- Narrow scrollbar for qtlayer list --------- */ + +QtListView { + background: {{ background }}; +} + +QtListView QScrollBar:vertical { + max-width: 8px; +} + +QtListView QScrollBar::add-line:vertical, +QtListView QScrollBar::sub-line:vertical { + height: 10px; + width: 8px; + margin-top: 2px; + margin-bottom: 2px; +} + +QtListView QScrollBar:up-arrow, +QtListView QScrollBar:down-arrow { + min-height: 6px; + min-width: 6px; + max-height: 6px; + max-width: 6px; +} + +QtListView::item { + padding: 4px; + margin: 2px 2px 2px 2px; + background-color: {{ foreground }}; + border: 1px solid {{ foreground }}; +} + +QtListView::item:hover { + background-color: {{ lighten(foreground, 3) }}; +} + +/* in the QSS context "active" means the window is active */ +/* (as opposed to focused on another application) */ +QtListView::item:selected:active{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 {{ current }}, stop: 1 {{ darken(current, 15) }}); +} + + +QtListView::item:selected:!active { + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 {{ darken(current, 10) }}, stop: 1 {{ darken(current, 25) }}); +} + + +QtListView QLineEdit { + background-color: {{ darken(current, 20) }}; + selection-background-color: {{ lighten(current, 20) }}; + font-size: 12px; +} + +QtLayerList::item { + margin: 2px 2px 2px 28px; + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; + border: 0; +} + +/* the first one is the "partially checked" state */ +QtLayerList::indicator { + width: 16px; + height: 16px; + position: absolute; + left: 0px; + image: url(":/themes/{{ folder }}/visibility_off.svg"); +} + +QtLayerList::indicator:unchecked { + image: url(":/themes/{{ folder }}/2D.svg"); +} + +QtLayerList::indicator:checked { + image: url(":/themes/{{ folder }}/visibility.svg"); +} From 67751a6a43f7007e4fbcc6a507d3797bab195d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Thu, 15 Apr 2021 15:42:54 -0500 Subject: [PATCH 10/46] PR: Add initial welcome screen on canvas (#2542) * Add initial welcome screen on canvas * Use secondary color for napari logo on welcome screen and remove oll vispy welcome paths * change with theme * Hook svg image change on theme change * Fix logic for displaying welcome screen * Fix tests * Remove debug code * Fix and run tests again * trim * Fix tests * Go back to signals * Update code and remove welcome kwarg * Fix review comments * Fix canvas test and add try except for test failing on teardown * Add a skip local Co-authored-by: Talley Lambert --- napari/_qt/qt_resources/styles/02_custom.qss | 25 +++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 13311a3..1bec517 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -245,6 +245,10 @@ QLabel#Vectors { image: url(":/themes/{{ folder }}/new_vectors.svg"); } +QLabel#logo_silhouette { + image: url(":/themes/{{ folder }}/logo_silhouette.svg"); +} + /* ------------------------------------------------------ */ @@ -585,7 +589,26 @@ QtFontSizePreview { } QListWidget#Preferences { - background: {{ background }}; + background: {{ background }}; +} + + +QtWelcomeWidget, QtWelcomeWidget[drag=false] { + background: {{ canvas }}; +} + +QtWelcomeWidget[drag=true] { + background: {{ highlight }}; +} + +QtWelcomeLabel { + color: {{ foreground }}; + font-size: 20px; +} + +QtShortcutLabel { + color: {{ foreground }}; + font-size: 16px; } From 99cf30a52acda8dee2c18427bd5594df65500d41 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 13 May 2021 11:45:59 -0400 Subject: [PATCH 11/46] Fix tracks icons, and visibility icons (#2708) * add tracks icon, fix visibility icon * add test * release notes --- napari/_qt/qt_resources/styles/02_custom.qss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 1bec517..3f5eea4 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -684,7 +684,8 @@ QtLayerList::indicator { } QtLayerList::indicator:unchecked { - image: url(":/themes/{{ folder }}/2D.svg"); + image: url(":/themes/{{ folder }}/visibility_off_50.svg"); + } QtLayerList::indicator:checked { From 40bce773ec4bb5c299b9027314e3645e95100b35 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Mon, 28 Jun 2021 12:40:43 -0400 Subject: [PATCH 12/46] Use QDoubleRangeSlider from superqt package (#2752) * start replacing range slider * wip * wip * getting closer * non-blocking dialog * pretty good * more cleanup * add dep * newline * wip * bump version * fix precision * fix test * update test * fix precision * add tooltip * styles * use superqt * remove version pin * Update napari/_qt/widgets/qt_range_slider_popup.py Co-authored-by: Juan Nunez-Iglesias Co-authored-by: Juan Nunez-Iglesias --- napari/_qt/qt_resources/styles/02_custom.qss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 3f5eea4..d208c0a 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -287,9 +287,13 @@ QtColorBox { QtLayerControls > QLabel { font-size: 11pt; - font-color: {{ text}}; + color: {{ text }}; } +QLabeledRangeSlider > QAbstractSpinBox { + font-size: 12pt; + color: {{ secondary }}; +} /* ------------- DimsSliders --------- */ QtDimSliderWidget > QScrollBar::handle[last_used=false]:horizontal { From 50feb7d8444ed662dfe127ad69d72378722e1da4 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Mon, 28 Jun 2021 17:53:34 -0400 Subject: [PATCH 13/46] Use labeled sliders from superqt (#2753) * replace * styles * add dependency * bump * proper double slider * fix font size * use superqt * remove version pin --- napari/_qt/qt_resources/styles/02_custom.qss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index d208c0a..c46efa5 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -285,7 +285,7 @@ QtColorBox { /* ----------------- QtLayerControls -------------------- */ -QtLayerControls > QLabel { +QtLayerControls > QLabel, QtLayerControls > QLabeledSlider > QAbstractSpinBox { font-size: 11pt; color: {{ text }}; } From 346ac16edfa41f408399658f92bf4be20cc32b02 Mon Sep 17 00:00:00 2001 From: Pam <54282105+ppwadhwa@users.noreply.github.com> Date: Wed, 7 Jul 2021 18:52:12 -0500 Subject: [PATCH 14/46] Shortcuts UI (#2864) * add initial work for keyboard shortcuts UI in preference dialog * in progress. can change shortcut, will save in settings, will display warning * activate drop down menu to show layers shortcuts * enable reset shortcuts button * making progress * update warning icon. re-work table * handle case where you delete a shortcut and don't replace * save in settings * update shortcuts to use symbols. remove lines in table * update validations. improve the key press events * updates to keypress events * may not need section * move methods. fix error when binding shortcut * rearrange a bit * make cancel and restore work. fix bug for plugin sorter. clean up. * fix bug * clean up. add comments and docstrings * add test file * remove duplicate method * change regex * fix regex * revert interactions.py file * add fix for tests * add comments * handle invalid shortcuts more gracefully * add comments * remove commented line. update docstring --- napari/_qt/qt_resources/styles/02_custom.qss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index c46efa5..542e5c0 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -409,6 +409,14 @@ QtAbout > QTextEdit{ padding: 2px; } +/* ------------ Shortcut Editor ------------ */ + +ShortcutEditor QHeaderView::section { + padding: 2px; + border: None; +} + + /* ------------ Plugin Sorter ------------ */ ImplementationListItem { From 07bc932e57936e21c555326c4bed0c92f70c8818 Mon Sep 17 00:00:00 2001 From: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:47:46 +1000 Subject: [PATCH 15/46] Add activity dialog and style progress bars (#2656) * Add placeholder progress bar dock * Add prototype progress bar dock and code to take progress bar widgets and place them in the dock * Tidying up * Starting to implement a decorator for tqdm for use in napari * Starting to implement a decorator for tqdm for use in napari * Remove internal reference to progress * Add skeleton infrastructure for global progress bars * Implement set_total and set_value for pbar * Implement basic ProgressBar API and higher level progress API * Add convenience methods for showing, hiding and deleting progress bar * Inspect stack for initial pbar description * Add examples for different progress bars * Add some comments to example * Add description setter * Add another example * small example tweaks * Add increment and decrement methods * Update API to match tqdm more closely * Add __len__ to progress * Modify progress to inherit from tqdm * Update ProgressBar to inherit from QWidget() * Split tqdm and pbar kwargs, add ETA to pbar * Remove examples for now * Add some documentation * Add tests for progress * Update napari/layers/shapes/shapes.py Co-authored-by: Matthias Bussonnier * Update napari/_qt/utils.py Co-authored-by: Matthias Bussonnier * Add cell thresholding example * Add context manager example * Add more explanation * Change example to first threshold and then segment * Remove thresholds with very poor segmentation results * Add manual update example * Formatting * More tidy up * Add QApplication import back to notification * Import qtpy not PyQt5 * Move progress import to see if it fixes tests * isort fix * Don't close if already closed * Small tweaks * Use importorskip for qtpy Co-authored-by: Talley Lambert * Use absolute import for testing Co-authored-by: Talley Lambert * Define context manager for testing addition of ProgressBar to viewer Co-authored-by: Talley Lambert * Fix and add a few more tests * Remove erroneous break leftover from merge * add progrange shorthand for progress(range(n)) * Get etas by trimming formatted ascii bar * Remove potentially costly 'in' check * Remove method entirely since we just need this for display * Add examples and fix indeterminate progress bar etas * Basic incorporation with thread-worker * Remove crazy asterisk import * Add option to exceed total * Add a few tests for threading * Add example for progress with threading * Add beginnings of nesting logic * Add support for nesting progress bars * Add minimal nested example * Add tests for nested progress * Make basic ActivityDialog and remove ActivityDock * Add progress bars to activity dialog * Pull out move_to_bottom_right from notifications and use to move activity_dialog * Add progress bars to scrollable area * Add title bar styling for activity dock * Add hover to activity button * Layout bars in grid to align * Reverting nesting logic * Tweak examples to always use a context manager * Set total to 0 when it's None, update example * Clean up segmentation example * Move ProgressBar to qt widgets * Move qt import into __init__ to avoid failing when running in headless * Fix activityDock layout * Fix adding pbar to layout * Use QMainWindow.current instead of get_viewer_instance * Add nesting back in after merge * Fix styling after merge * Revert blank line change to clean up diff * Remove stack inspection for setting description * Switch context var to ID of pbar widget * Store ref to parent pbar group in contextvar for easy retrieval * Tidy up if statement, add docstring for progrange * Add tqdm dependency * Remove tqdm from release dependencies * Move progress to _qt * Fix import after move to _qt * Set canvas parent to activity dock parent * Revert changes to notifications * Fix moving to canvas offset * Add opacity effect * Add separator for ProgressBarGroups * Moveprogress into qprogress * Replace progress with qprogress, fix import in threading * Fix test after adding separator to nested groups * Fix pyqt import * Add option to pass progress bar description * Add test for description * If no total is passed, make pbar indeterminate * Fix insertion index for nested progress bars * Translate error * Fix import order * Fix tests * Mostly fix notifications always on top * Add progress indicator when activity dialog has something in it * Make indicator work with multiple progress bars * Add test for indicator * Change widget attributes to private and follow qt naming convention * Fix activity dock toggle to behave correctly when toggled programmatically * Add height to activity dialog to fit 3 progress bars before scroll * Add closed signal to ProgressBarGroups and connect hiding progress indicator * Add names to example dock widgets * Add activity dock to view menu * Try to narrow down test failures - comment out indicator * Don't emit closed signals * Don't connect * Emit but don't connect * Connect simple function that hides indicator * Add check before hide * Add check before hide * Try starting and stopping movie on show and hide * Don't start movie before necessary * Add test and visibility logic back in * Remove commented out line * Add missing docstrings for custom widgets * Remove closed signal and connect to pbar destroyed instead * Set icon size to smaller, remove commented out line * Update napari/_qt/dialogs/activity_dialog.py Co-authored-by: Juan Nunez-Iglesias * Comment out sleep calls in segmentation example * Clarify hiding progress indicator docstring * Change underscore parameter to event to be more explicit * Update napari/_qt/dialogs/activity_dialog.py Co-authored-by: Juan Nunez-Iglesias Co-authored-by: Matthias Bussonnier Co-authored-by: Talley Lambert Co-authored-by: Juan Nunez-Iglesias --- napari/_qt/qt_resources/styles/02_custom.qss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 542e5c0..f0aece1 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -499,6 +499,16 @@ NapariQtNotification #severity_icon { color: {{ icon }}; } +/* ------------ Activity Dock ------------ */ + +#QtCustomTitleLabel { + color: {{ primary }}; + font-size: 11pt; +} + +#QtActivityButton:hover { + background-color: {{ lighten(background, 10) }}; +} /* ------------ Plugin Dialog ------------ */ From afe4fb686f30dd229d639faf0495def8c942732f Mon Sep 17 00:00:00 2001 From: Kevin Yamauchi Date: Thu, 15 Jul 2021 07:07:56 +0200 Subject: [PATCH 16/46] Add isosurface rendering to Labels (#3006) * initial labels iso rendering * add subset for image and labels Rendering * update Image layer controls * add rendering combobox to labels layer controls * add rendering to Labels init * add rendering to Labels init * clean up iso_categorical shader * clarify shader comment * add rendering to _get_state * use u_threshold for backgorund * threshold -> tolerance * remove unused first arg from `detectAdjacentBackground()` * refator class method names * threshold -> tolerance * fix docstring typo Co-authored-by: alisterburt * convert background and tolerance to const * fix typo * set iso_categorical as default rendering mode * fix layer controls height * fix rendering combobox visibility Co-authored-by: Alister Burt --- napari/_qt/qt_resources/styles/02_custom.qss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index f0aece1..d2a2477 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -256,8 +256,8 @@ QtLayerControlsContainer { border-radius: 2px; padding: 0px; margin: 10px; - min-height: 265px; - max-height: 265px; + min-height: 295px; + max-height: 295px; min-width: 240px; max-width: 240px; margin-left: 10px; From fc22fa3a10343a249f4b6c29b160fa996b3723b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Tue, 20 Jul 2021 22:45:30 -0500 Subject: [PATCH 17/46] PR: Allow for multiple installs and update buttons to reflect state (#3067) * Allow for multiple installs and update buttons to reflect state * Use separate process and improve logic * Remove stray comments --- napari/_qt/qt_resources/styles/02_custom.qss | 22 +++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index d2a2477..cbcd90b 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -523,15 +523,15 @@ PluginListItem { border-radius: 3px; } -PluginListItem > QPushButton { +PluginListItem > QPushButton#install_button { background-color: {{ current }} } -PluginListItem > QPushButton:hover { +PluginListItem > QPushButton#install_button:hover { background-color: {{ lighten(current, 10) }} } -PluginListItem > QPushButton:pressed { +PluginListItem > QPushButton#install_button:pressed { background-color: {{ darken(current, 10) }} } @@ -547,6 +547,22 @@ PluginListItem > QPushButton#remove_button:pressed { background-color: {{ darken(warning, 10) }} } +PluginListItem > QPushButton#busy_button:pressed { + background-color: {{ darken(secondary, 10) }} +} + +PluginListItem > QPushButton#busy_button { + background-color: {{ secondary }} +} + +PluginListItem > QPushButton#busy_button:hover { + background-color: {{ lighten(secondary, 10) }} +} + +PluginListItem > QPushButton#busy_button:pressed { + background-color: {{ darken(secondary, 10) }} +} + #small_text { color: {{ opacity(text, 150) }}; font-size: 10px; From 4ade17e2a7244b9655a48ff42f30ad0d22bfd456 Mon Sep 17 00:00:00 2001 From: Pam <54282105+ppwadhwa@users.noreply.github.com> Date: Thu, 5 Aug 2021 17:21:40 -0500 Subject: [PATCH 18/46] Grid mode popup (#3084) * adding in initial grid pop up * make all connections between pref dialog, settings and widget. start work on help tool tips * clean up help buttons on widget * clean up. rearrange * adjustments to skip zero in pref dialog. minor edits * Update napari/_qt/widgets/qt_viewer_buttons.py Co-authored-by: Talley Lambert * Update napari/_qt/widgets/qt_viewer_buttons.py Co-authored-by: Talley Lambert * Update napari/_qt/widgets/qt_viewer_buttons.py Co-authored-by: Talley Lambert * Update napari/_qt/widgets/qt_viewer_buttons.py Co-authored-by: Talley Lambert * update qt spinbox to skip value * update grid options in model * add validation method * add validation method * fixes. connect change in settings to viewer to make pop up changes * edit tooltip * suggestions * remove hardcode from grid pop up * match gridCanvas to settings types * take out updates to grid settings * move update to viewer after settings change into viewer_model.py * rearrange grid settings * rearrange defaults, imports * change import * remove file Co-authored-by: Talley Lambert --- napari/_qt/qt_resources/styles/02_custom.qss | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index cbcd90b..43bdbaa 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -611,6 +611,17 @@ PluginListItem > QPushButton#busy_button:pressed { padding: 2px; } +#help_label { + image: url(":/themes/{{ folder }}/help.svg"); + max-width: 18px; + max-height: 18px; + min-width: 18px; + min-height: 18px; + margin: 0px; + margin-left: 1px; + padding: 2px; +} + QtPluginDialog QSplitter{ padding-right: 2; } From bafe7de04096820b0dfd97282cfdc36dc0842ba8 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Sat, 14 Aug 2021 13:23:54 -0400 Subject: [PATCH 19/46] Add autoscale modes to image layer model, and buttons to GUI (#3022) * add autoscale to gui * autoscale on check * add mode to surface * make private * remove line * remove slice/data buttons --- napari/_qt/qt_resources/styles/02_custom.qss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 43bdbaa..2f9eb89 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -294,6 +294,12 @@ QLabeledRangeSlider > QAbstractSpinBox { font-size: 12pt; color: {{ secondary }}; } + +AutoScaleButtons QPushButton { + font-size: 9pt; + padding: 4; +} + /* ------------- DimsSliders --------- */ QtDimSliderWidget > QScrollBar::handle[last_used=false]:horizontal { From 86598d5f824b60a2597101e71bc60ced8265ce88 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Tue, 17 Aug 2021 15:24:29 -0400 Subject: [PATCH 20/46] Use QElidingLabel from superqt (#3188) --- napari/_qt/qt_resources/styles/02_custom.qss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 2f9eb89..31e1891 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -461,11 +461,6 @@ NapariQtNotification::hover{ background: {{ lighten(background, 5) }}; } -MultilineElidedLabel{ - background: none; - color: {{ icon }}; - font-size: 12px; -} NapariQtNotification #expand_button { background: none; From 89720f1eebbbc0b1b4c1363d1741d8701f6b396b Mon Sep 17 00:00:00 2001 From: Lukasz Migas Date: Fri, 27 Aug 2021 22:40:48 +0200 Subject: [PATCH 21/46] Add `napari_experimental_provide_theme` hook specification (#3034) * Add hook specification to add new themes, icons and stylesheets - added new hook specification to allow addition of new themes, icons and stylesheets to napari - minor improvements to how qt resources are loaded * Update docstrings - updated docstrings * WIP: added evented dict container, split hook spec into three hooks - split the hook implementation into three separate hooks (qss, icons and theme) - added new container class: `EventedDict` and `TypedMutableMapping` so we can migrate themes to an evented class - refactored how theme plugin data is read * Theme dict is now evented, immediate updates to stylesheet - theme dict is now an evented model - changes to any theme data will result in immediate update of the stylesheet - minor bug fix to the evented dict not propagating child events * Themes now reflect state of plugin, preferences shows all available themes - themes are now dynamically updated whenever a plugin is enabled/disabled/removed - theme dropdown is now updated whenever new theme is added/removed - plugin manager now displays more useful information if theme data failed validation * Icon colors can be changed dynamically - fixed issue in settings tests (the test should have always failed since it was passing wrong data to the `register_theme` function) - found a workaround for dynamically updating icon colors without causing crash... * Tidy up - removed unused code * [WIP] Add pydantic-based Theme, refactor theme - added pydantic-based Theme class with better validation of values - modified the way `get_theme` is retrieved. Currently it will trigger warnings whenever somebody calls it which might not be desired - removed the `palettes` warning from utils/theme.py since it was meant to be removed in 0.4.6 * Update qt_main_window.py - existing themes will now be properly connected at startup * Added theme tests, theme improvements - removed custom Themes model since its not necessary - added a couple extra tests to handle new theme model (wip) - improved docs regarding new theme hooks * Temporarily remove evented dict * Minor improvements - changes to canvas/console and syntax style will now immediately update the ui - minor changes to Theme model * Disabled warning * Update vispy_canvas.py * Minor bug fixes Fixes to `UserWarning` warnings when transforming color to 0-1 scale * Remove icons/stylesheet hooks - temporarily remove stylesheet/icon hooks - rename `napari_experimenta_provide_theme` to `napari_provide_theme` hook spec - auto-format few pesky files * Tidy up - remove unused files - minor bug fixes and typos * Update docs * Disconnect event - explicitly disconnect the theme event in `qt_about_key_bindings` dialog * Update test_qt_about_key_bindings.py * Tidied up, removed unnecessary methods, simplified behaviour - Add examples to the hook specification - Removed unnecessary methods - Added console `style_syntax` validation method - Changed `napari_provide_theme` signature - Added more tests * Bring up to date * Improved testing and theme validation - the `_theme_data` dict on plugin manager now stores the `Theme` object - improved theme validation - improved tests * Changed qt resources hash calculation - changed the way qt resources hash is computed - fixed potential future bug where the `os.path` could be overwritten by variable named `path` * Added more tests, few bug fixes and general improvements - renamed `folder` to `name` in the Theme model - renamed `folder` to `name` in the stylesheet templates - disabled memory hungry test - added more tests for the plugin hookspec behaviour - removed unnecessary methods from the MainWindow - removed unused code - added docs * Brought up to date with master * Added more tests - removed unused method - added more tests * Fixed tests * Bug fix? * Undo auto-formatting * Undo auto-formatting * Renamed hook spec, fixed warning, removed example - removed the `theme_plugin` example implementation - one can be found in the docs - renamed `napari_provide_theme` to `napari_experimental_provide_theme` - added catch warning to prevent qtconsole warnings at the start * Bring up to date * Fix failed test * Temporarily disable few tests... * Disable more tests * Undo disable tests * Bring up to date * Update qt_main_window.py * Uncomment all tests * Update 02_custom.qss * Update qt_main_window.py --- napari/_qt/qt_resources/styles/02_custom.qss | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 31e1891..9e3c338 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -75,12 +75,12 @@ QStatusBar { width: 12px; height: 12px; padding: 0; - image: url(":/themes/{{ folder }}/delete_shape.svg"); + image: url(":/themes/{{ name }}/delete_shape.svg"); } #QTitleBarFloatButton{ - image: url(":/themes/{{ folder }}/pop_out.svg"); + image: url(":/themes/{{ name }}/pop_out.svg"); width: 10px; height: 8px; padding: 2 1 2 1; @@ -201,11 +201,11 @@ QtLayerWidget > QCheckBox#visibility::indicator{ } QtLayerWidget > QCheckBox#visibility::indicator:unchecked { - image: url(":/themes/{{ folder }}/visibility_off_50.svg"); + image: url(":/themes/{{ name }}/visibility_off_50.svg"); } QtLayerWidget > QCheckBox#visibility::indicator:checked { - image: url(":/themes/{{ folder }}/visibility.svg"); + image: url(":/themes/{{ name }}/visibility.svg"); } @@ -218,35 +218,35 @@ QLabel[layer_type_label="true"] { } QLabel#Shapes { - image: url(":/themes/{{ folder }}/new_shapes.svg"); + image: url(":/themes/{{ name }}/new_shapes.svg"); } QLabel#Points { - image: url(":/themes/{{ folder }}/new_points.svg"); + image: url(":/themes/{{ name }}/new_points.svg"); } QLabel#Labels { - image: url(":/themes/{{ folder }}/new_labels.svg"); + image: url(":/themes/{{ name }}/new_labels.svg"); } QLabel#Image { - image: url(":/themes/{{ folder }}/new_image.svg"); + image: url(":/themes/{{ name }}/new_image.svg"); } QLabel#Multiscale { - image: url(":/themes/{{ folder }}/new_image.svg"); + image: url(":/themes/{{ name }}/new_image.svg"); } QLabel#Surface { - image: url(":/themes/{{ folder }}/new_surface.svg"); + image: url(":/themes/{{ name }}/new_surface.svg"); } QLabel#Vectors { - image: url(":/themes/{{ folder }}/new_vectors.svg"); + image: url(":/themes/{{ name }}/new_vectors.svg"); } QLabel#logo_silhouette { - image: url(":/themes/{{ folder }}/logo_silhouette.svg"); + image: url(":/themes/{{ name }}/logo_silhouette.svg"); } @@ -311,11 +311,11 @@ QtDimSliderWidget > QScrollBar::handle[last_used=true]:horizontal { } QtDimSliderWidget > QScrollBar:left-arrow:horizontal { - image: url(":/themes/{{ folder }}/step_left.svg"); + image: url(":/themes/{{ name }}/step_left.svg"); } QtDimSliderWidget > QScrollBar::right-arrow:horizontal { - image: url(":/themes/{{ folder }}/step_right.svg"); + image: url(":/themes/{{ name }}/step_right.svg"); } QtDimSliderWidget > QLineEdit { @@ -339,7 +339,7 @@ QtDimSliderWidget > QLineEdit { } #playDirectionCheckBox::indicator { - image: url(":/themes/{{ folder }}/long_right_arrow.svg"); + image: url(":/themes/{{ name }}/long_right_arrow.svg"); width: 22px; height: 22px; padding: 0 6px; @@ -351,7 +351,7 @@ QtDimSliderWidget > QLineEdit { } #playDirectionCheckBox::indicator:checked { - image: url(":/themes/{{ folder }}/long_left_arrow.svg"); + image: url(":/themes/{{ name }}/long_left_arrow.svg"); } #playDirectionCheckBox::indicator:pressed { @@ -470,17 +470,17 @@ NapariQtNotification #expand_button { } NapariQtNotification[expanded="false"] #expand_button { - image: url(":/themes/{{ folder }}/chevron_up.svg"); + image: url(":/themes/{{ name }}/chevron_up.svg"); } NapariQtNotification[expanded="true"] #expand_button { - image: url(":/themes/{{ folder }}/chevron_down.svg"); + image: url(":/themes/{{ name }}/chevron_down.svg"); } NapariQtNotification #close_button { background: none; - image: url(":/themes/{{ folder }}/delete_shape.svg"); + image: url(":/themes/{{ name }}/delete_shape.svg"); padding: 0px; margin: 0px; max-width: 20px; @@ -575,14 +575,14 @@ PluginListItem > QPushButton#busy_button:pressed { } #info_icon { - image: url(":/themes/{{ folder }}/info.svg"); + image: url(":/themes/{{ name }}/info.svg"); min-width: 18px; min-height: 18px; margin: 2px; } #warning_icon { - image: url(":/themes/{{ folder }}/warning.svg"); + image: url(":/themes/{{ name }}/warning.svg"); max-width: 14px; max-height: 14px; min-width: 14px; @@ -602,7 +602,7 @@ PluginListItem > QPushButton#busy_button:pressed { } #error_label { - image: url(":/themes/{{ folder }}/warning.svg"); + image: url(":/themes/{{ name }}/warning.svg"); max-width: 18px; max-height: 18px; min-width: 18px; @@ -613,7 +613,7 @@ PluginListItem > QPushButton#busy_button:pressed { } #help_label { - image: url(":/themes/{{ folder }}/help.svg"); + image: url(":/themes/{{ name }}/help.svg"); max-width: 18px; max-height: 18px; min-width: 18px; @@ -730,14 +730,14 @@ QtLayerList::indicator { height: 16px; position: absolute; left: 0px; - image: url(":/themes/{{ folder }}/visibility_off.svg"); + image: url(":/themes/{{ name }}/visibility_off.svg"); } QtLayerList::indicator:unchecked { - image: url(":/themes/{{ folder }}/visibility_off_50.svg"); + image: url(":/themes/{{ name }}/visibility_off_50.svg"); } QtLayerList::indicator:checked { - image: url(":/themes/{{ folder }}/visibility.svg"); + image: url(":/themes/{{ name }}/visibility.svg"); } From 3b7d15dbc16dc95b476238e4d69cdc12537ef3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Sun, 12 Sep 2021 11:49:54 -0500 Subject: [PATCH 22/46] Add cancel and cancel all actions to plugin dialog and improve UI (#3369) * Add cancel option to install dialog actions * Update plugin dialog interactions and ability to cancel processes * Update update logic * Add typing information --- napari/_qt/qt_resources/styles/02_custom.qss | 31 +++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 9e3c338..2b4b562 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -524,51 +524,62 @@ PluginListItem { border-radius: 3px; } -PluginListItem > QPushButton#install_button { +QPushButton#install_button { background-color: {{ current }} } -PluginListItem > QPushButton#install_button:hover { +QPushButton#install_button:hover { background-color: {{ lighten(current, 10) }} } -PluginListItem > QPushButton#install_button:pressed { +QPushButton#install_button:pressed { background-color: {{ darken(current, 10) }} } -PluginListItem > QPushButton#remove_button { +QPushButton#remove_button { background-color: {{ warning }} } -PluginListItem > QPushButton#remove_button:hover { +QPushButton#remove_button:hover { background-color: {{ lighten(warning, 10) }} } -PluginListItem > QPushButton#remove_button:pressed { +QPushButton#remove_button:pressed { background-color: {{ darken(warning, 10) }} } -PluginListItem > QPushButton#busy_button:pressed { +QPushButton#busy_button:pressed { background-color: {{ darken(secondary, 10) }} } -PluginListItem > QPushButton#busy_button { +QPushButton#busy_button { background-color: {{ secondary }} } -PluginListItem > QPushButton#busy_button:hover { +QPushButton#busy_button:hover { background-color: {{ lighten(secondary, 10) }} } -PluginListItem > QPushButton#busy_button:pressed { +QPushButton#busy_button:pressed { background-color: {{ darken(secondary, 10) }} } +QPushButton#close_button:disabled { + background-color: {{ lighten(secondary, 10) }} +} + + #small_text { color: {{ opacity(text, 150) }}; font-size: 10px; } +#small_italic_text { + color: {{ opacity(text, 150) }}; + font-size: 12px; + font-style: italic; +} + #pip_install_status{ background: {{ background }}; color: {{ opacity(text, 200) }}; From 88dab5738406f23699575fddd790aecdd4f53c2d Mon Sep 17 00:00:00 2001 From: Pam <54282105+ppwadhwa@users.noreply.github.com> Date: Mon, 27 Sep 2021 22:01:59 -0500 Subject: [PATCH 23/46] Hide or Destroy dock widgets (#3331) * add new toolbar button * backtrack part way to make fix for window menu * only have hide option for non-plugin dock widgets. send signals appropriately to update check box on menus * revert qt_viewer changes * more fixes * clean up * add comment * updates * fix test * update toggle * add test * remove duplicated code * minor update --- napari/_qt/qt_resources/styles/02_custom.qss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 2b4b562..d52d36b 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -86,6 +86,13 @@ QStatusBar { padding: 2 1 2 1; } +#QTitleBarHideButton{ + image: url(":/themes/{{ name }}/visibility_off.svg"); + width: 10px; + height: 8px; + padding: 2 1 2 1; +} + /* ----------------- Console ------------------ */ QtConsole { From 595499d1d6977b6ecc920ff7462344d97be05d16 Mon Sep 17 00:00:00 2001 From: Pam <54282105+ppwadhwa@users.noreply.github.com> Date: Mon, 6 Dec 2021 19:20:16 -0600 Subject: [PATCH 24/46] Add npe2 plugins to plugins installed list (#3694) * add npe2 plugins to plugins installed list on the plugins dialog * only add plugin to list if meta data exists * create iter_manifest function * disable checkbox for npe2 * update qss to darken checkbox when disabled * adjust opacity of widget * add pop up for install/uninstall * fix --- napari/_qt/qt_resources/styles/02_custom.qss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index d52d36b..e22866e 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -531,6 +531,13 @@ PluginListItem { border-radius: 3px; } + +PluginListItem QCheckBox::indicator:disabled { + background-color: {{ opacity(foreground, 127) }}; + image: url(":/themes/{{ name }}/check_50.svg"); +} + + QPushButton#install_button { background-color: {{ current }} } From 8d0d516da02ea28fa1190115f713089358518d6e Mon Sep 17 00:00:00 2001 From: alisterburt Date: Wed, 2 Mar 2022 22:34:36 +0000 Subject: [PATCH 25/46] volume plane interactive controls (#3759) Co-authored-by: Alister Burt Co-authored-by: Juan Nunez-Iglesias Co-authored-by: Lorenzo Gaifas Co-authored-by: Kevin Yamauchi --- napari/_qt/qt_resources/styles/02_custom.qss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index e22866e..60bc8cb 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -292,7 +292,7 @@ QtColorBox { /* ----------------- QtLayerControls -------------------- */ -QtLayerControls > QLabel, QtLayerControls > QLabeledSlider > QAbstractSpinBox { +QtLayerControls > QLabel, QtLayerControls, QtPlaneControls > QLabeledSlider > QAbstractSpinBox { font-size: 11pt; color: {{ text }}; } @@ -307,6 +307,10 @@ AutoScaleButtons QPushButton { padding: 4; } +PlaneNormalButtons QPushButton { + font-size: 9pt; + padding: 4; +} /* ------------- DimsSliders --------- */ QtDimSliderWidget > QScrollBar::handle[last_used=false]:horizontal { From ef05f54823b228afa3ce8dff0499ba8af0049ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Mon, 7 Mar 2022 14:39:13 -0500 Subject: [PATCH 26/46] Use napari hub api to list plugins (#4074) * USe napari hub api to list plugins * Fix typing error * Fix typing * Use package metadata model from np2 * Adding plugin api options * Fix issue with extension to reader * Update plugin visibility based on hub/pypi and conda usage * Replace standard_metadata * Hide plugin api option on bundles * Fix install/uninstall with conda/mamba * Remove py37 support on import of matadata Co-authored-by: Talley Lambert * Fix type hints * Run precommits and update warning message * Fix typing errors * Update warning message Co-authored-by: Talley Lambert --- napari/_qt/qt_resources/styles/02_custom.qss | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 60bc8cb..41ff59f 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -535,13 +535,18 @@ PluginListItem { border-radius: 3px; } +PluginListItem#unavailable { + background: {{ lighten(foreground, 20) }}; + padding: 0; + margin: 2px 4px; + border-radius: 3px; +} PluginListItem QCheckBox::indicator:disabled { background-color: {{ opacity(foreground, 127) }}; image: url(":/themes/{{ name }}/check_50.svg"); } - QPushButton#install_button { background-color: {{ current }} } @@ -554,6 +559,10 @@ QPushButton#install_button:pressed { background-color: {{ darken(current, 10) }} } +QPushButton#install_button:disabled { + background-color: {{ lighten(current, 20) }} +} + QPushButton#remove_button { background-color: {{ warning }} } @@ -652,6 +661,7 @@ QPushButton#close_button:disabled { padding: 2px; } + QtPluginDialog QSplitter{ padding-right: 2; } From 765b5641ca5ff9616841375cfb4b15903da39e7c Mon Sep 17 00:00:00 2001 From: Lorenzo Gaifas Date: Mon, 25 Apr 2022 13:25:02 +0200 Subject: [PATCH 27/46] Allow resizing left dock widgets (#4368) * remove size constraint to allow resizing of builtin dock widgets * prettier separators * better svgs * fix dock size --- napari/_qt/qt_resources/styles/02_custom.qss | 29 ++++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 41ff59f..7b0e7c0 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -18,7 +18,6 @@ QtViewer { QtLayerButtons, QtViewerButtons, QtLayerList { min-width: 242px; - max-width: 242px; } /* ------------- QMainWindow --------- */ @@ -26,20 +25,30 @@ QtLayerButtons, QtViewerButtons, QtLayerList { as long as they are docked (though they use the style of QDockWidget when undocked) */ +QStatusBar { + background: {{ background }}; + color: {{ text }}; +} + +/* ------------- Window separator --------- */ QMainWindow::separator { - background: {{ foreground }}; - width: 2px; /* when vertical */ - height: 2px; /* when horizontal */ + width: 4px; + height: 4px; + border: none; + background: transparent; } QMainWindow::separator:hover { - background: {{ highlight }}; + background: {{ foreground }}; } -QStatusBar { - background: {{ background }}; - color: {{ text }}; +QMainWindow::separator:horizontal { + image: url(":/themes/{{ name }}/horizontal_separator.svg"); +} + +QMainWindow::separator:vertical { + image: url(":/themes/{{ name }}/vertical_separator.svg"); } /* ------------- DockWidgets --------- */ @@ -130,7 +139,6 @@ QtDivider { border: 0px; margin: 0px 3px 0px 3px; min-width: 214px; - max-width: 214px; min-height: 1px; max-height: 1px; } @@ -153,7 +161,6 @@ QtLayerWidget { min-height: 32px; max-height: 32px; min-width: 228px; - max-width: 228px; } QtLayerWidget[selected="true"] { @@ -264,9 +271,7 @@ QtLayerControlsContainer { padding: 0px; margin: 10px; min-height: 295px; - max-height: 295px; min-width: 240px; - max-width: 240px; margin-left: 10px; margin-right: 8px; margin-bottom: 4px; From 28252b2c314f7c8a1c64a614e1f7b1d4e8a07810 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Mon, 18 Jul 2022 15:01:13 -0400 Subject: [PATCH 28/46] support PyQt6, remove logic for `compile_qt_svgs` (#3707) * no longer compile resources * more fixes * misc other updates * use qtpy main * block signal when changing * undo qtpy change * remove print * update qss * more styles fixes * update gitignore * fix overload * fix image reshape for pyside6 * fix more tests in _qt * fix pos() * fix examples tests * remove icons altogether * fix headless * fix menus and globalPosition * fix pyside6 * fix last pyqt6 test * Update napari/__main__.py Co-authored-by: Grzegorz Bokota * unskip console tests on qt6 * Update napari/_qt/qt_main_window.py Co-authored-by: Andy Sweet * Update napari/resources/_icons.py Co-authored-by: Andy Sweet * comments and fixes * go back to bool * add comment * add back fix for point in scrollbar Co-authored-by: Grzegorz Bokota Co-authored-by: Andy Sweet --- napari/_qt/qt_resources/styles/02_custom.qss | 63 ++++++++++---------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 7b0e7c0..6842899 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -36,7 +36,7 @@ QMainWindow::separator { width: 4px; height: 4px; border: none; - background: transparent; + background-color: {{ background }}; } QMainWindow::separator:hover { @@ -44,17 +44,18 @@ QMainWindow::separator:hover { } QMainWindow::separator:horizontal { - image: url(":/themes/{{ name }}/horizontal_separator.svg"); + image: url("theme_{{ name }}:/horizontal_separator.svg"); } QMainWindow::separator:vertical { - image: url(":/themes/{{ name }}/vertical_separator.svg"); + image: url("theme_{{ name }}:/vertical_separator.svg"); } /* ------------- DockWidgets --------- */ #QtCustomTitleBar { padding-top:3px; + background-color: {{ background }}; } #QtCustomTitleBar:hover { @@ -84,19 +85,19 @@ QMainWindow::separator:vertical { width: 12px; height: 12px; padding: 0; - image: url(":/themes/{{ name }}/delete_shape.svg"); + image: url("theme_{{ name }}:/delete_shape.svg"); } #QTitleBarFloatButton{ - image: url(":/themes/{{ name }}/pop_out.svg"); + image: url("theme_{{ name }}:/pop_out.svg"); width: 10px; height: 8px; padding: 2 1 2 1; } #QTitleBarHideButton{ - image: url(":/themes/{{ name }}/visibility_off.svg"); + image: url("theme_{{ name }}:/visibility_off.svg"); width: 10px; height: 8px; padding: 2 1 2 1; @@ -215,11 +216,11 @@ QtLayerWidget > QCheckBox#visibility::indicator{ } QtLayerWidget > QCheckBox#visibility::indicator:unchecked { - image: url(":/themes/{{ name }}/visibility_off_50.svg"); + image: url("theme_{{ name }}:/visibility_off_50.svg"); } QtLayerWidget > QCheckBox#visibility::indicator:checked { - image: url(":/themes/{{ name }}/visibility.svg"); + image: url("theme_{{ name }}:/visibility.svg"); } @@ -232,35 +233,35 @@ QLabel[layer_type_label="true"] { } QLabel#Shapes { - image: url(":/themes/{{ name }}/new_shapes.svg"); + image: url("theme_{{ name }}:/new_shapes.svg"); } QLabel#Points { - image: url(":/themes/{{ name }}/new_points.svg"); + image: url("theme_{{ name }}:/new_points.svg"); } QLabel#Labels { - image: url(":/themes/{{ name }}/new_labels.svg"); + image: url("theme_{{ name }}:/new_labels.svg"); } QLabel#Image { - image: url(":/themes/{{ name }}/new_image.svg"); + image: url("theme_{{ name }}:/new_image.svg"); } QLabel#Multiscale { - image: url(":/themes/{{ name }}/new_image.svg"); + image: url("theme_{{ name }}:/new_image.svg"); } QLabel#Surface { - image: url(":/themes/{{ name }}/new_surface.svg"); + image: url("theme_{{ name }}:/new_surface.svg"); } QLabel#Vectors { - image: url(":/themes/{{ name }}/new_vectors.svg"); + image: url("theme_{{ name }}:/new_vectors.svg"); } QLabel#logo_silhouette { - image: url(":/themes/{{ name }}/logo_silhouette.svg"); + image: url("theme_{{ name }}:/logo_silhouette.svg"); } @@ -327,11 +328,11 @@ QtDimSliderWidget > QScrollBar::handle[last_used=true]:horizontal { } QtDimSliderWidget > QScrollBar:left-arrow:horizontal { - image: url(":/themes/{{ name }}/step_left.svg"); + image: url("theme_{{ name }}:/step_left.svg"); } QtDimSliderWidget > QScrollBar::right-arrow:horizontal { - image: url(":/themes/{{ name }}/step_right.svg"); + image: url("theme_{{ name }}:/step_right.svg"); } QtDimSliderWidget > QLineEdit { @@ -355,7 +356,7 @@ QtDimSliderWidget > QLineEdit { } #playDirectionCheckBox::indicator { - image: url(":/themes/{{ name }}/long_right_arrow.svg"); + image: url("theme_{{ name }}:/long_right_arrow.svg"); width: 22px; height: 22px; padding: 0 6px; @@ -367,7 +368,7 @@ QtDimSliderWidget > QLineEdit { } #playDirectionCheckBox::indicator:checked { - image: url(":/themes/{{ name }}/long_left_arrow.svg"); + image: url("theme_{{ name }}:/long_left_arrow.svg"); } #playDirectionCheckBox::indicator:pressed { @@ -486,17 +487,17 @@ NapariQtNotification #expand_button { } NapariQtNotification[expanded="false"] #expand_button { - image: url(":/themes/{{ name }}/chevron_up.svg"); + image: url("theme_{{ name }}:/chevron_up.svg"); } NapariQtNotification[expanded="true"] #expand_button { - image: url(":/themes/{{ name }}/chevron_down.svg"); + image: url("theme_{{ name }}:/chevron_down.svg"); } NapariQtNotification #close_button { background: none; - image: url(":/themes/{{ name }}/delete_shape.svg"); + image: url("theme_{{ name }}:/delete_shape.svg"); padding: 0px; margin: 0px; max-width: 20px; @@ -549,7 +550,7 @@ PluginListItem#unavailable { PluginListItem QCheckBox::indicator:disabled { background-color: {{ opacity(foreground, 127) }}; - image: url(":/themes/{{ name }}/check_50.svg"); + image: url("theme_{{ name }}:/check_50.svg"); } QPushButton#install_button { @@ -618,14 +619,14 @@ QPushButton#close_button:disabled { } #info_icon { - image: url(":/themes/{{ name }}/info.svg"); + image: url("theme_{{ name }}:/info.svg"); min-width: 18px; min-height: 18px; margin: 2px; } #warning_icon { - image: url(":/themes/{{ name }}/warning.svg"); + image: url("theme_{{ name }}:/warning.svg"); max-width: 14px; max-height: 14px; min-width: 14px; @@ -645,7 +646,7 @@ QPushButton#close_button:disabled { } #error_label { - image: url(":/themes/{{ name }}/warning.svg"); + image: url("theme_{{ name }}:/warning.svg"); max-width: 18px; max-height: 18px; min-width: 18px; @@ -656,7 +657,7 @@ QPushButton#close_button:disabled { } #help_label { - image: url(":/themes/{{ name }}/help.svg"); + image: url("theme_{{ name }}:/help.svg"); max-width: 18px; max-height: 18px; min-width: 18px; @@ -774,14 +775,14 @@ QtLayerList::indicator { height: 16px; position: absolute; left: 0px; - image: url(":/themes/{{ name }}/visibility_off.svg"); + image: url("theme_{{ name }}:/visibility_off.svg"); } QtLayerList::indicator:unchecked { - image: url(":/themes/{{ name }}/visibility_off_50.svg"); + image: url("theme_{{ name }}:/visibility_off_50.svg"); } QtLayerList::indicator:checked { - image: url(":/themes/{{ name }}/visibility.svg"); + image: url("theme_{{ name }}:/visibility.svg"); } From bf922ad26765ea9173a9519d3f9cc84b6d6ed275 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Mon, 1 Aug 2022 13:49:26 +0200 Subject: [PATCH 29/46] Confirmation on close, alternative approach (#4820) * confirm on close vol2 * add confirmation on close by alt+f4 or close button * add tests * fix tests --- napari/_qt/qt_resources/styles/02_custom.qss | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 6842899..5580314 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -786,3 +786,20 @@ QtLayerList::indicator:unchecked { QtLayerList::indicator:checked { image: url("theme_{{ name }}:/visibility.svg"); } + + +#warning_icon_btn { + qproperty-icon: url(":/themes/{{ name }}/warning.svg"); +} + +#warning_icon_element { + image: url(":/themes/{{ name }}/warning.svg"); + min-height: 36px; + min-width: 36px; +} + +#error_icon_element { + image: url(":/themes/{{ name }}/error.svg"); + min-height: 36px; + min-width: 36px; +} \ No newline at end of file From 7301eada1a84217f32ba34d53a40e7e25a91efe4 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Mon, 1 Aug 2022 08:44:04 -0400 Subject: [PATCH 30/46] fix icon urls (#4887) --- napari/_qt/qt_resources/styles/02_custom.qss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 5580314..c9ca0dd 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -789,17 +789,17 @@ QtLayerList::indicator:checked { #warning_icon_btn { - qproperty-icon: url(":/themes/{{ name }}/warning.svg"); + qproperty-icon: url("theme_{{ name }}:/warning.svg"); } #warning_icon_element { - image: url(":/themes/{{ name }}/warning.svg"); + image: url("theme_{{ name }}:/warning.svg"); min-height: 36px; min-width: 36px; } #error_icon_element { - image: url(":/themes/{{ name }}/error.svg"); + image: url("theme_{{ name }}:/error.svg"); min-height: 36px; min-width: 36px; } \ No newline at end of file From 7926c81656bfc64bad7c4ec8e975da7929a1d455 Mon Sep 17 00:00:00 2001 From: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:47:34 +0200 Subject: [PATCH 31/46] Feature: Minimum blending (#4875) * Add `minimum` blending mode * Add `minimum` blending mode * Add simple test, as other blending modes * Ensure transl_no_depth has a blend_eq (vispy#2324) * Hide opacity slider for minimum blending mode * Update napari/_qt/layer_controls/qt_layer_controls_base.py Co-authored-by: Grzegorz Bokota * Update napari/_qt/layer_controls/qt_layer_controls_base.py Co-authored-by: Grzegorz Bokota * Add test for show/hide opacitySlider * Update all doc strings * tooltip + layer.help for min blending * add `minimum` blending example * update layers guide * Update napari/_vispy/utils/gl.py * Disable and dim the opacity slider * Fix tests for disable rather than hide * Disable by matching color to right side of slider * Dim SliderLabel text to be similar to the slider * use QLabel for opacity and dim it * Use self.opacityLabel for all layers * end the example with a new line Co-authored-by: Grzegorz Bokota * Add inverse colormaps from ChrisLUT * Ignore case when sorting * Add INVERSE_LUT to __init__ * naming: lut to cmap * clarify comment re: opacity slider * fix typo in I Purple * Use added cmaps in the example Co-authored-by: Grzegorz Bokota Co-authored-by: alisterburt --- napari/_qt/qt_resources/styles/02_custom.qss | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index c9ca0dd..8eb52c8 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -308,6 +308,22 @@ QLabeledRangeSlider > QAbstractSpinBox { color: {{ secondary }}; } +QWidget[emphasized="true"] QDoubleSlider::sub-page:horizontal:disabled { + background: {{ primary }}; +} + +QWidget[emphasized="true"] QDoubleSlider::handle:disabled { + background: {{ primary }}; +} + +QWidget[emphasized="true"] SliderLabel:disabled { + color: {{ opacity(text, 50) }}; +} + +QWidget[emphasized="true"] QLabel:disabled { + color: {{ opacity(text, 50) }}; +} + AutoScaleButtons QPushButton { font-size: 9pt; padding: 4; From 8d95ce94312a9c5630a215fb0c2ddd8a1117fe27 Mon Sep 17 00:00:00 2001 From: Lorenzo Gaifas Date: Mon, 19 Dec 2022 12:03:47 +0100 Subject: [PATCH 32/46] fix theme id not being used correctly (#5412) --- napari/_qt/qt_resources/styles/02_custom.qss | 68 ++++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 8eb52c8..c95a0b9 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -44,11 +44,11 @@ QMainWindow::separator:hover { } QMainWindow::separator:horizontal { - image: url("theme_{{ name }}:/horizontal_separator.svg"); + image: url("theme_{{ id }}:/horizontal_separator.svg"); } QMainWindow::separator:vertical { - image: url("theme_{{ name }}:/vertical_separator.svg"); + image: url("theme_{{ id }}:/vertical_separator.svg"); } /* ------------- DockWidgets --------- */ @@ -85,19 +85,19 @@ QMainWindow::separator:vertical { width: 12px; height: 12px; padding: 0; - image: url("theme_{{ name }}:/delete_shape.svg"); + image: url("theme_{{ id }}:/delete_shape.svg"); } #QTitleBarFloatButton{ - image: url("theme_{{ name }}:/pop_out.svg"); + image: url("theme_{{ id }}:/pop_out.svg"); width: 10px; height: 8px; padding: 2 1 2 1; } #QTitleBarHideButton{ - image: url("theme_{{ name }}:/visibility_off.svg"); + image: url("theme_{{ id }}:/visibility_off.svg"); width: 10px; height: 8px; padding: 2 1 2 1; @@ -216,11 +216,11 @@ QtLayerWidget > QCheckBox#visibility::indicator{ } QtLayerWidget > QCheckBox#visibility::indicator:unchecked { - image: url("theme_{{ name }}:/visibility_off_50.svg"); + image: url("theme_{{ id }}:/visibility_off_50.svg"); } QtLayerWidget > QCheckBox#visibility::indicator:checked { - image: url("theme_{{ name }}:/visibility.svg"); + image: url("theme_{{ id }}:/visibility.svg"); } @@ -233,35 +233,35 @@ QLabel[layer_type_label="true"] { } QLabel#Shapes { - image: url("theme_{{ name }}:/new_shapes.svg"); + image: url("theme_{{ id }}:/new_shapes.svg"); } QLabel#Points { - image: url("theme_{{ name }}:/new_points.svg"); + image: url("theme_{{ id }}:/new_points.svg"); } QLabel#Labels { - image: url("theme_{{ name }}:/new_labels.svg"); + image: url("theme_{{ id }}:/new_labels.svg"); } QLabel#Image { - image: url("theme_{{ name }}:/new_image.svg"); + image: url("theme_{{ id }}:/new_image.svg"); } QLabel#Multiscale { - image: url("theme_{{ name }}:/new_image.svg"); + image: url("theme_{{ id }}:/new_image.svg"); } QLabel#Surface { - image: url("theme_{{ name }}:/new_surface.svg"); + image: url("theme_{{ id }}:/new_surface.svg"); } QLabel#Vectors { - image: url("theme_{{ name }}:/new_vectors.svg"); + image: url("theme_{{ id }}:/new_vectors.svg"); } QLabel#logo_silhouette { - image: url("theme_{{ name }}:/logo_silhouette.svg"); + image: url("theme_{{ id }}:/logo_silhouette.svg"); } @@ -344,11 +344,11 @@ QtDimSliderWidget > QScrollBar::handle[last_used=true]:horizontal { } QtDimSliderWidget > QScrollBar:left-arrow:horizontal { - image: url("theme_{{ name }}:/step_left.svg"); + image: url("theme_{{ id }}:/step_left.svg"); } QtDimSliderWidget > QScrollBar::right-arrow:horizontal { - image: url("theme_{{ name }}:/step_right.svg"); + image: url("theme_{{ id }}:/step_right.svg"); } QtDimSliderWidget > QLineEdit { @@ -372,7 +372,7 @@ QtDimSliderWidget > QLineEdit { } #playDirectionCheckBox::indicator { - image: url("theme_{{ name }}:/long_right_arrow.svg"); + image: url("theme_{{ id }}:/long_right_arrow.svg"); width: 22px; height: 22px; padding: 0 6px; @@ -384,7 +384,7 @@ QtDimSliderWidget > QLineEdit { } #playDirectionCheckBox::indicator:checked { - image: url("theme_{{ name }}:/long_left_arrow.svg"); + image: url("theme_{{ id }}:/long_left_arrow.svg"); } #playDirectionCheckBox::indicator:pressed { @@ -503,17 +503,17 @@ NapariQtNotification #expand_button { } NapariQtNotification[expanded="false"] #expand_button { - image: url("theme_{{ name }}:/chevron_up.svg"); + image: url("theme_{{ id }}:/chevron_up.svg"); } NapariQtNotification[expanded="true"] #expand_button { - image: url("theme_{{ name }}:/chevron_down.svg"); + image: url("theme_{{ id }}:/chevron_down.svg"); } NapariQtNotification #close_button { background: none; - image: url("theme_{{ name }}:/delete_shape.svg"); + image: url("theme_{{ id }}:/delete_shape.svg"); padding: 0px; margin: 0px; max-width: 20px; @@ -566,7 +566,7 @@ PluginListItem#unavailable { PluginListItem QCheckBox::indicator:disabled { background-color: {{ opacity(foreground, 127) }}; - image: url("theme_{{ name }}:/check_50.svg"); + image: url("theme_{{ id }}:/check_50.svg"); } QPushButton#install_button { @@ -635,14 +635,14 @@ QPushButton#close_button:disabled { } #info_icon { - image: url("theme_{{ name }}:/info.svg"); + image: url("theme_{{ id }}:/info.svg"); min-width: 18px; min-height: 18px; margin: 2px; } #warning_icon { - image: url("theme_{{ name }}:/warning.svg"); + image: url("theme_{{ id }}:/warning.svg"); max-width: 14px; max-height: 14px; min-width: 14px; @@ -662,7 +662,7 @@ QPushButton#close_button:disabled { } #error_label { - image: url("theme_{{ name }}:/warning.svg"); + image: url("theme_{{ id }}:/warning.svg"); max-width: 18px; max-height: 18px; min-width: 18px; @@ -673,7 +673,7 @@ QPushButton#close_button:disabled { } #help_label { - image: url("theme_{{ name }}:/help.svg"); + image: url("theme_{{ id }}:/help.svg"); max-width: 18px; max-height: 18px; min-width: 18px; @@ -791,31 +791,31 @@ QtLayerList::indicator { height: 16px; position: absolute; left: 0px; - image: url("theme_{{ name }}:/visibility_off.svg"); + image: url("theme_{{ id }}:/visibility_off.svg"); } QtLayerList::indicator:unchecked { - image: url("theme_{{ name }}:/visibility_off_50.svg"); + image: url("theme_{{ id }}:/visibility_off_50.svg"); } QtLayerList::indicator:checked { - image: url("theme_{{ name }}:/visibility.svg"); + image: url("theme_{{ id }}:/visibility.svg"); } #warning_icon_btn { - qproperty-icon: url("theme_{{ name }}:/warning.svg"); + qproperty-icon: url("theme_{{ id }}:/warning.svg"); } #warning_icon_element { - image: url("theme_{{ name }}:/warning.svg"); + image: url("theme_{{ id }}:/warning.svg"); min-height: 36px; min-width: 36px; } #error_icon_element { - image: url("theme_{{ name }}:/error.svg"); + image: url("theme_{{ id }}:/error.svg"); min-height: 36px; min-width: 36px; -} \ No newline at end of file +} From 879315e181dc7bbc876ccd6750d54a386032af1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Althviz=20Mor=C3=A9?= Date: Thu, 22 Dec 2022 17:40:43 -0500 Subject: [PATCH 33/46] Add parent when creating layer context menu to inherit application theme and add style entry for disabled widgets and menus (#5381) * Add parent when creating layer context menu to inherit application theme * Remove opacity for disabled widgets background color style * Set border-color for disabled widgets to background * Set selection-background-color to transparent for disabled widgets * Swap border-color and background-color for disabled widgets style * Apply suggestions from code review Style for menu separators and padding Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com> * Move QModelMenu styles to 02_custom styles Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com> --- napari/_qt/qt_resources/styles/02_custom.qss | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index c95a0b9..7b8c797 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -819,3 +819,18 @@ QtLayerList::indicator:checked { min-height: 36px; min-width: 36px; } + +/* --------------- Menus (application and context menus) ---------------- */ + +QModelMenu::separator { + height: 1 px; + background: {{ opacity(text, 90) }}; + margin-left: 17 px; + margin-right: 6 px; + margin-top: 5 px; + margin-bottom: 3 px; +} + +QModelMenu { + padding: 6 px; +} From ca8d739c440c9b485d39b88cec7ed601eed78808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Fri, 23 Dec 2022 00:59:07 +0100 Subject: [PATCH 34/46] Clarify package installer interface with abstract base class, and Pip/Conda subclasses (continued) (#5124) The UI now takes a Queue of InstallerTasks, which can be either conda or pip based commands. Right now the UI still chooses one of the two for all actions depending on whether we are running from a conda bundle or not, but in a future iteration this should depend on which action button triggered the task. This makes an Abstract interface that the package installers in the qt plugin dialog need to implement, then refactors out all the if/then conditionals of the old Installer class into two pip/conda subclasses. Also adds (new) tests for both cases. Co-authored-by: aganders3 Co-authored-by: Grzegorz Bokota Co-authored-by: Talley Lambert Co-authored-by: Matthias Bussonnier Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- napari/_qt/qt_resources/styles/02_custom.qss | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 7b8c797..890a28b 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -629,7 +629,7 @@ QPushButton#close_button:disabled { font-style: italic; } -#pip_install_status{ +#plugin_manager_process_status{ background: {{ background }}; color: {{ opacity(text, 200) }}; } @@ -672,6 +672,17 @@ QPushButton#close_button:disabled { padding: 2px; } +#success_label { + image: url("theme_{{ name }}:/check.svg"); + max-width: 18px; + max-height: 18px; + min-width: 18px; + min-height: 18px; + margin: 0px; + margin-left: 1px; + padding: 2px; +} + #help_label { image: url("theme_{{ id }}:/help.svg"); max-width: 18px; From 9bb2abf738b66ceae6f7d473977c102ee0863478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Althviz=20Mor=C3=A9?= Date: Thu, 5 Jan 2023 12:28:32 -0500 Subject: [PATCH 35/46] Fix theme id reference to get image for 'success_label' style (#5447) --- napari/_qt/qt_resources/styles/02_custom.qss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 890a28b..71554af 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -673,7 +673,7 @@ QPushButton#close_button:disabled { } #success_label { - image: url("theme_{{ name }}:/check.svg"); + image: url("theme_{{ id }}:/check.svg"); max-width: 18px; max-height: 18px; min-width: 18px; From 892fe3c0dc84229d5e7628b57c051af1fd20a0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Althviz=20Mor=C3=A9?= Date: Sun, 8 Jan 2023 09:10:02 -0500 Subject: [PATCH 36/46] Add error color to themes and change application close/exit dialogs (#5442) --- napari/_qt/qt_resources/styles/02_custom.qss | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 71554af..6edbea7 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -586,15 +586,15 @@ QPushButton#install_button:disabled { } QPushButton#remove_button { - background-color: {{ warning }} + background-color: {{ error }} } QPushButton#remove_button:hover { - background-color: {{ lighten(warning, 10) }} + background-color: {{ lighten(error, 10) }} } QPushButton#remove_button:pressed { - background-color: {{ darken(warning, 10) }} + background-color: {{ darken(error, 10) }} } QPushButton#busy_button:pressed { @@ -815,6 +815,10 @@ QtLayerList::indicator:checked { } +#error_icon_btn { + qproperty-icon: url("theme_{{ id }}:/error.svg"); +} + #warning_icon_btn { qproperty-icon: url("theme_{{ id }}:/warning.svg"); } From 87723810e188cc374c1869232864401d730c1352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Althviz=20Mor=C3=A9?= Date: Wed, 11 Jan 2023 11:52:35 -0500 Subject: [PATCH 37/46] Apply disabled widgets style only for menus. Set menus styles for QModelMenu and QMenu (#5446) --- napari/_qt/qt_resources/styles/02_custom.qss | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 6edbea7..d6e7c60 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -837,7 +837,7 @@ QtLayerList::indicator:checked { /* --------------- Menus (application and context menus) ---------------- */ -QModelMenu::separator { +QMenu::separator, QModelMenu::separator { height: 1 px; background: {{ opacity(text, 90) }}; margin-left: 17 px; @@ -846,6 +846,14 @@ QModelMenu::separator { margin-bottom: 3 px; } -QModelMenu { +QMenu:disabled, QModelMenu:disabled { + background-color: {{ background }}; + selection-background-color: transparent; + border: 1px solid; + border-color: {{ foreground }}; + color: {{ opacity(text, 90) }}; +} + +QMenu, QModelMenu { padding: 6 px; } From 2661ba4f86cd493bbb08adb90ae6ab8c97507fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Althviz=20Mor=C3=A9?= Date: Mon, 23 Jan 2023 05:52:07 -0500 Subject: [PATCH 38/46] Allow layers control section to resize to contents (#5474) Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com> closes https://github.com/napari/napari/issues/2337 closes https://github.com/napari/napari/issues/5472 --- napari/_qt/qt_resources/styles/02_custom.qss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index d6e7c60..6d2dd30 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -267,12 +267,15 @@ QLabel#logo_silhouette { /* ------------------------------------------------------ */ +QFrame#empty_controls_widget { + min-height: 225px; + min-width: 240px; +} + QtLayerControlsContainer { border-radius: 2px; padding: 0px; margin: 10px; - min-height: 295px; - min-width: 240px; margin-left: 10px; margin-right: 8px; margin-bottom: 4px; From 431fe6cfe175efd7870218d03f821b4ea0fb2496 Mon Sep 17 00:00:00 2001 From: Pam <54282105+ppwadhwa@users.noreply.github.com> Date: Fri, 10 Mar 2023 07:04:20 -0600 Subject: [PATCH 39/46] Update plugin dialog design & functionality to add conda install (#5198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes the plugin dialog to match the design discussed in #4952 Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com> Co-authored-by: Gonzalo Pena-Castellanos Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Grzegorz Bokota Co-authored-by: Daniel Althviz Moré Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com> --- napari/_qt/qt_resources/styles/02_custom.qss | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 6d2dd30..ab1477d 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -549,6 +549,50 @@ NapariQtNotification #severity_icon { /* ------------ Plugin Dialog ------------ */ +QCollapsible#install_info_button { + background-color: {{ darken(foreground, 20) }}; + color: {{ darken(text, 15) }}; +} +QWidget#info_widget { + background-color: {{ darken(foreground, 20) }}; + margin: 0px; + padding: 0px; + font: 11px; +} + +QLabel#author_text { + color: {{ darken(text, 35) }}; +} + +QPushButton#install_choice { + background-color: {{ current }}; + color: {{ darken(text, 35) }}; +} + +QPushButton#plugin_name_web { + background-color: {{ darken(foreground, 20) }}; +} + +QPushButton#plugin_name_web:hover { + background-color: {{ foreground }} +} + +QPushButton#plugin_name { + background-color: {{ darken(foreground, 20) }}; +} +QPushButton#plugin_name:hover { + background-color: {{ darken(foreground, 20) }}; +} + + +QWidget#install_choice_widget { + background-color: {{ darken(foreground, 20) }}; + color: {{ darken(text, 35) }}; + margin: 0px; + padding: 0px; + font: 11px; +} + QPluginList { background: {{ console }}; } From 2160e92371ede0d16c0bc06acd41b20ce8ee5ac6 Mon Sep 17 00:00:00 2001 From: Lukasz Migas Date: Tue, 1 Aug 2023 03:01:12 +0100 Subject: [PATCH 40/46] Add `font-size` to theme (#5607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Fixes/Closes Closes #1417 # Description This PR adds a new `font_size` attribute to the theme which is injected sporadically throughout the stylesheets. A fix for an issue on Windows (perhaps other OSs too?) that have multiple high-res screens connected (and use PySide2 as the backend) was done initially here but was moved to its own PR. See PR #5968 Before: - text in the app is way too small to use ![image](https://user-images.githubusercontent.com/25161821/223431336-1358824b-ef92-4a4c-998b-6438535533e4.png) After: - text is of expected size and can be changed by changing the `.font_size` attribute of the current theme ![image](https://user-images.githubusercontent.com/25161821/223431591-7c6cedf2-3e1d-48dd-bb69-f433e0f1b4f1.png) ## Type of change - [x] New feature (non-breaking change which adds functionality) # How has this been tested? - [x] all tests pass with my change - [x] I check if my changes works with both PySide and PyQt backends as there are small differences between the two Qt bindings. Co-authored-by: Daniel Althviz Moré Co-authored-by: Matthias Bussonnier Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- napari/_qt/qt_resources/styles/02_custom.qss | 35 ++++++++++---------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index ab1477d..84a7e00 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -78,7 +78,7 @@ QMainWindow::separator:vertical { #QtCustomTitleBar > QLabel { color: {{ primary }}; - font-size: 11pt; + font-size: {{ decrease(font_size, 1) }}; } #QTitleBarCloseButton{ @@ -115,6 +115,7 @@ QtConsole > QTextEdit { color: {{ text }}; selection-background-color: {{ highlight }}; margin: 10px; + font-family: Menlo, Consolas, "Ubuntu Mono", "Roboto Mono", "DejaVu Sans Mono", monospace; } .inverted { background-color: {{ background }}; @@ -182,7 +183,7 @@ QtLayerWidget > QLineEdit { border: none; border-radius: 2px; padding: 2px; - font-size: 14px; + font-size: {{ increase(font_size, 2) }}; qproperty-alignment: right; } @@ -301,13 +302,13 @@ QtColorBox { /* ----------------- QtLayerControls -------------------- */ -QtLayerControls > QLabel, QtLayerControls, QtPlaneControls > QLabeledSlider > QAbstractSpinBox { - font-size: 11pt; +QtLayerControls > QComboBox, QtLayerControls > QLabel, QtLayerControls, QtPlaneControls > QLabeledSlider > QAbstractSpinBox { + font-size: {{ decrease(font_size, 1) }}; color: {{ text }}; } QLabeledRangeSlider > QAbstractSpinBox { - font-size: 12pt; + font-size: {{ font_size }}; color: {{ secondary }}; } @@ -328,12 +329,12 @@ QWidget[emphasized="true"] QLabel:disabled { } AutoScaleButtons QPushButton { - font-size: 9pt; + font-size: {{ decrease(font_size, 3) }}; padding: 4; } PlaneNormalButtons QPushButton { - font-size: 9pt; + font-size: {{ decrease(font_size, 3) }}; padding: 4; } /* ------------- DimsSliders --------- */ @@ -371,7 +372,7 @@ QtDimSliderWidget > QLineEdit { #QtPopupFrame > QLabel { color: {{ darken(text, 35) }}; - font-size: 12px; + font-size: {{ font_size }}; } #playDirectionCheckBox::indicator { @@ -427,7 +428,7 @@ QtDimSliderWidget > QLineEdit { } #slice_label { - font-size: 11pt; + font-size: {{ decrease(font_size, 1) }}; color: {{ secondary }}; background: transparent; } @@ -524,7 +525,7 @@ NapariQtNotification #close_button { NapariQtNotification #source_label { color: {{ primary }}; - font-size: 11px; + font-size: {{ decrease(font_size, 1) }}; } NapariQtNotification #severity_icon { @@ -532,7 +533,7 @@ NapariQtNotification #severity_icon { margin: 0 0 -3px 0; min-width: 20px; min-height: 18px; - font-size: 15px; + font-size: {{ increase(font_size, 3) }}; color: {{ icon }}; } @@ -540,7 +541,7 @@ NapariQtNotification #severity_icon { #QtCustomTitleLabel { color: {{ primary }}; - font-size: 11pt; + font-size: {{ decrease(font_size, 1) }}; } #QtActivityButton:hover { @@ -667,12 +668,12 @@ QPushButton#close_button:disabled { #small_text { color: {{ opacity(text, 150) }}; - font-size: 10px; + font-size: {{ decrease(font_size, 2) }}; } #small_italic_text { color: {{ opacity(text, 150) }}; - font-size: 12px; + font-size: {{ font_size }}; font-style: italic; } @@ -772,12 +773,12 @@ QtWelcomeWidget[drag=true] { QtWelcomeLabel { color: {{ foreground }}; - font-size: 20px; + font-size: {{ increase(font_size, 8) }}; } QtShortcutLabel { color: {{ foreground }}; - font-size: 16px; + font-size: {{ increase(font_size, 4) }}; } @@ -833,7 +834,7 @@ QtListView::item:selected:!active { QtListView QLineEdit { background-color: {{ darken(current, 20) }}; selection-background-color: {{ lighten(current, 20) }}; - font-size: 12px; + font-size: {{ font_size }}; } QtLayerList::item { From 748d0249e2fc229b7675ea20eec1de25bf4b5beb Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Sun, 8 Oct 2023 21:39:30 +0200 Subject: [PATCH 41/46] Add pre-commit check for basic formattings bugs (#6315) This PR add few checks from https://github.com/pre-commit/pre-commit-hooks repository to catch basing errors. --- napari/_qt/qt_resources/styles/02_custom.qss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index 84a7e00..a17e51e 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -25,7 +25,7 @@ QtLayerButtons, QtViewerButtons, QtLayerList { as long as they are docked (though they use the style of QDockWidget when undocked) */ -QStatusBar { +QStatusBar { background: {{ background }}; color: {{ text }}; } @@ -855,7 +855,7 @@ QtLayerList::indicator { QtLayerList::indicator:unchecked { image: url("theme_{{ id }}:/visibility_off_50.svg"); - + } QtLayerList::indicator:checked { From e8330ded32f80cceb3d178d657267445ec904e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Nauroth-Kre=C3=9F?= Date: Mon, 1 Apr 2024 17:45:18 +0200 Subject: [PATCH 42/46] Lock dimensions / axes while rolling (#5986) # Description The ability to roll through dimensions is a useful functionality in `napari`. However, in many use cases, it is desirable to only roll through or reorder the spatial dimensions. Particularly when dealing with time-resolved data, the time dimension should remain fixed most of the time. Currently, achieving this requires manually reordering the dimensions, which can be a tedious process. ## Original Behaviour In the current version, all dimensions are in the reorder dimensions pop-up window are draggable, and users can freely reorder or roll through them. ## New Behaviour The dimensions in the reorder dimensions pop-up window have a lock symbol in front of there name. If clicked the lock closes and the item is no longer draggable. When rolling these dimensions will stay in place while the other dimensions are rolled. [lock_dimensions_demo](https://github.com/napari/napari/assets/56394171/8caeff74-b437-45bf-9ee2-c2967c0372f5) # References - vscode - https://doc.qt.io/qt.html#qtforpython - https://github.com/napari/docs ## Type of change - [x] New feature (non-breaking change which adds functionality) - [x] Enhancement (non-breaking improvements of an existing feature) - [x] Documentation (update of docstrings and deprecation information) - [x] This change requires a documentation update # How has this been tested? - added tests for all newly introduced / modified functions and classes - added test for new functionality of `QtDimsSorter` - reworked old tests of `QtDimsSorter` to match new structure ## Final checklist: - [x] My PR is the minimum possible work for the desired functionality - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] I have added tests that prove my fix is effective or that my feature works - [x] If I included new strings, I have used `trans.` to make them localizable. For more information see our [translations guide](https://napari.org/developers/translations.html). --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Andy Sweet Co-authored-by: Grzegorz Bokota Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com> Co-authored-by: Peter Sobolewski --- napari/_qt/qt_resources/styles/02_custom.qss | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari/_qt/qt_resources/styles/02_custom.qss index a17e51e..2638cc4 100644 --- a/napari/_qt/qt_resources/styles/02_custom.qss +++ b/napari/_qt/qt_resources/styles/02_custom.qss @@ -883,6 +883,23 @@ QtLayerList::indicator:checked { min-width: 36px; } +/* ------------- Set size for dims sorter --------- */ + +QtDimsSorter > QtListView { + max-height: 100px; + max-width: 150px; +} + +/* ------------- Lock check buttons for dims sorter --------- */ + +QtDimsSorter > QtListView::indicator::unchecked { + image: url("theme_{{ id }}:/lock.svg"); +} + +QtDimsSorter > QtListView::indicator::checked { + image: url("theme_{{ id }}:/lock_open.svg"); +} + /* --------------- Menus (application and context menus) ---------------- */ QMenu::separator, QModelMenu::separator { From 66cdb1fd3fcf585bda3a0051f6596474bb5dceb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Wed, 29 May 2024 17:27:01 -0500 Subject: [PATCH 43/46] Move qss file with history, rename and relocate --- .../styles/02_custom.qss => napari_plugin_manager/styles.qss | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename napari/_qt/qt_resources/styles/02_custom.qss => napari_plugin_manager/styles.qss (100%) diff --git a/napari/_qt/qt_resources/styles/02_custom.qss b/napari_plugin_manager/styles.qss similarity index 100% rename from napari/_qt/qt_resources/styles/02_custom.qss rename to napari_plugin_manager/styles.qss From c19647e112759e345984a2b3a65bbd563bbdab7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Wed, 29 May 2024 17:41:04 -0500 Subject: [PATCH 44/46] Remove general qss and only leave plugin dialog one --- napari_plugin_manager/qt_plugin_dialog.py | 9 +- napari_plugin_manager/styles.qss | 591 +--------------------- 2 files changed, 9 insertions(+), 591 deletions(-) diff --git a/napari_plugin_manager/qt_plugin_dialog.py b/napari_plugin_manager/qt_plugin_dialog.py index b083cf7..77a91d3 100644 --- a/napari_plugin_manager/qt_plugin_dialog.py +++ b/napari_plugin_manager/qt_plugin_dialog.py @@ -8,7 +8,7 @@ import napari.plugins import napari.resources import npe2 -from napari._qt.qt_resources import QColoredSVGIcon +from napari._qt.qt_resources import QColoredSVGIcon, get_current_stylesheet from napari._qt.qthreading import create_worker from napari._qt.widgets.qt_message_popup import WarnPopup from napari._qt.widgets.qt_tooltip import QtToolTipLabel @@ -58,6 +58,7 @@ PYPI = 'PyPI' ON_BUNDLE = running_as_constructor_app() IS_NAPARI_CONDA_INSTALLED = is_conda_package('napari') +STYLES_PATH = Path(__file__).parent / 'styles.qss' class ProjectInfoVersions(NamedTuple): @@ -432,6 +433,9 @@ def __init__(self, parent: QWidget, installer: InstallerQueue) -> None: self.setSortingEnabled(True) self._remove_list = [] + stylesheet = get_current_stylesheet([STYLES_PATH]) + self.setStyleSheet(stylesheet) + def _count_visible(self) -> int: """Return the number of visible items. @@ -965,6 +969,9 @@ def setup_ui(self): self.packages_filter.setFocus() + stylesheet = get_current_stylesheet([STYLES_PATH]) + self.setStyleSheet(stylesheet) + def _update_count_in_label(self): """Counts all available but not installed plugins. Updates value.""" diff --git a/napari_plugin_manager/styles.qss b/napari_plugin_manager/styles.qss index 2638cc4..77c91db 100644 --- a/napari_plugin_manager/styles.qss +++ b/napari_plugin_manager/styles.qss @@ -1,553 +1,3 @@ -QLabel#h1 { - font-size: 28px; -} - -QLabel#h2 { - font-size: 22px; - color: {{ secondary }}; -} - -QLabel#h3 { - font-size: 18px; - color: {{ secondary }}; -} - -QtViewer { - padding-top: 0px; -} - -QtLayerButtons, QtViewerButtons, QtLayerList { - min-width: 242px; -} - -/* ------------- QMainWindow --------- */ -/* QDockWidgets will use the MainWindow styles -as long as they are docked (though they use the -style of QDockWidget when undocked) */ - -QStatusBar { - background: {{ background }}; - color: {{ text }}; -} - -/* ------------- Window separator --------- */ - -QMainWindow::separator { - width: 4px; - height: 4px; - border: none; - background-color: {{ background }}; -} - -QMainWindow::separator:hover { - background: {{ foreground }}; -} - -QMainWindow::separator:horizontal { - image: url("theme_{{ id }}:/horizontal_separator.svg"); -} - -QMainWindow::separator:vertical { - image: url("theme_{{ id }}:/vertical_separator.svg"); -} - -/* ------------- DockWidgets --------- */ - -#QtCustomTitleBar { - padding-top:3px; - background-color: {{ background }}; -} - -#QtCustomTitleBar:hover { - background-color: {{ darken(background, 10) }}; -} - -#QtCustomTitleBarLine { - background-color: {{ foreground }}; -} - -#QtCustomTitleBar > QPushButton { - background-color: none; - max-width: 12px; - max-height: 12px; -} - -#QtCustomTitleBar > QPushButton:hover { - background-color: {{ foreground }}; -} - -#QtCustomTitleBar > QLabel { - color: {{ primary }}; - font-size: {{ decrease(font_size, 1) }}; -} - -#QTitleBarCloseButton{ - width: 12px; - height: 12px; - padding: 0; - image: url("theme_{{ id }}:/delete_shape.svg"); -} - - -#QTitleBarFloatButton{ - image: url("theme_{{ id }}:/pop_out.svg"); - width: 10px; - height: 8px; - padding: 2 1 2 1; -} - -#QTitleBarHideButton{ - image: url("theme_{{ id }}:/visibility_off.svg"); - width: 10px; - height: 8px; - padding: 2 1 2 1; -} - -/* ----------------- Console ------------------ */ - -QtConsole { - min-height: 100px; -} - -QtConsole > QTextEdit { - background-color: {{ console }}; - background-clip: padding; - color: {{ text }}; - selection-background-color: {{ highlight }}; - margin: 10px; - font-family: Menlo, Consolas, "Ubuntu Mono", "Roboto Mono", "DejaVu Sans Mono", monospace; -} -.inverted { - background-color: {{ background }}; - color: {{ foreground }}; -} -.error { color: #b72121; } -.in-prompt-number { font-weight: bold; } -.out-prompt-number { font-weight: bold; } -.in-prompt { color: #6ab825; } -.out-prompt { color: #b72121; } - - -/* controls the area around the canvas */ -QSplitter { - spacing: 0px; - padding: 0px; - margin: 0px; -} - -QtDivider { - spacing: 0px; - padding: 0px; - border: 0px; - margin: 0px 3px 0px 3px; - min-width: 214px; - min-height: 1px; - max-height: 1px; -} - -QtDivider[selected=true] { - background-color: {{ text }}; -} - -QtDivider[selected=false] { - background-color: {{ background }}; -} - - -/* --------------- QtLayerWidget -------------------- */ - -QtLayerWidget { - padding: 0px; - background-color: {{ foreground }}; - border-radius: 2px; - min-height: 32px; - max-height: 32px; - min-width: 228px; -} - -QtLayerWidget[selected="true"] { - background-color: {{ current }}; -} - - -QtLayerWidget > QLabel { - background-color: transparent; - padding: 0px; - qproperty-alignment: AlignCenter; -} - - -/* The name of the layer*/ -QtLayerWidget > QLineEdit { - background-color: transparent; - border: none; - border-radius: 2px; - padding: 2px; - font-size: {{ increase(font_size, 2) }}; - qproperty-alignment: right; -} - -QtLayerWidget > QLineEdit:disabled { - background-color: transparent; - border-color: transparent; - border-radius: 3px; -} - -QtLayerWidget > QLineEdit:focus { - background-color: {{ darken(current, 20) }}; - selection-background-color: {{ lighten(current, 20) }}; -} - -QtLayerWidget QCheckBox::indicator { - background-color: transparent; -} - -QtLayerWidget QCheckBox::indicator:hover { - background-color: transparent; -} - -QtLayerWidget > QCheckBox#visibility { - spacing: 0px; - margin: 0px 0px 0px 4px; -} - -QtLayerWidget > QCheckBox#visibility::indicator{ - width: 18px; - height: 18px; -} - -QtLayerWidget > QCheckBox#visibility::indicator:unchecked { - image: url("theme_{{ id }}:/visibility_off_50.svg"); -} - -QtLayerWidget > QCheckBox#visibility::indicator:checked { - image: url("theme_{{ id }}:/visibility.svg"); -} - - -QLabel[layer_type_label="true"] { - max-width: 20px; - min-width: 20px; - min-height: 20px; - max-height: 20px; - margin-right: 4px; -} - -QLabel#Shapes { - image: url("theme_{{ id }}:/new_shapes.svg"); -} - -QLabel#Points { - image: url("theme_{{ id }}:/new_points.svg"); -} - -QLabel#Labels { - image: url("theme_{{ id }}:/new_labels.svg"); -} - -QLabel#Image { - image: url("theme_{{ id }}:/new_image.svg"); -} - -QLabel#Multiscale { - image: url("theme_{{ id }}:/new_image.svg"); -} - -QLabel#Surface { - image: url("theme_{{ id }}:/new_surface.svg"); -} - -QLabel#Vectors { - image: url("theme_{{ id }}:/new_vectors.svg"); -} - -QLabel#logo_silhouette { - image: url("theme_{{ id }}:/logo_silhouette.svg"); -} - - -/* ------------------------------------------------------ */ - -QFrame#empty_controls_widget { - min-height: 225px; - min-width: 240px; -} - -QtLayerControlsContainer { - border-radius: 2px; - padding: 0px; - margin: 10px; - margin-left: 10px; - margin-right: 8px; - margin-bottom: 4px; -} - -QtLayerControlsContainer > QFrame { - padding: 5px; - padding-right: 8px; - border-radius: 2px; -} - -/* the box that shows the current Label color */ -QtColorBox { - padding: 0px; - border: 0px; - margin: -1px 0 0 -1px; - border-radius: 2px; - min-height: 20px; - max-height: 20px; - min-width: 20px; - max-width: 20px; -} - -/* ----------------- QtLayerControls -------------------- */ - -QtLayerControls > QComboBox, QtLayerControls > QLabel, QtLayerControls, QtPlaneControls > QLabeledSlider > QAbstractSpinBox { - font-size: {{ decrease(font_size, 1) }}; - color: {{ text }}; -} - -QLabeledRangeSlider > QAbstractSpinBox { - font-size: {{ font_size }}; - color: {{ secondary }}; -} - -QWidget[emphasized="true"] QDoubleSlider::sub-page:horizontal:disabled { - background: {{ primary }}; -} - -QWidget[emphasized="true"] QDoubleSlider::handle:disabled { - background: {{ primary }}; -} - -QWidget[emphasized="true"] SliderLabel:disabled { - color: {{ opacity(text, 50) }}; -} - -QWidget[emphasized="true"] QLabel:disabled { - color: {{ opacity(text, 50) }}; -} - -AutoScaleButtons QPushButton { - font-size: {{ decrease(font_size, 3) }}; - padding: 4; -} - -PlaneNormalButtons QPushButton { - font-size: {{ decrease(font_size, 3) }}; - padding: 4; -} -/* ------------- DimsSliders --------- */ - -QtDimSliderWidget > QScrollBar::handle[last_used=false]:horizontal { - background: {{ highlight }}; -} - -QtDimSliderWidget > QScrollBar::handle[last_used=true]:horizontal { - background: {{ secondary }}; -} - -QtDimSliderWidget > QScrollBar:left-arrow:horizontal { - image: url("theme_{{ id }}:/step_left.svg"); -} - -QtDimSliderWidget > QScrollBar::right-arrow:horizontal { - image: url("theme_{{ id }}:/step_right.svg"); -} - -QtDimSliderWidget > QLineEdit { - background-color: {{ background }}; -} - - -#QtModalPopup { - /* required for rounded corners to not have background color */ - background: transparent; -} - -#QtPopupFrame { - border: 1px solid {{ secondary }}; - border-radius: 5px; -} - -#QtPopupFrame > QLabel { - color: {{ darken(text, 35) }}; - font-size: {{ font_size }}; -} - -#playDirectionCheckBox::indicator { - image: url("theme_{{ id }}:/long_right_arrow.svg"); - width: 22px; - height: 22px; - padding: 0 6px; - border: 0px; -} - -#fpsSpinBox { - min-width: 60px; -} - -#playDirectionCheckBox::indicator:checked { - image: url("theme_{{ id }}:/long_left_arrow.svg"); -} - -#playDirectionCheckBox::indicator:pressed { - background-color: {{ highlight }}; -} - - -#colorSwatch { - border-radius: 1px; - min-height: 22px; - max-height: 22px; - min-width: 22px; - max-width: 22px; -} - -#QtColorPopup{ - background-color: transparent; -} - -#CustomColorDialog QPushButton { - padding: 4px 10px; -} - -#CustomColorDialog QLabel { - background-color: {{ background }}; - color: {{ secondary }}; -} - - -/* editable slice label and axis name */ -QtDimSliderWidget > QLineEdit { - padding: 0 0 1px 2px; - max-height: 14px; - min-height: 12px; - min-width: 16px; - color: {{ text }}; -} - -#slice_label { - font-size: {{ decrease(font_size, 1) }}; - color: {{ secondary }}; - background: transparent; -} - -#slice_label_sep{ - background-color: {{ background }}; - border: 1px solid {{ primary }}; -} - - -/* ------------ Special Dialogs ------------ */ - -QtAboutKeybindings { - min-width: 600px; - min-height: 605px; -} - -QtAbout > QTextEdit{ - margin: 0px; - border: 0px; - padding: 2px; -} - -/* ------------ Shortcut Editor ------------ */ - -ShortcutEditor QHeaderView::section { - padding: 2px; - border: None; -} - - -/* ------------ Plugin Sorter ------------ */ - -ImplementationListItem { - background-color: {{ background }}; - border-radius: 2px; -} - -QtHookImplementationListWidget::item { - background: transparent; -} - -QtHookImplementationListWidget { - background-color: {{ console }}; -} - -/* for the error reporter */ -#pluginInfo { - color: text; -} - -QtPluginErrReporter > QTextEdit { - background-color: {{ console }}; - background-clip: padding; - color: {{ text }}; - selection-background-color: {{ highlight }}; - margin: 10px; -} - -/* ------------ Notifications ------------ */ - -NapariQtNotification > QWidget { - background: none; -} - -NapariQtNotification::hover{ - background: {{ lighten(background, 5) }}; -} - - -NapariQtNotification #expand_button { - background: none; - padding: 0px; - margin: 0px; - max-width: 20px; -} - -NapariQtNotification[expanded="false"] #expand_button { - image: url("theme_{{ id }}:/chevron_up.svg"); -} - -NapariQtNotification[expanded="true"] #expand_button { - image: url("theme_{{ id }}:/chevron_down.svg"); -} - - -NapariQtNotification #close_button { - background: none; - image: url("theme_{{ id }}:/delete_shape.svg"); - padding: 0px; - margin: 0px; - max-width: 20px; -} - -NapariQtNotification #source_label { - color: {{ primary }}; - font-size: {{ decrease(font_size, 1) }}; -} - -NapariQtNotification #severity_icon { - padding: 0; - margin: 0 0 -3px 0; - min-width: 20px; - min-height: 18px; - font-size: {{ increase(font_size, 3) }}; - color: {{ icon }}; -} - -/* ------------ Activity Dock ------------ */ - -#QtCustomTitleLabel { - color: {{ primary }}; - font-size: {{ decrease(font_size, 1) }}; -} - -#QtActivityButton:hover { - background-color: {{ lighten(background, 10) }}; -} - /* ------------ Plugin Dialog ------------ */ QCollapsible#install_info_button { @@ -596,6 +46,7 @@ QWidget#install_choice_widget { QPluginList { background: {{ console }}; + background: black; } PluginListItem { @@ -882,43 +333,3 @@ QtLayerList::indicator:checked { min-height: 36px; min-width: 36px; } - -/* ------------- Set size for dims sorter --------- */ - -QtDimsSorter > QtListView { - max-height: 100px; - max-width: 150px; -} - -/* ------------- Lock check buttons for dims sorter --------- */ - -QtDimsSorter > QtListView::indicator::unchecked { - image: url("theme_{{ id }}:/lock.svg"); -} - -QtDimsSorter > QtListView::indicator::checked { - image: url("theme_{{ id }}:/lock_open.svg"); -} - -/* --------------- Menus (application and context menus) ---------------- */ - -QMenu::separator, QModelMenu::separator { - height: 1 px; - background: {{ opacity(text, 90) }}; - margin-left: 17 px; - margin-right: 6 px; - margin-top: 5 px; - margin-bottom: 3 px; -} - -QMenu:disabled, QModelMenu:disabled { - background-color: {{ background }}; - selection-background-color: transparent; - border: 1px solid; - border-color: {{ foreground }}; - color: {{ opacity(text, 90) }}; -} - -QMenu, QModelMenu { - padding: 6 px; -} From b952779dc1adf2d811d85a74dfe0efa4c4f9737b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Wed, 29 May 2024 17:54:49 -0500 Subject: [PATCH 45/46] Update class names on qss for display name --- napari_plugin_manager/styles.qss | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/napari_plugin_manager/styles.qss b/napari_plugin_manager/styles.qss index 77c91db..984bb20 100644 --- a/napari_plugin_manager/styles.qss +++ b/napari_plugin_manager/styles.qss @@ -15,27 +15,26 @@ QLabel#author_text { color: {{ darken(text, 35) }}; } -QPushButton#install_choice { +QLabel#install_choice { background-color: {{ current }}; color: {{ darken(text, 35) }}; } -QPushButton#plugin_name_web { +QLabel#plugin_name_web { background-color: {{ darken(foreground, 20) }}; } -QPushButton#plugin_name_web:hover { +QLabel#plugin_name_web:hover { background-color: {{ foreground }} } -QPushButton#plugin_name { +QLabel#plugin_name { background-color: {{ darken(foreground, 20) }}; } -QPushButton#plugin_name:hover { +QLabel#plugin_name:hover { background-color: {{ darken(foreground, 20) }}; } - QWidget#install_choice_widget { background-color: {{ darken(foreground, 20) }}; color: {{ darken(text, 35) }}; From 0ee3445179428826b63777c5c6cec50cc23d2b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Tue, 4 Jun 2024 12:03:53 -0500 Subject: [PATCH 46/46] Set stylesheet only once and add comments --- napari_plugin_manager/qt_plugin_dialog.py | 3 --- napari_plugin_manager/styles.qss | 11 +++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/napari_plugin_manager/qt_plugin_dialog.py b/napari_plugin_manager/qt_plugin_dialog.py index 77a91d3..9d631ab 100644 --- a/napari_plugin_manager/qt_plugin_dialog.py +++ b/napari_plugin_manager/qt_plugin_dialog.py @@ -433,9 +433,6 @@ def __init__(self, parent: QWidget, installer: InstallerQueue) -> None: self.setSortingEnabled(True) self._remove_list = [] - stylesheet = get_current_stylesheet([STYLES_PATH]) - self.setStyleSheet(stylesheet) - def _count_visible(self) -> int: """Return the number of visible items. diff --git a/napari_plugin_manager/styles.qss b/napari_plugin_manager/styles.qss index 984bb20..28ee023 100644 --- a/napari_plugin_manager/styles.qss +++ b/napari_plugin_manager/styles.qss @@ -1,5 +1,16 @@ /* ------------ Plugin Dialog ------------ */ +/* +To be able to use this custom qss, we must use the `get_current_stylesheet` helper that napari provides. +By using that function we can replace the variables that are used in this stylesheet, e.g. `foreground`. + +To use `get_current_stylesheet` you can import from: + +```python +from napari._qt.qt_resources import get_current_stylesheet +``` + +*/ QCollapsible#install_info_button { background-color: {{ darken(foreground, 20) }}; color: {{ darken(text, 15) }};