Add support for dark tab updown control

Fix #10054, close #11554
This commit is contained in:
ozone10 2022-04-19 16:25:50 +02:00 committed by Don Ho
parent 1eb5b10e41
commit 87f4249d6b
6 changed files with 177 additions and 2 deletions

View File

@ -743,7 +743,7 @@ namespace NppDarkMode
{ {
if (!hTheme) if (!hTheme)
{ {
hTheme = OpenThemeData(hwnd, L"Button"); hTheme = OpenThemeData(hwnd, WC_BUTTON);
} }
return hTheme != nullptr; return hTheme != nullptr;
} }
@ -1522,6 +1522,170 @@ namespace NppDarkMode
autoSubclassAndThemeChildControls(hwndParent, false, true); 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<ButtonData*>(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<HFONT>(SendMessage(hWnd, WM_GETFONT, 0, 0));
::GetObject(font, sizeof(lf), &lf);
lf.lfHeight = (dpiManager.scaleY(16) - 5) * -1;
auto holdFont = static_cast<HFONT>(::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<HPEN>(::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<HDC>(wParam), &rcClient, NppDarkMode::getDarkerBackgroundBrush());
return TRUE;
}
break;
}
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
void subclassTabUpDownControl(HWND hwnd)
{
auto pButtonData = reinterpret_cast<DWORD_PTR>(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<HWND*>(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<LPARAM>(&hwndUpdown));
}
void setDarkTitleBar(HWND hwnd) void setDarkTitleBar(HWND hwnd)
{ {
NppDarkMode::allowDarkModeForWindow(hwnd, NppDarkMode::isEnabled()); NppDarkMode::allowDarkModeForWindow(hwnd, NppDarkMode::isEnabled());

View File

@ -153,6 +153,8 @@ namespace NppDarkMode
void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass = true, bool theme = true); void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass = true, bool theme = true);
void autoThemeChildControls(HWND hwndParent); void autoThemeChildControls(HWND hwndParent);
void autoSubclassAndThemeTabUpDownControl(HWND hwndParent, HWND hwndUpdown);
void setDarkTitleBar(HWND hwnd); void setDarkTitleBar(HWND hwnd);
void setDarkExplorerTheme(HWND hwnd); void setDarkExplorerTheme(HWND hwnd);
void setDarkScrollBar(HWND hwnd); void setDarkScrollBar(HWND hwnd);

View File

@ -1224,6 +1224,8 @@ void DockingCont::onSize()
::SetWindowPos(_hContTab, NULL, ::SetWindowPos(_hContTab, NULL,
rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom,
SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
NppDarkMode::autoSubclassAndThemeTabUpDownControl(_hContTab, _hTabUpdown);
} }
// resize client area for plugin // resize client area for plugin
@ -1244,6 +1246,8 @@ void DockingCont::onSize()
::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL, ::SetWindowPos(::GetDlgItem(_hSelf, IDC_CLIENT_TAB), NULL,
rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom,
SWP_NOZORDER | SWP_NOACTIVATE); SWP_NOZORDER | SWP_NOACTIVATE);
NppDarkMode::autoSubclassAndThemeTabUpDownControl(_hContTab, _hTabUpdown);
} }
// resize to float window // resize to float window
else else

View File

@ -176,6 +176,7 @@ private:
bool _isFloating = FALSE; bool _isFloating = FALSE;
HWND _hCaption = nullptr; HWND _hCaption = nullptr;
HWND _hContTab = nullptr; HWND _hContTab = nullptr;
HWND _hTabUpdown = nullptr;
// horizontal font for caption and tab // horizontal font for caption and tab
HFONT _hFont = nullptr; HFONT _hFont = nullptr;

View File

@ -241,6 +241,8 @@ void TabBar::reSizeTo(RECT & rc2Ajust)
rc2Ajust.top += tabsHight; rc2Ajust.top += tabsHight;
rc2Ajust.bottom -= tabsHight; rc2Ajust.bottom -= tabsHight;
} }
NppDarkMode::autoSubclassAndThemeTabUpDownControl(_hSelf, _hTabUpdown);
} }
@ -1075,7 +1077,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
{ {
if (isDarkMode) if (isDarkMode)
{ {
::FillRect(hDC, &barRect, NppDarkMode::getSofterBackgroundBrush()); ::FillRect(hDC, &pDrawItemStruct->rcItem, NppDarkMode::getSofterBackgroundBrush());
} }
if (_drawTopBar) if (_drawTopBar)
{ {

View File

@ -114,6 +114,8 @@ protected:
long getRowCount() const { long getRowCount() const {
return long(::SendMessage(_hSelf, TCM_GETROWCOUNT, 0, 0)); return long(::SendMessage(_hSelf, TCM_GETROWCOUNT, 0, 0));
} }
private:
HWND _hTabUpdown = nullptr;
}; };