Add toolbar and background theming to YACReader

This commit is contained in:
luisangelsm
2026-01-14 15:51:32 +01:00
parent b46f34adb1
commit 721da42c8c
20 changed files with 482 additions and 37 deletions

View File

@ -37,8 +37,6 @@ void Configuration::load(QSettings *settings)
settings->setValue(MAXIMIZED, false); settings->setValue(MAXIMIZED, false);
if (!settings->contains(DOUBLE_PAGE)) if (!settings->contains(DOUBLE_PAGE))
settings->setValue(DOUBLE_PAGE, false); settings->setValue(DOUBLE_PAGE, false);
if (!settings->contains(BACKGROUND_COLOR))
settings->setValue(BACKGROUND_COLOR, QColor(40, 40, 40));
if (!settings->contains(SHOW_TOOLBARS)) if (!settings->contains(SHOW_TOOLBARS))
settings->setValue(SHOW_TOOLBARS, true); settings->setValue(SHOW_TOOLBARS, true);
if (!settings->contains(QUICK_NAVI_MODE)) if (!settings->contains(QUICK_NAVI_MODE))

View File

@ -85,8 +85,8 @@ public:
bool getEnlargeImages() { return settings->value(ENLARGE_IMAGES, true).toBool(); } bool getEnlargeImages() { return settings->value(ENLARGE_IMAGES, true).toBool(); }
void setEnlargeImages(bool b) { settings->setValue(ENLARGE_IMAGES, b); } void setEnlargeImages(bool b) { settings->setValue(ENLARGE_IMAGES, b); }
QColor getBackgroundColor() { return settings->value(BACKGROUND_COLOR).value<QColor>(); } QColor getBackgroundColor(const QColor &color) { return settings->value(BACKGROUND_COLOR, color).value<QColor>(); }
void setBackgroundColor(const QColor &color) { settings->value(BACKGROUND_COLOR, color); } void setBackgroundColor(const QColor &color) { settings->setValue(BACKGROUND_COLOR, color); }
bool getShowToolbars() { return settings->value(SHOW_TOOLBARS).toBool(); } bool getShowToolbars() { return settings->value(SHOW_TOOLBARS).toBool(); }
void setShowToolbars(bool b) { settings->setValue(SHOW_TOOLBARS, b); } void setShowToolbars(bool b) { settings->setValue(SHOW_TOOLBARS, b); }
bool getShowInformation() { return settings->value(SHOW_INFO, false).toBool(); } bool getShowInformation() { return settings->value(SHOW_INFO, false).toBool(); }

View File

@ -2,6 +2,8 @@
#include "viewer.h" #include "viewer.h"
#include "configuration.h" #include "configuration.h"
#include "theme_manager.h"
#include <QScrollBar> #include <QScrollBar>
MagnifyingGlass::MagnifyingGlass(int w, int h, float zoomLevel, QWidget *parent) MagnifyingGlass::MagnifyingGlass(int w, int h, float zoomLevel, QWidget *parent)
@ -77,7 +79,7 @@ void MagnifyingGlass::updateImage(int x, int y)
if (outImage) { if (outImage) {
QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32); QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32);
img.setDevicePixelRatio(devicePixelRatioF()); img.setDevicePixelRatio(devicePixelRatioF());
img.fill(Configuration::getConfiguration().getBackgroundColor()); img.fill(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor));
if (zw > 0 && zh > 0) { if (zw > 0 && zh > 0) {
QPainter painter(&img); QPainter painter(&img);
painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh));
@ -118,7 +120,7 @@ void MagnifyingGlass::updateImage(int x, int y)
if (outImage) { if (outImage) {
QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32); QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32);
img.setDevicePixelRatio(devicePixelRatioF()); img.setDevicePixelRatio(devicePixelRatioF());
img.fill(Configuration::getConfiguration().getBackgroundColor()); img.fill(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor));
if (zw > 0 && zh > 0) { if (zw > 0 && zh > 0) {
QPainter painter(&img); QPainter painter(&img);
painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh));

View File

