From 1bd4926b2574676a3a45a9a8ecf0a0b381aef6db Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 14 Jan 2026 19:58:43 +0100 Subject: [PATCH] Add a theme factory to YACReaderLibrary and theme the comic vine dialog --- .../comic_vine/comic_vine_dialog.cpp | 38 ++- .../comic_vine/comic_vine_dialog.h | 8 +- .../comic_vine/scraper_checkbox.cpp | 31 +- .../comic_vine/scraper_checkbox.h | 7 +- .../comic_vine/scraper_lineedit.cpp | 19 +- .../comic_vine/scraper_lineedit.h | 5 +- .../comic_vine/scraper_results_paginator.cpp | 32 +- .../comic_vine/scraper_results_paginator.h | 9 +- .../comic_vine/scraper_scroll_label.cpp | 26 +- .../comic_vine/scraper_scroll_label.h | 9 +- .../comic_vine/scraper_tableview.cpp | 32 +- .../comic_vine/scraper_tableview.h | 9 +- .../comic_vine/search_single_comic.cpp | 13 +- .../comic_vine/search_single_comic.h | 8 +- YACReaderLibrary/comic_vine/search_volume.cpp | 13 +- YACReaderLibrary/comic_vine/search_volume.h | 7 +- YACReaderLibrary/comic_vine/select_comic.cpp | 17 +- YACReaderLibrary/comic_vine/select_comic.h | 7 +- YACReaderLibrary/comic_vine/select_volume.cpp | 17 +- YACReaderLibrary/comic_vine/select_volume.h | 7 +- .../comic_vine/series_question.cpp | 23 +- YACReaderLibrary/comic_vine/series_question.h | 11 +- .../comic_vine/sort_volume_comics.cpp | 68 +++- .../comic_vine/sort_volume_comics.h | 47 +-- YACReaderLibrary/comic_vine/title_header.cpp | 15 +- YACReaderLibrary/comic_vine/title_header.h | 7 +- YACReaderLibrary/themes/theme.h | 122 +++++++ YACReaderLibrary/themes/theme_factory.cpp | 299 ++++++++++++++++++ YACReaderLibrary/themes/theme_factory.h | 9 + YACReaderLibrary/themes/themes.pri | 3 + 30 files changed, 740 insertions(+), 178 deletions(-) create mode 100644 YACReaderLibrary/themes/theme_factory.cpp create mode 100644 YACReaderLibrary/themes/theme_factory.h diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index 1faa0aae..d53b1e4c 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -27,6 +27,8 @@ #include "db_helper.h" #include "response_parser.h" +#include "theme_manager.h" + #include "QsLog.h" ComicVineDialog::ComicVineDialog(QWidget *parent) @@ -38,6 +40,8 @@ ComicVineDialog::ComicVineDialog(QWidget *parent) doLayout(); doStackedWidgets(); doConnections(); + + initTheme(this); } void ComicVineDialog::closeEvent(QCloseEvent *event) @@ -49,12 +53,6 @@ void ComicVineDialog::closeEvent(QCloseEvent *event) void ComicVineDialog::doLayout() { - setStyleSheet("" - "QDialog {background-color: #404040; }" - ""); - - QString dialogButtonsStyleSheet = "QPushButton {border: 1px solid #242424; background: #2e2e2e; color:white; padding: 5px 26px 5px 26px; font-size:12px;font-family:Arial; font-weight:bold;}"; - skipButton = new QPushButton(tr("skip")); backButton = new QPushButton(tr("back")); nextButton = new QPushButton(tr("next")); @@ -66,12 +64,6 @@ void ComicVineDialog::doLayout() closeButton->setDefault(false); closeButton->setAutoDefault(false); - skipButton->setStyleSheet(dialogButtonsStyleSheet); - backButton->setStyleSheet(dialogButtonsStyleSheet); - nextButton->setStyleSheet(dialogButtonsStyleSheet); - searchButton->setStyleSheet(dialogButtonsStyleSheet); - closeButton->setStyleSheet(dialogButtonsStyleSheet); - content = new QStackedWidget(this); auto mainLayout = new QVBoxLayout; @@ -274,13 +266,11 @@ void ComicVineDialog::doLoading() QWidget *w = new QWidget; auto l = new QVBoxLayout; - auto bw = new YACReaderBusyWidget; + busyWidget = new YACReaderBusyWidget; loadingMessage = new QLabel; - loadingMessage->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); - l->addStretch(); - l->addWidget(bw, 0, Qt::AlignHCenter); + l->addWidget(busyWidget, 0, Qt::AlignHCenter); l->addStretch(); l->addWidget(loadingMessage); @@ -666,3 +656,19 @@ void ComicVineDialog::launchSearchComic() // if(comicInfo.isEmpty() && comicNumber == -1) searchVolume({ volumeInfo, 1, exactMatch }); } + +void ComicVineDialog::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + setStyleSheet(comicVineTheme.dialogQSS); + + skipButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + backButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + nextButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + searchButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + closeButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + + loadingMessage->setStyleSheet(comicVineTheme.defaultLabelQSS); + busyWidget->setColor(comicVineTheme.busyIndicatorColor); +} diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.h b/YACReaderLibrary/comic_vine/comic_vine_dialog.h index e6ccfc78..b9626cd8 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.h +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.h @@ -5,6 +5,7 @@ #include "comic_db.h" #include "volume_search_query.h" +#include "themable.h" class QPushButton; class QStackedWidget; @@ -21,10 +22,11 @@ class SelectVolume; struct SelectedVolumeInfo; class SortVolumeComics; struct VolumeSearchQuery; +class YACReaderBusyWidget; // TODO this should use a QStateMachine //---------------------------------------- -class ComicVineDialog : public QDialog +class ComicVineDialog : public QDialog, protected Themable { Q_OBJECT public: @@ -107,6 +109,7 @@ private: QWidget *singleComicBrowser; QLabel *loadingMessage; + YACReaderBusyWidget *busyWidget; void doLayout(); void doStackedWidgets(); @@ -124,6 +127,9 @@ private: VolumeSearchQuery currentVolumeSearchQuery; QString currentVolumeId; + +protected: + void applyTheme() override; }; #endif // COMIC_VINE_DIALOG_H diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp index 9a538121..f7131d77 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp @@ -1,27 +1,16 @@ #include "scraper_checkbox.h" -#include "qwidget.h" + +#include "theme_manager.h" ScraperCheckBox::ScraperCheckBox(const QString &text, QWidget *parent) : QCheckBox(text, parent) { - setStyleSheet( - "QCheckBox {" - " color: white;" - " font-size: 12px;" - " font-family: Arial;" - " spacing: 10px;" - "}" - "QCheckBox::indicator {" - " width: 13px;" - " height: 13px;" - " border: 1px solid #242424;" - " background: #2e2e2e;" - "}" - "QCheckBox::indicator:checked {" - " image: url(:/images/comic_vine/checkBoxTick.svg);" - " background: #2e2e2e;" - "}" - "QCheckBox::indicator:unchecked {" - " background: #2e2e2e;" - "}"); + initTheme(this); +} + +void ScraperCheckBox::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + setStyleSheet(comicVineTheme.checkBoxQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.h b/YACReaderLibrary/comic_vine/scraper_checkbox.h index ad684670..ce2200c2 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.h +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.h @@ -3,10 +3,15 @@ #include -class ScraperCheckBox : public QCheckBox +#include "themable.h" + +class ScraperCheckBox : public QCheckBox, protected Themable { public: ScraperCheckBox(const QString &text, QWidget *parent = nullptr); + +protected: + void applyTheme() override; }; #endif // SCRAPER_CHECKBOX_H diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp index d1227085..a5b2fc34 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp @@ -1,18 +1,17 @@ #include "scraper_lineedit.h" + +#include "theme_manager.h" + #include ScraperLineEdit::ScraperLineEdit(const QString &title, QWidget *widget) : QLineEdit(widget) { titleLabel = new QLabel(title, this); - titleLabel->setStyleSheet("QLabel {color:white;}"); - - setStyleSheet(QString("QLineEdit {" - "border:none; background-color: #2E2E2E; color : white; padding-left: %1; padding-bottom: 1px; margin-bottom: 0px;" - "}") - .arg(titleLabel->sizeHint().width() + 6)); setFixedHeight(22); + + initTheme(this); } void ScraperLineEdit::resizeEvent(QResizeEvent *) @@ -20,3 +19,11 @@ void ScraperLineEdit::resizeEvent(QResizeEvent *) QSize szl = titleLabel->sizeHint(); titleLabel->move(6, (rect().bottom() + 1 - szl.height()) / 2); } + +void ScraperLineEdit::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + titleLabel->setStyleSheet(comicVineTheme.scraperLineEditTitleLabelQSS); + setStyleSheet(comicVineTheme.scraperLineEditQSS.arg(titleLabel->sizeHint().width() + 6)); +} diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.h b/YACReaderLibrary/comic_vine/scraper_lineedit.h index 8de8b45d..e7d41d43 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.h +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.h @@ -3,9 +3,11 @@ #include +#include "themable.h" + class QLabel; -class ScraperLineEdit : public QLineEdit +class ScraperLineEdit : public QLineEdit, protected Themable { Q_OBJECT public: @@ -13,6 +15,7 @@ public: protected: void resizeEvent(QResizeEvent *) override; + void applyTheme() override; private: QLabel *titleLabel; diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp index 6dd5f163..e2f56205 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp @@ -1,5 +1,6 @@ #include "scraper_results_paginator.h" #include "response_parser.h" +#include "theme_manager.h" #include #include @@ -10,27 +11,14 @@ ScraperResultsPaginator::ScraperResultsPaginator(QWidget *parent) { auto pagesButtonsLayout = new QHBoxLayout; - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; - nextPage = new QToolButton; - nextPage->setStyleSheet("QToolButton {border:none;}"); - QPixmap np(":/images/comic_vine/nextPage.png"); - nextPage->setIconSize(np.size()); - nextPage->setIcon(np); - previousPage = new QToolButton; - previousPage->setStyleSheet("QToolButton {border:none;}"); - QPixmap pp(":/images/comic_vine/previousPage.png"); - previousPage->setIconSize(pp.size()); - previousPage->setIcon(pp); connect(nextPage, &QAbstractButton::clicked, this, &ScraperResultsPaginator::loadNextPage); connect(previousPage, &QAbstractButton::clicked, this, &ScraperResultsPaginator::loadPreviousPage); numElements = new QLabel(tr("Number of volumes found : %1")); - numElements->setStyleSheet(labelStylesheet); numPages = new QLabel(tr("page %1 of %2")); - numPages->setStyleSheet(labelStylesheet); pagesButtonsLayout->addSpacing(15); pagesButtonsLayout->addWidget(numElements); @@ -43,6 +31,8 @@ ScraperResultsPaginator::ScraperResultsPaginator(QWidget *parent) pagesButtonsLayout->setContentsMargins(0, 0, 0, 0); setLayout(pagesButtonsLayout); + + initTheme(this); } void ScraperResultsPaginator::update(const QString &json) @@ -71,3 +61,19 @@ void ScraperResultsPaginator::setCustomLabel(const QString &label) { customLabel = label; } + +void ScraperResultsPaginator::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + numElements->setStyleSheet(comicVineTheme.defaultLabelQSS); + numPages->setStyleSheet(comicVineTheme.defaultLabelQSS); + + nextPage->setStyleSheet(comicVineTheme.noBorderToolButtonQSS); + nextPage->setIconSize(comicVineTheme.nextPageIcon.size); + nextPage->setIcon(comicVineTheme.nextPageIcon.icon); + + previousPage->setStyleSheet(comicVineTheme.noBorderToolButtonQSS); + previousPage->setIconSize(comicVineTheme.previousPageIcon.size); + previousPage->setIcon(comicVineTheme.previousPageIcon.icon); +} diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.h b/YACReaderLibrary/comic_vine/scraper_results_paginator.h index 4395df4c..d099e1af 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.h +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.h @@ -1,12 +1,14 @@ #ifndef SCRAPER_RESULTS_PAGINATOR_H #define SCRAPER_RESULTS_PAGINATOR_H +#include "themable.h" + #include class QToolButton; class QLabel; -class ScraperResultsPaginator : public QWidget +class ScraperResultsPaginator : public QWidget, protected Themable { Q_OBJECT public: @@ -18,8 +20,6 @@ signals: void loadNextPage(); void loadPreviousPage(); -public slots: - private: QToolButton *nextPage; QToolButton *previousPage; @@ -29,6 +29,9 @@ private: int currentPage; QString customLabel; + +protected: + void applyTheme() override; }; #endif // SCRAPER_RESULTS_PAGINATOR_H diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp index f067a4e0..1fd4cdd3 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp @@ -1,5 +1,7 @@ #include "scraper_scroll_label.h" +#include "theme_manager.h" + #include #include #include @@ -8,28 +10,16 @@ ScraperScrollLabel::ScraperScrollLabel(QWidget *parent) : QScrollArea(parent) { textLabel = new QLabel(this); - textLabel->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }"); textLabel->setWordWrap(true); textLabel->setMinimumSize(168, 12); setWidget(textLabel); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setStyleSheet( - "QScrollArea {background-color:#2B2B2B; border:none;}" - "QScrollBar:vertical { border: none; background: #2B2B2B; width: 3px; margin: 0; }" - "QScrollBar:horizontal { border: none; background: #2B2B2B; height: 3px; margin: 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::handle:horizontal { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::add-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::sub-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"); connect(textLabel, &QLabel::linkActivated, this, &ScraperScrollLabel::openLink); + + initTheme(this); } void ScraperScrollLabel::setAltText(const QString &text) @@ -50,3 +40,11 @@ void ScraperScrollLabel::openLink(const QString &link) { QDesktopServices::openUrl(QUrl("http://www.comicvine.com" + link)); } + +void ScraperScrollLabel::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + textLabel->setStyleSheet(comicVineTheme.scraperScrollLabelTextQSS); + setStyleSheet(comicVineTheme.scraperScrollLabelScrollAreaQSS); +} diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.h b/YACReaderLibrary/comic_vine/scraper_scroll_label.h index 6dc428dd..7c555d5c 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.h +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.h @@ -3,16 +3,16 @@ #include +#include "themable.h" + class QLabel; -class ScraperScrollLabel : public QScrollArea +class ScraperScrollLabel : public QScrollArea, protected Themable { Q_OBJECT public: explicit ScraperScrollLabel(QWidget *parent = nullptr); -signals: - public slots: void setText(const QString &text); void setAltText(const QString &text); @@ -21,6 +21,9 @@ public slots: private: QLabel *textLabel; + +protected: + void applyTheme() override; }; #endif // SCRAPER_SCROLL_LABEL_H diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.cpp b/YACReaderLibrary/comic_vine/scraper_tableview.cpp index eec6da83..a9c50978 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.cpp +++ b/YACReaderLibrary/comic_vine/scraper_tableview.cpp @@ -1,31 +1,12 @@ #include "scraper_tableview.h" +#include "theme_manager.h" + #include ScraperTableView::ScraperTableView(QWidget *parent) : QTableView(parent) { - QString tableStylesheet = "QTableView {color:white; border:0px;alternate-background-color: #2E2E2E;background-color: #2B2B2B; outline: 0px;}" - "QTableView::item {outline: 0px; border: 0px; color:#FFFFFF;}" - "QTableView::item:selected {outline: 0px; background-color: #555555; }" - "QHeaderView::section:horizontal {background-color:#292929; border-bottom:1px solid #1F1F1F; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #292929, stop: 1 #1F1F1F); border-left:none; border-top:none; padding:4px; color:#ebebeb;}" - "QHeaderView::section:vertical {border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE;}" - "QHeaderView::down-arrow {image: url(':/images/comic_vine/downArrow.png');}" - "QHeaderView::up-arrow {image: url(':/images/comic_vine/upArrow.png');}" - "QScrollBar:vertical { border: none; background: #2B2B2B; width: 3px; margin: 0; }" - "QScrollBar:horizontal { border: none; background: #2B2B2B; height: 3px; margin: 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::handle:horizontal { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::add-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::sub-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"; - - setStyleSheet(tableStylesheet); - setShowGrid(false); #if QT_VERSION >= 0x050000 verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); @@ -59,4 +40,13 @@ ScraperTableView::ScraperTableView(QWidget *parent) verticalHeader()->hide(); setSelectionMode(QAbstractItemView::SingleSelection); + + initTheme(this); +} + +void ScraperTableView::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + setStyleSheet(comicVineTheme.scraperTableViewQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.h b/YACReaderLibrary/comic_vine/scraper_tableview.h index 03eb0322..8061b8b8 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.h +++ b/YACReaderLibrary/comic_vine/scraper_tableview.h @@ -3,15 +3,16 @@ #include -class ScraperTableView : public QTableView +#include "themable.h" + +class ScraperTableView : public QTableView, protected Themable { Q_OBJECT public: explicit ScraperTableView(QWidget *parent = nullptr); -signals: - -public slots: +protected: + void applyTheme() override; }; #endif // SCRAPPER_TABLEVIEW_H diff --git a/YACReaderLibrary/comic_vine/search_single_comic.cpp b/YACReaderLibrary/comic_vine/search_single_comic.cpp index 1d637990..f9e44688 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.cpp +++ b/YACReaderLibrary/comic_vine/search_single_comic.cpp @@ -1,6 +1,7 @@ #include "search_single_comic.h" #include "scraper_lineedit.h" +#include "theme_manager.h" #include #include @@ -11,8 +12,7 @@ SearchSingleComic::SearchSingleComic(QWidget *parent) { // QLabel * label = new QLabel(tr("Please provide some additional information. At least one field is needed.")); - QLabel *label = new QLabel(tr("Please provide some additional information for this comic.")); - label->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); + label = new QLabel(tr("Please provide some additional information for this comic.")); // titleEdit = new ScraperLineEdit(tr("Title:")); // numberEdit = new ScraperLineEdit(tr("Number:")); @@ -39,6 +39,8 @@ SearchSingleComic::SearchSingleComic(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } QString SearchSingleComic::getVolumeInfo() const @@ -70,3 +72,10 @@ void SearchSingleComic::clean() { volumeEdit->clear(); } + +void SearchSingleComic::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/search_single_comic.h b/YACReaderLibrary/comic_vine/search_single_comic.h index 7a8d7c10..12195f77 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.h +++ b/YACReaderLibrary/comic_vine/search_single_comic.h @@ -4,10 +4,12 @@ #include #include "scraper_checkbox.h" +#include "themable.h" class ScraperLineEdit; +class QLabel; -class SearchSingleComic : public QWidget +class SearchSingleComic : public QWidget, protected Themable { Q_OBJECT public: @@ -24,5 +26,9 @@ private: // ScraperLineEdit *numberEdit; ScraperLineEdit *volumeEdit; ScraperCheckBox *exactMatchCheckBox; + QLabel *label; + +protected: + void applyTheme() override; }; #endif // SEARCH_SINGLE_COMIC_H diff --git a/YACReaderLibrary/comic_vine/search_volume.cpp b/YACReaderLibrary/comic_vine/search_volume.cpp index bace4425..29790686 100644 --- a/YACReaderLibrary/comic_vine/search_volume.cpp +++ b/YACReaderLibrary/comic_vine/search_volume.cpp @@ -2,6 +2,7 @@ #include "scraper_lineedit.h" #include "scraper_checkbox.h" +#include "theme_manager.h" #include #include @@ -9,8 +10,7 @@ SearchVolume::SearchVolume(QWidget *parent) : QWidget(parent) { - QLabel *label = new QLabel(tr("Please provide some additional information.")); - label->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); + label = new QLabel(tr("Please provide some additional information.")); volumeEdit = new ScraperLineEdit(tr("Series:")); volumeEdit->setClearButtonEnabled(true); @@ -29,6 +29,8 @@ SearchVolume::SearchVolume(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } void SearchVolume::clean() @@ -45,3 +47,10 @@ QString SearchVolume::getVolumeInfo() const { return volumeEdit->text(); } + +void SearchVolume::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/search_volume.h b/YACReaderLibrary/comic_vine/search_volume.h index 4ad8db80..09ca6437 100644 --- a/YACReaderLibrary/comic_vine/search_volume.h +++ b/YACReaderLibrary/comic_vine/search_volume.h @@ -3,11 +3,12 @@ #include #include "scraper_checkbox.h" +#include "themable.h" class ScraperLineEdit; class ScraperCheckBox; -class SearchVolume : public QWidget +class SearchVolume : public QWidget, protected Themable { Q_OBJECT public: @@ -20,6 +21,10 @@ public: private: ScraperLineEdit *volumeEdit; ScraperCheckBox *exactMatchCheckBox; + QLabel *label; + +protected: + void applyTheme() override; }; #endif // SEARCH_VOLUME_H diff --git a/YACReaderLibrary/comic_vine/select_comic.cpp b/YACReaderLibrary/comic_vine/select_comic.cpp index 70b64359..8c5a06a2 100644 --- a/YACReaderLibrary/comic_vine/select_comic.cpp +++ b/YACReaderLibrary/comic_vine/select_comic.cpp @@ -4,6 +4,7 @@ #include "scraper_scroll_label.h" #include "scraper_tableview.h" #include "volume_comics_model.h" +#include "theme_manager.h" #include #include @@ -13,10 +14,7 @@ SelectComic::SelectComic(QWidget *parent) : QWidget(parent), model(0) { - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; - - QLabel *label = new QLabel(tr("Please, select the right comic info.")); - label->setStyleSheet(labelStylesheet); + label = new QLabel(tr("Please, select the right comic info.")); auto l = new QVBoxLayout; QWidget *leftWidget = new QWidget; @@ -28,7 +26,6 @@ SelectComic::SelectComic(QWidget *parent) cover->setScaledContents(true); cover->setAlignment(Qt::AlignTop | Qt::AlignHCenter); cover->setMinimumSize(168, 168 * 5.0 / 3); - cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }"); detailLabel = new ScraperScrollLabel(this); tableComics = new ScraperTableView(this); @@ -63,6 +60,8 @@ SelectComic::SelectComic(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } void SelectComic::load(const QString &json, const QString &volumeId) @@ -164,3 +163,11 @@ QString SelectComic::getSelectedComicId() { return model->getComicId(tableComics->currentIndex()); } + +void SelectComic::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); + cover->setStyleSheet(comicVineTheme.coverLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/select_comic.h b/YACReaderLibrary/comic_vine/select_comic.h index 427c3e29..4b1120c6 100644 --- a/YACReaderLibrary/comic_vine/select_comic.h +++ b/YACReaderLibrary/comic_vine/select_comic.h @@ -4,6 +4,7 @@ #include #include "scraper_results_paginator.h" +#include "themable.h" class QLabel; class VolumeComicsModel; @@ -12,7 +13,7 @@ class QModelIndex; class ScraperScrollLabel; class ScraperTableView; -class SelectComic : public QWidget +class SelectComic : public QWidget, protected Themable { Q_OBJECT public: @@ -34,12 +35,16 @@ private slots: void loadPreviousPage(); private: + QLabel *label; QLabel *cover; ScraperScrollLabel *detailLabel; ScraperTableView *tableComics; VolumeComicsModel *model; QString currentVolumeId; ScraperResultsPaginator *paginator; + +protected: + void applyTheme() override; }; #endif // SELECT_COMIC_H diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index 86bd49ac..9a190d65 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -25,6 +25,7 @@ #include "scraper_results_paginator.h" #include "selected_volume_info.h" +#include "theme_manager.h" SelectVolume::SelectVolume(QWidget *parent) : QWidget(parent), model(0) @@ -32,10 +33,7 @@ SelectVolume::SelectVolume(QWidget *parent) proxyModel = new QSortFilterProxyModel; proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; - - QLabel *label = new QLabel(tr("Please, select the right series for your comic.")); - label->setStyleSheet(labelStylesheet); + label = new QLabel(tr("Please, select the right series for your comic.")); auto l = new QVBoxLayout; QWidget *leftWidget = new QWidget; @@ -48,7 +46,6 @@ SelectVolume::SelectVolume(QWidget *parent) cover->setScaledContents(true); cover->setAlignment(Qt::AlignTop | Qt::AlignHCenter); cover->setMinimumSize(168, 168 * 5.0 / 3); - cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }"); detailLabel = new ScraperScrollLabel(); tableVolumes = new ScraperTableView(); @@ -94,6 +91,8 @@ SelectVolume::SelectVolume(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } void SelectVolume::load(const QString &json, const VolumeSearchQuery &searchQuery) @@ -218,3 +217,11 @@ SelectedVolumeInfo SelectVolume::getSelectedVolumeInfo() return { volumeId, numIssues, publisher, selectedVolumeDescription }; } + +void SelectVolume::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); + cover->setStyleSheet(comicVineTheme.coverLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/select_volume.h b/YACReaderLibrary/comic_vine/select_volume.h index 944c833b..f4e06d1b 100644 --- a/YACReaderLibrary/comic_vine/select_volume.h +++ b/YACReaderLibrary/comic_vine/select_volume.h @@ -6,6 +6,7 @@ #include "scraper_results_paginator.h" #include "selected_volume_info.h" #include "volume_search_query.h" +#include "themable.h" class QLabel; class VolumesModel; @@ -17,7 +18,7 @@ class ScraperScrollLabel; class ScraperTableView; class ScraperLineEdit; -class SelectVolume : public QWidget +class SelectVolume : public QWidget, protected Themable { Q_OBJECT public: @@ -40,6 +41,7 @@ private slots: void loadPreviousPage(); private: + QLabel *label; QLabel *cover; ScraperScrollLabel *detailLabel; ScraperTableView *tableVolumes; @@ -49,6 +51,9 @@ private: QString selectedVolumeDescription; VolumeSearchQuery currentSearchQuery; ScraperResultsPaginator *paginator; + +protected: + void applyTheme() override; }; #endif // SELECT_VOLUME_H diff --git a/YACReaderLibrary/comic_vine/series_question.cpp b/YACReaderLibrary/comic_vine/series_question.cpp index d04fba67..80b43bf3 100644 --- a/YACReaderLibrary/comic_vine/series_question.cpp +++ b/YACReaderLibrary/comic_vine/series_question.cpp @@ -1,5 +1,7 @@ #include "series_question.h" +#include "theme_manager.h" + #include #include #include @@ -9,18 +11,10 @@ SeriesQuestion::SeriesQuestion(QWidget *parent) { auto l = new QVBoxLayout; - QLabel *questionLabel = new QLabel(tr("You are trying to get information for various comics at once, are they part of the same series?")); - questionLabel->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); + questionLabel = new QLabel(tr("You are trying to get information for various comics at once, are they part of the same series?")); yes = new QRadioButton(tr("yes")); no = new QRadioButton(tr("no")); - QString rbStyle = "QRadioButton {margin-left:27px; margin-top:5px; color:white;font-size:12px;font-family:Arial;}" - "QRadioButton::indicator {width:11px;height:11px;}" - "QRadioButton::indicator::unchecked {image : url(:/images/comic_vine/radioUnchecked.png);}" - "QRadioButton::indicator::checked {image : url(:/images/comic_vine/radioChecked.png);}"; - yes->setStyleSheet(rbStyle); - no->setStyleSheet(rbStyle); - yes->setChecked(true); l->addSpacing(35); @@ -32,6 +26,8 @@ SeriesQuestion::SeriesQuestion(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } bool SeriesQuestion::getYes() @@ -43,3 +39,12 @@ void SeriesQuestion::setYes(bool y) { yes->setChecked(y); } + +void SeriesQuestion::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + questionLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); + yes->setStyleSheet(comicVineTheme.radioButtonQSS); + no->setStyleSheet(comicVineTheme.radioButtonQSS); +} diff --git a/YACReaderLibrary/comic_vine/series_question.h b/YACReaderLibrary/comic_vine/series_question.h index a02654f8..b354fb5c 100644 --- a/YACReaderLibrary/comic_vine/series_question.h +++ b/YACReaderLibrary/comic_vine/series_question.h @@ -3,9 +3,12 @@ #include -class QRadioButton; +#include "themable.h" -class SeriesQuestion : public QWidget +class QRadioButton; +class QLabel; + +class SeriesQuestion : public QWidget, protected Themable { Q_OBJECT @@ -15,8 +18,12 @@ public: void setYes(bool yes = true); private: + QLabel *questionLabel; QRadioButton *yes; QRadioButton *no; + +protected: + void applyTheme() override; }; #endif // SERIES_QUESTION_H diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp index fedd54a9..40f6d097 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp @@ -9,23 +9,60 @@ #include "scraper_tableview.h" #include "local_comic_list_model.h" #include "volume_comics_model.h" +#include "theme_manager.h" + +ScrapperToolButton::ScrapperToolButton(ScrapperToolButton::Appearance appearance, QWidget *parent) + : QPushButton(parent), appearance(appearance) +{ + setFixedSize(18, 17); + initTheme(this); +} + +QWidget *ScrapperToolButton::getSeparator() +{ + QWidget *w = new QWidget; + w->setFixedWidth(1); + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + w->setStyleSheet(comicVineTheme.scraperToolButtonSeparatorQSS); + return w; +} + +void ScrapperToolButton::paintEvent(QPaintEvent *e) +{ + QPainter p(this); + + switch (appearance) { + case LEFT: + p.fillRect(16, 0, 2, 18, fillColor); + break; + case RIGHT: + p.fillRect(0, 0, 2, 18, fillColor); + break; + default: + break; + } + + QPushButton::paintEvent(e); +} + +void ScrapperToolButton::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + setStyleSheet(comicVineTheme.scraperToolButtonQSS); + fillColor = comicVineTheme.scraperToolButtonFillColor; + update(); +} SortVolumeComics::SortVolumeComics(QWidget *parent) : QWidget(parent) { - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; + label = new QLabel(tr("Please, sort the list of comics on the left until it matches the comics' information.")); - QLabel *label = new QLabel(tr("Please, sort the list of comics on the left until it matches the comics' information.")); - label->setStyleSheet(labelStylesheet); - - QLabel *sortLabel = new QLabel(tr("sort comics to match comic information")); - sortLabel->setStyleSheet(labelStylesheet); + sortLabel = new QLabel(tr("sort comics to match comic information")); moveUpButtonCL = new ScrapperToolButton(ScrapperToolButton::LEFT); - moveUpButtonCL->setIcon(QIcon(":/images/comic_vine/rowUp.png")); moveUpButtonCL->setAutoRepeat(true); moveDownButtonCL = new ScrapperToolButton(ScrapperToolButton::RIGHT); - moveDownButtonCL->setIcon(QIcon(":/images/comic_vine/rowDown.png")); moveDownButtonCL->setAutoRepeat(true); // moveUpButtonIL = new ScrapperToolButton(ScrapperToolButton::LEFT); // moveUpButtonIL->setIcon(QIcon(":/images/comic_vine/rowUp.png")); @@ -98,6 +135,8 @@ SortVolumeComics::SortVolumeComics(QWidget *parent) connect(removeItemFromList, &QAction::triggered, this, &SortVolumeComics::removeSelectedComics); connect(restoreAllItems, &QAction::triggered, this, &SortVolumeComics::restoreAllComics); // connect(restoreItems,SIGNAL(triggered()),this,SLOT(showRemovedComicsSelector())); + + initTheme(this); } void SortVolumeComics::setData(QList &comics, const QString &json, const QString &vID) @@ -225,3 +264,16 @@ QList> SortVolumeComics::getMatchingInfo() return l; } + +void SortVolumeComics::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); + sortLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); + + moveUpButtonCL->setIconSize(comicVineTheme.rowUpIcon.size); + moveUpButtonCL->setIcon(comicVineTheme.rowUpIcon.icon); + moveDownButtonCL->setIconSize(comicVineTheme.rowDownIcon.size); + moveDownButtonCL->setIcon(comicVineTheme.rowDownIcon.icon); +} diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.h b/YACReaderLibrary/comic_vine/sort_volume_comics.h index 2a600341..5e891337 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.h +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.h @@ -8,12 +8,14 @@ #include "comic_db.h" #include "scraper_results_paginator.h" +#include "themable.h" class ScraperTableView; class LocalComicListModel; class VolumeComicsModel; +class QLabel; -class ScrapperToolButton : public QPushButton +class ScrapperToolButton : public QPushButton, protected Themable { Q_OBJECT public: @@ -23,47 +25,21 @@ public: RIGHT }; - ScrapperToolButton(ScrapperToolButton::Appearance appearance = DEFAULT, QWidget *parent = nullptr) - : QPushButton(parent), appearance(appearance) - { - setStyleSheet("QPushButton {border: none; background: #2e2e2e; color:white; border-radius:2px;}" - "QPushButton::pressed {border: none; background: #282828; color:white; border-radius:2px;}"); - setFixedSize(18, 17); - } - static QWidget *getSeparator() - { - QWidget *w = new QWidget; - w->setFixedWidth(1); - w->setStyleSheet("QWidget {background:#282828;}"); - return w; - } + ScrapperToolButton(ScrapperToolButton::Appearance appearance = DEFAULT, QWidget *parent = nullptr); + static QWidget *getSeparator(); void setAppearance(ScrapperToolButton::Appearance appearance) { this->appearance = appearance; } virtual ~ScrapperToolButton() { } protected: - void paintEvent(QPaintEvent *e) override - { - QPainter p(this); - - switch (appearance) { - case LEFT: - p.fillRect(16, 0, 2, 18, QColor("#2E2E2E")); - break; - case RIGHT: - p.fillRect(0, 0, 2, 18, QColor("#2E2E2E")); - break; - default: - break; - } - - QPushButton::paintEvent(e); - } + void paintEvent(QPaintEvent *e) override; + void applyTheme() override; private: Appearance appearance; + QColor fillColor; }; -class SortVolumeComics : public QWidget +class SortVolumeComics : public QWidget, protected Themable { Q_OBJECT public: @@ -92,6 +68,8 @@ private slots: void loadPreviousPage(); private: + QLabel *label; + QLabel *sortLabel; ScraperTableView *tableFiles; ScraperTableView *tableVolumeComics; @@ -105,6 +83,9 @@ private: QString currentVolumeId; ScraperResultsPaginator *paginator; + +protected: + void applyTheme() override; }; #endif // SORT_VOLUME_COMICS_H diff --git a/YACReaderLibrary/comic_vine/title_header.cpp b/YACReaderLibrary/comic_vine/title_header.cpp index 4dd4a2aa..77931b57 100644 --- a/YACReaderLibrary/comic_vine/title_header.cpp +++ b/YACReaderLibrary/comic_vine/title_header.cpp @@ -1,5 +1,7 @@ #include "title_header.h" +#include "theme_manager.h" + #include #include #include @@ -10,9 +12,6 @@ TitleHeader::TitleHeader(QWidget *parent) mainTitleLabel = new QLabel(); subTitleLabel = new QLabel(); - mainTitleLabel->setStyleSheet("QLabel {color:white; font-size:18px;font-family:Arial;}"); - subTitleLabel->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); - auto titleLayout = new QHBoxLayout; auto titleLabelsLayout = new QVBoxLayout; @@ -28,6 +27,8 @@ TitleHeader::TitleHeader(QWidget *parent) setContentsMargins(0, 0, 0, 0); setTitle(tr("SEARCH")); + + initTheme(this); } void TitleHeader::setTitle(const QString &title) @@ -47,3 +48,11 @@ void TitleHeader::showButtons(bool show) } else { } } + +void TitleHeader::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + mainTitleLabel->setStyleSheet(comicVineTheme.titleLabelQSS); + subTitleLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/title_header.h b/YACReaderLibrary/comic_vine/title_header.h index 4a359ede..01956e40 100644 --- a/YACReaderLibrary/comic_vine/title_header.h +++ b/YACReaderLibrary/comic_vine/title_header.h @@ -3,9 +3,11 @@ #include +#include "themable.h" + class QLabel; -class TitleHeader : public QWidget +class TitleHeader : public QWidget, protected Themable { Q_OBJECT public: @@ -18,6 +20,9 @@ public slots: private: QLabel *mainTitleLabel; QLabel *subTitleLabel; + +protected: + void applyTheme() override; }; #endif // TITLE_HEADER_H diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index c770f3e2..884c48f0 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -1,7 +1,129 @@ #ifndef THEME_H #define THEME_H +#include + +#include "yacreader_icon.h" + +struct ComicVineThemeTemplates { + QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; + QString titleLabelQSS = "QLabel {color:%1; font-size:18px;font-family:Arial;}"; + QString coverLabelQSS = "QLabel {background-color: %1; color:%2; font-size:12px; font-family:Arial; }"; + + QString radioButtonQSS = "QRadioButton {margin-left:27px; margin-top:5px; color:%1;font-size:12px;font-family:Arial;}" + "QRadioButton::indicator {width:11px;height:11px;}" + "QRadioButton::indicator::unchecked {image : url(%2);}" + "QRadioButton::indicator::checked {image : url(%3);}"; + + QString checkBoxQSS = "QCheckBox {" + " color: %1;" + " font-size: 12px;" + " font-family: Arial;" + " spacing: 10px;" + "}" + "QCheckBox::indicator {" + " width: 13px;" + " height: 13px;" + " border: 1px solid %2;" + " background: %3;" + "}" + "QCheckBox::indicator:checked {" + " image: url(%4);" + " background: %3;" + "}" + "QCheckBox::indicator:unchecked {" + " background: %3;" + "}"; + + QString scraperLineEditTitleLabelQSS = "QLabel {color:%1;}"; + QString scraperLineEditQSS = "QLineEdit {" + "border:none; background-color: %1; color : %2; padding-left: %3; padding-bottom: 1px; margin-bottom: 0px;" + "}"; + + QString scraperToolButtonQSS = "QPushButton {border: none; background: %1; color:%2; border-radius:2px;}" + "QPushButton::pressed {border: none; background: %3; color:%2; border-radius:2px;}"; + QString scraperToolButtonSeparatorQSS = "QWidget {background:%1;}"; + + QString scraperScrollLabelTextQSS = "QLabel {background-color: %1; color:%2; font-size:12px; font-family:Arial; } QLabel::link { color: %3; font-size:12px; font-family:Arial; }"; + QString scraperScrollLabelScrollAreaQSS = "QScrollArea {background-color:%1; border:none;}" + "QScrollBar:vertical { border: none; background: %1; width: 3px; margin: 0; }" + "QScrollBar:horizontal { border: none; background: %1; height: 3px; margin: 0; }" + "QScrollBar::handle:vertical { background: %2; width: 7px; min-height: 20px; }" + "QScrollBar::handle:horizontal { background: %2; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::add-line:horizontal { border: none; background: %3; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::sub-line:horizontal { border: none; background: %3; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"; + + QString scraperTableViewQSS = "QTableView {color:%1; border:0px;alternate-background-color: %2;background-color: %3; outline: 0px;}" + "QTableView::item {outline: 0px; border: 0px; color:%1;}" + "QTableView::item:selected {outline: 0px; background-color: %4; }" + "QHeaderView::section:horizontal {background-color:%5; border-bottom:1px solid %6; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %6); border-left:none; border-top:none; padding:4px; color:%7;}" + "QHeaderView::section:vertical {border-bottom: 1px solid %8;border-top: 1px solid %9;}" + "QHeaderView::down-arrow {image: url('%12');width: 8px;height: 7px;padding-right: 10px;}" + "QHeaderView::up-arrow {image: url('%13');width: 8px;height: 7px; padding-right: 10px;}" + "QScrollBar:vertical { border: none; background: %3; width: 3px; margin: 0; }" + "QScrollBar:horizontal { border: none; background: %3; height: 3px; margin: 0; }" + "QScrollBar::handle:vertical { background: %10; width: 7px; min-height: 20px; }" + "QScrollBar::handle:horizontal { background: %10; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %11; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %11; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::add-line:horizontal { border: none; background: %11; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::sub-line:horizontal { border: none; background: %11; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"; + + QString dialogQSS = "QDialog {background-color: %1; }"; + QString dialogButtonsQSS = "QPushButton {border: 1px solid %1; background: %2; color:%3; padding: 5px 26px 5px 26px; font-size:12px;font-family:Arial; font-weight:bold;}"; + + QString nextPageIcon = ":/images/comic_vine/nextPage.svg"; + QString previousPageIcon = ":/images/comic_vine/previousPage.svg"; + QSize pageIconSize = QSize(7, 8); + + QString rowUpIcon = ":/images/comic_vine/rowUp.svg"; + QString rowDownIcon = ":/images/comic_vine/rowDown.svg"; + QSize rowIconSize = QSize(8, 7); +}; + +struct ComicVineTheme { + QString defaultLabelQSS; + QString titleLabelQSS; + QString coverLabelQSS; + QString radioButtonQSS; + QString checkBoxQSS; + + QString scraperLineEditTitleLabelQSS; + QString scraperLineEditQSS; + + QString scraperToolButtonQSS; + QString scraperToolButtonSeparatorQSS; + QColor scraperToolButtonFillColor; + + QString scraperScrollLabelTextQSS; + QString scraperScrollLabelScrollAreaQSS; + + QString scraperTableViewQSS; + + QString dialogQSS; + QString dialogButtonsQSS; + + QString noBorderToolButtonQSS = "QToolButton { border: none; }"; + + QColor busyIndicatorColor; + + YACReaderIcon nextPageIcon; + YACReaderIcon previousPageIcon; + + YACReaderIcon rowUpIcon; + YACReaderIcon rowDownIcon; +}; + struct Theme { + ComicVineTheme comicVine; }; #endif // THEME_H diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp new file mode 100644 index 00000000..93c5fa0e --- /dev/null +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -0,0 +1,299 @@ +#include "theme_factory.h" + +#include "icon_utils.h" + +struct ComicVineParams { + + ComicVineThemeTemplates t; + + QColor contentTextColor; + QColor contentBackgroundColor; + QColor contentAltBackgroundColor; + QColor dialogBackgroundColor; + + QColor tableBackgroundColor; + QColor tableAltBackgroundColor; + QColor tableBorderColor; + QColor tableSelectedColor; + QColor tableHeaderBackgroundColor; + QColor tableHeaderBorderColor; + QColor tableHeaderTextColor; + QColor tableScrollHandleColor; + QColor tableScrollBackgroundColor; + QColor tableSectionBorderLight; + QColor tableSectionBorderDark; + + QColor labelTextColor; + QColor labelBackgroundColor; + QColor hyperlinkColor; // TODO: it doesn't work + + QColor buttonBackgroundColor; + QColor buttonTextColor; + QColor buttonBorderColor; + + QString radioUncheckedPath; + QColor radioUncheckedColor; + + QString radioCheckedPath; + QColor radioCheckedBackgroundColor; + QColor radioCheckedIndicatorColor; + + QColor checkBoxTickColor; + + QColor toolButtonAccentColor; + + QColor downArrowColor; + QColor upArrowColor; + + QColor busyIndicatorColor; + QColor navIconColor; + QColor rowIconColor; +}; + +struct ThemeParams { + QString themeName; + + ComicVineParams comicVineParams; +}; + +Theme makeTheme(const ThemeParams ¶ms) +{ + Theme theme; + + const auto &cv = params.comicVineParams; + const auto &t = cv.t; + + auto recolor = [&](const QString &path, const QColor &color) { + return recoloredSvgToThemeFile(path, color, params.themeName); + }; + + theme.comicVine.defaultLabelQSS = t.defaultLabelQSS.arg(cv.labelTextColor.name()); + theme.comicVine.titleLabelQSS = t.titleLabelQSS.arg(cv.labelTextColor.name()); + theme.comicVine.coverLabelQSS = t.coverLabelQSS.arg(cv.labelBackgroundColor.name(), cv.labelTextColor.name()); + theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(cv.radioUncheckedPath, cv.radioUncheckedColor), recoloredSvgToThemeFile(cv.radioCheckedPath, cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.themeName)); + theme.comicVine.checkBoxQSS = t.checkBoxQSS.arg(cv.buttonTextColor.name(), cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), recolor(":/images/comic_vine/checkBoxTick.svg", cv.checkBoxTickColor)); + + theme.comicVine.scraperLineEditTitleLabelQSS = t.scraperLineEditTitleLabelQSS.arg(cv.contentTextColor.name()); + theme.comicVine.scraperLineEditQSS = t.scraperLineEditQSS.arg(cv.contentAltBackgroundColor.name(), cv.contentTextColor.name(), "%1"); + + theme.comicVine.scraperToolButtonQSS = t.scraperToolButtonQSS.arg(cv.buttonBackgroundColor.name(), cv.buttonTextColor.name(), cv.toolButtonAccentColor.name()); + theme.comicVine.scraperToolButtonSeparatorQSS = t.scraperToolButtonSeparatorQSS.arg(cv.toolButtonAccentColor.name()); + theme.comicVine.scraperToolButtonFillColor = cv.buttonBackgroundColor; + + theme.comicVine.scraperScrollLabelTextQSS = t.scraperScrollLabelTextQSS.arg(cv.contentBackgroundColor.name(), cv.contentTextColor.name(), cv.hyperlinkColor.name()); + theme.comicVine.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(cv.contentBackgroundColor.name(), cv.tableScrollHandleColor.name(), cv.tableScrollBackgroundColor.name()); + + theme.comicVine.scraperTableViewQSS = t.scraperTableViewQSS + .arg(cv.tableHeaderTextColor.name()) + .arg(cv.tableAltBackgroundColor.name()) + .arg(cv.tableBackgroundColor.name()) + .arg(cv.tableSelectedColor.name()) + .arg(cv.tableHeaderBackgroundColor.name()) + .arg(cv.tableHeaderBorderColor.name()) + .arg(cv.tableHeaderTextColor.name()) + .arg(cv.tableSectionBorderDark.name()) + .arg(cv.tableSectionBorderLight.name()) + .arg(cv.tableScrollHandleColor.name()) + .arg(cv.tableScrollBackgroundColor.name()) + .arg(recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor)) + .arg(recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); + + theme.comicVine.dialogQSS = t.dialogQSS.arg(cv.dialogBackgroundColor.name()); + theme.comicVine.dialogButtonsQSS = t.dialogButtonsQSS.arg(cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), cv.buttonTextColor.name()); + + theme.comicVine.busyIndicatorColor = cv.busyIndicatorColor; + + theme.comicVine.nextPageIcon = { QIcon(recolor(t.nextPageIcon, cv.navIconColor)), t.pageIconSize }; + theme.comicVine.previousPageIcon = { QIcon(recolor(t.previousPageIcon, cv.navIconColor)), t.pageIconSize }; + + theme.comicVine.rowUpIcon = { QIcon(recolor(t.rowUpIcon, cv.rowIconColor)), t.rowIconSize }; + theme.comicVine.rowDownIcon = { QIcon(recolor(t.rowDownIcon, cv.rowIconColor)), t.rowIconSize }; + + return theme; +} + +ThemeParams classicThemeParams(); +ThemeParams lightThemeParams(); +ThemeParams darkThemeParams(); + +Theme makeTheme(ThemeId themeId) +{ + switch (themeId) { + case ThemeId::Classic: + return makeTheme(classicThemeParams()); + case ThemeId::Light: + return makeTheme(lightThemeParams()); + case ThemeId::Dark: + return makeTheme(darkThemeParams()); + } + + return makeTheme(classicThemeParams()); +} + +ThemeParams classicThemeParams() +{ + ThemeParams params; + params.themeName = "classic"; + + ComicVineParams cv; + cv.contentTextColor = Qt::white; + cv.contentBackgroundColor = QColor(0x2B2B2B); + cv.contentAltBackgroundColor = QColor(0x2B2B2B); + cv.dialogBackgroundColor = QColor(0x404040); + + cv.tableBackgroundColor = QColor(0x2B2B2B); + cv.tableAltBackgroundColor = QColor(0x2E2E2E); + cv.tableBorderColor = QColor(0x242424); + cv.tableSelectedColor = QColor(0x555555); + cv.tableHeaderBackgroundColor = QColor(0x292929); + cv.tableHeaderBorderColor = QColor(0x1F1F1F); + cv.tableHeaderTextColor = QColor(0xEBEBEB); + cv.tableScrollHandleColor = QColor(0xDDDDDD); + cv.tableScrollBackgroundColor = QColor(0x404040); + cv.tableSectionBorderLight = QColor(0xFEFEFE); + cv.tableSectionBorderDark = QColor(0xDFDFDF); + + cv.labelTextColor = Qt::white; + cv.labelBackgroundColor = QColor(0x2B2B2B); + cv.hyperlinkColor = QColor(0xFFCC00); + + cv.buttonBackgroundColor = QColor(0x2E2E2E); + cv.buttonTextColor = Qt::white; + cv.buttonBorderColor = QColor(0x242424); + + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedColor = QColor(0xE5E5E5); + + cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; + cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); + cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); + + cv.checkBoxTickColor = Qt::white; + + cv.toolButtonAccentColor = QColor(0x282828); + + cv.downArrowColor = QColor(0x9F9F9F); + cv.upArrowColor = QColor(0x9F9F9F); + + cv.busyIndicatorColor = Qt::white; + cv.navIconColor = Qt::white; + cv.rowIconColor = QColor(0xE5E5E5); + + cv.t = ComicVineThemeTemplates(); + + params.comicVineParams = cv; + + return params; +} + +ThemeParams lightThemeParams() +{ + ThemeParams params; + params.themeName = "light"; + + ComicVineParams cv; + cv.contentTextColor = Qt::black; + cv.contentBackgroundColor = QColor(0xECECEC); + cv.contentAltBackgroundColor = QColor(0xE0E0E0); + cv.dialogBackgroundColor = QColor(0xFBFBFB); + + cv.tableBackgroundColor = QColor(0xF4F4F4); + cv.tableAltBackgroundColor = QColor(0xFAFAFA); + cv.tableBorderColor = QColor(0xCCCCCC); + cv.tableSelectedColor = QColor(0xDDDDDD); + cv.tableHeaderBackgroundColor = QColor(0xE0E0E0); + cv.tableHeaderBorderColor = QColor(0xC0C0C0); + cv.tableHeaderTextColor = QColor(0x333333); + cv.tableScrollHandleColor = QColor(0x888888); + cv.tableScrollBackgroundColor = QColor(0xD0D0D0); + cv.tableSectionBorderLight = QColor(0xFFFFFF); + cv.tableSectionBorderDark = QColor(0xCCCCCC); + + cv.labelTextColor = Qt::black; + cv.labelBackgroundColor = QColor(0xECECEC); + cv.hyperlinkColor = QColor(0xFFCC00); + + cv.buttonBackgroundColor = QColor(0xE0E0E0); + cv.buttonTextColor = Qt::black; + cv.buttonBorderColor = QColor(0xCCCCCC); + + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; + cv.radioUncheckedColor = QColor(0xE0E0E0); + + cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; + cv.radioCheckedBackgroundColor = QColor(0xE0E0E0); + cv.radioCheckedIndicatorColor = QColor(0x222222); + + cv.checkBoxTickColor = Qt::black; + + cv.toolButtonAccentColor = QColor(0xA0A0A0); + + cv.downArrowColor = QColor(0x222222); + cv.upArrowColor = QColor(0x222222); + + cv.busyIndicatorColor = Qt::black; + cv.navIconColor = QColor(0x222222); + cv.rowIconColor = QColor(0x222222); + + cv.t = ComicVineThemeTemplates(); + + params.comicVineParams = cv; + + return params; +} + +ThemeParams darkThemeParams() +{ + ThemeParams params; + params.themeName = "dark"; + + ComicVineParams cv; + cv.contentTextColor = Qt::white; + cv.contentBackgroundColor = QColor(0x2B2B2B); + cv.contentAltBackgroundColor = QColor(0x2E2E2E); + cv.dialogBackgroundColor = QColor(0x404040); + + cv.tableBackgroundColor = QColor(0x2B2B2B); + cv.tableAltBackgroundColor = QColor(0x2E2E2E); + cv.tableBorderColor = QColor(0x242424); + cv.tableSelectedColor = QColor(0x555555); + cv.tableHeaderBackgroundColor = QColor(0x292929); + cv.tableHeaderBorderColor = QColor(0x1F1F1F); + cv.tableHeaderTextColor = QColor(0xEBEBEB); + cv.tableScrollHandleColor = QColor(0xDDDDDD); + cv.tableScrollBackgroundColor = QColor(0x404040); + cv.tableSectionBorderLight = QColor(0xFEFEFE); + cv.tableSectionBorderDark = QColor(0xDFDFDF); + + cv.labelTextColor = Qt::white; + cv.labelBackgroundColor = QColor(0x2B2B2B); + cv.hyperlinkColor = QColor(0xFFCC00); + + cv.buttonBackgroundColor = QColor(0x2E2E2E); + cv.buttonTextColor = Qt::white; + cv.buttonBorderColor = QColor(0x242424); + + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedColor = QColor(0xE5E5E5); + + cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; + cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); + cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); + + cv.checkBoxTickColor = Qt::white; + + cv.toolButtonAccentColor = QColor(0x282828); + + cv.downArrowColor = QColor(0x9F9F9F); + cv.upArrowColor = QColor(0x9F9F9F); + + cv.busyIndicatorColor = Qt::white; + cv.navIconColor = Qt::white; + cv.rowIconColor = QColor(0xE5E5E5); + + cv.t = ComicVineThemeTemplates(); + + params.comicVineParams = cv; + + return params; +} diff --git a/YACReaderLibrary/themes/theme_factory.h b/YACReaderLibrary/themes/theme_factory.h new file mode 100644 index 00000000..72cb4ca2 --- /dev/null +++ b/YACReaderLibrary/themes/theme_factory.h @@ -0,0 +1,9 @@ +#ifndef THEME_FACTORY_H +#define THEME_FACTORY_H + +#include "theme.h" +#include "theme_id.h" + +Theme makeTheme(ThemeId themeId); + +#endif // THEME_FACTORY_H diff --git a/YACReaderLibrary/themes/themes.pri b/YACReaderLibrary/themes/themes.pri index 9e42ad15..eee35324 100644 --- a/YACReaderLibrary/themes/themes.pri +++ b/YACReaderLibrary/themes/themes.pri @@ -2,3 +2,6 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/theme.h \ + $$PWD/theme_factory.h +SOURCES += \ + $$PWD/theme_factory.cpp