From 87f4249d6b4a02ffd01a5fb766c183294c4ece72 Mon Sep 17 00:00:00 2001 From: ozone10 Date: Tue, 19 Apr 2022 16:25:50 +0200 Subject: [PATCH] Add support for dark tab updown control Fix #10054, close #11554 --- PowerEditor/src/NppDarkMode.cpp | 166 +++++++++++++++++- PowerEditor/src/NppDarkMode.h | 2 + .../WinControls/DockingWnd/DockingCont.cpp | 4 + .../src/WinControls/DockingWnd/DockingCont.h | 1 + PowerEditor/src/WinControls/TabBar/TabBar.cpp | 4 +- PowerEditor/src/WinControls/TabBar/TabBar.h | 2 + 6 files changed, 177 insertions(+), 2 deletions(-) diff --git a/PowerEditor/src/NppDarkMode.cpp b/PowerEditor/src/NppDarkMode.cpp index 6c749832c..49176fb69 100644 --- a/PowerEditor/src/NppDarkMode.cpp +++ b/PowerEditor/src/NppDarkMode.cpp @@ -743,7 +743,7 @@ namespace NppDarkMode { if (!hTheme) { - hTheme = OpenThemeData(hwnd, L"Button"); + hTheme = OpenThemeData(hwnd, WC_BUTTON); } return hTheme != nullptr; } @@ -1522,6 +1522,170 @@ namespace NppDarkMode autoSubclassAndThemeChildControls(hwndParent, false, true); } + constexpr UINT_PTR g_tabUpDownSubclassID = 42; + + LRESULT CALLBACK TabUpDownSubclass( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + UINT_PTR uIdSubclass, + DWORD_PTR dwRefData + ) + { + auto pButtonData = reinterpret_cast(dwRefData); + + switch (uMsg) + { + case WM_PRINTCLIENT: + case WM_PAINT: + { + if (!NppDarkMode::isEnabled()) + { + break; + } + + bool hasTheme = pButtonData->ensureTheme(hWnd); + + RECT rcClient{}; + ::GetClientRect(hWnd, &rcClient); + + PAINTSTRUCT ps{}; + auto hdc = ::BeginPaint(hWnd, &ps); + + ::FillRect(hdc, &rcClient, NppDarkMode::getDarkerBackgroundBrush()); + + auto dpiManager = NppParameters::getInstance()._dpiManager; + + RECT rcArrowLeft = { + rcClient.left, rcClient.top, + rcClient.right - ((rcClient.right - rcClient.left) / 2) , rcClient.bottom + }; + + RECT rcArrowRight = { + rcArrowLeft.right, rcClient.top, + rcClient.right, rcClient.bottom + }; + + POINT ptCursor = {}; + ::GetCursorPos(&ptCursor); + ::ScreenToClient(hWnd, &ptCursor); + + bool isHotLeft = ::PtInRect(&rcArrowLeft, ptCursor); + bool isHotRight = ::PtInRect(&rcArrowRight, ptCursor); + + ::SetBkMode(hdc, TRANSPARENT); + + if (hasTheme) + { + ::DrawThemeBackground(pButtonData->hTheme, hdc, BP_PUSHBUTTON, isHotLeft ? PBS_HOT : PBS_NORMAL, &rcArrowLeft, nullptr); + ::DrawThemeBackground(pButtonData->hTheme, hdc, BP_PUSHBUTTON, isHotRight ? PBS_HOT : PBS_NORMAL, &rcArrowRight, nullptr); + } + else + { + ::FillRect(hdc, &rcArrowLeft, isHotLeft ? NppDarkMode::getHotBackgroundBrush() : NppDarkMode::getBackgroundBrush()); + ::FillRect(hdc, &rcArrowRight, isHotRight ? NppDarkMode::getHotBackgroundBrush() : NppDarkMode::getBackgroundBrush()); + } + + LOGFONT lf = {}; + auto font = reinterpret_cast(SendMessage(hWnd, WM_GETFONT, 0, 0)); + ::GetObject(font, sizeof(lf), &lf); + lf.lfHeight = (dpiManager.scaleY(16) - 5) * -1; + auto holdFont = static_cast(::SelectObject(hdc, CreateFontIndirect(&lf))); + + auto mPosX = ((rcArrowLeft.right - rcArrowLeft.left - dpiManager.scaleX(7) + 1) / 2); + auto mPosY = ((rcArrowLeft.bottom - rcArrowLeft.top + lf.lfHeight - dpiManager.scaleY(1) - 3) / 2); + + ::SetTextColor(hdc, isHotLeft ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); + ::ExtTextOut(hdc, + rcArrowLeft.left + mPosX, + rcArrowLeft.top + mPosY, + ETO_CLIPPED, + &rcArrowLeft, L"<", + 1, + nullptr); + + ::SetTextColor(hdc, isHotRight ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); + ::ExtTextOut(hdc, + rcArrowRight.left + mPosX - dpiManager.scaleX(2) + 3, + rcArrowRight.top + mPosY, + ETO_CLIPPED, + &rcArrowRight, L">", + 1, + nullptr); + + if (!hasTheme) + { + auto holdPen = static_cast(::SelectObject(hdc, NppDarkMode::getEdgePen())); + auto holdBrush = ::SelectObject(hdc, ::GetStockObject(NULL_BRUSH)); + ::Rectangle(hdc, rcArrowLeft.left, rcArrowLeft.top, rcArrowLeft.right, rcArrowLeft.bottom); + ::Rectangle(hdc, rcArrowRight.left, rcArrowRight.top, rcArrowRight.right, rcArrowRight.bottom); + + ::SelectObject(hdc, holdPen); + ::SelectObject(hdc, holdBrush); + } + + ::SelectObject(hdc, holdFont); + ::EndPaint(hWnd, &ps); + return FALSE; + } + + case WM_THEMECHANGED: + { + pButtonData->closeTheme(); + break; + } + + case WM_NCDESTROY: + { + ::RemoveWindowSubclass(hWnd, TabUpDownSubclass, uIdSubclass); + delete pButtonData; + break; + } + + case WM_ERASEBKGND: + { + if (NppDarkMode::isEnabled()) + { + RECT rcClient{}; + ::GetClientRect(hWnd, &rcClient); + ::FillRect(reinterpret_cast(wParam), &rcClient, NppDarkMode::getDarkerBackgroundBrush()); + return TRUE; + } + break; + } + } + return DefSubclassProc(hWnd, uMsg, wParam, lParam); + } + + void subclassTabUpDownControl(HWND hwnd) + { + auto pButtonData = reinterpret_cast(new ButtonData()); + SetWindowSubclass(hwnd, TabUpDownSubclass, g_tabUpDownSubclassID, pButtonData); + } + + void autoSubclassAndThemeTabUpDownControl(HWND hwndParent, HWND hwndUpdown) + { + EnumChildWindows(hwndParent, [](HWND hwnd, LPARAM lParam) WINAPI_LAMBDA{ + auto && hwndUpdown = *reinterpret_cast(lParam); + if (hwndUpdown == nullptr) + { + constexpr size_t classNameLen = 16; + TCHAR className[classNameLen]{}; + GetClassName(hwnd, className, classNameLen); + if (wcscmp(className, UPDOWN_CLASS) == 0) + { + hwndUpdown = hwnd; + NppDarkMode::subclassTabUpDownControl(hwndUpdown); + NppDarkMode::setDarkExplorerTheme(hwndUpdown); + ::InvalidateRect(hwndUpdown, nullptr, TRUE); + ::UpdateWindow(hwndUpdown); + } + } + return TRUE; + }, reinterpret_cast(&hwndUpdown)); + } + void setDarkTitleBar(HWND hwnd) { NppDarkMode::allowDarkModeForWindow(hwnd, NppDarkMode::isEnabled()); diff --git a/PowerEditor/src/NppDarkMode.h b/PowerEditor/src/NppDarkMode.h index 32649c3d7..280080a37 100644 --- a/PowerEditor/src/NppDarkMode.h +++ b/PowerEditor/src/NppDarkMode.h @@ -153,6 +153,8 @@ namespace NppDarkMode void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass = true, bool theme = true); void autoThemeChildControls(HWND hwndParent); + void autoSubclassAndThemeTabUpDownControl(HWND hwndParent, HWND hwndUpdown); + void setDarkTitleBar(HWND hwnd); void setDarkExplorerTheme(HWND hwnd); void setDarkScrollBar(HWND hwnd); diff --git a/PowerEditor/src/WinControls/DockingWnd/DockingCont.cpp b/PowerEditor/src/WinControls/DockingWnd/DockingCont.cpp index 17f74ae89..440d3ec40 100644 --- a/PowerEditor/src/WinControls/DockingWnd/DockingCont.cpp +++ b/PowerEditor/src/WinControls/DockingWnd/DockingCont.cpp @@ -1224,6 +1224,8 @@ void DockingCont::onSize() ::SetWindowPos(_hContTab, NULL, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + NppDarkMode::autoSubclassAndThemeTabUpDownControl(_hContTab, _hTabUpdown); } // resize client area for plugin @@ -1244,6 +1246,8 @@ void DockingCont::onSize() ::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, SWP_NOZORDER | SWP_NOACTIVATE); + + NppDarkMode::autoSubclassAndThemeTabUpDownControl(_hContTab, _hTabUpdown); } // resize to float window else diff --git a/PowerEditor/src/WinControls/DockingWnd/DockingCont.h b/PowerEditor/src/WinControls/DockingWnd/DockingCont.h index d99ead982..1f7fb37db 100644 --- a/PowerEditor/src/WinControls/DockingWnd/DockingCont.h +++ b/PowerEditor/src/WinControls/DockingWnd/DockingCont.h @@ -176,6 +176,7 @@ private: bool _isFloating = FALSE; HWND _hCaption = nullptr; HWND _hContTab = nullptr; + HWND _hTabUpdown = nullptr; // horizontal font for caption and tab HFONT _hFont = nullptr; diff --git a/PowerEditor/src/WinControls/TabBar/TabBar.cpp b/PowerEditor/src/WinControls/TabBar/TabBar.cpp index 618762d91..71f1844d6 100644 --- a/PowerEditor/src/WinControls/TabBar/TabBar.cpp +++ b/PowerEditor/src/WinControls/TabBar/TabBar.cpp @@ -241,6 +241,8 @@ void TabBar::reSizeTo(RECT & rc2Ajust) rc2Ajust.top += tabsHight; rc2Ajust.bottom -= tabsHight; } + + NppDarkMode::autoSubclassAndThemeTabUpDownControl(_hSelf, _hTabUpdown); } @@ -1075,7 +1077,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) { if (isDarkMode) { - ::FillRect(hDC, &barRect, NppDarkMode::getSofterBackgroundBrush()); + ::FillRect(hDC, &pDrawItemStruct->rcItem, NppDarkMode::getSofterBackgroundBrush()); } if (_drawTopBar) { diff --git a/PowerEditor/src/WinControls/TabBar/TabBar.h b/PowerEditor/src/WinControls/TabBar/TabBar.h index 47db586fc..a58d75224 100644 --- a/PowerEditor/src/WinControls/TabBar/TabBar.h +++ b/PowerEditor/src/WinControls/TabBar/TabBar.h @@ -114,6 +114,8 @@ protected: long getRowCount() const { return long(::SendMessage(_hSelf, TCM_GETROWCOUNT, 0, 0)); } +private: + HWND _hTabUpdown = nullptr; };