@ -18,6 +18,7 @@
#include "yacreader_global.h" #include "yacreader_global.h"
#include "edit_shortcuts_dialog.h" #include "edit_shortcuts_dialog.h"
#include "shortcuts_manager.h" #include "shortcuts_manager.h"
#include "theme_manager.h"
#include "whats_new_controller.h" #include "whats_new_controller.h"
@ -40,11 +41,12 @@
#endif #endif
MainWindowViewer::MainWindowViewer() MainWindowViewer::MainWindowViewer()
: QMainWindow(), fullscreen(false), toolbars(true), currentDirectory("."), currentDirectoryImgDest("."), isClient(false) : QMainWindow(), fullscreen(false), toolbars(true), currentDirectory("."), currentDirectoryImgDest("."), openToolButton(nullptr), isClient(false)
{ {
loadConfiguration(); loadConfiguration();
setupUI(); setupUI();
afterLaunchTasks(); afterLaunchTasks();
initTheme(this);
} }
void MainWindowViewer::afterLaunchTasks() void MainWindowViewer::afterLaunchTasks()
@ -503,16 +505,16 @@ void MainWindowViewer::createToolBars()
recentmenu->addAction(clearRecentFilesAction); recentmenu->addAction(clearRecentFilesAction);
refreshRecentFilesActionList(); refreshRecentFilesActionList();
auto tb = new QToolButton(); openToolButton = new QToolButton();
auto open = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction); auto open = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction);
tb->addAction(open); openToolButton->addAction(open);
tb->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction)); openToolButton->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction));
tb->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); openToolButton->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction));
tb->addAction(recentmenu->menuAction()); openToolButton->addAction(recentmenu->menuAction());
tb->setPopupMode(QToolButton::MenuButtonPopup); openToolButton->setPopupMode(QToolButton::MenuButtonPopup);
tb->setDefaultAction(open); openToolButton->setDefaultAction(open);
comicToolBar->addWidget(tb); comicToolBar->addWidget(openToolButton);
#endif #endif
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/save")), saveImageAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/save")), saveImageAction));
@ -1554,6 +1556,56 @@ void MainWindowViewer::setLoadedComicActionsEnabled(bool enabled)
a->setEnabled(enabled); a->setEnabled(enabled);
} }
void MainWindowViewer::applyTheme()
{
const auto toolbarTheme = ThemeManager::instance().getCurrentTheme().toolbar;
if (comicToolBar) {
comicToolBar->setStyleSheet(toolbarTheme.toolbarQSS);
}
auto setIcon = [](QAction *action, const QIcon &icon, const QIcon &icon18x18) {
if (action) {
action->setIcon(icon);
auto action18x18 = action->property("customIconAction").value<QAction *>();
if (action18x18) {
action18x18->setIcon(icon18x18);
}
}
};
setIcon(openAction, toolbarTheme.openAction, toolbarTheme.openAction18x18);
setIcon(openFolderAction, toolbarTheme.openFolderAction, toolbarTheme.openFolderAction18x18);
setIcon(openLatestComicAction, toolbarTheme.openLatestComicAction, toolbarTheme.openLatestComicAction18x18);
setIcon(saveImageAction, toolbarTheme.saveImageAction, toolbarTheme.saveImageAction18x18);
setIcon(openComicOnTheLeftAction, toolbarTheme.openComicOnTheLeftAction, toolbarTheme.openComicOnTheLeftAction18x18);
setIcon(openComicOnTheRightAction, toolbarTheme.openComicOnTheRightAction, toolbarTheme.openComicOnTheRightAction18x18);
setIcon(goToPageOnTheLeftAction, toolbarTheme.goToPageOnTheLeftAction, toolbarTheme.goToPageOnTheLeftAction18x18);
setIcon(goToPageOnTheRightAction, toolbarTheme.goToPageOnTheRightAction, toolbarTheme.goToPageOnTheRightAction18x18);
setIcon(adjustHeightAction, toolbarTheme.adjustHeightAction, toolbarTheme.adjustHeightAction18x18);
setIcon(adjustWidthAction, toolbarTheme.adjustWidthAction, toolbarTheme.adjustWidthAction18x18);
setIcon(leftRotationAction, toolbarTheme.leftRotationAction, toolbarTheme.leftRotationAction18x18);
setIcon(rightRotationAction, toolbarTheme.rightRotationAction, toolbarTheme.rightRotationAction18x18);
setIcon(doublePageAction, toolbarTheme.doublePageAction, toolbarTheme.doublePageAction18x18);
setIcon(doubleMangaPageAction, toolbarTheme.doubleMangaPageAction, toolbarTheme.doubleMangaPageAction18x18);
setIcon(showZoomSliderlAction, toolbarTheme.showZoomSliderlAction, toolbarTheme.showZoomSliderlAction18x18);
setIcon(goToPageAction, toolbarTheme.goToPageAction, toolbarTheme.goToPageAction18x18);
setIcon(optionsAction, toolbarTheme.optionsAction, toolbarTheme.optionsAction18x18);
setIcon(helpAboutAction, toolbarTheme.helpAboutAction, toolbarTheme.helpAboutAction18x18);
setIcon(showMagnifyingGlassAction, toolbarTheme.showMagnifyingGlassAction, toolbarTheme.showMagnifyingGlassAction18x18);
setIcon(setBookmarkAction, toolbarTheme.setBookmarkAction, toolbarTheme.setBookmarkAction18x18);
setIcon(showBookmarksAction, toolbarTheme.showBookmarksAction, toolbarTheme.showBookmarksAction18x18);
setIcon(showShorcutsAction, toolbarTheme.showShorcutsAction, toolbarTheme.showShorcutsAction18x18);
setIcon(showInfoAction, toolbarTheme.showInfoAction, toolbarTheme.showInfoAction18x18);
setIcon(closeAction, toolbarTheme.closeAction, toolbarTheme.closeAction18x18);
setIcon(showDictionaryAction, toolbarTheme.showDictionaryAction, toolbarTheme.showDictionaryAction18x18);
setIcon(adjustToFullSizeAction, toolbarTheme.adjustToFullSizeAction, toolbarTheme.adjustToFullSizeAction18x18);
setIcon(fitToPageAction, toolbarTheme.fitToPageAction, toolbarTheme.fitToPageAction18x18);
setIcon(showFlowAction, toolbarTheme.showFlowAction, toolbarTheme.showFlowAction18x18);
}
void MainWindowViewer::dropEvent(QDropEvent *event) void MainWindowViewer::dropEvent(QDropEvent *event)
{ {
QList<QUrl> urlList; QList<QUrl> urlList;

View File

@ -3,12 +3,14 @@
#include <QMainWindow> #include <QMainWindow>
#include <QScrollArea> #include <QScrollArea>
#include <QToolBar> #include <QToolBar>
#include <QToolButton>
#include <QAction> #include <QAction>
#include <QMouseEvent> #include <QMouseEvent>
#include <QCloseEvent> #include <QCloseEvent>
#include <QSettings> #include <QSettings>
#include "yacreader_global.h" #include "yacreader_global.h"
#include "themable.h"
#ifdef Y_MAC_UI #ifdef Y_MAC_UI
#include "yacreader_macosx_toolbar.h" #include "yacreader_macosx_toolbar.h"
@ -28,7 +30,7 @@ class EditShortcutsDialog;
namespace YACReader { namespace YACReader {
class MainWindowViewer : public QMainWindow class MainWindowViewer : public QMainWindow, protected Themable
{ {
Q_OBJECT Q_OBJECT
@ -153,6 +155,8 @@ private:
QList<QAction *> mglassActions; QList<QAction *> mglassActions;
QList<QAction *> loadedComicActions; QList<QAction *> loadedComicActions;
QToolButton *openToolButton;
YACReaderSlider *zoomSliderAction; YACReaderSlider *zoomSliderAction;
HttpVersionChecker *versionChecker; HttpVersionChecker *versionChecker;
@ -170,6 +174,8 @@ private:
void setMglassActionsEnabled(bool enabled); void setMglassActionsEnabled(bool enabled);
void setLoadedComicActionsEnabled(bool enabled); void setLoadedComicActionsEnabled(bool enabled);
void applyTheme() override;
//! Manejadores de evento: //! Manejadores de evento:
// void resizeEvent(QResizeEvent * event); // void resizeEvent(QResizeEvent * event);
void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override;

View File

@ -12,6 +12,7 @@
#include <QLabel> #include <QLabel>
#include <QColorDialog> #include <QColorDialog>
#include <QCheckBox> #include <QCheckBox>
#include "theme_manager.h"
#include "yacreader_spin_slider_widget.h" #include "yacreader_spin_slider_widget.h"
#include "yacreader_3d_flow_config_widget.h" #include "yacreader_3d_flow_config_widget.h"
@ -65,10 +66,12 @@ OptionsDialog::OptionsDialog(QWidget *parent)
// backgroundColor->setMinimumWidth(100); // backgroundColor->setMinimumWidth(100);
colorSelection->addWidget(backgroundColor); colorSelection->addWidget(backgroundColor);
colorSelection->addWidget(selectBackgroundColorButton = new QPushButton(tr("Choose"))); colorSelection->addWidget(selectBackgroundColorButton = new QPushButton(tr("Choose")));
colorSelection->addWidget(clearBackgroundColorButton = new QPushButton(tr("Clear")));
colorSelection->setStretchFactor(backgroundColor, 1); colorSelection->setStretchFactor(backgroundColor, 1);
colorSelection->setStretchFactor(selectBackgroundColorButton, 0); colorSelection->setStretchFactor(selectBackgroundColorButton, 0);
// colorSelection->addStretch(); // colorSelection->addStretch();
connect(selectBackgroundColorButton, &QAbstractButton::clicked, this, &OptionsDialog::showColorDialog); connect(selectBackgroundColorButton, &QAbstractButton::clicked, this, &OptionsDialog::showColorDialog);
connect(clearBackgroundColorButton, &QAbstractButton::clicked, this, &OptionsDialog::clearBackgroundColor);
colorBox->setLayout(colorSelection); colorBox->setLayout(colorSelection);
auto scrollBox = new QGroupBox(tr("Scroll behaviour")); auto scrollBox = new QGroupBox(tr("Scroll behaviour"));
@ -278,7 +281,7 @@ void OptionsDialog::restoreOptions(QSettings *settings)
showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation()); showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation());
updateColor(settings->value(BACKGROUND_COLOR).value<QColor>()); updateColor(settings->value(BACKGROUND_COLOR, ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor).value<QColor>());
// fitToWidthRatioS->setSliderPosition(settings->value(FIT_TO_WIDTH_RATIO).toFloat()*100); // fitToWidthRatioS->setSliderPosition(settings->value(FIT_TO_WIDTH_RATIO).toFloat()*100);
quickNavi->setChecked(settings->value(QUICK_NAVI_MODE).toBool()); quickNavi->setChecked(settings->value(QUICK_NAVI_MODE).toBool());
@ -324,8 +327,6 @@ void OptionsDialog::updateColor(const QColor &color)
backgroundColor->setAutoFillBackground(true); backgroundColor->setAutoFillBackground(true);
currentColor = color; currentColor = color;
settings->setValue(BACKGROUND_COLOR, color);
emit changedOptions(); emit changedOptions();
} }
@ -392,3 +393,10 @@ void OptionsDialog::setFilters(int brightness, int contrast, int gamma)
else else
gammaS->setValue(100); gammaS->setValue(100);
} }
void OptionsDialog::clearBackgroundColor()
{
settings->remove(BACKGROUND_COLOR);
updateColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor);
}

