- fix: In the create project dialog, the browser button doesn't work

- change: use QStyle to implement the dark style
This commit is contained in:
royqh1979@gmail.com 2021-10-18 22:06:33 +08:00
parent fee2115093
commit 19b1d042c0
29 changed files with 1190 additions and 53 deletions

View File

@ -1,6 +1,8 @@
Version 0.6.8
- enhancement: add link to cppreference in the help menu
- fix: add mutex lock to prevent editor crash in rare conditions
- fix: In the create project dialog, the browser button doesn't work
- change: use QStyle to implement the dark style
Version 0.6.7
- fix: messages send to the gdb process's standard error are not received

View File

@ -112,6 +112,7 @@ SOURCES += \
widgets/coloredit.cpp \
widgets/consolewidget.cpp \
widgets/custommakefileinfodialog.cpp \
widgets/darkfusionstyle.cpp \
widgets/filepropertiesdialog.cpp \
widgets/functiontooltipwidget.cpp \
widgets/headercompletionpopup.cpp \
@ -225,6 +226,7 @@ HEADERS += \
widgets/coloredit.h \
widgets/consolewidget.h \
widgets/custommakefileinfodialog.h \
widgets/darkfusionstyle.h \
widgets/filepropertiesdialog.h \
widgets/functiontooltipwidget.h \
widgets/headercompletionpopup.h \
@ -291,9 +293,7 @@ RESOURCES += \
codes.qrc \
colorschemes.qrc \
defaultconfigs.qrc \
themes/dark/dark.qrc \
themes/light/light.qrc \
themes/dracula/dracula.qrc \
themes.qrc \
icons.qrc \
translations.qrc

View File

@ -16,6 +16,8 @@
#include "widgets/aboutdialog.h"
#include "shortcutmanager.h"
#include "colorscheme.h"
#include "thememanager.h"
#include "widgets/darkfusionstyle.h"
#include <QCloseEvent>
#include <QComboBox>
@ -413,12 +415,19 @@ void MainWindow::updateEditorColorSchemes()
void MainWindow::applySettings()
{
changeTheme(pSettings->environment().theme());
//changeTheme(pSettings->environment().theme());
ThemeManager themeManager;
PAppTheme appTheme = themeManager.theme(pSettings->environment().theme());
if (appTheme->isDark())
QApplication::setStyle(new DarkFusionStyle());
else
QApplication::setStyle("fusion");
qApp->setPalette(appTheme->palette());
QFont font(pSettings->environment().interfaceFont(),
pSettings->environment().interfaceFontSize());
font.setStyleStrategy(QFont::PreferAntialias);
QApplication * app = dynamic_cast<QApplication*>(QApplication::instance());
app->setFont(font);
qApp->setFont(font);
this->setFont(font);
updateDebuggerSettings();
}

View File

@ -324,6 +324,9 @@
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
@ -470,7 +473,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tabDebugConsole">
<attribute name="title">
@ -520,6 +523,9 @@
</property>
<item>
<widget class="QTableView" name="tblStackTrace">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
@ -555,6 +561,9 @@
</property>
<item>
<widget class="QTableView" name="tblBreakpoints">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>

View File

@ -215,7 +215,8 @@ public:
signals:
void addedUndo();
protected:
void EnsureMaxEntries();
protected:
int mBlockChangeNumber;
int mBlockCount;
@ -226,7 +227,6 @@ protected:
int mNextChangeNumber;
int mInitialChangeNumber;
bool mInsideRedo;
void EnsureMaxEntries();
};
using PSynEditUndoList = std::shared_ptr<SynEditUndoList>;

View File

@ -78,6 +78,9 @@
</item>
<item>
<widget class="QTableView" name="tblAutolinks">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="textElideMode">
<enum>Qt::ElideNone</enum>
</property>

View File

@ -122,6 +122,9 @@
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
</layout>

View File

@ -35,6 +35,9 @@
</property>
<item>
<widget class="QTableView" name="tblSnippets">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>

View File

@ -13,12 +13,12 @@ EnvironmentAppearenceWidget::EnvironmentAppearenceWidget(const QString& name, co
ui->setupUi(this);
ui->cbTheme->addItem("default");
ui->cbTheme->addItem("dark");
ui->cbTheme->addItem("dracula");
ui->cbTheme->addItem("light");
QStyleFactory factory;
for (QString name:factory.keys()) {
ui->cbTheme->addItem(name);
}
// ui->cbTheme->addItem("dracula");
// ui->cbTheme->addItem("light");
// QStyleFactory factory;
// for (QString name:factory.keys()) {
// ui->cbTheme->addItem(name);
// }
ui->cbLanguage->addItem("English","en");
ui->cbLanguage->addItem(tr("Simplified Chinese"),"zh_CN");
}

View File

@ -98,7 +98,11 @@
<number>0</number>
</property>
<item>
<widget class="QFontComboBox" name="cbFont"/>
<widget class="QFontComboBox" name="cbFont">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">

View File

@ -21,7 +21,11 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="lstFileTypes"/>
<widget class="QListView" name="lstFileTypes">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>

View File

@ -16,6 +16,9 @@
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTableView" name="tblShortcut">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>

View File

@ -38,7 +38,7 @@
<item>
<widget class="QTabWidget" name="tabCommands">
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>674</width>
<width>685</width>
<height>639</height>
</rect>
</property>
@ -207,6 +207,9 @@
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="resizeMode">
<enum>QListView::Fixed</enum>
</property>

View File

@ -83,7 +83,11 @@
<number>0</number>
</property>
<item>
<widget class="QListView" name="lstTools"/>
<widget class="QListView" name="lstTools">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="panelEdit" native="true">

