unify custom and built-in, lua and json themes (#386)

This commit is contained in:
Cyano Hao 2024-04-16 20:46:17 +08:00 committed by GitHub
parent 6658d14ea0
commit 9650393db7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 152 additions and 624 deletions

View File

@ -608,11 +608,8 @@ qmake_qm_files.prefix = $$QM_FILES_RESOURCE_PREFIX
iconsets_files.files += $$files(resources/iconsets/*.svg, true) iconsets_files.files += $$files(resources/iconsets/*.svg, true)
iconsets_files.files += $$files(resources/iconsets/*.json, true) iconsets_files.files += $$files(resources/iconsets/*.json, true)
ENABLE_LUA_ADDON {
theme_files.files += $$files(resources/themes/*.lua, false) theme_files.files += $$files(resources/themes/*.lua, false)
} else {
theme_files.files += $$files(resources/themes/*.json, false) theme_files.files += $$files(resources/themes/*.json, false)
}
theme_files.files += $$files(resources/themes/*.png, false) theme_files.files += $$files(resources/themes/*.png, false)
colorscheme_files.files += $$files(resources/colorschemes/*.scheme, false) colorscheme_files.files += $$files(resources/colorschemes/*.scheme, false)

View File

@ -995,10 +995,6 @@ void MainWindow::updateEditorColorSchemes()
void MainWindow::applySettings() void MainWindow::applySettings()
{ {
ThemeManager themeManager; ThemeManager themeManager;
if (pSettings->environment().useCustomTheme()) {
themeManager.prepareCustomeTheme();
}
themeManager.setUseCustomTheme(pSettings->environment().useCustomTheme());
PAppTheme appTheme; PAppTheme appTheme;
try { try {
appTheme = themeManager.theme(pSettings->environment().theme()); appTheme = themeManager.theme(pSettings->environment().theme());

View File

@ -1,53 +0,0 @@
function apiVersion()
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap = {
en_US = "Contrast",
pt_BR = "Contraste",
zh_CN = "高对比度",
zh_TW = "高對比度",
}
function main()
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaDarkFusion",
["default scheme"] = "Twilight",
["default iconset"] = "contrast",
["palette"] = {
PaletteWindow = "#000000",
PaletteWindowText = "#FFFFFF",
PaletteBase = "#141414",
PaletteAlternateBase = "#191919",
PaletteButton = "#141414",
PaletteButtonDisabled = "#141414",
PaletteBrightText = "#ff0000",
PaletteText = "#FFFFFF",
PaletteButtonText = "#FFFFFF",
PaletteButtonTextDisabled = "#9DA9B5",
PaletteHighlight = "#aa1f75cc",
PaletteDark = "#232323",
PaletteHighlightedText = "#e7e7e7",
PaletteToolTipBase = "#66000000",
PaletteToolTipText = "#e7e7e7",
PaletteLink = "#007af4",
PaletteLinkVisited = "#a57aff",
PaletteWindowDisabled = "#0A0A0A",
PaletteWindowTextDisabled = "#9DA9B5",
PaletteHighlightDisabled = "#9DA9B5",
PaletteHighlightedTextDisabled = "#9DA9B5",
PaletteBaseDisabled = "#000000",
PaletteTextDisabled = "#9DA9B5",
PaletteMid = "#FFFFFF",
PaletteLight = "#505050",
PaletteMidlight = "#00ff00",
},
}
end

View File

@ -1,53 +0,0 @@
function apiVersion()
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap = {
en_US = "Dark",
pt_BR = "Escura",
zh_CN = "深色",
zh_TW = "深色",
}
function main()
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaDarkFusion",
["default scheme"] = "VS Code",
["default iconset"] = "contrast",
["palette"] = {
PaletteWindow = "#19232D",
PaletteWindowText = "#E0E1E3",
PaletteBase = "#1E1E1E",
PaletteAlternateBase = "#303030",
PaletteButton = "#19232D",
PaletteButtonDisabled = "#19232D",
PaletteBrightText = "#ff0000",
PaletteText = "#e7e7e7",
PaletteButtonText = "#d3d3d3",
PaletteButtonTextDisabled = "#9DA9B5",
PaletteHighlight = "#aa1f75cc",
PaletteDark = "#232323",
PaletteHighlightedText = "#e7e7e7",
PaletteToolTipBase = "#66000000",
PaletteToolTipText = "#e7e7e7",
PaletteLink = "#007af4",
PaletteLinkVisited = "#a57aff",
PaletteWindowDisabled = "#333333",
PaletteWindowTextDisabled = "#9DA9B5",
PaletteHighlightDisabled = "#26486B",
PaletteHighlightedTextDisabled = "#9DA9B5",
PaletteBaseDisabled = "#19232D",
PaletteTextDisabled = "#9DA9B5",
PaletteMid = "#707070",
PaletteLight = "#505050",
PaletteMidlight = "#00ff00",
},
}
end

View File

@ -1,51 +0,0 @@
function apiVersion()
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap = {
en_US = "Light",
pt_BR = "Clara",
zh_CN = "浅色",
zh_TW = "淺色",
}
function main()
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaLightFusion",
["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",
PaletteLink = "#0000ff",
PaletteLinkVisited = "#ff00ff",
PaletteLight = "#ffffff",
PaletteMidlight = "#cacaca",
PaletteDark = "#9f9f9f",
PaletteMid = "#b8b8b8",
PaletteWindowDisabled = "#efefef",
PaletteWindowTextDisabled = "#bebebe",
PaletteBaseDisabled = "#efefef",
PaletteTextDisabled = "#bebebe",
PaletteButtonDisabled = "#efefef",
PaletteButtonTextDisabled = "#bebebe",
PaletteHighlight = "#688DB2",
PaletteHighlightedText = "#ffffff",
},
}
end

View File

@ -1,53 +0,0 @@
function apiVersion()
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap = {
en_US = "MoLo",
pt_BR = "Molo",
zh_CN = "墨落",
zh_TW = "墨落",
}
function main()
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaDarkFusion",
["default scheme"] = "MoLo CodeBlack",
["default iconset"] = "newlook",
["palette"] = {
PaletteWindow = "#000000",
PaletteWindowText = "#FFFFFF",
PaletteBase = "#141414",
PaletteAlternateBase = "#191919",
PaletteButton = "#141414",
PaletteButtonDisabled = "#141414",
PaletteBrightText = "#ff0000",
PaletteText = "#FFFFFF",
PaletteButtonText = "#FFFFFF",
PaletteButtonTextDisabled = "#9DA9B5",
PaletteHighlight = "#aa1f75cc",
PaletteDark = "#232323",
PaletteHighlightedText = "#e7e7e7",
PaletteToolTipBase = "#66000000",
PaletteToolTipText = "#e7e7e7",
PaletteLink = "#007af4",
PaletteLinkVisited = "#a57aff",
PaletteWindowDisabled = "#0A0A0A",
PaletteWindowTextDisabled = "#9DA9B5",
PaletteHighlightDisabled = "#9DA9B5",
PaletteHighlightedTextDisabled = "#9DA9B5",
PaletteBaseDisabled = "#000000",
PaletteTextDisabled = "#9DA9B5",
PaletteMid = "#FFFFFF",
PaletteLight = "#505050",
PaletteMidlight = "#00ff00",
},
}
end

View File

@ -1,44 +0,0 @@
function apiVersion()
return {
kind = "theme",
major = 0,
minor = 1,
}
end
function main()
return {
["name"] = "One Dark",
["style"] = "RedPandaDarkFusion",
["default scheme"] = "One Dark",
["default iconset"] = "contrast",
["palette"] = {
PaletteWindow = "#282c34",
PaletteWindowDisabled = "#21252B",
PaletteWindowText = "#9da5b4",
PaletteWindowTextDisabled = "#676D7B",
PaletteBase = "#21252B",
PaletteBaseDisabled = "#1d2026",
PaletteAlternateBase = "#282c34",
PaletteToolTipBase = "#21252B",
PaletteToolTipText = "#9da5b4",
PaletteText = "#b4b4b4",
PaletteTextDisabled = "#676D7B",
PaletteButton = "#2c313c",
PaletteButtonDisabled = "#21252B",
PaletteButtonText = "#9da5b4",
PaletteButtonTextDisabled = "#676D7B",
PaletteHighlight = "#3b4048",
PaletteHighlightDisabled = "#21252B",
PaletteHighlightedText = "#d7dae0",
PaletteHighlightedTextDisabled = "#676D7B",
PaletteLink = "#98c379",
PaletteLinkVisited = "#c9c900",
PaletteBrightText = "#E0E1E3",
PaletteDark = "#282c34",
PaletteMid = "#282c34",
PaletteMidlight = "#282c34",
PaletteLight = "#282c34",
},
}
end

View File

@ -3749,7 +3749,6 @@ void Settings::Environment::doLoad()
mLanguage = stringValue("language", QLocale::system().name()); mLanguage = stringValue("language", QLocale::system().name());
mIconSet = stringValue("icon_set","contrast"); mIconSet = stringValue("icon_set","contrast");
mUseCustomIconSet = boolValue("use_custom_icon_set", false); mUseCustomIconSet = boolValue("use_custom_icon_set", false);
mUseCustomTheme = boolValue("use_custom_theme", false);
mCurrentFolder = stringValue("current_folder",QDir::currentPath()); mCurrentFolder = stringValue("current_folder",QDir::currentPath());
if (!fileExists(mCurrentFolder)) { if (!fileExists(mCurrentFolder)) {
@ -3877,16 +3876,6 @@ void Settings::Environment::setUseCustomIconSet(bool newUseCustomIconSet)
mUseCustomIconSet = newUseCustomIconSet; mUseCustomIconSet = newUseCustomIconSet;
} }
bool Settings::Environment::useCustomTheme() const
{
return mUseCustomTheme;
}
void Settings::Environment::setUseCustomTheme(bool newUseCustomTheme)
{
mUseCustomTheme = newUseCustomTheme;
}
bool Settings::Environment::hideNonSupportFilesInFileView() const bool Settings::Environment::hideNonSupportFilesInFileView() const
{ {
return mHideNonSupportFilesInFileView; return mHideNonSupportFilesInFileView;

View File

@ -566,9 +566,6 @@ public:
bool useCustomIconSet() const; bool useCustomIconSet() const;
void setUseCustomIconSet(bool newUseCustomIconSet); void setUseCustomIconSet(bool newUseCustomIconSet);
bool useCustomTheme() const;
void setUseCustomTheme(bool newUseCustomTheme);
bool hideNonSupportFilesInFileView() const; bool hideNonSupportFilesInFileView() const;
void setHideNonSupportFilesInFileView(bool newHideNonSupportFilesInFileView); void setHideNonSupportFilesInFileView(bool newHideNonSupportFilesInFileView);

View File

@ -54,7 +54,6 @@ void EnvironmentAppearanceWidget::doLoad()
} }
ui->spinZoomFactor->setValue(pSettings->environment().iconZoomFactor()); ui->spinZoomFactor->setValue(pSettings->environment().iconZoomFactor());
ui->chkUseCustomIconSet->setChecked(pSettings->environment().useCustomIconSet()); ui->chkUseCustomIconSet->setChecked(pSettings->environment().useCustomIconSet());
ui->chkUseCustomTheme->setChecked(pSettings->environment().useCustomTheme());
for (int i=0;i<ui->cbLanguage->count();i++) { for (int i=0;i<ui->cbLanguage->count();i++) {
if (ui->cbLanguage->itemData(i) == pSettings->environment().language()) { if (ui->cbLanguage->itemData(i) == pSettings->environment().language()) {
@ -68,7 +67,6 @@ void EnvironmentAppearanceWidget::doSave()
{ {
if (pSettings->environment().theme()!=ui->cbTheme->currentData().toString()) { if (pSettings->environment().theme()!=ui->cbTheme->currentData().toString()) {
ThemeManager themeManager; ThemeManager themeManager;
themeManager.setUseCustomTheme(pSettings->environment().useCustomTheme());
PAppTheme appTheme = themeManager.theme(ui->cbTheme->currentData().toString()); PAppTheme appTheme = themeManager.theme(ui->cbTheme->currentData().toString());
if (appTheme && !appTheme->defaultColorScheme().isEmpty()) { if (appTheme && !appTheme->defaultColorScheme().isEmpty()) {
pSettings->editor().setColorScheme(appTheme->defaultColorScheme()); pSettings->editor().setColorScheme(appTheme->defaultColorScheme());
@ -84,7 +82,6 @@ void EnvironmentAppearanceWidget::doSave()
pSettings->environment().setIconZoomFactor(ui->spinZoomFactor->value()); pSettings->environment().setIconZoomFactor(ui->spinZoomFactor->value());
pSettings->environment().setUseCustomIconSet(ui->chkUseCustomIconSet->isChecked()); pSettings->environment().setUseCustomIconSet(ui->chkUseCustomIconSet->isChecked());
pSettings->environment().setUseCustomTheme(ui->chkUseCustomTheme->isChecked());
pSettings->environment().save(); pSettings->environment().save();
pMainWindow->applySettings(); pMainWindow->applySettings();
@ -93,7 +90,6 @@ void EnvironmentAppearanceWidget::doSave()
void EnvironmentAppearanceWidget::init() void EnvironmentAppearanceWidget::init()
{ {
ThemeManager themeManager; ThemeManager themeManager;
themeManager.setUseCustomTheme(pSettings->environment().useCustomTheme());
QList<PAppTheme> appThemes = themeManager.getThemes(); QList<PAppTheme> appThemes = themeManager.getThemes();
foreach(const PAppTheme& appTheme, appThemes) { foreach(const PAppTheme& appTheme, appThemes) {
ui->cbTheme->addItem(appTheme->displayName(),appTheme->name()); ui->cbTheme->addItem(appTheme->displayName(),appTheme->name());
@ -112,9 +108,9 @@ void EnvironmentAppearanceWidget::init()
void EnvironmentAppearanceWidget::on_cbTheme_currentIndexChanged(int /* index */) void EnvironmentAppearanceWidget::on_cbTheme_currentIndexChanged(int /* index */)
{ {
ThemeManager themeManager; ThemeManager themeManager;
themeManager.setUseCustomTheme(pSettings->environment().useCustomTheme());
PAppTheme appTheme = themeManager.theme(ui->cbTheme->currentData().toString()); PAppTheme appTheme = themeManager.theme(ui->cbTheme->currentData().toString());
if (appTheme && !appTheme->defaultIconSet().isEmpty()) { ui->lblThemeCategory->setText(appTheme->category());
if(!appTheme->defaultIconSet().isEmpty()) {
for (int i=0; i<ui->cbIconSet->count();i++) { for (int i=0; i<ui->cbIconSet->count();i++) {
if (ui->cbIconSet->itemData(i) == appTheme->defaultIconSet()) { if (ui->cbIconSet->itemData(i) == appTheme->defaultIconSet()) {
ui->cbIconSet->setCurrentIndex(i); ui->cbIconSet->setCurrentIndex(i);

View File

@ -136,9 +136,9 @@
<widget class="QComboBox" name="cbTheme"/> <widget class="QComboBox" name="cbTheme"/>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="chkUseCustomTheme"> <widget class="QLabel" name="lblThemeCategory">
<property name="text"> <property name="text">
<string>Use custom theme</string> <string>theme category</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -322,7 +322,6 @@
</widget> </widget>
<tabstops> <tabstops>
<tabstop>cbTheme</tabstop> <tabstop>cbTheme</tabstop>
<tabstop>chkUseCustomTheme</tabstop>
<tabstop>cbFont</tabstop> <tabstop>cbFont</tabstop>
<tabstop>spinFontSize</tabstop> <tabstop>spinFontSize</tabstop>
<tabstop>cbIconSet</tabstop> <tabstop>cbIconSet</tabstop>

View File

@ -45,12 +45,8 @@ void EnvironmentFoldersWidget::doLoad()
if (pSettings->environment().useCustomIconSet()) { if (pSettings->environment().useCustomIconSet()) {
ui->txtIconSetFolder->setText(pSettings->dirs().config(Settings::Dirs::DataType::IconSet)); ui->txtIconSetFolder->setText(pSettings->dirs().config(Settings::Dirs::DataType::IconSet));
} }
ui->txtThemeFolder->setEnabled(pSettings->environment().useCustomTheme());
ui->btnOpenThemeFolderInFileBrowser->setEnabled(pSettings->environment().useCustomTheme());
if (pSettings->environment().useCustomTheme()) {
ui->txtThemeFolder->setText(pSettings->dirs().config(Settings::Dirs::DataType::Theme)); ui->txtThemeFolder->setText(pSettings->dirs().config(Settings::Dirs::DataType::Theme));
} }
}
void EnvironmentFoldersWidget::doSave() void EnvironmentFoldersWidget::doSave()
{ {

View File

@ -33,79 +33,57 @@
#include "addon/runtime.h" #include "addon/runtime.h"
#endif #endif
ThemeManager::ThemeManager(QObject *parent) : QObject(parent), ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
mUseCustomTheme(false)
{ {
} }
PAppTheme ThemeManager::theme(const QString &themeName) PAppTheme ThemeManager::theme(const QString &themeName)
{ {
if (mUseCustomTheme) QString customThemeDir = pSettings->dirs().config(Settings::Dirs::DataType::Theme);
prepareCustomeTheme(); QString builtInThemeDir = pSettings->dirs().data(Settings::Dirs::DataType::Theme);
QString themeDir; PAppTheme appTheme = nullptr;
if (mUseCustomTheme) {
themeDir = pSettings->dirs().config(Settings::Dirs::DataType::Theme); // custom overrides built-in
} else { if (tryLoadThemeFromDir(customThemeDir, tr("custom"), themeName, appTheme))
themeDir = pSettings->dirs().data(Settings::Dirs::DataType::Theme);
}
#ifdef ENABLE_LUA_ADDON
PAppTheme appTheme = std::make_shared<AppTheme>(QString("%1/%2.lua").arg(themeDir, themeName), AppTheme::ThemeType::Lua);
#else
PAppTheme appTheme = std::make_shared<AppTheme>(QString("%1/%2.json").arg(themeDir, themeName), AppTheme::ThemeType::JSON);
#endif
return appTheme; return appTheme;
} if (tryLoadThemeFromDir(builtInThemeDir, tr("built-in"), themeName, appTheme))
return appTheme;
bool ThemeManager::useCustomTheme() const return AppTheme::fallbackTheme();
{
return mUseCustomTheme;
}
void ThemeManager::setUseCustomTheme(bool newUseCustomTheme)
{
mUseCustomTheme = newUseCustomTheme;
}
void ThemeManager::prepareCustomeTheme()
{
if (QFile(pSettings->dirs().config(Settings::Dirs::DataType::Theme)).exists())
return;
copyFolder(pSettings->dirs().data(Settings::Dirs::DataType::Theme),pSettings->dirs().config(Settings::Dirs::DataType::Theme));
} }
QList<PAppTheme> ThemeManager::getThemes() QList<PAppTheme> ThemeManager::getThemes()
{ {
if (mUseCustomTheme) QString customThemeDir = pSettings->dirs().config(Settings::Dirs::DataType::Theme);
prepareCustomeTheme(); QString builtInThemeDir = pSettings->dirs().data(Settings::Dirs::DataType::Theme);
std::set<PAppTheme, ThemeCompare> themes;
QList<PAppTheme> result; // custom overrides built-in
QString themeDir; loadThemesFromDir(customThemeDir, tr("custom"), themes);
QString themeExtension; loadThemesFromDir(builtInThemeDir, tr("built-in"), themes);
AppTheme::ThemeType themeType;
if (mUseCustomTheme) { QList<PAppTheme> result(themes.begin(), themes.end());
themeDir = pSettings->dirs().config(Settings::Dirs::DataType::Theme); return result;
themeExtension = "json";
themeType = AppTheme::ThemeType::JSON;
} else {
themeDir = pSettings->dirs().data(Settings::Dirs::DataType::Theme);
#ifdef ENABLE_LUA_ADDON
themeExtension = "lua";
themeType = AppTheme::ThemeType::Lua;
#else
themeExtension = "json";
themeType = AppTheme::ThemeType::JSON;
#endif
} }
QDirIterator it(themeDir);
while (it.hasNext()) { bool ThemeManager::ThemeCompare::operator()(const PAppTheme &lhs, const PAppTheme &rhs) const
it.next(); {
QFileInfo fileInfo = it.fileInfo(); return QFileInfo(lhs->filename()).baseName() < QFileInfo(rhs->filename()).baseName();
if (fileInfo.suffix().compare(themeExtension, PATH_SENSITIVITY)==0) { }
bool ThemeManager::tryLoadThemeFromDir(const QString &dir, const QString &dirType, const QString &themeName, PAppTheme &theme)
{
for (const auto &[extension, type] : searchTypes) {
QString filename = QString("%2.%3").arg(themeName, extension);
QString fullPath = QString("%1/%2").arg(dir, filename);
if (QFile::exists(fullPath)) {
try { try {
PAppTheme appTheme = std::make_shared<AppTheme>(fileInfo.absoluteFilePath(), themeType); theme = std::make_shared<AppTheme>(fullPath, type);
result.append(appTheme); if (theme->displayName().isEmpty()) {
theme->setDisplayName(themeName);
}
theme->setCategory(QString("%1 %2").arg(dirType, filename));
return true;
} catch(FileError e) { } catch(FileError e) {
//just skip it //just skip it
} }
@ -116,14 +94,37 @@ QList<PAppTheme> ThemeManager::getThemes()
#endif #endif
} }
} }
std::sort(result.begin(),result.end(),[](const PAppTheme &theme1, const PAppTheme &theme2){ return false;
return QFileInfo(theme1->filename()).baseName() < QFileInfo(theme2->filename()).baseName();
});
if (result.isEmpty())
result.append(AppTheme::fallbackTheme());
return result;
} }
void ThemeManager::loadThemesFromDir(const QString &dir, const QString &dirType, std::set<PAppTheme, ThemeCompare> &themes)
{
for (const auto &[extension, type] : searchTypes) {
QDirIterator it(dir);
while (it.hasNext()) {
it.next();
QFileInfo fileInfo = it.fileInfo();
if (fileInfo.suffix().compare(extension, PATH_SENSITIVITY) == 0) {
try {
PAppTheme appTheme = std::make_shared<AppTheme>(fileInfo.absoluteFilePath(), type);
if (appTheme->displayName().isEmpty()) {
QString baseName = fileInfo.baseName();
appTheme->setDisplayName(baseName);
}
appTheme->setCategory(QString("%1 %2").arg(dirType, fileInfo.fileName()));
themes.insert(appTheme);
} catch(FileError e) {
//just skip it
}
#ifdef ENABLE_LUA_ADDON
catch(AddOn::LuaError e) {
qDebug() << e.reason();
}
#endif
}
}
}
}
QColor AppTheme::color(ColorRole role) const QColor AppTheme::color(ColorRole role) const
{ {
@ -335,6 +336,21 @@ const QString &AppTheme::displayName() const
return mDisplayName; return mDisplayName;
} }
void AppTheme::setDisplayName(const QString &newDisplayName)
{
mDisplayName = newDisplayName;
}
const QString &AppTheme::category() const
{
return mCategory;
}
void AppTheme::setCategory(const QString &newCategory)
{
mCategory = newCategory;
}
const QString &AppTheme::defaultColorScheme() const const QString &AppTheme::defaultColorScheme() const
{ {
return mDefaultColorScheme; return mDefaultColorScheme;
@ -352,7 +368,8 @@ const QString &AppTheme::style() const
AppTheme::AppTheme() : AppTheme::AppTheme() :
mName("__failsafe__theme__"), mName("__failsafe__theme__"),
mDisplayName("Fusion [fail-safe hard-coded]"), mDisplayName("Fusion"),
mCategory("fail-safe hard-coded"),
mStyle("fusion"), mStyle("fusion"),
mDefaultColorScheme("Adaptive"), mDefaultColorScheme("Adaptive"),
mDefaultIconSet("newlook") mDefaultIconSet("newlook")

View File

@ -21,6 +21,7 @@
#include <QColor> #include <QColor>
#include <memory> #include <memory>
#include <QObject> #include <QObject>
#include <set>
class AppTheme; class AppTheme;
using PAppTheme = std::shared_ptr<AppTheme>; using PAppTheme = std::shared_ptr<AppTheme>;
@ -94,6 +95,10 @@ public:
void setDefaultColorScheme(const QString &newDefaultColorScheme); void setDefaultColorScheme(const QString &newDefaultColorScheme);
const QString &displayName() const; const QString &displayName() const;
void setDisplayName(const QString &newDisplayName);
const QString &category() const;
void setCategory(const QString &newCategory);
const QString &name() const; const QString &name() const;
@ -117,6 +122,7 @@ private:
QHash<int,QColor> mColors; QHash<int,QColor> mColors;
QString mName; QString mName;
QString mDisplayName; QString mDisplayName;
QString mCategory;
QString mStyle; QString mStyle;
QString mDefaultColorScheme; QString mDefaultColorScheme;
QString mDefaultIconSet; QString mDefaultIconSet;
@ -129,13 +135,24 @@ class ThemeManager : public QObject
public: public:
explicit ThemeManager(QObject *parent = nullptr); explicit ThemeManager(QObject *parent = nullptr);
PAppTheme theme(const QString& themeName); PAppTheme theme(const QString& themeName);
bool useCustomTheme() const;
void setUseCustomTheme(bool newUseCustomTheme);
void prepareCustomeTheme();
QList<PAppTheme> getThemes(); QList<PAppTheme> getThemes();
private: private:
bool mUseCustomTheme; struct ThemeCompare {
bool operator()(const PAppTheme &lhs, const PAppTheme &rhs) const;
};
private:
bool tryLoadThemeFromDir(const QString &dir, const QString &dirType, const QString &themeName, PAppTheme &theme);
void loadThemesFromDir(const QString &dir, const QString &dirType, std::set<PAppTheme, ThemeCompare> &themes);
// lua overrides json
inline static const std::pair<QString, AppTheme::ThemeType> searchTypes[] = {
#ifdef ENABLE_LUA_ADDON
{ "lua", AppTheme::ThemeType::Lua },
#endif
{ "json", AppTheme::ThemeType::JSON },
};
}; };
#endif // THEMEMANAGER_H #endif // THEMEMANAGER_H

View File

@ -10656,6 +10656,19 @@
<translation type="vanished">A colocação de destaques parece estar em repetição infinita</translation> <translation type="vanished">A colocação de destaques parece estar em repetição infinita</translation>
</message> </message>
</context> </context>
<context>
<name>ThemeManager</name>
<message>
<location filename="../thememanager.cpp" line="-206"/>
<source>custom</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<source>built-in</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>TodoModel</name> <name>TodoModel</name>
<message> <message>

View File

@ -11534,6 +11534,19 @@ p, li { white-space: pre-wrap; }
<translation type="vanished">&apos;%2&apos;!</translation> <translation type="vanished">&apos;%2&apos;!</translation>
</message> </message>
</context> </context>
<context>
<name>ThemeManager</name>
<message>
<location filename="../thememanager.cpp" line="-206"/>
<source>custom</source>
<translation></translation>
</message>
<message>
<location line="+1"/>
<source>built-in</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>SynEdit</name> <name>SynEdit</name>
<message> <message>

View File

@ -9887,6 +9887,19 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>ThemeManager</name>
<message>
<location filename="../thememanager.cpp" line="-206"/>
<source>custom</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<source>built-in</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>TodoModel</name> <name>TodoModel</name>
<message> <message>

View File

@ -179,7 +179,7 @@ target("RedPandaIDE")
add_files( add_files(
"resources/iconsets/**.svg", "resources/iconsets/**.json", "resources/iconsets/**.svg", "resources/iconsets/**.json",
"resources/themes/*.png", "resources/themes/*.lua", "resources/themes/*.json", "resources/themes/*.png",
"resources/colorschemes/*.scheme", "resources/colorschemes/*.scheme",
"resources/fonts/asciicontrol.ttf", "resources/fonts/asciicontrol.ttf",
{rule = "RedPandaIDE.auto_qrc"}) {rule = "RedPandaIDE.auto_qrc"})
@ -199,14 +199,7 @@ target("RedPandaIDE")
"addon/api.cpp", "addon/api.cpp",
"addon/executor.cpp", "addon/executor.cpp",
"addon/runtime.cpp") "addon/runtime.cpp")
add_files(
"resources/themes/*.lua",
{rule = "RedPandaIDE.auto_qrc"})
add_links("lua") add_links("lua")
else
add_files(
"resources/themes/*.json",
{rule = "RedPandaIDE.auto_qrc"})
end end
if has_config("sdcc") then if has_config("sdcc") then

View File

@ -1,53 +0,0 @@
global function apiVersion(): ApiVersion
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap: {string:string} = {
en_US = "Contrast",
pt_BR = "Contraste",
zh_CN = "高对比度",
zh_TW = "高對比度",
}
global function main(): Theme
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaDarkFusion",
["default scheme"] = "Twilight",
["default iconset"] = "contrast",
["palette"] = {
PaletteWindow = "#000000",
PaletteWindowText = "#FFFFFF",
PaletteBase = "#141414",
PaletteAlternateBase = "#191919",
PaletteButton = "#141414",
PaletteButtonDisabled = "#141414",
PaletteBrightText = "#ff0000",
PaletteText = "#FFFFFF",
PaletteButtonText = "#FFFFFF",
PaletteButtonTextDisabled = "#9DA9B5",
PaletteHighlight = "#aa1f75cc",
PaletteDark = "#232323",
PaletteHighlightedText = "#e7e7e7",
PaletteToolTipBase = "#66000000",
PaletteToolTipText = "#e7e7e7",
PaletteLink = "#007af4",
PaletteLinkVisited = "#a57aff",
PaletteWindowDisabled = "#0A0A0A",
PaletteWindowTextDisabled = "#9DA9B5",
PaletteHighlightDisabled = "#9DA9B5",
PaletteHighlightedTextDisabled = "#9DA9B5",
PaletteBaseDisabled = "#000000",
PaletteTextDisabled = "#9DA9B5",
PaletteMid = "#FFFFFF",
PaletteLight = "#505050",
PaletteMidlight = "#00ff00",
},
}
end

View File

@ -1,53 +0,0 @@
global function apiVersion(): ApiVersion
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap: {string:string} = {
en_US = "Dark",
pt_BR = "Escura",
zh_CN = "深色",
zh_TW = "深色",
}
global function main(): Theme
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaDarkFusion",
["default scheme"] = "VS Code",
["default iconset"] = "contrast",
["palette"] = {
PaletteWindow = "#19232D",
PaletteWindowText = "#E0E1E3",
PaletteBase = "#1E1E1E",
PaletteAlternateBase = "#303030",
PaletteButton = "#19232D",
PaletteButtonDisabled = "#19232D",
PaletteBrightText = "#ff0000",
PaletteText = "#e7e7e7",
PaletteButtonText = "#d3d3d3",
PaletteButtonTextDisabled = "#9DA9B5",
PaletteHighlight = "#aa1f75cc",
PaletteDark = "#232323",
PaletteHighlightedText = "#e7e7e7",
PaletteToolTipBase = "#66000000",
PaletteToolTipText = "#e7e7e7",
PaletteLink = "#007af4",
PaletteLinkVisited = "#a57aff",
PaletteWindowDisabled = "#333333",
PaletteWindowTextDisabled = "#9DA9B5",
PaletteHighlightDisabled = "#26486B",
PaletteHighlightedTextDisabled = "#9DA9B5",
PaletteBaseDisabled = "#19232D",
PaletteTextDisabled = "#9DA9B5",
PaletteMid = "#707070",
PaletteLight = "#505050",
PaletteMidlight = "#00ff00",
},
}
end

View File

@ -1,51 +0,0 @@
global function apiVersion(): ApiVersion
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap: {string:string} = {
en_US = "Light",
pt_BR = "Clara",
zh_CN = "浅色",
zh_TW = "淺色",
}
global function main(): Theme
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaLightFusion",
["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",
PaletteLink = "#0000ff",
PaletteLinkVisited = "#ff00ff",
PaletteLight = "#ffffff",
PaletteMidlight = "#cacaca",
PaletteDark = "#9f9f9f",
PaletteMid = "#b8b8b8",
PaletteWindowDisabled = "#efefef",
PaletteWindowTextDisabled = "#bebebe",
PaletteBaseDisabled = "#efefef",
PaletteTextDisabled = "#bebebe",
PaletteButtonDisabled = "#efefef",
PaletteButtonTextDisabled = "#bebebe",
PaletteHighlight = "#dddddd",
PaletteHighlightedText = "#000000",
},
}
end

View File

@ -1,53 +0,0 @@
global function apiVersion(): ApiVersion
return {
kind = "theme",
major = 0,
minor = 1,
}
end
local nameMap: {string:string} = {
en_US = "MoLo",
pt_BR = "Molo",
zh_CN = "墨落",
zh_TW = "墨落",
}
global function main(): Theme
local lang = C_Desktop.language()
return {
["name"] = nameMap[lang] or nameMap.en_US,
["style"] = "RedPandaDarkFusion",
["default scheme"] = "MoLo CodeBlack",
["default iconset"] = "newlook",
["palette"] = {
PaletteWindow = "#000000",
PaletteWindowText = "#FFFFFF",
PaletteBase = "#141414",
PaletteAlternateBase = "#191919",
PaletteButton = "#141414",
PaletteButtonDisabled = "#141414",
PaletteBrightText = "#ff0000",
PaletteText = "#FFFFFF",
PaletteButtonText = "#FFFFFF",
PaletteButtonTextDisabled = "#9DA9B5",
PaletteHighlight = "#aa1f75cc",
PaletteDark = "#232323",
PaletteHighlightedText = "#e7e7e7",
PaletteToolTipBase = "#66000000",
PaletteToolTipText = "#e7e7e7",
PaletteLink = "#007af4",
PaletteLinkVisited = "#a57aff",
PaletteWindowDisabled = "#0A0A0A",
PaletteWindowTextDisabled = "#9DA9B5",
PaletteHighlightDisabled = "#9DA9B5",
PaletteHighlightedTextDisabled = "#9DA9B5",
PaletteBaseDisabled = "#000000",
PaletteTextDisabled = "#9DA9B5",
PaletteMid = "#FFFFFF",
PaletteLight = "#505050",
PaletteMidlight = "#00ff00",
},
}
end

View File

@ -1,44 +0,0 @@
global function apiVersion(): ApiVersion
return {
kind = "theme",
major = 0,
minor = 1,
}
end
global function main(): Theme
return {
["name"] = "One Dark", -- do not translate
["style"] = "RedPandaDarkFusion",
["default scheme"] = "One Dark",
["default iconset"] = "contrast",
["palette"] = {
PaletteWindow = "#282c34",
PaletteWindowDisabled = "#21252B",
PaletteWindowText = "#9da5b4",
PaletteWindowTextDisabled = "#676D7B",
PaletteBase = "#21252B",
PaletteBaseDisabled = "#1d2026",
PaletteAlternateBase = "#282c34",
PaletteToolTipBase = "#21252B",
PaletteToolTipText = "#9da5b4",
PaletteText = "#b4b4b4",
PaletteTextDisabled = "#676D7B",
PaletteButton = "#2c313c",
PaletteButtonDisabled = "#21252B",
PaletteButtonText = "#9da5b4",
PaletteButtonTextDisabled = "#676D7B",
PaletteHighlight = "#3b4048",
PaletteHighlightDisabled = "#21252B",
PaletteHighlightedText = "#d7dae0",
PaletteHighlightedTextDisabled = "#676D7B",
PaletteLink = "#98c379",
PaletteLinkVisited = "#c9c900",
PaletteBrightText = "#E0E1E3",
PaletteDark = "#282c34",
PaletteMid = "#282c34",
PaletteMidlight = "#282c34",
PaletteLight = "#282c34",
},
}
end