View File

@ -42,6 +42,7 @@ private:
QLabel *backgroundColor; QLabel *backgroundColor;
QPushButton *selectBackgroundColorButton; QPushButton *selectBackgroundColorButton;
QPushButton *clearBackgroundColorButton;
QCheckBox *doNotTurnPageOnScroll; QCheckBox *doNotTurnPageOnScroll;
QCheckBox *useSingleScrollStepToTurnPage; QCheckBox *useSingleScrollStepToTurnPage;
@ -72,6 +73,7 @@ public slots:
void resetImageConfig(); void resetImageConfig();
void show(); void show();
void setFilters(int brightness, int contrast, int gamma); void setFilters(int brightness, int contrast, int gamma);
void clearBackgroundColor();
signals: signals:
void changedOptions(); void changedOptions();

View File

@ -2,6 +2,8 @@
#include <QtWidgets> #include <QtWidgets>
#include "theme_manager.h"
PageLabelWidget::PageLabelWidget(QWidget *parent) PageLabelWidget::PageLabelWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
@ -25,13 +27,13 @@ PageLabelWidget::PageLabelWidget(QWidget *parent)
int contentMargin = 0; int contentMargin = 0;
if (verticalRes <= 1024) { if (verticalRes <= 1024) {
textLabel->setStyleSheet("QLabel { color : white; font-size:12px; }"); fontSizePx = 12;
contentMargin = 12; contentMargin = 12;
} else if (verticalRes <= 1200) { } else if (verticalRes <= 1200) {
textLabel->setStyleSheet("QLabel { color : white; font-size:16px; }"); fontSizePx = 16;
contentMargin = 16; contentMargin = 16;
} else { } else {
textLabel->setStyleSheet("QLabel { color : white; font-size:20px; }"); fontSizePx = 20;
contentMargin = 20; contentMargin = 20;
} }
@ -47,6 +49,8 @@ PageLabelWidget::PageLabelWidget(QWidget *parent)
if (parent != nullptr) if (parent != nullptr)
move(QPoint((parent->geometry().size().width() - this->width()), -this->height())); move(QPoint((parent->geometry().size().width() - this->width()), -this->height()));
initTheme(this);
} }
void PageLabelWidget::show() void PageLabelWidget::show()
@ -90,7 +94,7 @@ void PageLabelWidget::paintEvent(QPaintEvent *)
{ {
QPainter painter(this); QPainter painter(this);
painter.fillRect(0, 0, width(), height(), QColor(0xBB000000)); painter.fillRect(rect(), infoBackgroundColor);
} }
void PageLabelWidget::updatePosition() void PageLabelWidget::updatePosition()
@ -106,3 +110,14 @@ void PageLabelWidget::updatePosition()
else else
move(QPoint((parent->geometry().size().width() - this->width()), -this->height())); move(QPoint((parent->geometry().size().width() - this->width()), -this->height()));
} }
void PageLabelWidget::applyTheme()
{
const auto viewerTheme = ThemeManager::instance().getCurrentTheme().viewer;
infoBackgroundColor = viewerTheme.infoBackgroundColor;
textLabel->setStyleSheet(viewerTheme.infoLabelQSS.arg(fontSizePx));
update();
}

