From 5447ef76235d7bdac7bdd1020d896dd9eb5cae28 Mon Sep 17 00:00:00 2001 From: ozone10 Date: Thu, 3 Apr 2025 17:46:00 +0200 Subject: [PATCH] Add option to apply different color to fluent toolbar icons Fix #16369, fix #15430, close #16370 --- PowerEditor/installer/nativeLang/english.xml | 12 +- .../nativeLang/english_customizable.xml | 12 +- PowerEditor/src/Notepad_plus.cpp | 17 +- PowerEditor/src/NppBigSwitch.cpp | 16 +- PowerEditor/src/NppDarkMode.cpp | 331 ++++++++++++++++- PowerEditor/src/NppDarkMode.h | 50 ++- PowerEditor/src/Parameters.cpp | 88 ++++- PowerEditor/src/Parameters.h | 1 + .../WinControls/ImageListSet/ImageListSet.cpp | 12 +- .../WinControls/ImageListSet/ImageListSet.h | 2 +- .../src/WinControls/Preference/preference.rc | 10 +- .../WinControls/Preference/preferenceDlg.cpp | 346 ++++++++++++------ .../WinControls/Preference/preferenceDlg.h | 4 + .../WinControls/Preference/preference_rc.h | 14 +- 14 files changed, 722 insertions(+), 193 deletions(-) diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 8cb60cf6b..34f5d4e93 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -948,11 +948,13 @@ Translation note: - - - - - + + + + + + + diff --git a/PowerEditor/installer/nativeLang/english_customizable.xml b/PowerEditor/installer/nativeLang/english_customizable.xml index a26e87206..a4a1b8a18 100644 --- a/PowerEditor/installer/nativeLang/english_customizable.xml +++ b/PowerEditor/installer/nativeLang/english_customizable.xml @@ -948,11 +948,13 @@ Translation note: - - - - - + + + + + + + diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 7a8981e57..c16171c32 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -689,11 +689,10 @@ LRESULT Notepad_plus::init(HWND hwnd) //-- Tool Bar Section --// - const int toolbarState = NppDarkMode::getToolBarIconSet(NppDarkMode::isEnabled()); - if (toolbarState != -1) - { - nppGUI._toolBarStatus = static_cast(toolbarState); - } + const NppDarkMode::TbIconInfo toolbarIconInfo = NppDarkMode::getToolbarIconInfo(); + nppGUI._tbIconInfo = toolbarIconInfo; + nppGUI._toolBarStatus = static_cast(nppGUI._tbIconInfo._tbIconSet); + toolBarStatusType tbStatus = nppGUI._toolBarStatus; willBeShown = nppGUI._toolbarShow; @@ -8522,8 +8521,12 @@ void Notepad_plus::refreshDarkMode(bool resetStyle) } } - const int iconState = NppDarkMode::getToolBarIconSet(NppDarkMode::isEnabled()); - toolBarStatusType state = (iconState == -1) ? _toolBar.getState() : static_cast(iconState); + toolBarStatusType state = TB_STANDARD; + auto& nppGUITbInfo = nppParams.getNppGUI()._tbIconInfo; + const NppDarkMode::TbIconInfo toolbarIconInfo = NppDarkMode::getToolbarIconInfo(); + nppGUITbInfo = toolbarIconInfo; + state = static_cast(nppGUITbInfo._tbIconSet); + switch (state) { case TB_SMALL: diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index afeffebe8..cdd7d1e57 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -322,8 +322,12 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa nppGUI._darkmode._isEnabled = enableDarkMode; if (!_preference.isCreated()) { - const int iconState = NppDarkMode::getToolBarIconSet(NppDarkMode::isEnabled()); - toolBarStatusType state = (iconState == -1) ? _toolBar.getState() : static_cast(iconState); + toolBarStatusType state = TB_STANDARD; + auto& nppGUITbInfo = nppGUI._tbIconInfo; + const NppDarkMode::TbIconInfo toolbarIconInfo = NppDarkMode::getToolbarIconInfo(); + nppGUITbInfo = toolbarIconInfo; + state = static_cast(nppGUITbInfo._tbIconSet); + switch (state) { case TB_SMALL: @@ -3920,7 +3924,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { toolBarStatusType state = _toolBar.getState(); - if (state != TB_SMALL) + if (state != TB_SMALL || static_cast(wParam)) { _toolBar.reduce(); } @@ -3931,7 +3935,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { toolBarStatusType state = _toolBar.getState(); - if (state != TB_LARGE) + if (state != TB_LARGE || static_cast(wParam)) { _toolBar.enlarge(); } @@ -3942,7 +3946,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { toolBarStatusType state = _toolBar.getState(); - if (state != TB_SMALL2) + if (state != TB_SMALL2 || static_cast(wParam)) { _toolBar.reduceToSet2(); } @@ -3953,7 +3957,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { toolBarStatusType state = _toolBar.getState(); - if (state != TB_LARGE2) + if (state != TB_LARGE2 || static_cast(wParam)) { _toolBar.enlargeToSet2(); } diff --git a/PowerEditor/src/NppDarkMode.cpp b/PowerEditor/src/NppDarkMode.cpp index c24ced466..4ea02cd87 100644 --- a/PowerEditor/src/NppDarkMode.cpp +++ b/PowerEditor/src/NppDarkMode.cpp @@ -34,6 +34,7 @@ #ifdef __GNUC__ #include +#include #define WINAPI_LAMBDA WINAPI #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 @@ -392,6 +393,56 @@ namespace NppDarkMode return opt; } + constexpr COLORREF cDefaultMainDark = RGB(0xDE, 0xDE, 0xDE); + constexpr COLORREF cDefaultSecondaryDark = RGB(0x4C, 0xC2, 0xFF); + constexpr COLORREF cDefaultMainLight = RGB(0x21, 0x21, 0x21); + constexpr COLORREF cDefaultSecondaryLight = RGB(0x00, 0x78, 0xD4); + + static COLORREF cAccentDark = cDefaultSecondaryDark; + static COLORREF cAccentLight = cDefaultSecondaryLight; + + static COLORREF adjustClrLightness(COLORREF clr, bool useDark) + { + WORD h = 0; + WORD s = 0; + WORD l = 0; + ::ColorRGBToHLS(clr, &h, &l, &s); + + constexpr double lightnessThreshold = 50.0 - 3.0; + if (NppDarkMode::calculatePerceivedLightness(clr) < lightnessThreshold) + { + s -= 20; + l += 50; + return useDark ? ::ColorHLSToRGB(h, l, s) : clr; + } + else + { + s += 20; + l -= 50; + return useDark ? clr : ::ColorHLSToRGB(h, l, s); + } + } + + static bool initAccentColor() + { + BOOL opaque = TRUE; + COLORREF cAccent = 0; + + if (SUCCEEDED(::DwmGetColorizationColor(&cAccent, &opaque))) + { + cAccent = RGB(GetBValue(cAccent), GetGValue(cAccent), GetRValue(cAccent)); + + cAccentDark = NppDarkMode::adjustClrLightness(cAccent, true); + cAccentLight = NppDarkMode::adjustClrLightness(cAccent, false); + return true; + } + + cAccentDark = cDefaultSecondaryDark; + cAccentLight = cDefaultSecondaryLight; + return false; + } + + static bool g_isAtLeastWindows10 = false; static bool g_isWine = false; @@ -401,6 +452,7 @@ namespace NppDarkMode initExperimentalDarkMode(); initAdvancedOptions(); + initAccentColor(); g_isAtLeastWindows10 = NppDarkMode::isWindows10(); @@ -520,23 +572,72 @@ namespace NppDarkMode return (lstrcmp(theme.c_str(), L"stylers.xml") == 0) ? L"" : theme; } - static bool g_isCustomToolIconUsed = NppParameters::getInstance().getCustomizedToolButtons() != nullptr; - - void setToolBarIconSet(int state2Set, bool useDark) + TbIconInfo getToolbarIconInfo(bool useDark) { - if (useDark) - g_advOptions._darkDefaults._toolBarIconSet = state2Set; - else - g_advOptions._lightDefaults._toolBarIconSet = state2Set; + auto& toolbarInfo = useDark ? g_advOptions._darkDefaults._tbIconInfo + : g_advOptions._lightDefaults._tbIconInfo; + + if (toolbarInfo._tbCustomColor == 0) + toolbarInfo._tbCustomColor = NppDarkMode::getAccentColor(); + + return toolbarInfo; } - int getToolBarIconSet(bool useDark) + TbIconInfo getToolbarIconInfo() { - if (g_isCustomToolIconUsed) - { - return -1; - } - return useDark ? g_advOptions._darkDefaults._toolBarIconSet : g_advOptions._lightDefaults._toolBarIconSet; + return NppDarkMode::getToolbarIconInfo(NppDarkMode::isEnabled()); + } + + void setToolbarIconSet(int state2Set, bool useDark) + { + if (useDark) + g_advOptions._darkDefaults._tbIconInfo._tbIconSet = state2Set; + else + g_advOptions._lightDefaults._tbIconInfo._tbIconSet = state2Set; + } + + void setToolbarIconSet(int state2Set) + { + NppDarkMode::setToolbarIconSet(state2Set, NppDarkMode::isEnabled()); + } + + void setToolbarFluentColor(FluentColor color2Set, bool useDark) + { + if (useDark) + g_advOptions._darkDefaults._tbIconInfo._tbColor = color2Set; + else + g_advOptions._lightDefaults._tbIconInfo._tbColor = color2Set; + } + + void setToolbarFluentColor(FluentColor color2Set) + { + NppDarkMode::setToolbarFluentColor(color2Set, NppDarkMode::isEnabled()); + } + + void setToolbarFluentMonochrome(bool setMonochrome, bool useDark) + { + if (useDark) + g_advOptions._darkDefaults._tbIconInfo._tbUseMono = setMonochrome; + else + g_advOptions._lightDefaults._tbIconInfo._tbUseMono = setMonochrome; + } + + void setToolbarFluentMonochrome(bool setMonochrome) + { + NppDarkMode::setToolbarFluentMonochrome(setMonochrome, NppDarkMode::isEnabled()); + } + + void setToolbarFluentCustomColor(COLORREF color, bool useDark) + { + if (useDark) + g_advOptions._darkDefaults._tbIconInfo._tbCustomColor = color; + else + g_advOptions._lightDefaults._tbIconInfo._tbCustomColor = color; + } + + void setToolbarFluentCustomColor(COLORREF color) + { + NppDarkMode::setToolbarFluentCustomColor(color, NppDarkMode::isEnabled()); } void setTabIconSet(bool useAltIcons, bool useDark) @@ -620,6 +721,11 @@ namespace NppDarkMode return lightness; } + COLORREF getAccentColor() + { + return NppDarkMode::isEnabled() ? cAccentDark : cAccentLight; + } + COLORREF getBackgroundColor() { return getTheme()._colors.background; } COLORREF getCtrlBackgroundColor() { return getTheme()._colors.softerBackground; } COLORREF getHotBackgroundColor() { return getTheme()._colors.hotBackground; } @@ -3751,4 +3857,203 @@ namespace NppDarkMode return NppDarkMode::onCtlColor(hdc); } + bool changeFluentIconColor(HICON* phIcon, const std::vector>& colorMappings, int tolerance) + { + if (!*phIcon) + { + return false; + } + + HDC hdcScreen = nullptr; + HDC hdcBitmap = nullptr; + BITMAP bm{}; + ICONINFO ii{}; + HBITMAP hbmNew = nullptr; + std::unique_ptr pixels; + + const bool changeEverything = colorMappings[0].first == 0; + + auto cleanup = [&]() + { + if (hdcScreen) ::ReleaseDC(nullptr, hdcScreen); + if (hdcBitmap) ::DeleteDC(hdcBitmap); + if (ii.hbmColor) ::DeleteObject(ii.hbmColor); + if (ii.hbmMask) ::DeleteObject(ii.hbmMask); + if (hbmNew) ::DeleteObject(hbmNew); + }; + + hdcScreen = ::GetDC(nullptr); + hdcBitmap = ::CreateCompatibleDC(nullptr); + + if (!hdcScreen || !hdcBitmap || !::GetIconInfo(*phIcon, &ii) || !ii.hbmColor || !::GetObject(ii.hbmColor, sizeof(BITMAP), &bm)) + { + cleanup(); + return false; + } + + BITMAPINFO bmi{}; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = bm.bmWidth; + bmi.bmiHeader.biHeight = -bm.bmHeight; // Top-down bitmap + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + pixels = std::make_unique(static_cast(bm.bmWidth) * bm.bmHeight); + if (!pixels || !::GetDIBits(hdcBitmap, ii.hbmColor, 0, bm.bmHeight, pixels.get(), &bmi, DIB_RGB_COLORS)) + { + cleanup(); + return false; + } + + for (int i = 0; i < bm.bmWidth * bm.bmHeight; i++) + { + if (pixels[i].rgbReserved != 0) // Modify non-transparent pixels + { + if (changeEverything) + { + COLORREF cNew = colorMappings[0].second == 0 ? NppDarkMode::getAccentColor() : colorMappings[0].second; + pixels[i].rgbRed = GetRValue(cNew); + pixels[i].rgbGreen = GetGValue(cNew); + pixels[i].rgbBlue = GetBValue(cNew); + } + else + { + for (const auto& [cToChange, cNew] : colorMappings) + { + + if (std::abs(pixels[i].rgbRed - GetRValue(cToChange)) <= tolerance && + std::abs(pixels[i].rgbGreen - GetGValue(cToChange)) <= tolerance && + std::abs(pixels[i].rgbBlue - GetBValue(cToChange)) <= tolerance) + { + COLORREF finalNewColor = (cNew == 0) ? NppDarkMode::getAccentColor() : cNew; + pixels[i].rgbRed = GetRValue(finalNewColor); + pixels[i].rgbGreen = GetGValue(finalNewColor); + pixels[i].rgbBlue = GetBValue(finalNewColor); + break; + } + } + } + } + } + + hbmNew = ::CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight); + if (!hbmNew || !::SetDIBits(hdcBitmap, hbmNew, 0, bm.bmHeight, pixels.get(), &bmi, DIB_RGB_COLORS)) + { + cleanup(); + return false; + } + + if (ii.hbmColor) + { + ::DeleteObject(ii.hbmColor); + ii.hbmColor = nullptr; + } + + ii.hbmColor = hbmNew; + HICON hIconNew = ::CreateIconIndirect(&ii); + if (!hIconNew) + { + cleanup(); + return false; + } + + ::DestroyIcon(*phIcon); + *phIcon = hIconNew; + + cleanup(); + return true; + } + + bool changeFluentIconColor(HICON* phIcon) + { + const auto cMain = NppDarkMode::isEnabled() ? cDefaultMainDark : cDefaultMainLight; + const auto cSecondary = NppDarkMode::isEnabled() ? cDefaultSecondaryDark : cDefaultSecondaryLight; + std::vector> colorMappings; + + NppParameters& nppParams = NppParameters::getInstance(); + const auto& tbInfo = nppParams.getNppGUI()._tbIconInfo; + + COLORREF cOld = tbInfo._tbUseMono ? 0 : cSecondary; + COLORREF cNew = 0; + + switch (tbInfo._tbColor) + { + case FluentColor::accent: + { + cNew = 0; + break; + } + + case FluentColor::red: + { + cNew = RGB(0xE8, 0x11, 0x23); + break; + } + + case FluentColor::green: + { + cNew = RGB(0x00, 0x8B, 0x00); + break; + } + + case FluentColor::blue: + { + cNew = RGB(0x00, 0x78, 0xD4); + break; + } + + case FluentColor::purple: + { + cNew = RGB(0xB1, 0x46, 0xC2); + break; + } + + case FluentColor::cyan: + { + cNew = RGB(0x00, 0xB7, 0xC3); + break; + } + + case FluentColor::olive: + { + cNew = RGB(0x49, 0x82, 0x05); + break; + } + + case FluentColor::yellow: + { + cNew = RGB(0xFF, 0xB9, 0x00); + break; + } + + case FluentColor::custom: + { + if (tbInfo._tbCustomColor != 0) + { + cNew = tbInfo._tbCustomColor; + break; + } + [[fallthrough]]; + } + + case FluentColor::defaultColor: + { + if (tbInfo._tbUseMono) + { + cNew = cMain; + break; + } + [[fallthrough]]; + } + + default: + { + return false; + } + } + + colorMappings = { {cOld, cNew} }; + return NppDarkMode::changeFluentIconColor(phIcon, colorMappings); + } } diff --git a/PowerEditor/src/NppDarkMode.h b/PowerEditor/src/NppDarkMode.h index 92ffee80e..2161012b7 100644 --- a/PowerEditor/src/NppDarkMode.h +++ b/PowerEditor/src/NppDarkMode.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include @@ -79,10 +80,36 @@ namespace NppDarkMode dark = 2 }; + enum class FluentColor + { + defaultColor = 0, + accent = 1, + red = 2, + green = 3, + blue = 4, + purple = 5, + cyan = 6, + olive = 7, + yellow = 8, + custom = 9, + maxValue = 10 + }; + + struct TbIconInfo + { + int _tbIconSet = 4; + // fluent icon color + FluentColor _tbColor = FluentColor::defaultColor; + // fluent icon custom color, used when _tbColor == FluentColor::custom + COLORREF _tbCustomColor = 0; + // does fluent icon use monochrome colorization + bool _tbUseMono = false; + }; + struct AdvOptDefaults { std::wstring _xmlFileName; - int _toolBarIconSet = -1; + TbIconInfo _tbIconInfo{}; int _tabIconSet = -1; bool _tabUseTheme = false; }; @@ -91,8 +118,8 @@ namespace NppDarkMode { bool _enableWindowsMode = false; - NppDarkMode::AdvOptDefaults _darkDefaults{ L"DarkModeDefault.xml", 0, 2, false }; - NppDarkMode::AdvOptDefaults _lightDefaults{ L"", 4, 0, true }; + NppDarkMode::AdvOptDefaults _darkDefaults{ L"DarkModeDefault.xml", {0, FluentColor::defaultColor, 0, false}, 2, false}; + NppDarkMode::AdvOptDefaults _lightDefaults{ L"", { 4, FluentColor::defaultColor, 0, false }, 0, true }; }; constexpr UINT WM_SETBUTTONIDEALSIZE = (WM_USER + 4200); @@ -112,8 +139,16 @@ namespace NppDarkMode void setWindowsMode(bool enable); std::wstring getThemeName(); void setThemeName(const std::wstring& newThemeName); - int getToolBarIconSet(bool useDark); - void setToolBarIconSet(int state2Set, bool useDark); + TbIconInfo getToolbarIconInfo(bool useDark); + TbIconInfo getToolbarIconInfo(); + void setToolbarIconSet(int state2Set, bool useDark); + void setToolbarIconSet(int state2Set); + void setToolbarFluentColor(FluentColor color2Set, bool useDark); + void setToolbarFluentColor(FluentColor color2Set); + void setToolbarFluentMonochrome(bool setMonochrome, bool useDark); + void setToolbarFluentMonochrome(bool setMonochrome); + void setToolbarFluentCustomColor(COLORREF color, bool useDark); + void setToolbarFluentCustomColor(COLORREF color); int getTabIconSet(bool useDark); void setTabIconSet(bool useAltIcons, bool useDark); bool useTabTheme(); @@ -128,6 +163,8 @@ namespace NppDarkMode void setDarkTone(ColorTone colorToneChoice); + COLORREF getAccentColor(); + COLORREF getBackgroundColor(); COLORREF getCtrlBackgroundColor(); COLORREF getHotBackgroundColor(); @@ -240,4 +277,7 @@ namespace NppDarkMode LRESULT onCtlColorError(HDC hdc); LRESULT onCtlColorDlgStaticText(HDC hdc, bool isTextEnabled); LRESULT onCtlColorListbox(WPARAM wParam, LPARAM lParam); + + bool changeFluentIconColor(HICON* phIcon, const std::vector>& colorMappings, int tolerance = 3); + bool changeFluentIconColor(HICON* phIcon); } diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 39e64c599..00bc7a1af 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -4797,6 +4797,32 @@ void NppParameters::feedGUIParameters(TiXmlNode *node) else// if (!lstrcmp(val, L"yes")) _nppGUI._toolbarShow = true; } + + int i = 0; + val = element->Attribute(L"fluentColor", &i); + if (val) + { + auto& tbColor = _nppGUI._tbIconInfo._tbColor; + tbColor = static_cast(i); + } + + val = element->Attribute(L"fluentCustomColor", &i); + if (val) + { + auto& tbColor = _nppGUI._tbIconInfo._tbCustomColor; + tbColor = i; + } + + val = element->Attribute(L"fluentMono"); + if (val) + { + auto& tbMono = _nppGUI._tbIconInfo._tbUseMono; + if (!lstrcmp(val, L"no")) + tbMono = false; + else// if (!lstrcmp(val, L"yes")) + tbMono = true; + } + TiXmlNode *n = childNode->FirstChild(); if (n) { @@ -4814,6 +4840,7 @@ void NppParameters::feedGUIParameters(TiXmlNode *node) else //if (!lstrcmp(val, L"standard")) _nppGUI._toolBarStatus = TB_STANDARD; } + } } else if (!lstrcmp(nm, L"StatusBar")) @@ -6343,20 +6370,20 @@ void NppParameters::feedGUIParameters(TiXmlNode *node) return defaultName; }; - auto parseToolBarIconsAttribute = [&element](const wchar_t* name, int defaultValue = -1) -> int { + auto parseMinMaxAttribute = [&element](const wchar_t* name, int defaultValue = -1, int maxValue = 2, int minValue = 0) -> int { int val; const wchar_t* valStr = element->Attribute(name, &val); - if (valStr != nullptr && (val >= 0 && val <= 4)) + if (valStr != nullptr && (val >= minValue && val <= maxValue)) { return val; } return defaultValue; }; - auto parseTabIconsAttribute = [&element](const wchar_t* name, int defaultValue = -1) -> int { + auto parseIntAttribute = [&element](const wchar_t* name, int defaultValue = -1) -> int { int val; const wchar_t* valStr = element->Attribute(name, &val); - if (valStr != nullptr && (val >= 0 && val <= 2)) + if (valStr != nullptr) { return val; } @@ -6366,18 +6393,28 @@ void NppParameters::feedGUIParameters(TiXmlNode *node) auto& windowsMode = _nppGUI._darkmode._advOptions._enableWindowsMode; windowsMode = parseYesNoBoolAttribute(L"enableWindowsMode"); + constexpr int fluentColorMaxValue = static_cast(NppDarkMode::FluentColor::maxValue) - 1; + auto& darkDefaults = _nppGUI._darkmode._advOptions._darkDefaults; auto& darkThemeName = darkDefaults._xmlFileName; + auto& darkTbInfo = darkDefaults._tbIconInfo; darkThemeName = parseStringAttribute(L"darkThemeName", L"DarkModeDefault.xml"); - darkDefaults._toolBarIconSet = parseToolBarIconsAttribute(L"darkToolBarIconSet", 0); - darkDefaults._tabIconSet = parseTabIconsAttribute(L"darkTabIconSet", 2); + darkTbInfo._tbIconSet = parseMinMaxAttribute(L"darkToolBarIconSet", 0, 4); + darkTbInfo._tbColor = static_cast(parseMinMaxAttribute(L"darkTbFluentColor", 0, fluentColorMaxValue)); + darkTbInfo._tbCustomColor = parseIntAttribute(L"darkTbFluentCustomColor", 0); + darkTbInfo._tbUseMono = parseYesNoBoolAttribute(L"darkTbFluentMono"); + darkDefaults._tabIconSet = parseMinMaxAttribute(L"darkTabIconSet", 2); darkDefaults._tabUseTheme = parseYesNoBoolAttribute(L"darkTabUseTheme"); auto& lightDefaults = _nppGUI._darkmode._advOptions._lightDefaults; auto& lightThemeName = lightDefaults._xmlFileName; + auto& lightTbInfo = lightDefaults._tbIconInfo; lightThemeName = parseStringAttribute(L"lightThemeName"); - lightDefaults._toolBarIconSet = parseToolBarIconsAttribute(L"lightToolBarIconSet", 4); - lightDefaults._tabIconSet = parseTabIconsAttribute(L"lightTabIconSet", 0); + lightTbInfo._tbIconSet = parseMinMaxAttribute(L"lightToolBarIconSet", 4, 4); + lightTbInfo._tbColor = static_cast(parseMinMaxAttribute(L"lightTbFluentColor", 0, fluentColorMaxValue)); + lightTbInfo._tbCustomColor = parseIntAttribute(L"lightTbFluentCustomColor", 0); + lightTbInfo._tbUseMono = parseYesNoBoolAttribute(L"lightTbFluentMono"); + lightDefaults._tabIconSet = parseMinMaxAttribute(L"lightTabIconSet", 0); lightDefaults._tabUseTheme = parseYesNoBoolAttribute(L"lightTabUseTheme", true); // Windows mode is handled later in Notepad_plus_Window::init from Notepad_plus_Window.cpp @@ -7267,6 +7304,10 @@ void NppParameters::createXmlTreeFromGUIParams() GUIConfigElement->SetAttribute(L"name", L"ToolBar"); const wchar_t *pStr = (_nppGUI._toolbarShow) ? L"yes" : L"no"; GUIConfigElement->SetAttribute(L"visible", pStr); + GUIConfigElement->SetAttribute(L"fluentColor", static_cast(_nppGUI._tbIconInfo._tbColor)); + GUIConfigElement->SetAttribute(L"fluentCustomColor", _nppGUI._tbIconInfo._tbCustomColor); + pStr = (_nppGUI._tbIconInfo._tbUseMono) ? L"yes" : L"no"; + GUIConfigElement->SetAttribute(L"fluentMono", pStr); if (_nppGUI._toolBarStatus == TB_SMALL) pStr = L"small"; @@ -7841,17 +7882,30 @@ void NppParameters::createXmlTreeFromGUIParams() GUIConfigElement->SetAttribute(L"customColorDisabledEdge", _nppGUI._darkmode._customColors.disabledEdge); // advanced options section - setYesNoBoolAttribute(L"enableWindowsMode", _nppGUI._darkmode._advOptions._enableWindowsMode); + const auto& advOpt = _nppGUI._darkmode._advOptions; + setYesNoBoolAttribute(L"enableWindowsMode", advOpt._enableWindowsMode); - GUIConfigElement->SetAttribute(L"darkThemeName", _nppGUI._darkmode._advOptions._darkDefaults._xmlFileName.c_str()); - GUIConfigElement->SetAttribute(L"darkToolBarIconSet", _nppGUI._darkmode._advOptions._darkDefaults._toolBarIconSet); - GUIConfigElement->SetAttribute(L"darkTabIconSet", _nppGUI._darkmode._advOptions._darkDefaults._tabIconSet); - setYesNoBoolAttribute(L"darkTabUseTheme", _nppGUI._darkmode._advOptions._darkDefaults._tabUseTheme); + const auto& darkDefaults = advOpt._darkDefaults; + auto& darkThemeName = darkDefaults._xmlFileName; + auto& darkTbInfo = darkDefaults._tbIconInfo; + GUIConfigElement->SetAttribute(L"darkThemeName", darkThemeName.c_str()); + GUIConfigElement->SetAttribute(L"darkToolBarIconSet", darkTbInfo._tbIconSet); + GUIConfigElement->SetAttribute(L"darkTbFluentColor", static_cast(darkTbInfo._tbColor)); + GUIConfigElement->SetAttribute(L"darkTbFluentCustomColor", darkTbInfo._tbCustomColor); + setYesNoBoolAttribute(L"darkTbFluentMono", darkTbInfo._tbUseMono); + GUIConfigElement->SetAttribute(L"darkTabIconSet", darkDefaults._tabIconSet); + setYesNoBoolAttribute(L"darkTabUseTheme", darkDefaults._tabUseTheme); - GUIConfigElement->SetAttribute(L"lightThemeName", _nppGUI._darkmode._advOptions._lightDefaults._xmlFileName.c_str()); - GUIConfigElement->SetAttribute(L"lightToolBarIconSet", _nppGUI._darkmode._advOptions._lightDefaults._toolBarIconSet); - GUIConfigElement->SetAttribute(L"lightTabIconSet", _nppGUI._darkmode._advOptions._lightDefaults._tabIconSet); - setYesNoBoolAttribute(L"lightTabUseTheme", _nppGUI._darkmode._advOptions._lightDefaults._tabUseTheme); + const auto& lightDefaults = advOpt._lightDefaults; + const auto& lightThemeName = lightDefaults._xmlFileName; + const auto& lightTbInfo = lightDefaults._tbIconInfo; + GUIConfigElement->SetAttribute(L"lightThemeName", lightThemeName.c_str()); + GUIConfigElement->SetAttribute(L"lightToolBarIconSet", lightTbInfo._tbIconSet); + GUIConfigElement->SetAttribute(L"lightTbFluentColor", static_cast(lightTbInfo._tbColor)); + GUIConfigElement->SetAttribute(L"lightTbFluentCustomColor", lightTbInfo._tbCustomColor); + setYesNoBoolAttribute(L"lightTbFluentMono", lightTbInfo._tbUseMono); + GUIConfigElement->SetAttribute(L"lightTabIconSet", lightDefaults._tabIconSet); + setYesNoBoolAttribute(L"lightTabUseTheme", lightDefaults._tabUseTheme); } // diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index d58024093..eabe6f48c 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -792,6 +792,7 @@ struct LargeFileRestriction final struct NppGUI final { toolBarStatusType _toolBarStatus = TB_STANDARD; + NppDarkMode::TbIconInfo _tbIconInfo{ TB_STANDARD, NppDarkMode::FluentColor::defaultColor, 0, false }; bool _toolbarShow = true; bool _statusBarShow = true; bool _menuBarShow = true; diff --git a/PowerEditor/src/WinControls/ImageListSet/ImageListSet.cpp b/PowerEditor/src/WinControls/ImageListSet/ImageListSet.cpp index 31b1f1bbe..6f811ed7d 100644 --- a/PowerEditor/src/WinControls/ImageListSet/ImageListSet.cpp +++ b/PowerEditor/src/WinControls/ImageListSet/ImageListSet.cpp @@ -43,7 +43,7 @@ void IconList::create(int iconSize, HINSTANCE hInst, int* iconIDArray, int iconI addIcon(iconIDArray[i], iconSize, iconSize); } -void IconList::addIcon(int iconID, int cx, int cy, int failIconID) const +void IconList::addIcon(int iconID, int cx, int cy, int failIconID, bool isToolbarNormal) const { HICON hIcon = nullptr; DPIManagerV2::loadIcon(_hInst, MAKEINTRESOURCE(iconID), cx, cy, &hIcon, LR_DEFAULTSIZE); @@ -81,6 +81,8 @@ void IconList::addIcon(int iconID, int cx, int cy, int failIconID) const if (hIcon != nullptr) { + if (isToolbarNormal) + NppDarkMode::changeFluentIconColor(&hIcon); ::ImageList_AddIcon(_hImglst, hIcon); ::DestroyIcon(hIcon); } @@ -134,14 +136,14 @@ void ToolBarIcons::reInit(int size) { if (_tbiis[i]._defaultIcon != -1) { - _iconListVector[HLIST_DEFAULT].addIcon(_tbiis[i]._defaultIcon, size, size, _tbiis[i]._stdIcon); + _iconListVector[HLIST_DEFAULT].addIcon(_tbiis[i]._defaultIcon, size, size, _tbiis[i]._stdIcon, true); _iconListVector[HLIST_DISABLE].addIcon(_tbiis[i]._grayIcon, size, size, _tbiis[i]._stdIcon); - _iconListVector[HLIST_DEFAULT2].addIcon(_tbiis[i]._defaultIcon2, size, size, _tbiis[i]._stdIcon); + _iconListVector[HLIST_DEFAULT2].addIcon(_tbiis[i]._defaultIcon2, size, size, _tbiis[i]._stdIcon, true); _iconListVector[HLIST_DISABLE2].addIcon(_tbiis[i]._grayIcon2, size, size, _tbiis[i]._stdIcon); - _iconListVector[HLIST_DEFAULT_DM].addIcon(_tbiis[i]._defaultDarkModeIcon, size, size, _tbiis[i]._stdIcon); + _iconListVector[HLIST_DEFAULT_DM].addIcon(_tbiis[i]._defaultDarkModeIcon, size, size, _tbiis[i]._stdIcon, true); _iconListVector[HLIST_DISABLE_DM].addIcon(_tbiis[i]._grayDarkModeIcon, size, size, _tbiis[i]._stdIcon); - _iconListVector[HLIST_DEFAULT_DM2].addIcon(_tbiis[i]._defaultDarkModeIcon2, size, size, _tbiis[i]._stdIcon); + _iconListVector[HLIST_DEFAULT_DM2].addIcon(_tbiis[i]._defaultDarkModeIcon2, size, size, _tbiis[i]._stdIcon, true); _iconListVector[HLIST_DISABLE_DM2].addIcon(_tbiis[i]._grayDarkModeIcon2, size, size, _tbiis[i]._stdIcon); } } diff --git a/PowerEditor/src/WinControls/ImageListSet/ImageListSet.h b/PowerEditor/src/WinControls/ImageListSet/ImageListSet.h index 6d0b9a0c1..4236aa666 100644 --- a/PowerEditor/src/WinControls/ImageListSet/ImageListSet.h +++ b/PowerEditor/src/WinControls/ImageListSet/ImageListSet.h @@ -39,7 +39,7 @@ public : }; HIMAGELIST getHandle() const {return _hImglst;}; - void addIcon(int iconID, int cx = 16, int cy = 16, int failIconID = -1) const; + void addIcon(int iconID, int cx = 16, int cy = 16, int failIconID = -1, bool isToolbarNormal = false) const; void addIcon(HICON hIcon) const; bool changeIcon(size_t index, const wchar_t *iconLocation) const; diff --git a/PowerEditor/src/WinControls/Preference/preference.rc b/PowerEditor/src/WinControls/Preference/preference.rc index 8f5265ef4..36dc7ebad 100644 --- a/PowerEditor/src/WinControls/Preference/preference.rc +++ b/PowerEditor/src/WinControls/Preference/preference.rc @@ -47,11 +47,11 @@ BEGIN GROUPBOX "Toolbar",IDC_TOOLBAR_GB_STATIC,39,75,186,91,BS_CENTER CONTROL "Hide",IDC_CHECK_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,84,100,10 - CONTROL "Fluent UI: small",IDC_RADIO_SMALLICON,"Button",BS_AUTORADIOBUTTON,45,100,174,10 - CONTROL "Fluent UI: large",IDC_RADIO_BIGICON,"Button",BS_AUTORADIOBUTTON,45,113,174,10 - CONTROL "Filled Fluent UI: small",IDC_RADIO_SMALLICON2,"Button",BS_AUTORADIOBUTTON,45,126,174,10 - CONTROL "Filled Fluent UI: large",IDC_RADIO_BIGICON2,"Button",BS_AUTORADIOBUTTON,45,139,174,10 - CONTROL "Standard icons: small",IDC_RADIO_STANDARD,"Button",BS_AUTORADIOBUTTON,45,152,174,10 + COMBOBOX IDC_COMBO_TOOLBAR_ICON,45,97,174,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Fluent icon color",IDC_STATIC_TOOLBAR_ICON_COLOR,48,115,171,8 + COMBOBOX IDC_COMBO_TOOLBAR_ICON_COLOR,45,125,154,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "",IDC_STATIC,223,127,1,8 + CONTROL "Use monochrome color for Fluent UI",IDC_CHECK_TOOLBAR_ICON_MONO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,143,174,10 GROUPBOX "Status Bar",IDC_STATUSBAR_GB_STATIC,39,169,186,26,BS_CENTER CONTROL "Hide",IDC_CHECK_HIDESTATUSBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,179,174,10 diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp index 3bfe6db96..c5f38831d 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp @@ -185,7 +185,7 @@ intptr_t CALLBACK PreferenceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM _cloudAndLinkSubDlg.create(IDD_PREFERENCE_SUB_CLOUD_LINK, false, false); _searchEngineSubDlg.init(_hInst, _hSelf); - _searchEngineSubDlg.create(IDD_PREFERENCE_SUB_SEARCHENGINE, false, false); + _searchEngineSubDlg.create(IDD_PREFERENCE_SUB_SEARCHENGINE, false, false); _wVector.push_back(DlgInfo(&_generalSubDlg, L"General", L"Global")); _wVector.push_back(DlgInfo(&_editingSubDlg, L"Editing 1", L"Scintillas")); @@ -290,80 +290,22 @@ intptr_t CALLBACK PreferenceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM { const HWND hGeneralSubDlg = _generalSubDlg.getHSelf(); - auto checkOrUncheckBtn = [&hGeneralSubDlg](int id, WPARAM check = BST_UNCHECKED) -> void - { - ::SendDlgItemMessage(hGeneralSubDlg, id, BM_SETCHECK, check, 0); - }; - - const int iconState = NppDarkMode::getToolBarIconSet(static_cast(wParam)); NppParameters& nppParams = NppParameters::getInstance(); NppGUI& nppGUI = nppParams.getNppGUI(); + auto& nppGUITbInfo = nppGUI._tbIconInfo; + const NppDarkMode::TbIconInfo toolbarIconInfo = NppDarkMode::getToolbarIconInfo(static_cast(wParam)); + nppGUITbInfo = toolbarIconInfo; + nppGUI._toolBarStatus = static_cast(nppGUITbInfo._tbIconSet); - if (iconState != -1) - { - nppGUI._toolBarStatus = static_cast(iconState); - } - else - { - auto state = TB_STANDARD; - if (_generalSubDlg.isCheckedOrNot(IDC_RADIO_SMALLICON)) - { - state = TB_SMALL; - } - else if (_generalSubDlg.isCheckedOrNot(IDC_RADIO_BIGICON)) - { - state = TB_LARGE; - } - else if (_generalSubDlg.isCheckedOrNot(IDC_RADIO_SMALLICON2)) - { - state = TB_SMALL2; - } - else if (_generalSubDlg.isCheckedOrNot(IDC_RADIO_BIGICON2)) - { - state = TB_LARGE2; - } - nppGUI._toolBarStatus = state; - } + ::SendDlgItemMessage(hGeneralSubDlg, IDC_COMBO_TOOLBAR_ICON, CB_SETCURSEL, nppGUI._toolBarStatus, 0); + ::SendDlgItemMessage(hGeneralSubDlg, IDC_COMBO_TOOLBAR_ICON_COLOR, CB_SETCURSEL, static_cast(nppGUITbInfo._tbColor), 0); + ::SendDlgItemMessage(hGeneralSubDlg, IDC_CHECK_TOOLBAR_ICON_MONO, BM_SETCHECK, nppGUITbInfo._tbUseMono ? BST_CHECKED : BST_UNCHECKED, 0); - checkOrUncheckBtn(IDC_RADIO_STANDARD); - checkOrUncheckBtn(IDC_RADIO_SMALLICON); - checkOrUncheckBtn(IDC_RADIO_BIGICON); - checkOrUncheckBtn(IDC_RADIO_SMALLICON2); - checkOrUncheckBtn(IDC_RADIO_BIGICON2); + const bool enable = nppGUI._toolBarStatus != TB_STANDARD; + ::EnableWindow(::GetDlgItem(hGeneralSubDlg, IDC_COMBO_TOOLBAR_ICON_COLOR), enable ? TRUE : FALSE); + ::EnableWindow(::GetDlgItem(hGeneralSubDlg, IDC_CHECK_TOOLBAR_ICON_MONO), enable ? TRUE : FALSE); - switch (nppGUI._toolBarStatus) - { - case TB_LARGE: - { - checkOrUncheckBtn(IDC_RADIO_BIGICON, BST_CHECKED); - //::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARENLARGE, 0, 0); - break; - } - case TB_SMALL2: - { - checkOrUncheckBtn(IDC_RADIO_SMALLICON2, BST_CHECKED); - //::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARREDUCESET2, 0, 0); - break; - } - case TB_LARGE2: - { - checkOrUncheckBtn(IDC_RADIO_BIGICON2, BST_CHECKED); - //::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARENLARGESET2, 0, 0); - break; - } - case TB_STANDARD: - { - checkOrUncheckBtn(IDC_RADIO_STANDARD, BST_CHECKED); - //::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARSTANDARD, 0, 0); - break; - } - //case TB_SMALL: - default: - { - checkOrUncheckBtn(IDC_RADIO_SMALLICON, BST_CHECKED); - //::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARREDUCE, 0, 0); - } - } + _generalSubDlg.enableColorPicker(static_cast(wParam), enable); return TRUE; } @@ -559,44 +501,157 @@ void GeneralSubDlg::setTabbarAlternateIcons(bool enable) } } -intptr_t CALLBACK GeneralSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) +void GeneralSubDlg::enableColorPicker(bool useDark, bool doEnable) +{ + NppParameters& nppParam = NppParameters::getInstance(); + NppGUI& nppGUI = nppParam.getNppGUI(); + const auto& tbInfo = nppGUI._tbIconInfo; + + const bool enable = doEnable && (tbInfo._tbColor == NppDarkMode::FluentColor::custom); + + ::EnableWindow(_pIconColorPicker->getHSelf(), enable ? TRUE : FALSE); + if (enable) + { + _pIconColorPicker->setColour(tbInfo._tbCustomColor); + } + else + { + COLORREF disabledColor = useDark ? NppDarkMode::getDlgBackgroundColor() : ::GetSysColor(COLOR_3DFACE); + _pIconColorPicker->setColour(disabledColor); + } + _pIconColorPicker->setEnabled(enable); + _pIconColorPicker->redraw(); +} + +UINT GeneralSubDlg::getToolbarIconSetMsg(int* idxIconSet) +{ + + const auto idx = std::min(static_cast(::SendDlgItemMessage(_hSelf, IDC_COMBO_TOOLBAR_ICON, CB_GETCURSEL, 0, 0)), TB_STANDARD); + UINT msg = NPPM_INTERNAL_TOOLBARSTANDARD; + switch (idx) + { + case 0: + { + msg = NPPM_INTERNAL_TOOLBARREDUCE; + break; + } + + case 1: + { + msg = NPPM_INTERNAL_TOOLBARENLARGE; + break; + } + + case 2: + { + msg = NPPM_INTERNAL_TOOLBARREDUCESET2; + break; + } + + case 3: + { + msg = NPPM_INTERNAL_TOOLBARENLARGESET2; + break; + } + + case 4: + default: + { + break; + } + } + + if (idxIconSet != nullptr) + { + *idxIconSet = idx; + } + + return msg; +} + +void GeneralSubDlg::move2CtrlLeft(int ctrlID, HWND handle2Move, int handle2MoveWidth, int handle2MoveHeight) +{ + POINT p{}; + RECT rc{}; + ::GetWindowRect(::GetDlgItem(_hSelf, ctrlID), &rc); + + NppParameters& nppParam = NppParameters::getInstance(); + + if (nppParam.getNativeLangSpeaker()->isRTL()) + p.x = rc.right + _dpiManager.scale(5) + handle2MoveWidth; + else + p.x = rc.left - _dpiManager.scale(5) - handle2MoveWidth; + + p.y = rc.top + ((rc.bottom - rc.top) / 2) - handle2MoveHeight / 2; + + ::ScreenToClient(_hSelf, &p); + ::MoveWindow(handle2Move, p.x, p.y, handle2MoveWidth, handle2MoveHeight, TRUE); +} + +intptr_t CALLBACK GeneralSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { NppParameters& nppParam = NppParameters::getInstance(); NppGUI& nppGUI = nppParam.getNppGUI(); switch (message) { - case WM_INITDIALOG : + case WM_INITDIALOG: { toolBarStatusType tbStatus = nppGUI._toolBarStatus; + auto& nppGUITbInfo = nppGUI._tbIconInfo; + const auto fluentColor = static_cast(nppGUITbInfo._tbColor); int tabBarStatus = nppGUI._tabStatus; bool showTool = nppGUI._toolbarShow; bool showStatus = nppGUI._statusBarShow; bool showMenu = nppGUI._menuBarShow; bool hideRightShortcutsFromMenu = nppGUI._hideMenuRightShortcuts; - ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIDE, BM_SETCHECK, showTool?BST_UNCHECKED:BST_CHECKED, 0); - int ID2Check = 0; - switch (tbStatus) + auto addComboItem = [&](int comboBoxId, const wchar_t* itemText) -> void { - case TB_SMALL : - ID2Check = IDC_RADIO_SMALLICON; - break; - case TB_LARGE : - ID2Check = IDC_RADIO_BIGICON; - break; - case TB_SMALL2 : - ID2Check = IDC_RADIO_SMALLICON2; - break; - case TB_LARGE2 : - ID2Check = IDC_RADIO_BIGICON2; - break; - case TB_STANDARD: - default : - ID2Check = IDC_RADIO_STANDARD; - } - ::SendDlgItemMessage(_hSelf, ID2Check, BM_SETCHECK, BST_CHECKED, 0); - + ::SendDlgItemMessage(_hSelf, comboBoxId, CB_ADDSTRING, 0, reinterpret_cast(itemText)); + }; + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_HIDE, BM_SETCHECK, showTool ? BST_UNCHECKED:BST_CHECKED, 0); + + addComboItem(IDC_COMBO_TOOLBAR_ICON, L"Fluent UI: small"); + addComboItem(IDC_COMBO_TOOLBAR_ICON, L"Fluent UI: large"); + addComboItem(IDC_COMBO_TOOLBAR_ICON, L"Filled Fluent UI: small"); + addComboItem(IDC_COMBO_TOOLBAR_ICON, L"Filled Fluent UI: large"); + addComboItem(IDC_COMBO_TOOLBAR_ICON, L"Standard icons: small"); + + ::SendDlgItemMessage(_hSelf, IDC_COMBO_TOOLBAR_ICON, CB_SETCURSEL, tbStatus, 0); + + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Default color"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Accent"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Red"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Green"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Blue"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Purple"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Cyan"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Olive"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Yellow"); + addComboItem(IDC_COMBO_TOOLBAR_ICON_COLOR, L"Custom"); + + ::SendDlgItemMessage(_hSelf, IDC_COMBO_TOOLBAR_ICON_COLOR, CB_SETCURSEL, fluentColor, 0); + + setChecked(IDC_CHECK_TOOLBAR_ICON_MONO, nppGUITbInfo._tbUseMono); + + const bool enable = tbStatus != TB_STANDARD; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_TOOLBAR_ICON_COLOR), enable ? TRUE : FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_TOOLBAR_ICON_MONO), enable ? TRUE : FALSE); + + _dpiManager.setDpi(_hSelf); + const int cpDynamicalSize = _dpiManager.scale(25); + + _pIconColorPicker = new ColourPicker; + _pIconColorPicker->init(_hInst, _hSelf); + + move2CtrlLeft(IDC_STATIC, _pIconColorPicker->getHSelf(), cpDynamicalSize, cpDynamicalSize); + + enableColorPicker(NppDarkMode::isEnabled(), enable); + + _pIconColorPicker->display(); + ::SendDlgItemMessage(_hSelf, IDC_CHECK_REDUCE, BM_SETCHECK, tabBarStatus & TAB_REDUCE, 0); ::SendDlgItemMessage(_hSelf, IDC_CHECK_LOCK, BM_SETCHECK, !(tabBarStatus & TAB_DRAGNDROP), 0); ::SendDlgItemMessage(_hSelf, IDC_CHECK_ORANGE, BM_SETCHECK, tabBarStatus & TAB_DRAWTOPBAR, 0); @@ -663,8 +718,20 @@ intptr_t CALLBACK GeneralSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM } case WM_CTLCOLORDLG: + { + return NppDarkMode::onCtlColorDlg(reinterpret_cast(wParam)); + } + case WM_CTLCOLORSTATIC: { + int dlgCtrlID = ::GetDlgCtrlID(reinterpret_cast(lParam)); + + // handle blurry text with disabled states for the affected static controls + if (dlgCtrlID == IDC_STATIC_TOOLBAR_ICON_COLOR) + { + const bool isEnabled = ::IsWindowEnabled(::GetDlgItem(_hSelf, IDC_COMBO_TOOLBAR_ICON_COLOR)); + return NppDarkMode::onCtlColorDlgStaticText(reinterpret_cast(wParam), isEnabled); + } return NppDarkMode::onCtlColorDlg(reinterpret_cast(wParam)); } @@ -677,6 +744,13 @@ intptr_t CALLBACK GeneralSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM break; } + case WM_DESTROY: + { + _pIconColorPicker->destroy(); + delete _pIconColorPicker; + return TRUE; + } + case WM_COMMAND: { switch (wParam) @@ -916,46 +990,47 @@ intptr_t CALLBACK GeneralSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM return TRUE; } - case IDC_CHECK_HIDE : + case IDC_CHECK_HIDE: { bool isChecked = isCheckedOrNot(IDC_CHECK_HIDE); ::SendMessage(::GetParent(_hParent), NPPM_HIDETOOLBAR, 0, isChecked?TRUE:FALSE); } return TRUE; - - case IDC_RADIO_SMALLICON : - ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARREDUCE, 0, 0); - NppDarkMode::setToolBarIconSet(0, NppDarkMode::isEnabled()); - return TRUE; - - case IDC_RADIO_BIGICON : - ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARENLARGE, 0, 0); - NppDarkMode::setToolBarIconSet(1, NppDarkMode::isEnabled()); - return TRUE; - case IDC_RADIO_SMALLICON2: - ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARREDUCESET2, 0, 0); - NppDarkMode::setToolBarIconSet(2, NppDarkMode::isEnabled()); - return TRUE; + case IDC_CHECK_TOOLBAR_ICON_MONO: + { + const bool isChecked = isCheckedOrNot(IDC_CHECK_TOOLBAR_ICON_MONO); + NppDarkMode::setToolbarFluentMonochrome(isChecked); + nppGUI._tbIconInfo._tbUseMono = isChecked; - case IDC_RADIO_BIGICON2: - ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARENLARGESET2, 0, 0); - NppDarkMode::setToolBarIconSet(3, NppDarkMode::isEnabled()); + UINT msg = getToolbarIconSetMsg(nullptr); + ::SendMessage(::GetParent(_hParent), msg, TRUE, 0); return TRUE; + } - case IDC_RADIO_STANDARD : - ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_TOOLBARSTANDARD, 0, 0); - NppDarkMode::setToolBarIconSet(4, NppDarkMode::isEnabled()); - return TRUE; - - default : + default: switch (HIWORD(wParam)) { + case CPN_COLOURPICKED: + { + if (reinterpret_cast(lParam) == _pIconColorPicker->getHSelf()) + { + COLORREF c = _pIconColorPicker->getColour(); + nppGUI._tbIconInfo._tbCustomColor = c; + NppDarkMode::setToolbarFluentCustomColor(c); + + UINT msg = getToolbarIconSetMsg(nullptr); + ::SendMessage(::GetParent(_hParent), msg, TRUE, 0); + return TRUE; + } + break; + } + case CBN_SELCHANGE : // == case LBN_SELCHANGE : { switch (LOWORD(wParam)) { - case IDC_COMBO_LOCALIZATION : + case IDC_COMBO_LOCALIZATION: { LocalizationSwitcher & localizationSwitcher = nppParam.getLocalizationSwitcher(); auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_GETCURSEL, 0, 0); @@ -980,8 +1055,41 @@ intptr_t CALLBACK GeneralSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM ::InvalidateRect(_hParent, NULL, TRUE); } } + return TRUE; } - return TRUE; + + case IDC_COMBO_TOOLBAR_ICON: + { + int idxIconSet = 0; + UINT msg = getToolbarIconSetMsg(&idxIconSet); + ::SendMessage(::GetParent(_hParent), msg, 0, 0); + NppDarkMode::setToolbarIconSet(idxIconSet, NppDarkMode::isEnabled()); + + const bool enable = idxIconSet != TB_STANDARD; + ::EnableWindow(::GetDlgItem(_hSelf, IDC_COMBO_TOOLBAR_ICON_COLOR), enable ? TRUE : FALSE); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_CHECK_TOOLBAR_ICON_MONO), enable ? TRUE : FALSE); + redrawDlgItem(IDC_STATIC_TOOLBAR_ICON_COLOR); + + enableColorPicker(NppDarkMode::isEnabled(), enable); + + return TRUE; + } + + case IDC_COMBO_TOOLBAR_ICON_COLOR: + { + const auto boundMax = static_cast(NppDarkMode::FluentColor::maxValue) - 1; + auto idxFluentColor = static_cast(::SendDlgItemMessage(_hSelf, IDC_COMBO_TOOLBAR_ICON_COLOR, CB_GETCURSEL, 0, 0)); + idxFluentColor = static_cast(std::min(static_cast(idxFluentColor), boundMax)); + NppDarkMode::setToolbarFluentColor(idxFluentColor); + nppGUI._tbIconInfo._tbColor = idxFluentColor; + + enableColorPicker(NppDarkMode::isEnabled()); + + UINT msg = getToolbarIconSetMsg(nullptr); + ::SendMessage(::GetParent(_hParent), msg, TRUE, 0); + return TRUE; + } + default: break; } diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.h b/PowerEditor/src/WinControls/Preference/preferenceDlg.h index 0f24d372f..6d8b8471b 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.h +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.h @@ -46,9 +46,13 @@ class GeneralSubDlg : public StaticDialog public : GeneralSubDlg() = default; void setTabbarAlternateIcons(bool enable = false); + void enableColorPicker(bool useDark, bool doEnable = true); private : intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) override; + UINT getToolbarIconSetMsg(int* idxIconSet); + void move2CtrlLeft(int ctrlID, HWND handle2Move, int handle2MoveWidth, int handle2MoveHeight); + ColourPicker* _pIconColorPicker = nullptr; }; class EditingSubDlg : public StaticDialog diff --git a/PowerEditor/src/WinControls/Preference/preference_rc.h b/PowerEditor/src/WinControls/Preference/preference_rc.h index e26c37943..79a7d89ab 100644 --- a/PowerEditor/src/WinControls/Preference/preference_rc.h +++ b/PowerEditor/src/WinControls/Preference/preference_rc.h @@ -24,9 +24,9 @@ #define IDD_PREFERENCE_SUB_GENRAL 6100 //(IDD_PREFERENCE_BOX + 100) #define IDC_TOOLBAR_GB_STATIC (IDD_PREFERENCE_SUB_GENRAL + 1) #define IDC_CHECK_HIDE (IDD_PREFERENCE_SUB_GENRAL + 2) - #define IDC_RADIO_SMALLICON (IDD_PREFERENCE_SUB_GENRAL + 3) - #define IDC_RADIO_BIGICON (IDD_PREFERENCE_SUB_GENRAL + 4) - #define IDC_RADIO_STANDARD (IDD_PREFERENCE_SUB_GENRAL + 5) + //#define IDC_RADIO_SMALLICON (IDD_PREFERENCE_SUB_GENRAL + 3) + //#define IDC_RADIO_BIGICON (IDD_PREFERENCE_SUB_GENRAL + 4) + //#define IDC_RADIO_STANDARD (IDD_PREFERENCE_SUB_GENRAL + 5) #define IDC_TABBAR_GB_STATIC (IDD_PREFERENCE_SUB_GENRAL + 6) #define IDC_CHECK_REDUCE (IDD_PREFERENCE_SUB_GENRAL + 7) @@ -48,13 +48,17 @@ #define IDC_LOCALIZATION_GB_STATIC (IDD_PREFERENCE_SUB_GENRAL + 23) #define IDC_COMBO_LOCALIZATION (IDD_PREFERENCE_SUB_GENRAL + 24) #define IDC_CHECK_TAB_ALTICONS (IDD_PREFERENCE_SUB_GENRAL + 28) - #define IDC_RADIO_SMALLICON2 (IDD_PREFERENCE_SUB_GENRAL + 29) - #define IDC_RADIO_BIGICON2 (IDD_PREFERENCE_SUB_GENRAL + 30) + //#define IDC_RADIO_SMALLICON2 (IDD_PREFERENCE_SUB_GENRAL + 29) + //#define IDC_RADIO_BIGICON2 (IDD_PREFERENCE_SUB_GENRAL + 30) #define IDC_MENU_GB_STATIC (IDD_PREFERENCE_SUB_GENRAL + 31) #define IDC_CHECK_HIDERIGHTSHORTCUTSOFMENUBAR (IDD_PREFERENCE_SUB_GENRAL + 32) #define IDC_STATUSBAR_GB_STATIC (IDD_PREFERENCE_SUB_GENRAL + 33) #define IDC_CHECK_HIDESTATUSBAR (IDD_PREFERENCE_SUB_GENRAL + 34) #define IDC_CHECK_SHOWONLYPINNEDBUTTON (IDD_PREFERENCE_SUB_GENRAL + 35) + #define IDC_COMBO_TOOLBAR_ICON (IDD_PREFERENCE_SUB_GENRAL + 36) + #define IDC_STATIC_TOOLBAR_ICON_COLOR (IDD_PREFERENCE_SUB_GENRAL + 37) + #define IDC_COMBO_TOOLBAR_ICON_COLOR (IDD_PREFERENCE_SUB_GENRAL + 38) + #define IDC_CHECK_TOOLBAR_ICON_MONO (IDD_PREFERENCE_SUB_GENRAL + 39) #define IDD_PREFERENCE_SUB_MULTIINSTANCE 6150 //(IDD_PREFERENCE_BOX + 150) #define IDC_MULTIINST_GB_STATIC (IDD_PREFERENCE_SUB_MULTIINSTANCE + 1)