mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-06 13:58:01 +03:00
Split Qt stylesheets by component
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
+10
-1141
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,346 @@
|
||||
# Copyright (C) 2024–present Loren Eteval & contributors <loren.eteval@proton.me>
|
||||
#
|
||||
# This file is part of Furious.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Provide global, page, dialog, settings, and metrics QSS."""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
|
||||
def baseStyleSheet(palette):
|
||||
"""Return base application and page component styling."""
|
||||
return dedent(f"""
|
||||
* {{
|
||||
outline: none;
|
||||
}}
|
||||
|
||||
QWidget {{
|
||||
background-color: {palette['window']};
|
||||
color: {palette['text']};
|
||||
selection-background-color: {palette['selection']};
|
||||
selection-color: {palette['selection_text']};
|
||||
}}
|
||||
|
||||
QMainWindow,
|
||||
QDialog,
|
||||
QMessageBox {{
|
||||
background-color: {palette['window']};
|
||||
}}
|
||||
|
||||
QLabel,
|
||||
QDialogButtonBox,
|
||||
QSizeGrip {{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QLabel:disabled {{
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QFrame {{
|
||||
border-color: {palette['border']};
|
||||
}}
|
||||
|
||||
QFrame#NavigationPanel {{
|
||||
border: none;
|
||||
border-right: 1px solid {palette['border']};
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QFrame#NavigationRailPlaceholder {{
|
||||
border: none;
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxMask {{
|
||||
border: none;
|
||||
background-color: rgba(0, 0, 0, 84);
|
||||
}}
|
||||
|
||||
QDialog#AppMessageBox {{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxSurface {{
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 10px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxContent,
|
||||
QWidget#AppMessageBoxTextWidget,
|
||||
QScrollArea#AppMessageBoxTextViewport,
|
||||
QScrollArea#AppMessageBoxTextViewport > QWidget > QWidget,
|
||||
QLabel#AppMessageBoxIcon {{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QLabel#AppMessageBoxTitle {{
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QLabel#AppMessageBoxBody {{
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar {{
|
||||
border-top: 1px solid {palette['border']};
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton {{
|
||||
padding: 5px 14px;
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['input']};
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton:hover {{
|
||||
border-color: {palette['border_strong']};
|
||||
background-color: {palette['hover']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton:pressed {{
|
||||
background-color: {palette['pressed']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton[messageBoxRole="primary"] {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent']};
|
||||
color: {palette['accent_text']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton[messageBoxRole="primary"]:hover {{
|
||||
border-color: {palette['accent_hover']};
|
||||
background-color: {palette['accent_hover']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton[messageBoxRole="primary"]:pressed {{
|
||||
border-color: {palette['accent_pressed']};
|
||||
background-color: {palette['accent_pressed']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton[messageBoxRole="destructive"] {{
|
||||
border-color: {palette['danger']};
|
||||
background-color: {palette['danger_soft']};
|
||||
color: {palette['danger']};
|
||||
}}
|
||||
|
||||
QFrame#AppMessageBoxButtonBar QPushButton:disabled {{
|
||||
border-color: {palette['border']};
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QStackedWidget#ApplicationPageStack {{
|
||||
border: none;
|
||||
background-color: {palette['window']};
|
||||
}}
|
||||
|
||||
QScrollArea#MetricsScrollArea,
|
||||
QWidget#MetricsPageContent,
|
||||
QScrollArea#SettingsScrollArea,
|
||||
QWidget#SettingsPageContent,
|
||||
QScrollArea#SubscriptionScrollArea,
|
||||
QWidget#SubscriptionPageContent,
|
||||
QWidget#HomePageContent,
|
||||
QWidget#LogPageContent {{
|
||||
border: none;
|
||||
background-color: {palette['window']};
|
||||
}}
|
||||
|
||||
QLabel#MetricsPageTitle,
|
||||
QLabel#LogPageTitle,
|
||||
QLabel#SubscriptionPageTitle,
|
||||
QLabel#HomePageTitle,
|
||||
QLabel#SettingsPageTitle {{
|
||||
color: {palette['text_strong']};
|
||||
font-size: 16pt;
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QLabel#SettingsSectionTitle {{
|
||||
padding: 4px 2px;
|
||||
color: {palette['text_strong']};
|
||||
font-size: 12pt;
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#SettingsCard {{
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 9px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QFrame#SettingsCard:hover {{
|
||||
border-color: {palette['border_strong']};
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QFrame#SubscriptionEditorForm {{
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 9px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QLabel#SettingsCardTitle {{
|
||||
color: {palette['text_strong']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QLabel#SettingsCardDescription {{
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QPushButton#SettingsActionButton {{
|
||||
min-width: 82px;
|
||||
}}
|
||||
|
||||
QPushButton#SettingsLinkButton {{
|
||||
min-height: 20px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: {palette['accent']};
|
||||
}}
|
||||
|
||||
QPushButton#SettingsLinkButton:hover {{
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QCheckBox#SettingsToggle::indicator {{
|
||||
width: 34px;
|
||||
height: 18px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 9px;
|
||||
background-color: {palette['raised']};
|
||||
image: none;
|
||||
}}
|
||||
|
||||
QCheckBox#SettingsToggle::indicator:hover {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['hover']};
|
||||
}}
|
||||
|
||||
QCheckBox#SettingsToggle::indicator:checked {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent']};
|
||||
image: none;
|
||||
}}
|
||||
|
||||
QCheckBox#SettingsToggle::indicator:disabled {{
|
||||
border-color: {palette['border']};
|
||||
background-color: {palette['raised']};
|
||||
image: none;
|
||||
}}
|
||||
|
||||
QFrame#MetricsSection {{
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 10px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QLabel#MetricsSectionTitle {{
|
||||
color: {palette['text_strong']};
|
||||
font-size: 12pt;
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#MetricCard {{
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 8px;
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QLabel#MetricCardTitle {{
|
||||
color: {palette['muted']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QLabel#EndpointStatusLabel {{
|
||||
color: {palette['text_strong']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QWidget#EndpointStatusWidget {{
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QLabel#EndpointFieldName {{
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QLabel#EndpointFieldValue {{
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QWidget#EndpointFieldValueContainer {{
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QLabel#EndpointNoteLabel {{
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QPushButton#EndpointCopyButton {{
|
||||
min-width: 34px;
|
||||
padding: 0;
|
||||
}}
|
||||
|
||||
QWidget#EndpointMapWidget {{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QWidget#MetricsGraphWidget {{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QGroupBox {{
|
||||
margin-top: 16px;
|
||||
padding: 14px 12px 12px 12px;
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 8px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QGroupBox::title {{
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top left;
|
||||
left: 10px;
|
||||
padding: 0 6px;
|
||||
background-color: {palette['panel']};
|
||||
color: {palette['muted']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
""").strip()
|
||||
@@ -0,0 +1,517 @@
|
||||
# Copyright (C) 2024–present Loren Eteval & contributors <loren.eteval@proton.me>
|
||||
#
|
||||
# This file is part of Furious.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Provide menu, navigation, input, and common-control QSS."""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
|
||||
def controlStyleSheet(
|
||||
palette,
|
||||
caretDownIcon,
|
||||
caretUpIcon,
|
||||
caretRightIcon,
|
||||
checkIcon,
|
||||
):
|
||||
"""Return interactive control styling."""
|
||||
return dedent(f"""
|
||||
QToolTip {{
|
||||
padding: 7px 10px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['overlay']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QMenuBar {{
|
||||
padding: 2px 5px;
|
||||
border: none;
|
||||
border-bottom: 1px solid {palette['border']};
|
||||
background-color: {palette['panel']};
|
||||
spacing: 2px;
|
||||
}}
|
||||
|
||||
QMenuBar::item {{
|
||||
min-height: 22px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 5px;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QMenuBar::item:selected {{
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QMenuBar::item:pressed {{
|
||||
background-color: {palette['pressed']};
|
||||
}}
|
||||
|
||||
QMenu {{
|
||||
padding: 6px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 9px;
|
||||
background-color: {palette['overlay']};
|
||||
}}
|
||||
|
||||
QMenu::separator {{
|
||||
height: 1px;
|
||||
margin: 6px 9px;
|
||||
background-color: {palette['border_strong']};
|
||||
}}
|
||||
|
||||
QMenu::item {{
|
||||
min-width: 160px;
|
||||
min-height: 22px;
|
||||
padding: 7px 32px;
|
||||
border-radius: 6px;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QMenu::item:selected {{
|
||||
background-color: {palette['accent_soft_hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QMenu::item:pressed {{
|
||||
background-color: {palette['pressed']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QMenu::item:disabled {{
|
||||
background-color: transparent;
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QMenu::item:disabled:selected {{
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QMenu::icon {{
|
||||
position: relative;
|
||||
left: 8px;
|
||||
}}
|
||||
|
||||
QMenu::indicator {{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
position: relative;
|
||||
left: 8px;
|
||||
}}
|
||||
|
||||
QMenu::indicator:checked {{
|
||||
border-radius: 4px;
|
||||
background-color: {palette['accent']};
|
||||
image: url("{checkIcon}");
|
||||
}}
|
||||
|
||||
QMenu::right-arrow {{
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
position: relative;
|
||||
right: 8px;
|
||||
image: url("{caretRightIcon}");
|
||||
}}
|
||||
|
||||
QMenu[menuRole="tray"] {{
|
||||
padding: 7px;
|
||||
border-radius: 10px;
|
||||
}}
|
||||
|
||||
QMenu[menuRole="tray"]::item {{
|
||||
min-width: 176px;
|
||||
min-height: 24px;
|
||||
padding: 8px 34px;
|
||||
}}
|
||||
|
||||
QMenu[menuRole="tray"]::separator {{
|
||||
margin: 6px 10px;
|
||||
}}
|
||||
|
||||
QMenu[menuRole="tray"]::icon,
|
||||
QMenu[menuRole="tray"]::indicator {{
|
||||
left: 9px;
|
||||
}}
|
||||
|
||||
QMenu[menuRole="tray"]::right-arrow {{
|
||||
right: 9px;
|
||||
}}
|
||||
|
||||
QToolBar {{
|
||||
padding: 4px 6px;
|
||||
border: none;
|
||||
border-bottom: 1px solid {palette['border']};
|
||||
background-color: {palette['panel']};
|
||||
spacing: 3px;
|
||||
}}
|
||||
|
||||
QToolBar::separator {{
|
||||
width: 1px;
|
||||
margin: 5px 5px;
|
||||
background-color: {palette['border']};
|
||||
}}
|
||||
|
||||
QToolBar#AppMainWindow_AppQToolBar,
|
||||
QToolBar#HomePageToolBar {{
|
||||
padding: 6px 8px;
|
||||
spacing: 2px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QToolBar#AppMainWindow_AppQToolBar::separator,
|
||||
QToolBar#HomePageToolBar::separator {{
|
||||
margin: 8px 4px;
|
||||
}}
|
||||
|
||||
QToolButton {{
|
||||
min-height: 24px;
|
||||
padding: 5px 8px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
background-color: transparent;
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QToolBar#AppMainWindow_AppQToolBar QToolButton,
|
||||
QToolBar#HomePageToolBar QToolButton {{
|
||||
min-width: 72px;
|
||||
min-height: 54px;
|
||||
padding: 5px 11px;
|
||||
border-radius: 8px;
|
||||
}}
|
||||
|
||||
QPushButton#NavigationToggleButton,
|
||||
QPushButton#NavigationPageButton {{
|
||||
min-width: 0;
|
||||
min-height: 38px;
|
||||
padding: 0;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 7px;
|
||||
background-color: transparent;
|
||||
color: {palette['text']};
|
||||
text-align: left;
|
||||
}}
|
||||
|
||||
QPushButton#NavigationToggleButton:hover,
|
||||
QPushButton#NavigationPageButton:hover {{
|
||||
border-color: transparent;
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QPushButton#NavigationPageButton:checked {{
|
||||
border: none;
|
||||
border-radius: 7px;
|
||||
background-color: {palette['accent_soft']};
|
||||
color: {palette['text_strong']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#NavigationSelectionIndicator {{
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: {palette['accent']};
|
||||
}}
|
||||
|
||||
QPushButton#NavigationPageButton:checked:hover {{
|
||||
background-color: {palette['accent_soft_hover']};
|
||||
}}
|
||||
|
||||
QPushButton#NavigationPageButton QLabel {{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QPushButton#NavigationPageButton:checked QLabel {{
|
||||
color: {palette['text_strong']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QPushButton#SearchButton {{
|
||||
padding: 0;
|
||||
}}
|
||||
|
||||
QToolButton:hover {{
|
||||
border-color: {palette['border']};
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QToolButton:pressed {{
|
||||
border-color: {palette['border_strong']};
|
||||
background-color: {palette['pressed']};
|
||||
}}
|
||||
|
||||
QToolButton:checked {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent_soft']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QToolButton:checked:hover {{
|
||||
background-color: {palette['accent_soft_hover']};
|
||||
}}
|
||||
|
||||
QToolButton:disabled {{
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QPushButton {{
|
||||
min-height: 28px;
|
||||
padding: 3px 13px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['panel']};
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QPushButton:hover {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QPushButton:focus {{
|
||||
border: 1px solid {palette['accent']};
|
||||
}}
|
||||
|
||||
QPushButton:pressed {{
|
||||
border-color: {palette['accent_pressed']};
|
||||
background-color: {palette['pressed']};
|
||||
}}
|
||||
|
||||
QPushButton:default {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent']};
|
||||
color: {palette['accent_text']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QPushButton:default:hover {{
|
||||
border-color: {palette['accent_hover']};
|
||||
background-color: {palette['accent_hover']};
|
||||
}}
|
||||
|
||||
QPushButton:default:pressed {{
|
||||
border-color: {palette['accent_pressed']};
|
||||
background-color: {palette['accent_pressed']};
|
||||
}}
|
||||
|
||||
QPushButton:flat {{
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QPushButton:disabled {{
|
||||
border-color: {palette['border']};
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QLineEdit,
|
||||
QTextEdit,
|
||||
QPlainTextEdit,
|
||||
QComboBox,
|
||||
QSpinBox,
|
||||
QDoubleSpinBox,
|
||||
QDateEdit,
|
||||
QDateTimeEdit,
|
||||
QTimeEdit {{
|
||||
min-height: 28px;
|
||||
padding: 3px 8px;
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['input']};
|
||||
color: {palette['text']};
|
||||
selection-background-color: {palette['selection']};
|
||||
selection-color: {palette['selection_text']};
|
||||
}}
|
||||
|
||||
QLineEdit:hover,
|
||||
QTextEdit:hover,
|
||||
QPlainTextEdit:hover,
|
||||
QComboBox:hover,
|
||||
QSpinBox:hover,
|
||||
QDoubleSpinBox:hover,
|
||||
QDateEdit:hover,
|
||||
QDateTimeEdit:hover,
|
||||
QTimeEdit:hover {{
|
||||
border-color: {palette['border_strong']};
|
||||
}}
|
||||
|
||||
QLineEdit:focus,
|
||||
QTextEdit:focus,
|
||||
QPlainTextEdit:focus,
|
||||
QComboBox:focus,
|
||||
QSpinBox:focus,
|
||||
QDoubleSpinBox:focus,
|
||||
QDateEdit:focus,
|
||||
QDateTimeEdit:focus,
|
||||
QTimeEdit:focus {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['input_focus']};
|
||||
}}
|
||||
|
||||
QLineEdit:read-only,
|
||||
QTextEdit:read-only,
|
||||
QPlainTextEdit:read-only {{
|
||||
background-color: {palette['panel_alt']};
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QLineEdit:disabled,
|
||||
QTextEdit:disabled,
|
||||
QPlainTextEdit:disabled,
|
||||
QComboBox:disabled,
|
||||
QSpinBox:disabled,
|
||||
QDoubleSpinBox:disabled,
|
||||
QDateEdit:disabled,
|
||||
QDateTimeEdit:disabled,
|
||||
QTimeEdit:disabled {{
|
||||
border-color: {palette['border']};
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QComboBox {{
|
||||
padding-right: 32px;
|
||||
}}
|
||||
|
||||
QComboBox::drop-down {{
|
||||
subcontrol-origin: border;
|
||||
subcontrol-position: top right;
|
||||
width: 27px;
|
||||
border: none;
|
||||
border-left: 1px solid {palette['border']};
|
||||
border-top-right-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QComboBox::drop-down:hover {{
|
||||
background-color: {palette['hover']};
|
||||
}}
|
||||
|
||||
QComboBox::down-arrow {{
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
image: url("{caretDownIcon}");
|
||||
}}
|
||||
|
||||
QComboBox QAbstractItemView {{
|
||||
padding: 4px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['overlay']};
|
||||
color: {palette['text']};
|
||||
selection-background-color: {palette['selection']};
|
||||
selection-color: {palette['selection_text']};
|
||||
}}
|
||||
|
||||
QSpinBox,
|
||||
QDoubleSpinBox {{
|
||||
padding-right: 31px;
|
||||
}}
|
||||
|
||||
QSpinBox::up-button,
|
||||
QDoubleSpinBox::up-button {{
|
||||
subcontrol-origin: border;
|
||||
subcontrol-position: top right;
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
border: none;
|
||||
border-left: 1px solid {palette['border']};
|
||||
border-bottom: 1px solid {palette['border']};
|
||||
border-top-right-radius: 6px;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QSpinBox::down-button,
|
||||
QDoubleSpinBox::down-button {{
|
||||
subcontrol-origin: border;
|
||||
subcontrol-position: bottom right;
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
border: none;
|
||||
border-left: 1px solid {palette['border']};
|
||||
border-top: 1px solid {palette['border']};
|
||||
border-bottom-right-radius: 6px;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QSpinBox::up-button:hover,
|
||||
QSpinBox::down-button:hover,
|
||||
QDoubleSpinBox::up-button:hover,
|
||||
QDoubleSpinBox::down-button:hover {{
|
||||
background-color: {palette['hover']};
|
||||
}}
|
||||
|
||||
QSpinBox::up-arrow,
|
||||
QDoubleSpinBox::up-arrow {{
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
image: url("{caretUpIcon}");
|
||||
}}
|
||||
|
||||
QSpinBox::down-arrow,
|
||||
QDoubleSpinBox::down-arrow {{
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
image: url("{caretDownIcon}");
|
||||
}}
|
||||
|
||||
QTabWidget::pane {{
|
||||
top: -1px;
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 8px;
|
||||
background-color: {palette['panel']};
|
||||
}}
|
||||
|
||||
QTabBar {{
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QTabBar::tab {{
|
||||
min-height: 28px;
|
||||
padding: 6px 14px;
|
||||
margin-right: 2px;
|
||||
border: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
background-color: transparent;
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QTabBar::tab:selected {{
|
||||
border-bottom-color: {palette['accent']};
|
||||
background-color: {palette['panel']};
|
||||
color: {palette['text_strong']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QTabBar::tab:hover:!selected {{
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QTabBar::tab:disabled {{
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
""").strip()
|
||||
@@ -0,0 +1,360 @@
|
||||
# Copyright (C) 2024–present Loren Eteval & contributors <loren.eteval@proton.me>
|
||||
#
|
||||
# This file is part of Furious.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Provide item-view, scrolling, selection, and status QSS."""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
|
||||
def dataViewStyleSheet(palette, progressBarStyleSheet, checkIcon):
|
||||
"""Return data-view and status component styling."""
|
||||
return dedent(f"""
|
||||
QTableView,
|
||||
QTableWidget,
|
||||
QTreeView,
|
||||
QListView,
|
||||
QListWidget {{
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 8px;
|
||||
background-color: {palette['panel']};
|
||||
alternate-background-color: {palette['panel_alt']};
|
||||
gridline-color: {palette['border']};
|
||||
color: {palette['text']};
|
||||
selection-background-color: {palette['selection']};
|
||||
selection-color: {palette['selection_text']};
|
||||
}}
|
||||
|
||||
QTableView::item,
|
||||
QTableWidget::item,
|
||||
QTreeView::item,
|
||||
QListView::item,
|
||||
QListWidget::item {{
|
||||
min-height: 24px;
|
||||
padding: 4px 7px;
|
||||
border: none;
|
||||
}}
|
||||
|
||||
QTableView::item:hover,
|
||||
QTableWidget::item:hover,
|
||||
QTreeView::item:hover,
|
||||
QListView::item:hover,
|
||||
QListWidget::item:hover {{
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QTableView::item:selected,
|
||||
QTableWidget::item:selected,
|
||||
QTreeView::item:selected,
|
||||
QListView::item:selected,
|
||||
QListWidget::item:selected {{
|
||||
background-color: {palette['selection']};
|
||||
color: {palette['selection_text']};
|
||||
}}
|
||||
|
||||
QTableView::item:selected:!active,
|
||||
QTableWidget::item:selected:!active,
|
||||
QTreeView::item:selected:!active,
|
||||
QListView::item:selected:!active,
|
||||
QListWidget::item:selected:!active {{
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QHeaderView {{
|
||||
border: none;
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QHeaderView::section {{
|
||||
min-height: 28px;
|
||||
padding: 5px 8px;
|
||||
border: none;
|
||||
border-right: 1px solid {palette['border']};
|
||||
border-bottom: 1px solid {palette['border']};
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['muted']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QHeaderView::section:hover {{
|
||||
background-color: {palette['hover']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QHeaderView::section:pressed {{
|
||||
background-color: {palette['pressed']};
|
||||
}}
|
||||
|
||||
QAbstractScrollArea::corner {{
|
||||
border: none;
|
||||
background-color: {palette['panel_alt']};
|
||||
}}
|
||||
|
||||
QScrollBar:vertical {{
|
||||
width: 11px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QScrollBar:horizontal {{
|
||||
height: 11px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QScrollBar::handle:vertical,
|
||||
QScrollBar::handle:horizontal {{
|
||||
min-height: 28px;
|
||||
min-width: 28px;
|
||||
margin: 2px;
|
||||
border-radius: 3px;
|
||||
background-color: {palette['scroll_handle']};
|
||||
}}
|
||||
|
||||
QScrollBar::handle:vertical:hover,
|
||||
QScrollBar::handle:horizontal:hover {{
|
||||
background-color: {palette['scroll_handle_hover']};
|
||||
}}
|
||||
|
||||
QScrollBar::add-line,
|
||||
QScrollBar::sub-line,
|
||||
QScrollBar::add-page,
|
||||
QScrollBar::sub-page {{
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
{progressBarStyleSheet}
|
||||
|
||||
QCheckBox,
|
||||
QRadioButton {{
|
||||
spacing: 7px;
|
||||
background-color: transparent;
|
||||
color: {palette['text']};
|
||||
}}
|
||||
|
||||
QCheckBox:hover,
|
||||
QRadioButton:hover {{
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QCheckBox:disabled,
|
||||
QRadioButton:disabled {{
|
||||
color: {palette['disabled']};
|
||||
}}
|
||||
|
||||
QCheckBox::indicator {{
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 4px;
|
||||
background-color: {palette['input']};
|
||||
}}
|
||||
|
||||
QCheckBox::indicator:hover {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent_soft']};
|
||||
}}
|
||||
|
||||
QCheckBox::indicator:checked {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent']};
|
||||
image: url("{checkIcon}");
|
||||
}}
|
||||
|
||||
QCheckBox::indicator:indeterminate {{
|
||||
border: 4px solid {palette['accent']};
|
||||
background-color: {palette['input']};
|
||||
}}
|
||||
|
||||
QRadioButton::indicator {{
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 1px solid {palette['border_strong']};
|
||||
border-radius: 8px;
|
||||
background-color: {palette['input']};
|
||||
}}
|
||||
|
||||
QRadioButton::indicator:hover {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent_soft']};
|
||||
}}
|
||||
|
||||
QRadioButton::indicator:checked {{
|
||||
border: 5px solid {palette['accent']};
|
||||
background-color: {palette['input']};
|
||||
}}
|
||||
|
||||
QCheckBox::indicator:disabled,
|
||||
QRadioButton::indicator:disabled {{
|
||||
border-color: {palette['border']};
|
||||
background-color: {palette['raised']};
|
||||
}}
|
||||
|
||||
QSlider::groove:horizontal {{
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
background-color: {palette['raised']};
|
||||
}}
|
||||
|
||||
QSlider::sub-page:horizontal {{
|
||||
border-radius: 2px;
|
||||
background-color: {palette['accent']};
|
||||
}}
|
||||
|
||||
QSlider::handle:horizontal {{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: -6px 0;
|
||||
border: 2px solid {palette['panel']};
|
||||
border-radius: 8px;
|
||||
background-color: {palette['accent']};
|
||||
}}
|
||||
|
||||
QSlider::handle:horizontal:hover {{
|
||||
background-color: {palette['accent_hover']};
|
||||
}}
|
||||
|
||||
QStatusBar {{
|
||||
min-height: 30px;
|
||||
border-top: 1px solid {palette['border']};
|
||||
background-color: {palette['panel']};
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QStatusBar::item {{
|
||||
border: none;
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge {{
|
||||
min-height: 24px;
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge QLabel {{
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge QLabel#NetworkStateLabel {{
|
||||
color: {palette['text_strong']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="disconnected"] QLabel#NetworkStateLabel {{
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="connecting"] {{
|
||||
border-color: {palette['accent']};
|
||||
background-color: {palette['accent_soft']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="connecting"] QLabel#NetworkStateLabel {{
|
||||
color: {palette['accent']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="connected"],
|
||||
QFrame#NetworkStateBadge[networkState="success"] {{
|
||||
border-color: {palette['success']};
|
||||
background-color: {palette['success_soft']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="connected"] QLabel#NetworkStateLabel,
|
||||
QFrame#NetworkStateBadge[networkState="success"] QLabel#NetworkStateLabel {{
|
||||
color: {palette['success']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="disconnecting"] {{
|
||||
border-color: {palette['warning']};
|
||||
background-color: {palette['warning_soft']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="disconnecting"] QLabel#NetworkStateLabel {{
|
||||
color: {palette['warning']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="failure"] {{
|
||||
border-color: {palette['danger']};
|
||||
background-color: {palette['danger_soft']};
|
||||
}}
|
||||
|
||||
QFrame#NetworkStateBadge[networkState="failure"] QLabel#NetworkStateLabel {{
|
||||
color: {palette['danger']};
|
||||
}}
|
||||
|
||||
QWidget#TrafficStatsBadge {{
|
||||
min-height: 24px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}}
|
||||
|
||||
QFrame#TrafficDirectionBadge {{
|
||||
border: 1px solid {palette['border']};
|
||||
border-radius: 6px;
|
||||
background-color: {palette['raised']};
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QFrame#TrafficDirectionBadge QLabel {{
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
color: {palette['text_strong']};
|
||||
}}
|
||||
|
||||
QFrame#TrafficDirectionBadge[direction="download"] QLabel#TrafficSpeedLabel {{
|
||||
color: {palette['metrics_download']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#TrafficDirectionBadge[direction="upload"] QLabel#TrafficSpeedLabel {{
|
||||
color: {palette['metrics_upload']};
|
||||
font-weight: 600;
|
||||
}}
|
||||
|
||||
QFrame#TrafficDirectionBadge QLabel#TrafficUsageLabel {{
|
||||
color: {palette['muted']};
|
||||
}}
|
||||
|
||||
QSplitter::handle {{
|
||||
background-color: {palette['border']};
|
||||
}}
|
||||
|
||||
QSplitter::handle:hover {{
|
||||
background-color: {palette['accent']};
|
||||
}}
|
||||
|
||||
QSplitter::handle:horizontal {{
|
||||
width: 2px;
|
||||
}}
|
||||
|
||||
QSplitter::handle:vertical {{
|
||||
height: 2px;
|
||||
}}
|
||||
""").strip()
|
||||
@@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2024–present Loren Eteval & contributors <loren.eteval@proton.me>
|
||||
#
|
||||
# This file is part of Furious.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""Compose private component QSS behind :class:`AppStyleSheet`."""
|
||||
|
||||
from .Base import baseStyleSheet
|
||||
from .Controls import controlStyleSheet
|
||||
from .DataViews import dataViewStyleSheet
|
||||
|
||||
|
||||
def composeStyleSheet(
|
||||
palette,
|
||||
progressBarStyleSheet,
|
||||
caretDownIcon,
|
||||
caretUpIcon,
|
||||
caretRightIcon,
|
||||
checkIcon,
|
||||
):
|
||||
"""Return the complete stylesheet without exposing component fragments."""
|
||||
return '\n\n'.join(
|
||||
(
|
||||
baseStyleSheet(palette),
|
||||
controlStyleSheet(
|
||||
palette,
|
||||
caretDownIcon,
|
||||
caretUpIcon,
|
||||
caretRightIcon,
|
||||
checkIcon,
|
||||
),
|
||||
dataViewStyleSheet(palette, progressBarStyleSheet, checkIcon),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
__all__ = []
|
||||
Reference in New Issue
Block a user