View File

@ -3,18 +3,23 @@
#include <QWidget> #include <QWidget>
#include "themable.h"
class QLabel; class QLabel;
class QPropertyAnimation; class QPropertyAnimation;
class PageLabelWidget : public QWidget class PageLabelWidget : public QWidget, protected Themable
{ {
Q_OBJECT Q_OBJECT
private: private:
QLabel *textLabel; QLabel *textLabel;
QPropertyAnimation *animation; QPropertyAnimation *animation;
QColor infoBackgroundColor;
int fontSizePx = 0;
protected: protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
void applyTheme() override;
public: public:
PageLabelWidget(QWidget *parent); PageLabelWidget(QWidget *parent);

View File

@ -1,7 +1,100 @@
#ifndef THEME_H #ifndef THEME_H
#define THEME_H #define THEME_H
#include <QtGui>
struct ToolbarThemeTemplates {
QString toolbarQSS = "QToolBar { border: none; background: %1; }\n"
"QToolBar::separator { background: %2; width: 1px; margin: 5px 4px; }\n"
"QToolButton:checked { background-color: %3; }\n"
"QToolButton::menu-button {border: none; width: 18px; }\n"
"QToolButton::menu-arrow { image: url(%4); width: 8px; height: 8px; }\n";
QString menuArrowPath = ":/images/viewer_toolbar/menuArrow.svg";
};
struct ViewerThemeTemplates {
QString infoLabelQSS = "QLabel { color : %1; font-size:%2px; }";
};
struct ToolbarTheme {
QString toolbarQSS;
QIcon openAction;
QIcon openAction18x18;
QIcon openFolderAction;
QIcon openFolderAction18x18;
QIcon openLatestComicAction;
QIcon openLatestComicAction18x18;
QIcon saveImageAction;
QIcon saveImageAction18x18;
QIcon openComicOnTheLeftAction;
QIcon openComicOnTheLeftAction18x18;
QIcon openComicOnTheRightAction;
QIcon openComicOnTheRightAction18x18;
QIcon goToPageOnTheLeftAction;
QIcon goToPageOnTheLeftAction18x18;
QIcon goToPageOnTheRightAction;
QIcon goToPageOnTheRightAction18x18;
QIcon adjustHeightAction;
QIcon adjustHeightAction18x18;
QIcon adjustWidthAction;
QIcon adjustWidthAction18x18;
QIcon leftRotationAction;
QIcon leftRotationAction18x18;
QIcon rightRotationAction;
QIcon rightRotationAction18x18;
QIcon doublePageAction;
QIcon doublePageAction18x18;
QIcon doubleMangaPageAction;
QIcon doubleMangaPageAction18x18;
QIcon increasePageZoomAction;
QIcon increasePageZoomAction18x18;
QIcon decreasePageZoomAction;
QIcon decreasePageZoomAction18x18;
QIcon resetZoomAction;
QIcon resetZoomAction18x18;
QIcon showZoomSliderlAction;
QIcon showZoomSliderlAction18x18;
QIcon goToPageAction;
QIcon goToPageAction18x18;
QIcon optionsAction;
QIcon optionsAction18x18;
QIcon helpAboutAction;
QIcon helpAboutAction18x18;
QIcon showMagnifyingGlassAction;
QIcon showMagnifyingGlassAction18x18;
QIcon setBookmarkAction;
QIcon setBookmarkAction18x18;
QIcon showBookmarksAction;
QIcon showBookmarksAction18x18;
QIcon showShorcutsAction;
QIcon showShorcutsAction18x18;
QIcon showInfoAction;
QIcon showInfoAction18x18;
QIcon closeAction;
QIcon closeAction18x18;
QIcon showDictionaryAction;
QIcon showDictionaryAction18x18;
QIcon adjustToFullSizeAction;
QIcon adjustToFullSizeAction18x18;
QIcon fitToPageAction;
QIcon fitToPageAction18x18;
QIcon showFlowAction;
QIcon showFlowAction18x18;
};
struct ViewerTheme {
QColor defaultBackgroundColor;
QColor defaultTextColor;
QColor infoBackgroundColor;
QString infoLabelQSS;
};
struct Theme { struct Theme {
ToolbarTheme toolbar;
ViewerTheme viewer;
}; };
#endif // THEME_H #endif // THEME_H

View File

@ -0,0 +1,223 @@
#include "theme_factory.h"
#include "icon_utils.h"
struct ToolbarParams {
ToolbarThemeTemplates t;
QColor iconColor;
QColor iconDisabledColor;
QColor iconCheckedColor;
QColor backgroundColor;
QColor separatorColor;
QColor checkedButtonColor;
QColor menuIndicatorColor;
};
struct ViewerParams {
ViewerThemeTemplates t;
QColor defaultBackgroundColor;
QColor defaultTextColor;
QColor infoBackgroundColor;
QColor infoTextColor;
};
struct ThemeParams {
QString themeName;
ToolbarParams toolbarParams;
ViewerParams viewerParams;
};
void setToolbarIconPair(QIcon &icon,
QIcon &icon18,
const QString &basePath,
const QColor &iconColor,
const QColor &disabledColor,
const QColor &checkedColor,
const QString &themeName)
{
QString path18 = basePath;
if (path18.endsWith(".svg"))
path18.insert(path18.size() - 4, "_18x18");
else
path18.append("_18x18");
// Normal
const QString normalPath = recoloredSvgToThemeFile(basePath, iconColor, themeName);
const QString normalPath18 = recoloredSvgToThemeFile(path18, iconColor, themeName);
// Disabled
const QString disabledPath = recoloredSvgToThemeFile(basePath, disabledColor, themeName, "_disabled");
const QString disabledPath18 = recoloredSvgToThemeFile(path18, disabledColor, themeName, "_disabled");
// Checked (On state)
const QString checkedPath = recoloredSvgToThemeFile(basePath, checkedColor, themeName, "_checked");
const QString checkedPath18 = recoloredSvgToThemeFile(path18, checkedColor, themeName, "_checked");
icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off);
icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off);
icon.addFile(checkedPath, QSize(), QIcon::Normal, QIcon::On);
icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::On);
icon18.addFile(normalPath18, QSize(), QIcon::Normal, QIcon::Off);
icon18.addFile(disabledPath18, QSize(), QIcon::Disabled, QIcon::Off);
icon18.addFile(checkedPath18, QSize(), QIcon::Normal, QIcon::On);
icon18.addFile(disabledPath18, QSize(), QIcon::Disabled, QIcon::On);
}
Theme makeTheme(const ThemeParams &params)
{
Theme theme;
// Toolbar & actions
theme.toolbar.toolbarQSS = params.toolbarParams.t.toolbarQSS.arg(params.toolbarParams.backgroundColor.name(), params.toolbarParams.separatorColor.name(), params.toolbarParams.checkedButtonColor.name(), recoloredSvgToThemeFile(params.toolbarParams.t.menuArrowPath, params.toolbarParams.menuIndicatorColor, params.themeName));
auto setToolbarIconPairT = [&](QIcon &icon, QIcon &icon18, const QString &basePath) {
setToolbarIconPair(icon, icon18, basePath, params.toolbarParams.iconColor, params.toolbarParams.iconDisabledColor, params.toolbarParams.iconCheckedColor, params.themeName);
};
setToolbarIconPairT(theme.toolbar.openAction, theme.toolbar.openAction18x18, ":/images/viewer_toolbar/open.svg");
setToolbarIconPairT(theme.toolbar.openFolderAction, theme.toolbar.openFolderAction18x18, ":/images/viewer_toolbar/openFolder.svg");
setToolbarIconPairT(theme.toolbar.openLatestComicAction, theme.toolbar.openLatestComicAction18x18, ":/images/viewer_toolbar/openNext.svg");
setToolbarIconPairT(theme.toolbar.saveImageAction, theme.toolbar.saveImageAction18x18, ":/images/viewer_toolbar/save.svg");
setToolbarIconPairT(theme.toolbar.openComicOnTheLeftAction, theme.toolbar.openComicOnTheLeftAction18x18, ":/images/viewer_toolbar/openPrevious.svg");
setToolbarIconPairT(theme.toolbar.openComicOnTheRightAction, theme.toolbar.openComicOnTheRightAction18x18, ":/images/viewer_toolbar/openNext.svg");
setToolbarIconPairT(theme.toolbar.goToPageOnTheLeftAction, theme.toolbar.goToPageOnTheLeftAction18x18, ":/images/viewer_toolbar/previous.svg");
setToolbarIconPairT(theme.toolbar.goToPageOnTheRightAction, theme.toolbar.goToPageOnTheRightAction18x18, ":/images/viewer_toolbar/next.svg");
setToolbarIconPairT(theme.toolbar.adjustHeightAction, theme.toolbar.adjustHeightAction18x18, ":/images/viewer_toolbar/toHeight.svg");
setToolbarIconPairT(theme.toolbar.adjustWidthAction, theme.toolbar.adjustWidthAction18x18, ":/images/viewer_toolbar/toWidth.svg");
setToolbarIconPairT(theme.toolbar.leftRotationAction, theme.toolbar.leftRotationAction18x18, ":/images/viewer_toolbar/rotateL.svg");
setToolbarIconPairT(theme.toolbar.rightRotationAction, theme.toolbar.rightRotationAction18x18, ":/images/viewer_toolbar/rotateR.svg");
setToolbarIconPairT(theme.toolbar.doublePageAction, theme.toolbar.doublePageAction18x18, ":/images/viewer_toolbar/doublePage.svg");
setToolbarIconPairT(theme.toolbar.doubleMangaPageAction, theme.toolbar.doubleMangaPageAction18x18, ":/images/viewer_toolbar/doubleMangaPage.svg");
setToolbarIconPairT(theme.toolbar.showZoomSliderlAction, theme.toolbar.showZoomSliderlAction18x18, ":/images/viewer_toolbar/zoom.svg");
setToolbarIconPairT(theme.toolbar.goToPageAction, theme.toolbar.goToPageAction18x18, ":/images/viewer_toolbar/goto.svg");
setToolbarIconPairT(theme.toolbar.optionsAction, theme.toolbar.optionsAction18x18, ":/images/viewer_toolbar/options.svg");
setToolbarIconPairT(theme.toolbar.helpAboutAction, theme.toolbar.helpAboutAction18x18, ":/images/viewer_toolbar/help.svg");
setToolbarIconPairT(theme.toolbar.showMagnifyingGlassAction, theme.toolbar.showMagnifyingGlassAction18x18, ":/images/viewer_toolbar/magnifyingGlass.svg");
setToolbarIconPairT(theme.toolbar.setBookmarkAction, theme.toolbar.setBookmarkAction18x18, ":/images/viewer_toolbar/bookmark.svg");
setToolbarIconPairT(theme.toolbar.showBookmarksAction, theme.toolbar.showBookmarksAction18x18, ":/images/viewer_toolbar/showBookmarks.svg");
setToolbarIconPairT(theme.toolbar.showShorcutsAction, theme.toolbar.showShorcutsAction18x18, ":/images/viewer_toolbar/shortcuts.svg");
setToolbarIconPairT(theme.toolbar.showInfoAction, theme.toolbar.showInfoAction18x18, ":/images/viewer_toolbar/info.svg");
setToolbarIconPairT(theme.toolbar.closeAction, theme.toolbar.closeAction18x18, ":/images/viewer_toolbar/close.svg");
setToolbarIconPairT(theme.toolbar.showDictionaryAction, theme.toolbar.showDictionaryAction18x18, ":/images/viewer_toolbar/translator.svg");
setToolbarIconPairT(theme.toolbar.adjustToFullSizeAction, theme.toolbar.adjustToFullSizeAction18x18, ":/images/viewer_toolbar/full.svg");
setToolbarIconPairT(theme.toolbar.fitToPageAction, theme.toolbar.fitToPageAction18x18, ":/images/viewer_toolbar/fitToPage.svg");
setToolbarIconPairT(theme.toolbar.showFlowAction, theme.toolbar.showFlowAction18x18, ":/images/viewer_toolbar/flow.svg");
// end Toolbar & actions
// Viewer
theme.viewer.defaultBackgroundColor = params.viewerParams.defaultBackgroundColor;
theme.viewer.defaultTextColor = params.viewerParams.defaultTextColor;
theme.viewer.infoBackgroundColor = params.viewerParams.infoBackgroundColor;
theme.viewer.infoLabelQSS = params.viewerParams.t.infoLabelQSS.arg(params.viewerParams.infoTextColor.name());
// end Viewer
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());
}
}
ThemeParams classicThemeParams()
{
ThemeParams params;
params.themeName = "classic";
ToolbarParams toolbarParams;
toolbarParams.iconColor = QColor(0x404040);
toolbarParams.iconDisabledColor = QColor(0x858585);
toolbarParams.iconCheckedColor = QColor(0x5A5A5A);
toolbarParams.backgroundColor = QColor(0xF3F3F3);
toolbarParams.separatorColor = QColor(0xCCCCCC);
toolbarParams.checkedButtonColor = QColor(0xCCCCCC);
toolbarParams.menuIndicatorColor = QColor(0x404040);
params.toolbarParams = toolbarParams;
ViewerParams viewerParams;
viewerParams.defaultBackgroundColor = QColor(0x282828);
viewerParams.defaultTextColor = Qt::white;
viewerParams.infoBackgroundColor = QColor::fromRgba(0xBB000000);
viewerParams.infoTextColor = Qt::white;
viewerParams.t = ViewerThemeTemplates();
params.viewerParams = viewerParams;
return params;
}
ThemeParams lightThemeParams()
{
ThemeParams params;
params.themeName = "light";
ToolbarParams toolbarParams;
toolbarParams.iconColor = QColor(0x404040);
toolbarParams.iconDisabledColor = QColor(0xB0B0B0);
toolbarParams.iconCheckedColor = QColor(0x5A5A5A);
toolbarParams.backgroundColor = QColor(0xF3F3F3);
toolbarParams.separatorColor = QColor(0xCCCCCC);
toolbarParams.checkedButtonColor = QColor(0xCCCCCC);
toolbarParams.menuIndicatorColor = QColor(0x404040);
params.toolbarParams = toolbarParams;
ViewerParams viewerParams;
viewerParams.defaultBackgroundColor = QColor(0xF6F6F6);
viewerParams.defaultTextColor = QColor(0x202020);
viewerParams.infoBackgroundColor = QColor::fromRgba(0xBBFFFFFF);
viewerParams.infoTextColor = QColor(0x404040);
viewerParams.t = ViewerThemeTemplates();
params.viewerParams = viewerParams;
return params;
}
ThemeParams darkThemeParams()
{
ThemeParams params;
params.themeName = "dark";
ToolbarParams toolbarParams;
toolbarParams.iconColor = QColor(0xCCCCCC);
toolbarParams.iconDisabledColor = QColor(0x444444);
toolbarParams.iconCheckedColor = QColor(0xDADADA);
toolbarParams.backgroundColor = QColor(0x202020);
toolbarParams.separatorColor = QColor(0x444444);
toolbarParams.checkedButtonColor = QColor(0x3A3A3A);
toolbarParams.menuIndicatorColor = QColor(0xCCCCCC);
params.toolbarParams = toolbarParams;
ViewerParams viewerParams;
viewerParams.defaultBackgroundColor = QColor(40, 40, 40);
viewerParams.defaultTextColor = Qt::white;
viewerParams.infoBackgroundColor = QColor::fromRgba(0xBB000000);
viewerParams.infoTextColor = QColor(0xB0B0B0);
viewerParams.t = ViewerThemeTemplates();
params.viewerParams = viewerParams;
return params;
}
// TODO
ThemeParams paramsFromFile(const QString &filePath)
{
return {};
}

