Highlight dark mode combobox border on focus

Fix #11574, close #11575
This commit is contained in:
ozone10 2022-04-23 17:10:22 +02:00 committed by Don Ho
parent 2fbac354ed
commit dfc9fb6f3b
4 changed files with 90 additions and 33 deletions

View File

@ -505,6 +505,7 @@ enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64, PF_ARM64 };
// COLORREF disabledText = 0; // COLORREF disabledText = 0;
// COLORREF linkText = 0; // COLORREF linkText = 0;
// COLORREF edge = 0; // COLORREF edge = 0;
// COLORREF hotEdge = 0;
// }; // };
// } // }
// //

View File

@ -2635,6 +2635,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
currentColors->disabledText = NppDarkMode::getDisabledTextColor(); currentColors->disabledText = NppDarkMode::getDisabledTextColor();
currentColors->linkText = NppDarkMode::getLinkTextColor(); currentColors->linkText = NppDarkMode::getLinkTextColor();
currentColors->edge = NppDarkMode::getEdgeColor(); currentColors->edge = NppDarkMode::getEdgeColor();
currentColors->hotEdge = NppDarkMode::getHotEdgeColor();
return static_cast<LRESULT>(true); return static_cast<LRESULT>(true);
} }

View File

@ -47,12 +47,18 @@ namespace NppDarkMode
HBRUSH pureBackground = nullptr; HBRUSH pureBackground = nullptr;
HBRUSH errorBackground = nullptr; HBRUSH errorBackground = nullptr;
HBRUSH edgeBrush = nullptr;
HBRUSH hotEdgeBrush = nullptr;
Brushes(const Colors& colors) Brushes(const Colors& colors)
: background(::CreateSolidBrush(colors.background)) : background(::CreateSolidBrush(colors.background))
, softerBackground(::CreateSolidBrush(colors.softerBackground)) , softerBackground(::CreateSolidBrush(colors.softerBackground))
, hotBackground(::CreateSolidBrush(colors.hotBackground)) , hotBackground(::CreateSolidBrush(colors.hotBackground))
, pureBackground(::CreateSolidBrush(colors.pureBackground)) , pureBackground(::CreateSolidBrush(colors.pureBackground))
, errorBackground(::CreateSolidBrush(colors.errorBackground)) , errorBackground(::CreateSolidBrush(colors.errorBackground))
, edgeBrush(::CreateSolidBrush(colors.edge))
, hotEdgeBrush(::CreateSolidBrush(colors.hotEdge))
{} {}
~Brushes() ~Brushes()
@ -62,6 +68,9 @@ namespace NppDarkMode
::DeleteObject(hotBackground); hotBackground = nullptr; ::DeleteObject(hotBackground); hotBackground = nullptr;
::DeleteObject(pureBackground); pureBackground = nullptr; ::DeleteObject(pureBackground); pureBackground = nullptr;
::DeleteObject(errorBackground); errorBackground = nullptr; ::DeleteObject(errorBackground); errorBackground = nullptr;
::DeleteObject(edgeBrush); edgeBrush = nullptr;
::DeleteObject(hotEdgeBrush); hotEdgeBrush = nullptr;
} }
void change(const Colors& colors) void change(const Colors& colors)
@ -72,11 +81,17 @@ namespace NppDarkMode
::DeleteObject(pureBackground); ::DeleteObject(pureBackground);
::DeleteObject(errorBackground); ::DeleteObject(errorBackground);
::DeleteObject(edgeBrush);
::DeleteObject(hotEdgeBrush);
background = ::CreateSolidBrush(colors.background); background = ::CreateSolidBrush(colors.background);
softerBackground = ::CreateSolidBrush(colors.softerBackground); softerBackground = ::CreateSolidBrush(colors.softerBackground);
hotBackground = ::CreateSolidBrush(colors.hotBackground); hotBackground = ::CreateSolidBrush(colors.hotBackground);
pureBackground = ::CreateSolidBrush(colors.pureBackground); pureBackground = ::CreateSolidBrush(colors.pureBackground);
errorBackground = ::CreateSolidBrush(colors.errorBackground); errorBackground = ::CreateSolidBrush(colors.errorBackground);
edgeBrush = ::CreateSolidBrush(colors.edge);
hotEdgeBrush = ::CreateSolidBrush(colors.hotEdge);
} }
}; };
@ -84,25 +99,30 @@ namespace NppDarkMode
{ {
HPEN darkerTextPen = nullptr; HPEN darkerTextPen = nullptr;
HPEN edgePen = nullptr; HPEN edgePen = nullptr;
HPEN hotEdgePen = nullptr;
Pens(const Colors& colors) Pens(const Colors& colors)
: darkerTextPen(::CreatePen(PS_SOLID, 1, colors.darkerText)) : darkerTextPen(::CreatePen(PS_SOLID, 1, colors.darkerText))
, edgePen(::CreatePen(PS_SOLID, 1, colors.edge)) , edgePen(::CreatePen(PS_SOLID, 1, colors.edge))
, hotEdgePen(::CreatePen(PS_SOLID, 1, colors.hotEdge))
{} {}
~Pens() ~Pens()
{ {
::DeleteObject(darkerTextPen); darkerTextPen = nullptr; ::DeleteObject(darkerTextPen); darkerTextPen = nullptr;
::DeleteObject(edgePen); edgePen = nullptr; ::DeleteObject(edgePen); edgePen = nullptr;
::DeleteObject(hotEdgePen); hotEdgePen = nullptr;
} }
void change(const Colors& colors) void change(const Colors& colors)
{ {
::DeleteObject(darkerTextPen); ::DeleteObject(darkerTextPen);
::DeleteObject(edgePen); ::DeleteObject(edgePen);
::DeleteObject(hotEdgePen);
darkerTextPen = ::CreatePen(PS_SOLID, 1, colors.darkerText); darkerTextPen = ::CreatePen(PS_SOLID, 1, colors.darkerText);
edgePen = ::CreatePen(PS_SOLID, 1, colors.edge); edgePen = ::CreatePen(PS_SOLID, 1, colors.edge);
hotEdgePen = ::CreatePen(PS_SOLID, 1, colors.hotEdge);
} }
}; };
@ -118,7 +138,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x646464) // edgeColor HEXRGB(0x646464), // edgeColor
HEXRGB(0x9B9B9B) // hotEdgeColor
}; };
// red tone // red tone
@ -132,7 +153,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x908080) // edgeColor HEXRGB(0x908080), // edgeColor
HEXRGB(0xBBABAB) // hotEdgeColor
}; };
// green tone // green tone
@ -146,7 +168,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x809080) // edgeColor HEXRGB(0x809080), // edgeColor
HEXRGB(0xABBBAB) // hotEdgeColor
}; };
// blue tone // blue tone
@ -160,7 +183,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x8080A0) // edgeColor HEXRGB(0x8080A0), // edgeColor
HEXRGB(0xABABCB) // hotEdgeColor
}; };
// purple tone // purple tone
@ -174,7 +198,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x9080A0) // edgeColor HEXRGB(0x9080A0), // edgeColor
HEXRGB(0xBBABCB) // hotEdgeColor
}; };
// cyan tone // cyan tone
@ -188,7 +213,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x8090A0) // edgeColor HEXRGB(0x8090A0), // edgeColor
HEXRGB(0xBBBBCB) // hotEdgeColor
}; };
// olive tone // olive tone
@ -202,7 +228,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x909080) // edgeColor HEXRGB(0x909080), // edgeColor
HEXRGB(0xBBBBAB) // hotEdgeColor
}; };
// customized // customized
@ -216,7 +243,8 @@ namespace NppDarkMode
HEXRGB(0xC0C0C0), // darkerTextColor HEXRGB(0xC0C0C0), // darkerTextColor
HEXRGB(0x808080), // disabledTextColor HEXRGB(0x808080), // disabledTextColor
HEXRGB(0xFFFF00), // linkTextColor HEXRGB(0xFFFF00), // linkTextColor
HEXRGB(0x646464) // edgeColor HEXRGB(0x646464), // edgeColor
HEXRGB(0x9B9B9B) // hotEdgeColor
}; };
ColorTone g_colorToneChoice = blackTone; ColorTone g_colorToneChoice = blackTone;
@ -432,6 +460,7 @@ namespace NppDarkMode
COLORREF getDisabledTextColor() { return getTheme()._colors.disabledText; } COLORREF getDisabledTextColor() { return getTheme()._colors.disabledText; }
COLORREF getLinkTextColor() { return getTheme()._colors.linkText; } COLORREF getLinkTextColor() { return getTheme()._colors.linkText; }
COLORREF getEdgeColor() { return getTheme()._colors.edge; } COLORREF getEdgeColor() { return getTheme()._colors.edge; }
COLORREF getHotEdgeColor() { return getTheme()._colors.hotEdge; }
HBRUSH getBackgroundBrush() { return getTheme()._brushes.background; } HBRUSH getBackgroundBrush() { return getTheme()._brushes.background; }
HBRUSH getSofterBackgroundBrush() { return getTheme()._brushes.softerBackground; } HBRUSH getSofterBackgroundBrush() { return getTheme()._brushes.softerBackground; }
@ -439,8 +468,12 @@ namespace NppDarkMode
HBRUSH getDarkerBackgroundBrush() { return getTheme()._brushes.pureBackground; } HBRUSH getDarkerBackgroundBrush() { return getTheme()._brushes.pureBackground; }
HBRUSH getErrorBackgroundBrush() { return getTheme()._brushes.errorBackground; } HBRUSH getErrorBackgroundBrush() { return getTheme()._brushes.errorBackground; }
HBRUSH getEdgeBrush() { return getTheme()._brushes.edgeBrush; }
HBRUSH getHotEdgeBrush() { return getTheme()._brushes.hotEdgeBrush; }
HPEN getDarkerTextPen() { return getTheme()._pens.darkerTextPen; } HPEN getDarkerTextPen() { return getTheme()._pens.darkerTextPen; }
HPEN getEdgePen() { return getTheme()._pens.edgePen; } HPEN getEdgePen() { return getTheme()._pens.edgePen; }
HPEN getHotEdgePen() { return getTheme()._pens.hotEdgePen; }
void setBackgroundColor(COLORREF c) void setBackgroundColor(COLORREF c)
{ {
@ -1293,9 +1326,11 @@ namespace NppDarkMode
WPARAM wParam, WPARAM wParam,
LPARAM lParam, LPARAM lParam,
UINT_PTR uIdSubclass, UINT_PTR uIdSubclass,
DWORD_PTR /*dwRefData*/ DWORD_PTR dwRefData
) )
{ {
auto hwndEdit = reinterpret_cast<HWND>(dwRefData);
switch (uMsg) switch (uMsg)
{ {
case WM_PAINT: case WM_PAINT:
@ -1308,33 +1343,33 @@ namespace NppDarkMode
RECT rc = {}; RECT rc = {};
::GetClientRect(hWnd, &rc); ::GetClientRect(hWnd, &rc);
PAINTSTRUCT ps; PAINTSTRUCT ps{};
auto hdc = ::BeginPaint(hWnd, &ps); auto hdc = ::BeginPaint(hWnd, &ps);
auto holdPen = static_cast<HPEN>(::SelectObject(hdc, NppDarkMode::getEdgePen()));
::SelectObject(hdc, reinterpret_cast<HFONT>(::SendMessage(hWnd, WM_GETFONT, 0, 0))); ::SelectObject(hdc, reinterpret_cast<HFONT>(::SendMessage(hWnd, WM_GETFONT, 0, 0)));
::SetBkColor(hdc, NppDarkMode::getBackgroundColor()); ::SetBkColor(hdc, NppDarkMode::getBackgroundColor());
::SelectObject(hdc, ::GetStockObject(NULL_BRUSH)); // to avoid text flicker, use only border
::Rectangle(hdc, 0, 0, rc.right, rc.bottom);
auto holdBrush = ::SelectObject(hdc, NppDarkMode::getDarkerBackgroundBrush()); auto holdBrush = ::SelectObject(hdc, NppDarkMode::getDarkerBackgroundBrush());
RECT arrowRc = { RECT rcArrow = {
rc.right - NppParameters::getInstance()._dpiManager.scaleX(17), rc.top + 1, rc.right - NppParameters::getInstance()._dpiManager.scaleX(17), rc.top + 1,
rc.right - 1, rc.bottom - 1 rc.right - 1, rc.bottom - 1
}; };
bool hasFocus = false;
// CBS_DROPDOWN text is handled by parent by WM_CTLCOLOREDIT // CBS_DROPDOWN text is handled by parent by WM_CTLCOLOREDIT
auto style = ::GetWindowLongPtr(hWnd, GWL_STYLE); auto style = ::GetWindowLongPtr(hWnd, GWL_STYLE);
if ((style & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST) if ((style & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
{ {
RECT bkRc = rc; hasFocus = ::GetFocus() == hWnd;
bkRc.left += 1;
bkRc.top += 1; RECT rcTextBg = rc;
bkRc.right = arrowRc.left - 1; rcTextBg.left += 1;
bkRc.bottom -= 1; rcTextBg.top += 1;
::FillRect(hdc, &bkRc, NppDarkMode::getBackgroundBrush()); // erase background on item change rcTextBg.right = rcArrow.left - 1;
rcTextBg.bottom -= 1;
::FillRect(hdc, &rcTextBg, NppDarkMode::getBackgroundBrush()); // erase background on item change
auto index = static_cast<int>(::SendMessage(hWnd, CB_GETCURSEL, 0, 0)); auto index = static_cast<int>(::SendMessage(hWnd, CB_GETCURSEL, 0, 0));
if (index != CB_ERR) if (index != CB_ERR)
@ -1345,38 +1380,45 @@ namespace NppDarkMode
TCHAR* buffer = new TCHAR[(bufferLen + 1)]; TCHAR* buffer = new TCHAR[(bufferLen + 1)];
::SendMessage(hWnd, CB_GETLBTEXT, index, reinterpret_cast<LPARAM>(buffer)); ::SendMessage(hWnd, CB_GETLBTEXT, index, reinterpret_cast<LPARAM>(buffer));
RECT textRc = rc; RECT rcText = rc;
textRc.left += 4; rcText.left += 4;
textRc.right = arrowRc.left - 5; rcText.right = rcArrow.left - 5;
::DrawText(hdc, buffer, -1, &textRc, DT_NOPREFIX | DT_LEFT | DT_VCENTER | DT_SINGLELINE); ::DrawText(hdc, buffer, -1, &rcText, DT_NOPREFIX | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
delete[]buffer; delete[]buffer;
} }
} }
else if ((style & CBS_DROPDOWN) == CBS_DROPDOWN && hwndEdit != NULL)
{
hasFocus = ::GetFocus() == hwndEdit;
}
POINT ptCursor = {}; POINT ptCursor = {};
::GetCursorPos(&ptCursor); ::GetCursorPos(&ptCursor);
ScreenToClient(hWnd, &ptCursor); ::ScreenToClient(hWnd, &ptCursor);
bool isHot = PtInRect(&rc, ptCursor); bool isHot = ::PtInRect(&rc, ptCursor);
::SetTextColor(hdc, isHot ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); ::SetTextColor(hdc, isHot ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor());
::SetBkColor(hdc, isHot ? NppDarkMode::getHotBackgroundColor() : NppDarkMode::getBackgroundColor()); ::SetBkColor(hdc, isHot ? NppDarkMode::getHotBackgroundColor() : NppDarkMode::getBackgroundColor());
::ExtTextOut(hdc, ::ExtTextOut(hdc,
arrowRc.left + (arrowRc.right - arrowRc.left) / 2 - NppParameters::getInstance()._dpiManager.scaleX(4), rcArrow.left + (rcArrow.right - rcArrow.left) / 2 - NppParameters::getInstance()._dpiManager.scaleX(4),
arrowRc.top + 3, rcArrow.top + 3,
ETO_OPAQUE | ETO_CLIPPED, ETO_OPAQUE | ETO_CLIPPED,
&arrowRc, L"˅", &rcArrow, L"˅",
1, 1,
nullptr); nullptr);
::SetBkColor(hdc, NppDarkMode::getBackgroundColor()); ::SetBkColor(hdc, NppDarkMode::getBackgroundColor());
auto holdPen = static_cast<HPEN>(::SelectObject(hdc, isHot || hasFocus ? NppDarkMode::getHotEdgePen() : NppDarkMode::getEdgePen()));
POINT edge[] = { POINT edge[] = {
{arrowRc.left - 1, arrowRc.top}, {rcArrow.left - 1, rcArrow.top},
{arrowRc.left - 1, arrowRc.bottom} {rcArrow.left - 1, rcArrow.bottom}
}; };
::Polyline(hdc, edge, _countof(edge)); ::Polyline(hdc, edge, _countof(edge));
::FrameRect(hdc, &rc, isHot || hasFocus ? NppDarkMode::getHotEdgeBrush() : NppDarkMode::getEdgeBrush());
::SelectObject(hdc, holdPen); ::SelectObject(hdc, holdPen);
::SelectObject(hdc, holdBrush); ::SelectObject(hdc, holdBrush);
@ -1395,7 +1437,14 @@ namespace NppDarkMode
void subclassComboBoxControl(HWND hwnd) void subclassComboBoxControl(HWND hwnd)
{ {
SetWindowSubclass(hwnd, ComboBoxSubclass, g_comboBoxSubclassID, 0); DWORD_PTR hwndEditData = NULL;
auto style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
if ((style & CBS_DROPDOWN) == CBS_DROPDOWN)
{
POINT pt = { 5, 5 };
hwndEditData = reinterpret_cast<DWORD_PTR>(::ChildWindowFromPoint(hwnd, pt));
}
SetWindowSubclass(hwnd, ComboBoxSubclass, g_comboBoxSubclassID, hwndEditData);
} }
void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass, bool theme) void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass, bool theme)

View File

@ -41,6 +41,7 @@ namespace NppDarkMode
COLORREF disabledText = 0; COLORREF disabledText = 0;
COLORREF linkText = 0; COLORREF linkText = 0;
COLORREF edge = 0; COLORREF edge = 0;
COLORREF hotEdge = 0;
}; };
struct Options struct Options
@ -103,6 +104,7 @@ namespace NppDarkMode
COLORREF getLinkTextColor(); COLORREF getLinkTextColor();
COLORREF getEdgeColor(); COLORREF getEdgeColor();
COLORREF getHotEdgeColor();
HBRUSH getBackgroundBrush(); HBRUSH getBackgroundBrush();
HBRUSH getDarkerBackgroundBrush(); HBRUSH getDarkerBackgroundBrush();
@ -110,8 +112,12 @@ namespace NppDarkMode
HBRUSH getHotBackgroundBrush(); HBRUSH getHotBackgroundBrush();
HBRUSH getErrorBackgroundBrush(); HBRUSH getErrorBackgroundBrush();
HBRUSH getEdgeBrush();
HBRUSH getHotEdgeBrush();
HPEN getDarkerTextPen(); HPEN getDarkerTextPen();
HPEN getEdgePen(); HPEN getEdgePen();
HPEN getHotEdgePen();
void setBackgroundColor(COLORREF c); void setBackgroundColor(COLORREF c);
void setSofterBackgroundColor(COLORREF c); void setSofterBackgroundColor(COLORREF c);