Uniform look for Red Panda C++ under KDE/DDE (#119)
* KDE theme: fix visual problems with KDE dark mode; add system theme * Make "Light" theme truly light under Breeze Dark theme. * With this fix also expose dark mode support on Windows. * Add "Auto" (system) theme that follows system style and color. * Add "Adaptive" color scheme for system theme (using transparent background). * Add support for transparent background in color schemes. * move `alphaBlend` to utils * hide Auto (system) theme on Windows
This commit is contained in:
parent
c7a95d9eab
commit
e89f4400eb
|
@ -530,6 +530,10 @@ iconsets_files.files += $$files(resources/iconsets/*.json, true)
|
|||
theme_files.files += $$files(themes/*.json, false)
|
||||
theme_files.files += $$files(themes/*.png, false)
|
||||
|
||||
windows: {
|
||||
theme_files.files -= themes/system.json
|
||||
}
|
||||
|
||||
colorscheme_files.files += $$files(colorschemes/*.scheme, false)
|
||||
colorscheme_files.prefix = /colorschemes
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"Character" : {
|
||||
"foreground" : "#ce543b"
|
||||
},
|
||||
"Class" : {
|
||||
"foreground" : "#267f99"
|
||||
},
|
||||
"Comment" : {
|
||||
"foreground" : "#3b9827"
|
||||
},
|
||||
"Escape sequences" : {
|
||||
"foreground" : "#e28346"
|
||||
},
|
||||
"Float" : {
|
||||
"foreground" : "#4bc854"
|
||||
},
|
||||
"Function" : {
|
||||
"foreground" : "#c4b65f"
|
||||
},
|
||||
"Global variable" : {
|
||||
"foreground" : "#2381fe"
|
||||
},
|
||||
"Hexadecimal" : {
|
||||
"foreground" : "#4bc854"
|
||||
},
|
||||
"Identifier" : {
|
||||
"foreground" : "#ce543b"
|
||||
},
|
||||
"Illegal Char" : {
|
||||
"foreground" : "#e63b3b"
|
||||
},
|
||||
"Local Variable" : {
|
||||
"foreground" : "#2381fe"
|
||||
},
|
||||
"Number" : {
|
||||
"foreground" : "#4bc854"
|
||||
},
|
||||
"Octal" : {
|
||||
"foreground" : "#4bc854"
|
||||
},
|
||||
"Preprocessor" : {
|
||||
"foreground" : "#cf46d5"
|
||||
},
|
||||
"Reserve Word for Types": {
|
||||
"foreground": "#336be5"
|
||||
},
|
||||
"Reserved Word" : {
|
||||
"foreground" : "#cf46d5"
|
||||
},
|
||||
"Space" : {
|
||||
"foreground" : "#40808080"
|
||||
},
|
||||
"String" : {
|
||||
"foreground" : "#ce543b"
|
||||
},
|
||||
"Symbol" : {
|
||||
"foreground" : "#e0808080"
|
||||
},
|
||||
"Variable" : {
|
||||
"foreground" : "#2381fe"
|
||||
},
|
||||
"Editor Text": {
|
||||
"foreground" : "#808080",
|
||||
"background" : "#00000000"
|
||||
},
|
||||
"Current Highlighted Word": {
|
||||
"background": "#20808080"
|
||||
},
|
||||
"Selected text" : {
|
||||
"background" : "#3c55aaff"
|
||||
},
|
||||
"Gutter" : {
|
||||
"foreground" : "#c0808080",
|
||||
"background" : "#20808080"
|
||||
},
|
||||
"Gutter Active Line" : {
|
||||
"foreground" : "#808080"
|
||||
},
|
||||
"Error" : {
|
||||
"foreground" : "#f52a22"
|
||||
},
|
||||
"Active Breakpoint" : {
|
||||
"foreground" : "#FFFFCE",
|
||||
"background" : "#00376F"
|
||||
},
|
||||
"Fold Line" : {
|
||||
"foreground" : "#808080"
|
||||
},
|
||||
"Active Line" : {
|
||||
"background" : "#10808080"
|
||||
},
|
||||
"Warning" : {
|
||||
"foreground" : "#c69901"
|
||||
},
|
||||
"Indent Guide Line" : {
|
||||
"foreground" : "#80808080"
|
||||
},
|
||||
"brace/parenthesis/bracket level 1" : {
|
||||
"foreground" : "#569CD6"
|
||||
},
|
||||
"brace/parenthesis/bracket level 2" : {
|
||||
"foreground" : "#E080C0"
|
||||
},
|
||||
"brace/parenthesis/bracket level 3" : {
|
||||
"foreground" : "#D69D85"
|
||||
},
|
||||
"brace/parenthesis/bracket level 4" : {
|
||||
"foreground" : "#4EC9B0"
|
||||
}
|
||||
}
|
|
@ -5307,7 +5307,7 @@ void Editor::applyColorScheme(const QString& schemeName)
|
|||
item = pColorManager->getItem(schemeName,COLOR_SCHEME_GUTTER);
|
||||
if (item) {
|
||||
gutter().setTextColor(item->foreground());
|
||||
gutter().setColor(item->background());
|
||||
gutter().setColor(alphaBlend(palette().color(QPalette::Base), item->background()));
|
||||
}
|
||||
item = pColorManager->getItem(schemeName,COLOR_SCHEME_GUTTER_ACTIVE_LINE);
|
||||
if (item) {
|
||||
|
@ -5350,7 +5350,7 @@ void Editor::applyColorScheme(const QString& schemeName)
|
|||
item = pColorManager->getItem(schemeName,COLOR_SCHEME_TEXT);
|
||||
if (item) {
|
||||
this->setForegroundColor(item->foreground());
|
||||
this->setBackgroundColor(item->background());
|
||||
this->setBackgroundColor(alphaBlend(palette().color(QPalette::Base), item->background()));
|
||||
} else {
|
||||
this->setForegroundColor(palette().color(QPalette::Text));
|
||||
this->setBackgroundColor(palette().color(QPalette::Base));
|
||||
|
|
|
@ -243,6 +243,11 @@ void setTheme(const QString& theme) {
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// Make title bar and palette follow system-wide dark mode setting on recent Windows releases.
|
||||
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
@ -337,11 +342,21 @@ int main(int argc, char *argv[])
|
|||
if (firstRun) {
|
||||
//set theme
|
||||
ChooseThemeDialog themeDialog;
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// Qt's default style on Windows is not good.
|
||||
themeDialog.hideAutoFollowSystemTheme();
|
||||
#endif
|
||||
themeDialog.exec();
|
||||
switch (themeDialog.theme()) {
|
||||
case ChooseThemeDialog::Theme::AutoFollowSystem:
|
||||
setTheme("system");
|
||||
break;
|
||||
case ChooseThemeDialog::Theme::Dark:
|
||||
setTheme("dark");
|
||||
break;
|
||||
case ChooseThemeDialog::Theme::Light:
|
||||
setTheme("default");
|
||||
break;
|
||||
default:
|
||||
setTheme("default");
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QScreen>
|
||||
#include <QStyleFactory>
|
||||
#include <QTcpSocket>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextBlock>
|
||||
|
@ -867,10 +868,15 @@ void MainWindow::applySettings()
|
|||
themeManager.setUseCustomTheme(pSettings->environment().useCustomTheme());
|
||||
try {
|
||||
PAppTheme appTheme = themeManager.theme(pSettings->environment().theme());
|
||||
if (appTheme->isDark())
|
||||
QApplication::setStyle(new DarkFusionStyle());//app takes the onwership
|
||||
else
|
||||
QApplication::setStyle(new LightFusionStyle());//app takes the onwership
|
||||
if (appTheme->useQtFusionStyle()) {
|
||||
if (appTheme->isDark())
|
||||
QApplication::setStyle(new DarkFusionStyle());//app takes the onwership
|
||||
else
|
||||
QApplication::setStyle(new LightFusionStyle());//app takes the onwership
|
||||
} else {
|
||||
QString systemStyle = QStyleFactory::keys()[0]; // Breeze for KDE, etc.
|
||||
QApplication::setStyle(systemStyle);
|
||||
}
|
||||
qApp->setPalette(appTheme->palette());
|
||||
//fix for qstatusbar bug
|
||||
mFileEncodingStatus->setPalette(appTheme->palette());
|
||||
|
@ -1715,6 +1721,7 @@ void MainWindow::updateActionIcons()
|
|||
ui->toolbarCode->setIconSize(iconSize);
|
||||
ui->toolbarCompile->setIconSize(iconSize);
|
||||
ui->toolbarDebug->setIconSize(iconSize);
|
||||
ui->toolbarCompilerSet->setIconSize(iconSize);
|
||||
for (QToolButton* btn: mClassBrowserToolbar->findChildren<QToolButton *>()) {
|
||||
btn->setIconSize(iconSize);
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ void AppTheme::load(const QString &filename)
|
|||
QString localeName = obj["name_"+pSettings->environment().language()].toString();
|
||||
if (!localeName.isEmpty())
|
||||
mDisplayName = localeName;
|
||||
mUseQtFusionStyle = obj["useQtFusionStyle"].toBool(true);
|
||||
mIsDark = obj["isDark"].toBool(false);
|
||||
mDefaultColorScheme = obj["default scheme"].toString();
|
||||
mDefaultIconSet = obj["default iconset"].toString();
|
||||
|
@ -268,6 +269,11 @@ void AppTheme::setDefaultColorScheme(const QString &newDefaultColorScheme)
|
|||
mDefaultColorScheme = newDefaultColorScheme;
|
||||
}
|
||||
|
||||
bool AppTheme::useQtFusionStyle() const
|
||||
{
|
||||
return mUseQtFusionStyle;
|
||||
}
|
||||
|
||||
bool AppTheme::isDark() const
|
||||
{
|
||||
return mIsDark;
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
|
||||
void load(const QString& filename);
|
||||
|
||||
bool useQtFusionStyle() const;
|
||||
bool isDark() const;
|
||||
|
||||
const QString &defaultColorScheme() const;
|
||||
|
@ -98,6 +99,7 @@ private:
|
|||
QHash<int,QColor> mColors;
|
||||
QString mName;
|
||||
QString mDisplayName;
|
||||
bool mUseQtFusionStyle;
|
||||
bool mIsDark;
|
||||
QString mDefaultColorScheme;
|
||||
QString mDefaultIconSet;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"name":"contrast",
|
||||
"name":"Contract",
|
||||
"name_zh_CN": "高对比度主题",
|
||||
"useQtFusionStyle": true,
|
||||
"isDark": true,
|
||||
"default scheme": "Twilight",
|
||||
"default iconset": "contrast",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"name":"dark",
|
||||
"name":"Dark",
|
||||
"name_zh_CN": "深色主题",
|
||||
"useQtFusionStyle": true,
|
||||
"isDark": true,
|
||||
"default scheme": "VS Code",
|
||||
"default iconset": "contrast",
|
||||
|
|
|
@ -1,11 +1,36 @@
|
|||
{
|
||||
"name":"light",
|
||||
"name_zh_CN":"浅色主题",
|
||||
"isDark":false,
|
||||
"default scheme": "Intellij Classic",
|
||||
"default iconset": "newlook",
|
||||
"palette": {
|
||||
"PaletteHighlight":"#ffdddddd",
|
||||
"PaletteHighlightedText":"#ff000000"
|
||||
}
|
||||
"name":"Light",
|
||||
"name_zh_CN": "浅色主题",
|
||||
"useQtFusionStyle": true,
|
||||
"isDark": false,
|
||||
"default scheme": "Intellij Classic",
|
||||
"default iconset": "newlook",
|
||||
"palette": {
|
||||
"PaletteWindow":"#efefef",
|
||||
"PaletteWindowText":"#000000",
|
||||
"PaletteBase":"#ffffff",
|
||||
"PaletteAlternateBase":"#f7f7f7",
|
||||
"PaletteToolTipBase":"#ffffdc",
|
||||
"PaletteToolTipText":"#000000",
|
||||
"PaletteText":"#000000",
|
||||
"PaletteButton": "#efefef",
|
||||
"PaletteButtonText":"#000000",
|
||||
"PaletteBrightText": "#ffffff",
|
||||
"PaletteHighlight":"#308cc6",
|
||||
"PaletteHighlightedText":"#ffffff",
|
||||
"PaletteLink":"#0000ff",
|
||||
"PaletteLinkVisited":"#ff00ff",
|
||||
"PaletteLight": "#ffffff",
|
||||
"PaletteMidLight": "#cacaca",
|
||||
"PaletteDark":"#9f9f9f",
|
||||
"PaletteMid": "#b8b8b8",
|
||||
"PaletteWindowDisabled":"#efefef",
|
||||
"PaletteWindowTextDisabled":"#bebebe",
|
||||
"PaletteBaseDisabled":"#efefef",
|
||||
"PaletteTextDisabled":"#bebebe",
|
||||
"PaletteButtonDisabled": "#efefef",
|
||||
"PaletteButtonTextDisabled":"#bebebe",
|
||||
"PaletteHighlightDisabled":"#919191",
|
||||
"PaletteHighlightedTextDisabled":"#ffffff"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name":"Auto (follow system style and color)",
|
||||
"name_zh_CN":"自动(跟随系统样式和颜色)",
|
||||
"useQtFusionStyle": false,
|
||||
"isDark": false,
|
||||
"default scheme": "Adaptive",
|
||||
"default iconset": "newlook",
|
||||
"palette": {}
|
||||
}
|
|
@ -307,6 +307,10 @@
|
|||
<source>C++</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Auto (follow system style and color)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CodeSnippetsManager</name>
|
||||
|
|
|
@ -409,6 +409,11 @@ p, li { white-space: pre-wrap; }
|
|||
<source>Light Theme</source>
|
||||
<translation>浅色主题</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/choosethemedialog.ui" line="72"/>
|
||||
<source>Auto (follow system style and color)</source>
|
||||
<translation>自动(跟随系统样式和颜色)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/choosethemedialog.ui" line="78"/>
|
||||
<source>Default Language:</source>
|
||||
|
|
|
@ -216,6 +216,10 @@
|
|||
<source>C++</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Auto (follow system style and color)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CodeSnippetsManager</name>
|
||||
|
|
|
@ -579,3 +579,13 @@ void openFileFolderInExplorer(const QString &path)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
QColor alphaBlend(const QColor &lower, const QColor &upper) {
|
||||
qreal wu = upper.alphaF(); // weight of upper color
|
||||
qreal wl = 1 - wu; // weight of lower color
|
||||
return QColor(
|
||||
int(lower.red() * wl + upper.red() * wu),
|
||||
int(lower.green() * wl + upper.green() * wu),
|
||||
int(lower.blue() * wl + upper.blue() * wu)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -156,5 +156,6 @@ QString getSizeString(int size);
|
|||
class QComboBox;
|
||||
void saveComboHistory(QComboBox* cb,const QString& text);
|
||||
|
||||
QColor alphaBlend(const QColor &lower, const QColor &upper);
|
||||
|
||||
#endif // UTILS_H
|
||||
|
|
|
@ -33,9 +33,13 @@ ChooseThemeDialog::~ChooseThemeDialog()
|
|||
|
||||
ChooseThemeDialog::Theme ChooseThemeDialog::theme()
|
||||
{
|
||||
if (ui->rbAuto->isChecked())
|
||||
return Theme::AutoFollowSystem;
|
||||
if (ui->rbDark->isChecked())
|
||||
return Theme::Dark;
|
||||
return Theme::Light;
|
||||
if (ui->rbLight->isChecked())
|
||||
return Theme::Light;
|
||||
return Theme::Unknown;
|
||||
}
|
||||
|
||||
ChooseThemeDialog::Language ChooseThemeDialog::language()
|
||||
|
@ -48,3 +52,7 @@ void ChooseThemeDialog::on_btnOk_clicked()
|
|||
accept();
|
||||
}
|
||||
|
||||
void ChooseThemeDialog::hideAutoFollowSystemTheme()
|
||||
{
|
||||
ui->rbAuto->hide();
|
||||
}
|
||||
|
|
|
@ -29,8 +29,10 @@ class ChooseThemeDialog : public QDialog
|
|||
|
||||
public:
|
||||
enum class Theme {
|
||||
Unknown = -1,
|
||||
AutoFollowSystem = 0,
|
||||
Dark,
|
||||
Light
|
||||
Light,
|
||||
};
|
||||
enum class Language {
|
||||
C,
|
||||
|
@ -41,6 +43,7 @@ public:
|
|||
~ChooseThemeDialog();
|
||||
Theme theme();
|
||||
Language language();
|
||||
void hideAutoFollowSystemTheme();
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
|
|
|
@ -20,14 +20,23 @@
|
|||
<string>Choose Theme</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbDark">
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dark Theme</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../icons.qrc">:/demos/light.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
|
@ -43,26 +52,24 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="rbDark">
|
||||
<property name="text">
|
||||
<string>Dark Theme</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="rbLight">
|
||||
<property name="text">
|
||||
<string>Light Theme</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbAuto">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../icons.qrc">:/demos/light.png</pixmap>
|
||||
<string>Auto (follow system style and color)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in New Issue