View File

@ -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

View File

@ -2,3 +2,6 @@ INCLUDEPATH += $$PWD
HEADERS += \ HEADERS += \
$$PWD/theme.h \ $$PWD/theme.h \
$$PWD/theme_factory.h
SOURCES += \
$$PWD/theme_factory.cpp

View File

@ -10,6 +10,7 @@
#include "notifications_label_widget.h" #include "notifications_label_widget.h"
#include "comic_db.h" #include "comic_db.h"
#include "shortcuts_manager.h" #include "shortcuts_manager.h"
#include "theme_manager.h"
#include <QFile> #include <QFile>
#include <QKeyEvent> #include <QKeyEvent>
@ -42,17 +43,12 @@ Viewer::Viewer(QWidget *parent)
// current comic page // current comic page
content = new QLabel(this); content = new QLabel(this);
configureContent(tr("Press 'O' to open comic.")); configureContent(tr("Press 'O' to open comic."));
// scroll area configuration
setBackgroundRole(QPalette::Dark);
setWidget(content); setWidget(content);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFrameStyle(QFrame::NoFrame); setFrameStyle(QFrame::NoFrame);
setAlignment(Qt::AlignCenter); setAlignment(Qt::AlignCenter);
QPalette palette;
palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor());
setPalette(palette);
//--------------------------------------- //---------------------------------------
mglass = new MagnifyingGlass( mglass = new MagnifyingGlass(
Configuration::getConfiguration().getMagnifyingGlassSize(), Configuration::getConfiguration().getMagnifyingGlassSize(),
@ -116,6 +112,8 @@ Viewer::Viewer(QWidget *parent)
informationLabel = new PageLabelWidget(this); informationLabel = new PageLabelWidget(this);
setAcceptDrops(true); setAcceptDrops(true);
initTheme(this);
} }
Viewer::~Viewer() Viewer::~Viewer()
@ -1009,7 +1007,7 @@ void Viewer::showCursor()
void Viewer::updateOptions() void Viewer::updateOptions()
{ {
goToFlow->setFlowType(Configuration::getConfiguration().getFlowType()); goToFlow->setFlowType(Configuration::getConfiguration().getFlowType());
updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor()); updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor));
updateContentSize(); updateContentSize();
updateInformation(); updateInformation();
} }
@ -1021,6 +1019,16 @@ void Viewer::updateBackgroundColor(const QColor &color)
setPalette(palette); setPalette(palette);
} }
void Viewer::applyTheme()
{
const auto viewerTheme = ThemeManager::instance().getCurrentTheme().viewer;
updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor));
const QString textColor = viewerTheme.defaultTextColor.name(QColor::HexArgb);
content->setStyleSheet(QStringLiteral("QLabel { color : %1; background: transparent; }").arg(textColor));
}
void Viewer::animateShowTranslator() void Viewer::animateShowTranslator()
{ {
if (translator->isHidden() && translatorAnimation->state() != QPropertyAnimation::Running) { if (translator->isHidden() && translatorAnimation->state() != QPropertyAnimation::Running) {
@ -1084,7 +1092,7 @@ void Viewer::updateConfig(QSettings *settings)
goToFlow->updateConfig(settings); goToFlow->updateConfig(settings);
QPalette palette; QPalette palette;
palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor()); palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor));
setPalette(palette); setPalette(palette);
} }