View File

@ -1,6 +1,162 @@
#include "thememanager.h"
#include <QApplication>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMetaEnum>
#include <QMetaObject>
#include "utils.h"
ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
{
}
PAppTheme ThemeManager::theme(const QString &themeName)
{
PAppTheme appTheme = std::make_shared<AppTheme>();
appTheme->load(QString(":/themes/%1.json").arg(themeName));
return appTheme;
}
AppTheme::AppTheme(QObject *parent):QObject(parent)
{
}
QColor AppTheme::color(ColorRole role) const
{
return mColors.value(role,QColor());
}
QPalette AppTheme::palette() const
{
QPalette pal = initialPalette();
const static struct {
ColorRole themeColor;
QPalette::ColorRole paletteColorRole;
QPalette::ColorGroup paletteColorGroup;
bool setColorRoleAsBrush;
} mapping[] = {
{ColorRole::PaletteWindow, QPalette::Window, QPalette::All, false},
{ColorRole::PaletteWindowDisabled, QPalette::Window, QPalette::Disabled, false},
{ColorRole::PaletteWindowText, QPalette::WindowText, QPalette::All, true},
{ColorRole::PaletteWindowTextDisabled, QPalette::WindowText, QPalette::Disabled, true},
{ColorRole::PaletteBase, QPalette::Base, QPalette::All, false},
{ColorRole::PaletteBaseDisabled, QPalette::Base, QPalette::Disabled, false},
{ColorRole::PaletteAlternateBase, QPalette::AlternateBase, QPalette::All, false},
{ColorRole::PaletteAlternateBaseDisabled, QPalette::AlternateBase, QPalette::Disabled, false},
{ColorRole::PaletteToolTipBase, QPalette::ToolTipBase, QPalette::All, true},
{ColorRole::PaletteToolTipBaseDisabled, QPalette::ToolTipBase, QPalette::Disabled, true},
{ColorRole::PaletteToolTipText, QPalette::ToolTipText, QPalette::All, false},
{ColorRole::PaletteToolTipTextDisabled, QPalette::ToolTipText, QPalette::Disabled, false},
{ColorRole::PaletteText, QPalette::Text, QPalette::All, true},
{ColorRole::PaletteTextDisabled, QPalette::Text, QPalette::Disabled, true},
{ColorRole::PaletteButton, QPalette::Button, QPalette::All, false},
{ColorRole::PaletteButtonDisabled, QPalette::Button, QPalette::Disabled, false},
{ColorRole::PaletteButtonText, QPalette::ButtonText, QPalette::All, true},
{ColorRole::PaletteButtonTextDisabled, QPalette::ButtonText, QPalette::Disabled, true},
{ColorRole::PaletteBrightText, QPalette::BrightText, QPalette::All, false},
{ColorRole::PaletteBrightTextDisabled, QPalette::BrightText, QPalette::Disabled, false},
{ColorRole::PaletteHighlight, QPalette::Highlight, QPalette::All, true},
{ColorRole::PaletteHighlightDisabled, QPalette::Highlight, QPalette::Disabled, true},
{ColorRole::PaletteHighlightedText, QPalette::HighlightedText, QPalette::All, true},
{ColorRole::PaletteHighlightedTextDisabled, QPalette::HighlightedText, QPalette::Disabled, true},
{ColorRole::PaletteLink, QPalette::Link, QPalette::All, false},
{ColorRole::PaletteLinkDisabled, QPalette::Link, QPalette::Disabled, false},
{ColorRole::PaletteLinkVisited, QPalette::LinkVisited, QPalette::All, false},
{ColorRole::PaletteLinkVisitedDisabled, QPalette::LinkVisited, QPalette::Disabled, false},
{ColorRole::PaletteLight, QPalette::Light, QPalette::All, false},
{ColorRole::PaletteLightDisabled, QPalette::Light, QPalette::Disabled, false},
{ColorRole::PaletteMidlight, QPalette::Midlight, QPalette::All, false},
{ColorRole::PaletteMidlightDisabled, QPalette::Midlight, QPalette::Disabled, false},
{ColorRole::PaletteDark, QPalette::Dark, QPalette::All, false},
{ColorRole::PaletteDarkDisabled, QPalette::Dark, QPalette::Disabled, false},
{ColorRole::PaletteMid, QPalette::Mid, QPalette::All, false},
{ColorRole::PaletteMidDisabled, QPalette::Mid, QPalette::Disabled, false},
{ColorRole::PaletteShadow, QPalette::Shadow, QPalette::All, false},
{ColorRole::PaletteShadowDisabled, QPalette::Shadow, QPalette::Disabled, false}
};
for (auto entry: mapping) {
const QColor themeColor = color(entry.themeColor);
// Use original color if color is not defined in theme.
if (themeColor.isValid()) {
// if (entry.setColorRoleAsBrush)
// // TODO: Find out why sometimes setBrush is used
// pal.setBrush(entry.paletteColorGroup, entry.paletteColorRole, themeColor);
// else
// pal.setColor(entry.paletteColorGroup, entry.paletteColorRole, themeColor);
pal.setBrush(entry.paletteColorGroup, entry.paletteColorRole, themeColor);
pal.setColor(entry.paletteColorGroup, entry.paletteColorRole, themeColor);
}
}
return pal;
}
void AppTheme::load(const QString &filename)
{
QFile file(filename);
if (!file.exists())
return;
if (file.open(QFile::ReadOnly)) {
QByteArray content = file.readAll();
QJsonParseError error;
QJsonDocument doc(QJsonDocument::fromJson(content,&error));
if (error.error != QJsonParseError::NoError) {
throw FileError(tr("Error in json file '%1':%2 : %3")
.arg(filename)
.arg(error.offset)
.arg(error.errorString()));
}
QJsonObject obj=doc.object();
mName = obj["name"].toString();
mIsDark = obj["isDark"].toBool(false);
QJsonObject colors = obj["palette"].toObject();
const QMetaObject &m = *metaObject();
QMetaEnum e = m.enumerator(m.indexOfEnumerator("ColorRole"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
if (colors.contains(key)) {
QString val=colors[key].toString();
mColors.insert(i, QColor(val));
}
}
} else {
throw FileError(tr("Can't open file '%1' for read.")
.arg(filename));
}
}
// If you copy QPalette, default values stay at default, even if that default is different
// within the context of different widgets. Create deep copy.
static QPalette copyPalette(const QPalette &p)
{
QPalette res;
for (int group = 0; group < QPalette::NColorGroups; ++group) {
for (int role = 0; role < QPalette::NColorRoles; ++role) {
res.setBrush(QPalette::ColorGroup(group),
QPalette::ColorRole(role),
p.brush(QPalette::ColorGroup(group), QPalette::ColorRole(role)));
res.setColor(QPalette::ColorGroup(group),
QPalette::ColorRole(role),
p.color(QPalette::ColorGroup(group), QPalette::ColorRole(role)));
}
}
return res;
}
QPalette AppTheme::initialPalette()
{
static QPalette palette = copyPalette(QApplication::palette());
return palette;
}
bool AppTheme::isDark() const
{
return mIsDark;
}

View File

@ -1,16 +1,88 @@
#ifndef THEMEMANAGER_H
#define THEMEMANAGER_H
#include <QObject>
#include <QPalette>
#include <QHash>
#include <QColor>
class AppTheme:public QObject {
Q_OBJECT
public:
explicit AppTheme(QObject* parent = nullptr);
enum ColorRole {
/* Color for QPalette */
PaletteWindow,
PaletteWindowText,
PaletteBase,
PaletteAlternateBase,
PaletteToolTipBase,
PaletteToolTipText,
PaletteText,
PaletteButton,
PaletteButtonText,
PaletteBrightText,
PaletteHighlight,
PaletteHighlightedText,
PaletteLink,
PaletteLinkVisited,
PaletteLight,
PaletteMidlight,
PaletteDark,
PaletteMid,
PaletteShadow,
PaletteWindowDisabled,
PaletteWindowTextDisabled,
PaletteBaseDisabled,
PaletteAlternateBaseDisabled,
PaletteToolTipBaseDisabled,
PaletteToolTipTextDisabled,
PaletteTextDisabled,
PaletteButtonDisabled,
PaletteButtonTextDisabled,
PaletteBrightTextDisabled,
PaletteHighlightDisabled,
PaletteHighlightedTextDisabled,
PaletteLinkDisabled,
PaletteLinkVisitedDisabled,
PaletteLightDisabled,
PaletteMidlightDisabled,
PaletteDarkDisabled,
PaletteMidDisabled,
PaletteShadowDisabled
};
Q_ENUM(ColorRole)
QColor color(ColorRole role) const;
QPalette palette() const;
void load(const QString& filename);
bool isDark() const;
private:
static QPalette initialPalette();
private:
QHash<int,QColor> mColors;
QString mName;
bool mIsDark;
};
using PAppTheme = std::shared_ptr<AppTheme>;
class ThemeManager : public QObject
{
Q_OBJECT
public:
explicit ThemeManager(QObject *parent = nullptr);
PAppTheme theme(const QString& themeName);
signals:
};
#endif // THEMEMANAGER_H

7
RedPandaIDE/themes.qrc Normal file
View File

@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/">
<file>themes/dark.json</file>
<file>themes/default.json</file>
<file>themes/dark_close.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,32 @@
{
"name":"dark",
"isDark": true,
"palette": {
"PaletteWindow":"#19232D",
"PaletteWindowText":"#E0E1E3",
"PaletteBase":"#1E1E1E",
"PaletteAlternateBase":"#303030",
"PaletteButton": "#19232D",
"PaletteButtonDisabled": "#000000",
"PaletteBrightText": "#ff0000",
"PaletteText":"#e7e7e7",
"PaletteButtonText":"#d3d3d3",
"PaletteButtonTextDisabled":"#9DA9B5",
"PaletteHighlight":"#aa1f75cc",
"PaletteDark":"#ff232323",
"PaletteHighlightedText":"#ffe7e7e7",
"PaletteToolTipBase":"#66000000",
"PaletteToolTipText":"#ffe7e7e7",
"PaletteLink":"#ff007af4",
"PaletteLinkVisited":"#ffa57aff",
"PaletteWindowDisabled":"#333333",
"PaletteWindowTextDisabled":"#9DA9B5",
"PaletteHighlightDisabled":"#26486B",
"PaletteHighlightedTextDisabled":"#9DA9B5",
"PaletteBaseDisabled":"#19232D",
"PaletteTextDisabled":"#9DA9B5",
"PaletteMid": "#707070",
"PaletteLight": "#505050",
"PaletteMidLight": "#00ff00"
}
}

View File

@ -388,7 +388,7 @@ https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu
QMenu {
border: 0px solid #455364;
color: #E0E1E3;
margin: 0px;
margin: 2px;
background-color: #37414F;
selection-background-color: #1A72BB;
}
@ -401,7 +401,7 @@ QMenu::separator {
QMenu::item {
background-color: #37414F;
padding: 4px 8px 4px 8px;
padding: 4px 15px 4px 20px;
/* Reserve space for selection border */
border: 1px transparent #455364;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,6 @@
{
"name":"default",
"isDark":false,
"palette": {
}
}

View File

@ -434,32 +434,32 @@ QString TrimLeft(const QString &s)
}
}
void changeTheme(const QString &themeName)
{
if (themeName.isEmpty() || themeName == "default") {
QApplication::setStyle("Fusion");
QApplication* app = dynamic_cast<QApplication*>(QApplication::instance());
app->setStyleSheet("");
return ;
}
QStyleFactory styleFactory;
if (styleFactory.keys().contains(themeName)) {
QApplication::setStyle(themeName);
QApplication* app = dynamic_cast<QApplication*>(QApplication::instance());
app->setStyleSheet("");
return;
}
QFile f(QString(":/themes/%1/style.qss").arg(themeName));
//void changeTheme(const QString &themeName)
//{
// if (themeName.isEmpty() || themeName == "default") {
// QApplication::setStyle("Fusion");
// QApplication* app = dynamic_cast<QApplication*>(QApplication::instance());
// //app->setStyleSheet("");
// return ;
// }
// QStyleFactory styleFactory;
// if (styleFactory.keys().contains(themeName)) {
// QApplication::setStyle(themeName);
// QApplication* app = dynamic_cast<QApplication*>(QApplication::instance());
// app->setStyleSheet("");
// return;
// }
// QFile f(QString(":/themes/%1/style.qss").arg(themeName));
if (!f.exists()) {
qDebug()<<"Unable to set stylesheet, file not found\n";
} else {
QApplication::setStyle("Windowsvista");
f.open(QFile::ReadOnly | QFile::Text);
QTextStream ts(&f);
dynamic_cast<QApplication*>(QApplication::instance())->setStyleSheet(ts.readAll());
}
}
// if (!f.exists()) {
// qDebug()<<"Unable to set stylesheet, file not found\n";
// } else {
// QApplication::setStyle("Fusion");
// f.open(QFile::ReadOnly | QFile::Text);
// QTextStream ts(&f);
// dynamic_cast<QApplication*>(QApplication::instance())->setStyleSheet(ts.readAll());
// }
//}
int compareFileModifiedTime(const QString &filename1, const QString &filename2)
{

View File

@ -165,7 +165,7 @@ QString TrimLeft(const QString& s);
bool StringIsBlank(const QString& s);
int compareFileModifiedTime(const QString& filename1, const QString& filename2);
void changeTheme(const QString& themeName);
//void changeTheme(const QString& themeName);
bool findComplement(const QString& s,
const QChar& fromToken,

View File

@ -159,6 +159,9 @@
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="textElideMode">
<enum>Qt::ElideNone</enum>
</property>

View File

@ -0,0 +1,795 @@
#include "darkfusionstyle.h"
#include <QPainter>
#include <QStyleOption>
#include <QGroupBox>
#include <qdrawutil.h>
#include <QPainterPath>
#include <QCoreApplication>
#include <QPixmapCache>
#include <QApplication>
#define BEGIN_STYLE_PIXMAPCACHE(a) \
QRect rect = option->rect; \
QPixmap internalPixmapCache; \
QImage imageCache; \
QPainter *p = painter; \
QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
bool doPixmapCache = (!option->rect.isEmpty()) \
&& ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale)); \
if (doPixmapCache && QPixmapCache::find(unique, &internalPixmapCache)) { \
painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
} else { \
if (doPixmapCache) { \
rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
imageCache = styleCacheImage(option->rect.size()); \
imageCache.fill(0); \
p = new QPainter(&imageCache); \
}
#define END_STYLE_PIXMAPCACHE \
if (doPixmapCache) { \
p->end(); \
delete p; \
internalPixmapCache = QPixmap::fromImage(imageCache); \
painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
QPixmapCache::insert(unique, internalPixmapCache); \
} \
}
namespace QStyleHelper {
static QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
{
const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
QString tmp = QString("%1%2%3%4%5%6%7")
.arg(key)
.arg(option->state)
.arg(option->direction)
.arg(complexOption ? uint(complexOption->activeSubControls) : 0u)
.arg(option->palette.cacheKey())
.arg(size.width())
.arg(size.height());
#if QT_CONFIG(spinbox)
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
tmp = tmp + QString("%1%2%3")
.arg(spinBox->buttonSymbols)
.arg(spinBox->stepEnabled)
.arg(QLatin1Char(spinBox->frame ? '1' : '0'));
}
#endif // QT_CONFIG(spinbox)
return tmp;
}
Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, const QPaintDevice *device);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, const QStyleOption *option);
}
enum Direction {
TopDown,
FromLeft,
BottomUp,
FromRight
};
// from windows style
static const int windowsItemFrame = 2; // menu item frame width
static const int windowsItemHMargin = 3; // menu item hor text margin
static const int windowsItemVMargin = 8; // menu item ver text margin
static const int windowsRightBorder = 15; // right border on windows
static const int groupBoxBottomMargin = 0; // space below the groupbox
static const int groupBoxTopMargin = 3;
DarkFusionStyle::DarkFusionStyle():QProxyStyle("fusion")
{
}
// On mac we want a standard blue color used when the system palette is used
static bool isMacSystemPalette(const QPalette &pal){
Q_UNUSED(pal);
#if defined(Q_OS_MACX)
const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette();
if (themePalette && themePalette->color(QPalette::Normal, QPalette::Highlight) ==
pal.color(QPalette::Normal, QPalette::Highlight) &&
themePalette->color(QPalette::Normal, QPalette::HighlightedText) ==
pal.color(QPalette::Normal, QPalette::HighlightedText))
return true;
#endif
return false;
}
// Used for grip handles
static QColor calcDarkShade() {
return QColor(255, 255, 255, 90);
}
static QColor calcLightShade() {
return QColor(0, 0, 0, 60);
}
// The default button and handle gradient
static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown)
{
int x = rect.center().x();
int y = rect.center().y();
QLinearGradient gradient;
switch (direction) {
case FromLeft:
gradient = QLinearGradient(rect.left(), y, rect.right(), y);
break;
case FromRight:
gradient = QLinearGradient(rect.right(), y, rect.left(), y);
break;
case BottomUp:
gradient = QLinearGradient(x, rect.bottom(), x, rect.top());
break;
case TopDown:
default:
gradient = QLinearGradient(x, rect.top(), x, rect.bottom());
break;
}
if (baseColor.gradient())
gradient.setStops(baseColor.gradient()->stops());
else {
QColor gradientStartColor = baseColor.color().lighter(124);
QColor gradientStopColor = baseColor.color().lighter(102);
gradient.setColorAt(0, gradientStartColor);
gradient.setColorAt(1, gradientStopColor);
// Uncomment for adding shiny shading
// QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 55);
// QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 45);
// gradient.setColorAt(0.5, midColor1);
// gradient.setColorAt(0.501, midColor2);
}
return gradient;
}
static QColor calcHighlight(const QPalette &pal) {
if (isMacSystemPalette(pal))
return QColor(60, 140, 230);
return pal.color(QPalette::Highlight);
}
static QColor calcOutline(const QPalette &pal) {
if (pal.window().style() == Qt::TexturePattern)
return QColor(255, 255, 255, 160);
return pal.window().color().lighter(180);
}
static QColor calcHighlightedOutline(const QPalette &pal) {
QColor highlightedOutline = calcHighlight(pal).lighter(125);
if (highlightedOutline.value() > 160)
highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160);
return highlightedOutline;
}
static QColor calcButtonColor(const QPalette &pal) {
QColor buttonColor = pal.button().color();
int val = qGray(buttonColor.rgb());
buttonColor = buttonColor.darker(100 + qMax(1, (180 - val)/6));
buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75, buttonColor.value());
return buttonColor;
}
static QColor calcTabFrameColor(const QPalette &pal) {
if (pal.window().style() == Qt::TexturePattern)
return QColor(255, 255, 255, 8);
return calcButtonColor(pal).lighter(104);
}
static QColor calcTopShadow() {
return QColor(255, 255, 255, 18);
}
static QColor calcInnerContrastLine() {
return QColor(0, 0, 0, 30);
}
static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
{
const int maxFactor = 100;
QColor tmp = colorA;
tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
return tmp;
}
static QImage styleCacheImage(const QSize &size)
{
const qreal pixelRatio = qApp->devicePixelRatio();
QImage cacheImage = QImage(size * pixelRatio, QImage::Format_ARGB32_Premultiplied);
cacheImage.setDevicePixelRatio(pixelRatio);
return cacheImage;
}
void DarkFusionStyle::drawPrimitive(PrimitiveElement elem, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
Q_ASSERT(option);
QRect rect = option->rect;
int state = option->state;
QColor outline = calcOutline(option->palette);
QColor highlightedOutline = calcHighlightedOutline(option->palette);
QColor tabFrameColor = calcTabFrameColor(option->palette);
switch (elem) {
//#if QT_CONFIG(groupbox)
// // No frame drawn
// case PE_FrameGroupBox:
// {
// QPixmap pixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_groupbox.png"));
// int topMargin = 0;
// auto control = qobject_cast<const QGroupBox *>(widget);
// if (control && !control->isCheckable() && control->title().isEmpty()) {
// // Shrinking the topMargin if Not checkable AND title is empty
// topMargin = groupBoxTopMargin;
// } else {
// topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin;
// }
// QRect frame = option->rect.adjusted(0, topMargin, 0, 0);
// qDrawBorderPixmap(painter, frame, QMargins(6, 6, 6, 6), pixmap);
// break;
// }
//#endif // QT_CONFIG(groupbox)
// case PE_IndicatorBranch: {
// if (!(option->state & State_Children))
// break;
// if (option->state & State_Open)
// drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
// else {
// const bool reverse = (option->direction == Qt::RightToLeft);
// drawPrimitive(reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight, option, painter, widget);
// }
// break;
// }
#if QT_CONFIG(tabbar)
case PE_FrameTabBarBase:
if (const QStyleOptionTabBarBase *tbb
= qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
painter->save();
painter->setPen(QPen(outline.darker(110)));
switch (tbb->shape) {
case QTabBar::RoundedNorth: {
QRegion region(tbb->rect);
region -= tbb->selectedTabRect;
painter->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
painter->setClipRegion(region);
painter->setPen(option->palette.light().color());
painter->drawLine(tbb->rect.topLeft() + QPoint(0, 1), tbb->rect.topRight() + QPoint(0, 1));
}
break;
case QTabBar::RoundedWest:
painter->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
break;
case QTabBar::RoundedSouth:
painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
tbb->rect.right(), tbb->rect.bottom());
break;
case QTabBar::RoundedEast:
painter->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
break;
case QTabBar::TriangularNorth:
case QTabBar::TriangularEast:
case QTabBar::TriangularWest:
case QTabBar::TriangularSouth:
painter->restore();
QCommonStyle::drawPrimitive(elem, option, painter, widget);
return;
}
painter->restore();
}
return;
#endif // QT_CONFIG(tabbar)
case PE_PanelScrollAreaCorner: {
painter->save();
QColor alphaOutline = outline;
alphaOutline.setAlpha(180);
painter->setPen(alphaOutline);
painter->setBrush(option->palette.brush(QPalette::Window));
painter->drawRect(option->rect);
painter->restore();
} break;
// case PE_IndicatorArrowUp:
// case PE_IndicatorArrowDown:
// case PE_IndicatorArrowRight:
// case PE_IndicatorArrowLeft:
// {
// if (option->rect.width() <= 1 || option->rect.height() <= 1)
// break;
// QColor arrowColor = option->palette.windowText().color();
// arrowColor.setAlpha(160);
// Qt::ArrowType arrow = Qt::UpArrow;
// switch (elem) {
// case PE_IndicatorArrowDown:
// arrow = Qt::DownArrow;
// break;
// case PE_IndicatorArrowRight:
// arrow = Qt::RightArrow;
// break;
// case PE_IndicatorArrowLeft:
// arrow = Qt::LeftArrow;
// break;
// default:
// break;
// }
// qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor);
// }
// break;
// case PE_IndicatorItemViewItemCheck:
// {
// QStyleOptionButton button;
// button.QStyleOption::operator=(*option);
// button.state &= ~State_MouseOver;
// proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
// }
// return;
// case PE_IndicatorHeaderArrow:
// if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
// QRect r = header->rect;
// QColor arrowColor = header->palette.windowText().color();
// arrowColor.setAlpha(180);
// QPoint offset = QPoint(0, -2);
//#if defined(Q_OS_LINUX)
// if (header->sortIndicator & QStyleOptionHeader::SortUp) {
// qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
// } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
// qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
// }
//#else
// if (header->sortIndicator & QStyleOptionHeader::SortUp) {
// qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor);
// } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
// qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor);
// }
//#endif
// }
// break;
// case PE_IndicatorButtonDropDown:
// proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
// break;
case PE_IndicatorToolBarSeparator:
{
QRect rect = option->rect;
const int margin = 6;
if (option->state & State_Horizontal) {
const int offset = rect.width()/2;
painter->setPen(QPen(option->palette.window().color().lighter(110)));
painter->drawLine(rect.bottomLeft().x() + offset,
rect.bottomLeft().y() - margin,
rect.topLeft().x() + offset,
rect.topLeft().y() + margin);
painter->setPen(QPen(option->palette.window().color().darker(110)));
painter->drawLine(rect.bottomLeft().x() + offset + 1,
rect.bottomLeft().y() - margin,
rect.topLeft().x() + offset + 1,
rect.topLeft().y() + margin);
} else { //Draw vertical separator
const int offset = rect.height()/2;
painter->setPen(QPen(option->palette.window().color().lighter(110)));
painter->drawLine(rect.topLeft().x() + margin ,
rect.topLeft().y() + offset,
rect.topRight().x() - margin,
rect.topRight().y() + offset);
painter->setPen(QPen(option->palette.window().color().darker(110)));
painter->drawLine(rect.topLeft().x() + margin ,
rect.topLeft().y() + offset + 1,
rect.topRight().x() - margin,
rect.topRight().y() + offset + 1);
}
}
break;
case PE_Frame: {
if (widget && widget->inherits("QComboBoxPrivateContainer")){
QStyleOption copy = *option;
copy.state |= State_Raised;
proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
break;
}
painter->save();
QPen thePen(outline.darker(108));
thePen.setCosmetic(false);
painter->setPen(thePen);
painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
painter->restore(); }
break;
case PE_FrameMenu:
painter->save();
{
painter->setPen(QPen(outline));
painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
QColor frameLight = option->palette.window().color().darker(160);
QColor frameShadow = option->palette.window().color().lighter(110);
//paint beveleffect
QRect frame = option->rect.adjusted(1, 1, -1, -1);
painter->setPen(frameLight);
painter->drawLine(frame.topLeft(), frame.bottomLeft());
painter->drawLine(frame.topLeft(), frame.topRight());
painter->setPen(frameShadow);
painter->drawLine(frame.topRight(), frame.bottomRight());
painter->drawLine(frame.bottomLeft(), frame.bottomRight());
}
painter->restore();
break;
case PE_FrameDockWidget:
painter->save();
{
QColor softshadow = option->palette.window().color().lighter(120);
QRect rect= option->rect;
painter->setPen(softshadow);
painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
painter->setPen(QPen(option->palette.light(), 1));
painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1));
painter->setPen(QPen(option->palette.window().color().lighter(120)));
painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1));
painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1));
}
painter->restore();
break;
// case PE_PanelButtonTool:
// painter->save();
// if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) {
// if (widget && widget->inherits("QDockWidgetTitleButton")) {
// if (option->state & State_MouseOver)
// proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
// } else {
// proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
// }
// }
// painter->restore();
// break;
// case PE_IndicatorDockWidgetResizeHandle:
// {
// QStyleOption dockWidgetHandle = *option;
// bool horizontal = option->state & State_Horizontal;
// dockWidgetHandle.state.setFlag(State_Horizontal, !horizontal);
// proxy()->drawControl(CE_Splitter, &dockWidgetHandle, painter, widget);
// }
// break;
case PE_FrameWindow:
painter->save();
{
QRect rect= option->rect;
painter->setPen(QPen(outline.lighter(150)));
painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
painter->setPen(QPen(option->palette.light(), 1));
painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
QPoint(rect.left() + 1, rect.bottom() - 1));
painter->setPen(QPen(option->palette.window().color().darker(120)));
painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
QPoint(rect.right() - 2, rect.bottom() - 1));
painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
QPoint(rect.right() - 1, rect.bottom() - 1));
}
painter->restore();
break;
case PE_FrameLineEdit:
{
QRect r = rect;
bool hasFocus = option->state & State_HasFocus;
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
// ### highdpi painter bug.
painter->translate(0.5, 0.5);
// Draw Outline
painter->setPen( QPen(hasFocus ? highlightedOutline : outline));
painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
if (hasFocus) {
QColor softHighlight = highlightedOutline;
softHighlight.setAlpha(40);
painter->setPen(softHighlight);
painter->drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7);
}
// Draw inner shadow
painter->setPen(calcTopShadow());
painter->drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
painter->restore();
}
break;
case PE_IndicatorCheckBox:
painter->save();
if (const QStyleOptionButton *checkbox = qstyleoption_cast<const QStyleOptionButton*>(option)) {
painter->setRenderHint(QPainter::Antialiasing, true);
painter->translate(0.5, 0.5);
rect = rect.adjusted(0, 0, -1, -1);
QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
painter->setBrush(Qt::NoBrush);
// Gradient fill
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
gradient.setColorAt(0, (state & State_Sunken) ? pressedColor : option->palette.base().color().lighter(115));
gradient.setColorAt(0.15, (state & State_Sunken) ? pressedColor : option->palette.base().color());
gradient.setColorAt(1, (state & State_Sunken) ? pressedColor : option->palette.base().color());
painter->setBrush((state & State_Sunken) ? QBrush(pressedColor) : gradient);
painter->setPen(QPen(outline.lighter(110)));
if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
painter->setPen(QPen(highlightedOutline));
painter->drawRect(rect);
QColor checkMarkColor = option->palette.text().color().lighter(120);
const qreal checkMarkPadding = 1 + rect.width() * 0.13; // at least one pixel padding
if (checkbox->state & State_NoChange) {
gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
checkMarkColor.setAlpha(80);
gradient.setColorAt(0, checkMarkColor);
checkMarkColor.setAlpha(140);
gradient.setColorAt(1, checkMarkColor);
checkMarkColor.setAlpha(180);
painter->setPen(QPen(checkMarkColor, 1));
painter->setBrush(gradient);
painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
} else if (checkbox->state & State_On) {
const qreal dpi = QStyleHelper::dpi(option);
qreal penWidth = QStyleHelper::dpiScaled(1.5, dpi);
penWidth = qMax<qreal>(penWidth, 0.13 * rect.height());
penWidth = qMin<qreal>(penWidth, 0.20 * rect.height());
QPen checkPen = QPen(checkMarkColor, penWidth);
checkMarkColor.setAlpha(210);
painter->translate(QStyleHelper::dpiScaled(-0.8, dpi), QStyleHelper::dpiScaled(0.5, dpi));
painter->setPen(checkPen);
painter->setBrush(Qt::NoBrush);
// Draw checkmark
QPainterPath path;
const qreal rectHeight = rect.height(); // assuming height equals width
path.moveTo(checkMarkPadding + rectHeight * 0.11, rectHeight * 0.47);
path.lineTo(rectHeight * 0.5, rectHeight - checkMarkPadding);
path.lineTo(rectHeight - checkMarkPadding, checkMarkPadding);
painter->drawPath(path.translated(rect.topLeft()));
}
}
painter->restore();
break;
case PE_IndicatorRadioButton:
painter->save();
{
QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color());
painter->setRenderHint(QPainter::Antialiasing, true);
QPainterPath circle;
const QPointF circleCenter = rect.center() + QPoint(1, 1);
const qreal outlineRadius = (rect.width() + (rect.width() + 1) % 2) / 2.0 - 1;
circle.addEllipse(circleCenter, outlineRadius, outlineRadius);
painter->setPen(QPen(option->palette.window().color().lighter(150)));
if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
painter->setPen(QPen(highlightedOutline));
painter->drawPath(circle);
if (state & (State_On )) {
circle = QPainterPath();
const qreal checkmarkRadius = outlineRadius / 2.32;
circle.addEllipse(circleCenter, checkmarkRadius, checkmarkRadius);
QColor checkMarkColor = option->palette.text().color().lighter(120);
checkMarkColor.setAlpha(200);
painter->setPen(checkMarkColor);
checkMarkColor.setAlpha(180);
painter->setBrush(checkMarkColor);
painter->drawPath(circle);
}
}
painter->restore();
break;
case PE_IndicatorToolBarHandle:
{
//draw grips
if (option->state & State_Horizontal) {
for (int i = -3 ; i < 2 ; i += 3) {
for (int j = -8 ; j < 10 ; j += 3) {
painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, calcLightShade());
painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, calcDarkShade());
}
}
} else { //vertical toolbar
for (int i = -6 ; i < 12 ; i += 3) {
for (int j = -3 ; j < 2 ; j += 3) {
painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, calcLightShade());
painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, calcDarkShade());
}
}
}
break;
}
case PE_FrameDefaultButton:
break;
case PE_FrameFocusRect:
if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) {
//### check for d->alt_down
if (!(fropt->state & State_KeyboardFocusChange))
return;
QRect rect = option->rect;
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->translate(0.5, 0.5);
QColor fillcolor = highlightedOutline;
fillcolor.setAlpha(80);
painter->setPen(fillcolor.lighter(120));
fillcolor.setAlpha(30);
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
gradient.setColorAt(0, fillcolor.darker(160));
gradient.setColorAt(1, fillcolor);
painter->setBrush(gradient);
painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1);
painter->restore();
}
break;
case PE_PanelButtonCommand:
{
bool isDefault = false;
bool isFlat = false;
bool isDown = (option->state & State_Sunken) || (option->state & State_On);
QRect r;
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) {
isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state & State_Enabled);
isFlat = (button->features & QStyleOptionButton::Flat);
}
if (isFlat && !isDown) {
if (isDefault) {
r = option->rect.adjusted(0, 1, 0, -1);
painter->setPen(QPen(QColorConstants::Svg::lightgray));
const QLine lines[4] = {
QLine(QPoint(r.left() + 2, r.top()),
QPoint(r.right() - 2, r.top())),
QLine(QPoint(r.left(), r.top() + 2),
QPoint(r.left(), r.bottom() - 2)),
QLine(QPoint(r.right(), r.top() + 2),
QPoint(r.right(), r.bottom() - 2)),
QLine(QPoint(r.left() + 2, r.bottom()),
QPoint(r.right() - 2, r.bottom()))
};
painter->drawLines(lines, 4);
const QPoint points[4] = {
QPoint(r.right() - 1, r.bottom() - 1),
QPoint(r.right() - 1, r.top() + 1),
QPoint(r.left() + 1, r.bottom() - 1),
QPoint(r.left() + 1, r.top() + 1)
};
painter->drawPoints(points, 4);
}
return;
}
bool isEnabled = option->state & State_Enabled;
bool hasFocus = (option->state & State_HasFocus && option->state & State_KeyboardFocusChange);
QColor buttonColor = calcButtonColor(option->palette);
QColor darkOutline = outline;
if (hasFocus | isDefault) {
darkOutline = highlightedOutline;
}
if (isDefault)
buttonColor = mergedColors(buttonColor, highlightedOutline.lighter(130), 90);
BEGIN_STYLE_PIXMAPCACHE(QStringLiteral("pushbutton-") + buttonColor.name(QColor::HexArgb))
r = rect.adjusted(0, 1, -1, 0);
p->setRenderHint(QPainter::Antialiasing, true);
p->translate(0.5, -0.5);
QLinearGradient gradient = qt_fusion_gradient(rect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
p->setPen(Qt::transparent);
p->setBrush(isDown ? QBrush(buttonColor.darker(110)) : gradient);
p->drawRoundedRect(r, 2.0, 2.0);
p->setBrush(Qt::NoBrush);
// Outline
p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline));
p->drawRoundedRect(r, 2.0, 2.0);
p->setPen(calcInnerContrastLine());
p->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2.0, 2.0);
END_STYLE_PIXMAPCACHE
}
break;
case PE_FrameTabWidget:
painter->save();
painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor);
#if QT_CONFIG(tabwidget)
if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
QColor borderColor = outline.lighter(110);
QRect rect = option->rect.adjusted(0, 0, -1, -1);
// Shadow outline
if (twf->shape != QTabBar::RoundedSouth) {
rect.adjust(0, 0, 0, -1);
QColor alphaShadow(Qt::black);
alphaShadow.setAlpha(15);
painter->setPen(alphaShadow);
painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); painter->setPen(borderColor);
}
// outline
painter->setPen(outline);
painter->drawRect(rect);
// Inner frame highlight
painter->setPen(calcInnerContrastLine());
painter->drawRect(rect.adjusted(1, 1, -1, -1));
}
#endif // QT_CONFIG(tabwidget)
painter->restore();
break ;
case PE_FrameStatusBarItem:
break;
// case PE_IndicatorTabClose:
// {
// Q_D(const QFusionStyle);
// if (d->tabBarcloseButtonIcon.isNull())
// d->tabBarcloseButtonIcon = proxy()->standardIcon(SP_DialogCloseButton, option, widget);
// if ((option->state & State_Enabled) && (option->state & State_MouseOver))
// proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
// QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(qt_getWindow(widget), QSize(16, 16), QIcon::Normal, QIcon::On);
// proxy()->drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap);
// }
// break;
case PE_PanelMenu: {
painter->save();
const QBrush menuBackground = option->palette.base().color().darker(108);
QColor borderColor = option->palette.window().color().lighter(160);
qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground);
painter->restore();
}
break;
default:
QProxyStyle::drawPrimitive(elem, option, painter, widget);
break;
}
}
QIcon DarkFusionStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const
{
switch (standardIcon) {
case SP_TitleBarCloseButton:
case SP_DockWidgetCloseButton:
case SP_DialogCloseButton:
return QIcon(":/themes/dark_close.png");
default:
break;
}
return QProxyStyle::standardIcon(standardIcon, option, widget);
}

View File

@ -0,0 +1,19 @@
#ifndef DARKFUSIONSTYLE_H
#define DARKFUSIONSTYLE_H
#include <QProxyStyle>
class DarkFusionStyle : public QProxyStyle
{
Q_OBJECT
public:
DarkFusionStyle();
// QStyle interface
public:
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr,
const QWidget *widget = nullptr) const override;
};
#endif // DARKFUSIONSTYLE_H

View File

@ -202,7 +202,7 @@ void NewProjectDialog::on_lstTemplates_currentItemChanged(QListWidgetItem *curre
}
void NewProjectDialog::on_btnBrowse_triggered(QAction *)
void NewProjectDialog::on_btnBrowse_clicked()
{
QString dirPath = ui->txtLocation->text();
if (!QDir(dirPath).exists()) {

View File

@ -29,7 +29,7 @@ private slots:
void on_lstTemplates_itemDoubleClicked(QListWidgetItem *item);
void on_lstTemplates_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
void on_btnBrowse_triggered(QAction *arg1);
void on_btnBrowse_clicked();
private:
void addTemplate(const QString& filename);