View File

@ -18,6 +18,7 @@
#include "scroll_management.h" #include "scroll_management.h"
#include "mouse_handler.h" #include "mouse_handler.h"
#include "themable.h"
class ComicDB; class ComicDB;
class Comic; class Comic;
@ -32,7 +33,7 @@ class Bookmarks;
class PageLabelWidget; class PageLabelWidget;
class NotificationsLabelWidget; class NotificationsLabelWidget;
class Viewer : public QScrollArea, public ScrollManagement class Viewer : public QScrollArea, public ScrollManagement, protected Themable
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -186,6 +187,9 @@ private:
//! Mouse handler //! Mouse handler
std::unique_ptr<YACReader::MouseHandler> mouseHandler; std::unique_ptr<YACReader::MouseHandler> mouseHandler;
protected:
void applyTheme() override;
public: public:
Viewer(QWidget *parent = nullptr); Viewer(QWidget *parent = nullptr);
~Viewer(); ~Viewer();

View File

@ -87,5 +87,6 @@
<file>../images/viewer_toolbar/toWidth_18x18.svg</file> <file>../images/viewer_toolbar/toWidth_18x18.svg</file>
<file>../images/viewer_toolbar/translator_18x18.svg</file> <file>../images/viewer_toolbar/translator_18x18.svg</file>
<file>../images/viewer_toolbar/zoom_18x18.svg</file> <file>../images/viewer_toolbar/zoom_18x18.svg</file>
<file>../images/viewer_toolbar/menuArrow.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,6 +1,7 @@
#include "theme_manager.h" #include "theme_manager.h"
#include "theme.h" #include "theme.h"
#include "theme_factory.h"
#include <QGuiApplication> #include <QGuiApplication>
#include <QStyleHints> #include <QStyleHints>
@ -46,5 +47,5 @@ void ThemeManager::setTheme(ThemeId themeId)
void ThemeManager::updateCurrentTheme() void ThemeManager::updateCurrentTheme()
{ {
// TODO currentTheme = makeTheme(themeId);
} }

View File

@ -32,7 +32,7 @@ QIcon YACReader::noHighlightedIcon(const QString &path)
return icon; return icon;
} }
void YACReader::colorize(QImage &img, QColor &col) void YACReader::colorize(QImage &img, const QColor &col)
{ {
QRgb *data = (QRgb *)img.bits(); QRgb *data = (QRgb *)img.bits();
QRgb *end = data + img.width() * img.height(); QRgb *end = data + img.width() * img.height();
@ -94,6 +94,9 @@ QAction *YACReader::actionWithCustomIcon(const QIcon &icon, QAction *action)
QObject::connect(a, &QAction::toggled, action, &QAction::setChecked); QObject::connect(a, &QAction::toggled, action, &QAction::setChecked);
QObject::connect(action, &QAction::toggled, a, &QAction::setChecked); QObject::connect(action, &QAction::toggled, a, &QAction::setChecked);
// asign a to action somehow so we can retrieve it later
action->setProperty("customIconAction", QVariant::fromValue<QObject *>(a));
return a; return a;
} }

View File

@ -24,7 +24,7 @@
#define DOUBLE_PAGE "DOUBLE_PAGE" #define DOUBLE_PAGE "DOUBLE_PAGE"
#define DOUBLE_MANGA_PAGE "DOUBLE_MANGA_PAGE" #define DOUBLE_MANGA_PAGE "DOUBLE_MANGA_PAGE"
#define COVER_IS_SP "COVER_IS_SP" #define COVER_IS_SP "COVER_IS_SP"
#define BACKGROUND_COLOR "BACKGROUND_COLOR" #define BACKGROUND_COLOR "BACKGROUND_COLOR_10"
#define SHOW_TOOLBARS "SHOW_TOOLBARS" #define SHOW_TOOLBARS "SHOW_TOOLBARS"
#define BRIGHTNESS "BRIGHTNESS" #define BRIGHTNESS "BRIGHTNESS"
#define CONTRAST "CONTRAST" #define CONTRAST "CONTRAST"
@ -108,7 +108,7 @@ enum LibraryUITheme {
void addSperator(QWidget *w); void addSperator(QWidget *w);
QAction *createSeparator(); QAction *createSeparator();
QIcon noHighlightedIcon(const QString &path); QIcon noHighlightedIcon(const QString &path);
void colorize(QImage &img, QColor &col); void colorize(QImage &img, const QColor &col);
QList<qulonglong> mimeDataToComicsIds(const QMimeData *data); QList<qulonglong> mimeDataToComicsIds(const QMimeData *data);
QString addExtensionToIconPath(const QString &path); QString addExtensionToIconPath(const QString &path);
QString addExtensionToIconPathInToolbar(const QString &path); QString addExtensionToIconPathInToolbar(const QString &path);

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 7 4">
<!-- Generator: Adobe Illustrator 29.8.4, SVG Export Plug-In . SVG Version: 2.1.1 Build 6) -->
<defs>
<style>
.st0 {
fill: #f0f;
}
</style>
</defs>
<path class="st0" d="M1,0h5l-2.5,4L1,0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 359 B