Skip to content

Commit 8692619

Browse files
committed
Enable Dark Mode support for the QuickOpenDialog
1 parent 3453fd4 commit 8692619

File tree

6 files changed

+156
-71
lines changed

6 files changed

+156
-71
lines changed

src/Explorer/Explorer.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,17 @@ void UpdateThemeColor()
336336

337337
auto nppColors = NppInterface::GetColors();
338338

339-
Colors colors{
340-
.face = nppColors.background,
341-
.text = nppColors.text,
342-
.bg = NppInterface::getEditorDefaultBackgroundColor(),
343-
.fg = NppInterface::getEditorDefaultForegroundColor(),
339+
ThemeColors colors{
340+
.body = nppColors.darkerText,
341+
.body_bg = nppColors.pureBackground,
342+
.secondary = NppInterface::getEditorDefaultForegroundColor(),
343+
.secondary_bg = NppInterface::getEditorDefaultBackgroundColor(),
344+
.border = nppColors.edge,
345+
.primary = nppColors.text,
346+
.primary_bg = nppColors.hotBackground,
347+
.primary_border = nppColors.hotEdge,
344348
};
345-
auto isDarkMode = IsDarkColor(colors.bg);
349+
auto isDarkMode = IsDarkColor(colors.body_bg);
346350
ThemeRenderer::Instance().SetTheme(isDarkMode, colors);
347351
}
348352

@@ -355,6 +359,7 @@ void initializeFonts()
355359
::DeleteObject(exProp.underlineFont);
356360
}
357361
exProp.defaultFont = ::CreateFontIndirect(&exProp.logfont);
362+
358363
LOGFONT logfontUnder = exProp.logfont;
359364
logfontUnder.lfUnderline = TRUE;
360365
exProp.underlineFont = ::CreateFontIndirect(&logfontUnder);

src/Explorer/FavesDialog.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ FavesDialog::FavesDialog()
100100

101101
FavesDialog::~FavesDialog()
102102
{
103-
ImageList_Destroy(_hImageList);
104103
}
105104

106105

src/Explorer/NppInterface.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ COLORREF NppInterface::getEditorDefaultBackgroundColor()
7777

7878
COLORREF NppInterface::getEditorCurrentLineBackgroundColor()
7979
{
80-
return static_cast<COLORREF>(::SendMessage(_nppData._scintillaMainHandle, SCI_GETELEMENTCOLOUR, SC_ELEMENT_CARET_LINE_BACK, 0));
80+
return static_cast<COLORREF>(::SendMessage(_nppData._scintillaMainHandle, SCI_GETCARETLINEBACK, 0, 0));
8181
}
8282

8383
BOOL NppInterface::IsDarkMode()
@@ -111,13 +111,13 @@ NppColors NppInterface::GetColors()
111111
}
112112
// default colors;
113113
return {
114-
.background = ::GetSysColor(COLOR_WINDOW),
115-
.softerBackground = ::GetSysColor(COLOR_3DFACE),
116-
.hotBackground = ::GetSysColor(COLOR_HIGHLIGHT),
117-
.pureBackground = ::GetSysColor(COLOR_WINDOW),
114+
.background = ::GetSysColor(COLOR_3DFACE),
115+
.softerBackground = ::GetSysColor(COLOR_WINDOW),
116+
.hotBackground = RGB(204, 232, 255),
117+
.pureBackground = ::GetSysColor(COLOR_3DFACE),
118118
.errorBackground = ::GetSysColor(COLOR_WINDOW),
119119
.text = ::GetSysColor(COLOR_WINDOWTEXT),
120-
.darkerText = ::GetSysColor(COLOR_HIGHLIGHTTEXT),
120+
.darkerText = ::GetSysColor(COLOR_WINDOWTEXT),
121121
.disabledText = ::GetSysColor(COLOR_GRAYTEXT),
122122
.linkText = ::GetSysColor(COLOR_HOTLIGHT),
123123
.edge = ::GetSysColor(COLOR_INACTIVEBORDER),

src/Explorer/QuickOpenDialog.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "ExplorerResource.h"
4040
#include "FuzzyMatcher.h"
4141
#include "NppInterface.h"
42+
#include "ThemeRenderer.h"
4243

4344
namespace {
4445
constexpr UINT WM_UPDATE_RESULT_LIST = WM_USER + 1;
@@ -517,6 +518,7 @@ void QuickOpenDlg::init(HINSTANCE hInst, HWND parent, ExProp* prop)
517518

518519
Window::init(hInst, parent);
519520
create(IDD_QUICK_OPEN_DLG, FALSE);
521+
ThemeRenderer::Instance().Register(_hSelf);
520522

521523
_filesystemWatcher.Created([this](const std::wstring& path) {
522524
if (IsFile(path)) {
@@ -645,15 +647,16 @@ BOOL QuickOpenDlg::onDrawItem(LPDRAWITEMSTRUCT drawItem)
645647
}
646648

647649
const HDC& hdc = drawItem->hDC;
648-
COLORREF backgroundColor = RGB(255, 255, 255);
649-
COLORREF backgroundMatchColor = RGB(252, 234, 128);
650-
COLORREF textColor1 = RGB( 0, 0, 0);
650+
COLORREF backgroundMatchColor = RGB(254, 230, 177);
651+
COLORREF matchColor = RGB(0, 0, 0);
652+
653+
COLORREF backgroundColor = ThemeRenderer::Instance().GetColors().secondary_bg;
654+
COLORREF textColor1 = ThemeRenderer::Instance().GetColors().secondary;
651655
COLORREF textColor2 = RGB(128, 128, 128);
652656

653657
if (ODS_SELECTED == ((drawItem->itemState) & (ODS_SELECTED))) {
654-
backgroundColor = RGB(230, 231, 239);
655-
backgroundMatchColor = RGB(252, 234, 128);
656-
textColor1 = RGB( 0, 0, 0);
658+
backgroundColor = ThemeRenderer::Instance().GetColors().primary_bg;
659+
textColor1 = ThemeRenderer::Instance().GetColors().primary;
657660
textColor2 = RGB(128, 128, 128);
658661
}
659662

@@ -665,7 +668,6 @@ BOOL QuickOpenDlg::onDrawItem(LPDRAWITEMSTRUCT drawItem)
665668
RECT drawPosition = drawItem->rcItem;
666669
drawPosition.top += _layout.itemMargin;
667670
drawPosition.left = drawItem->rcItem.left + _layout.itemMarginLeft;
668-
::SetTextColor(hdc, textColor1);
669671
::SetBkMode(hdc, OPAQUE);
670672

671673
RECT calcRect = {};
@@ -679,10 +681,12 @@ BOOL QuickOpenDlg::onDrawItem(LPDRAWITEMSTRUCT drawItem)
679681
if (type == QuickOpenEntry::MATCH_TYPE::FILE) {
680682
for (size_t i = 0; i < filename.length(); ++i) {
681683
if ((itr != last) && (i == *itr)) {
684+
::SetTextColor(hdc, matchColor);
682685
::SetBkColor(hdc, backgroundMatchColor);
683686
++itr;
684687
}
685688
else {
689+
::SetTextColor(hdc, textColor1);
686690
::SetBkColor(hdc, backgroundColor);
687691
}
688692
::DrawText(hdc, &filename[i], 1, &drawPosition, DT_SINGLELINE);
@@ -691,21 +695,24 @@ BOOL QuickOpenDlg::onDrawItem(LPDRAWITEMSTRUCT drawItem)
691695
}
692696
}
693697
else {
698+
::SetTextColor(hdc, textColor1);
694699
::SetBkColor(hdc, backgroundColor);
695700
::DrawText(hdc, filename.data(), static_cast<INT>(filename.length()), &drawPosition, DT_SINGLELINE);
696701
::DrawText(hdc, filename.data(), static_cast<INT>(filename.length()), &calcRect, DT_SINGLELINE | DT_CALCRECT);
697702
}
698703

699704
drawPosition.top += calcRect.bottom;
700705
drawPosition.left = drawItem->rcItem.left + _layout.itemMarginLeft;
701-
::SetTextColor(hdc, textColor2);
706+
702707
if (type == QuickOpenEntry::MATCH_TYPE::PATH) {
703708
for (size_t i = 0; i < path.length(); ++i) {
704709
if ((itr != last) && (i == *itr)) {
710+
::SetTextColor(hdc, matchColor);
705711
::SetBkColor(hdc, backgroundMatchColor);
706712
++itr;
707713
}
708714
else {
715+
::SetTextColor(hdc, textColor2);
709716
::SetBkColor(hdc, backgroundColor);
710717
}
711718
::DrawText(hdc, &path[i], 1, &drawPosition, DT_SINGLELINE);
@@ -714,6 +721,7 @@ BOOL QuickOpenDlg::onDrawItem(LPDRAWITEMSTRUCT drawItem)
714721
}
715722
}
716723
else {
724+
::SetTextColor(hdc, textColor2);
717725
::SetBkColor(hdc, backgroundColor);
718726
::DrawText(hdc, path.data(), static_cast<INT>(path.length()), &drawPosition, DT_SINGLELINE);
719727
}
@@ -760,26 +768,18 @@ INT_PTR CALLBACK QuickOpenDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM l
760768
if (!_directoryReader.IsReading()) {
761769
::KillTimer(_hSelf, UPDATE_PROGRESSBAR);
762770
}
763-
::InvalidateRect(_hSelf, &_progressBarRect, FALSE);
771+
::InvalidateRect(_hSelf, &_progressBarRect, TRUE);
764772
::UpdateWindow(_hSelf);
765773
ret = TRUE;
766774
break;
767775
default:
768776
break;
769777
}
770778
break;
771-
case WM_PRINTCLIENT:
772779
case WM_PAINT:
773780
{
774-
HDC hDC = (Message == WM_PRINTCLIENT)
775-
? reinterpret_cast<HDC>(wParam)
776-
: GetDCEx(_hSelf, nullptr, DCX_INTERSECTUPDATE | DCX_CACHE | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
777-
778-
// Erase progressbar background
779-
const COLORREF backgroundColor = ::GetSysColor(COLOR_3DFACE);
780-
const HBRUSH hBkBrush = ::CreateSolidBrush(backgroundColor);
781-
::FillRect(hDC, &_progressBarRect, hBkBrush);
782-
::DeleteObject(hBkBrush);
781+
PAINTSTRUCT ps;
782+
HDC hDC = ::BeginPaint(_hSelf, &ps);
783783

784784
// draw progress bar
785785
if (_directoryReader.IsReading()) {
@@ -799,8 +799,8 @@ INT_PTR CALLBACK QuickOpenDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM l
799799
::FillRect(hDC, &barRect, hPbBrush);
800800
::DeleteObject(hPbBrush);
801801
}
802-
803-
ret = FALSE; // continue default proc
802+
EndPaint(_hSelf, &ps);
803+
ret = TRUE;
804804
break;
805805
}
806806
case WM_COMMAND :

src/Explorer/ThemeRenderer.cpp

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace {
3131
constexpr UINT_PTR WINDOW_SUBCLASS_ID = 0;
3232
constexpr UINT_PTR REBAR_SUBCLASS_ID = 1;
3333
constexpr UINT_PTR BUTTON_SUBCLASS_ID = 2;
34+
constexpr UINT_PTR EDIT_SUBCLASS_ID = 3;
3435

3536
auto GetClassName(HWND hwnd) -> std::wstring
3637
{
@@ -73,18 +74,43 @@ ThemeRenderer& ThemeRenderer::Instance()
7374
return *s_instance;
7475
}
7576

77+
HBRUSH ThemeRenderer::GetBrush(BrushType type) const
78+
{
79+
switch (type) {
80+
case BrushType::Body:
81+
return m_brushes.body;
82+
case BrushType::BodyBg:
83+
return m_brushes.body_bg;
84+
case BrushType::Secondary:
85+
return m_brushes.secondary;
86+
case BrushType::SecondaryBg:
87+
return m_brushes.secondary_bg;
88+
case BrushType::Border:
89+
return m_brushes.border;
90+
case BrushType::Primary:
91+
return m_brushes.primary;
92+
case BrushType::PrimaryBg:
93+
return m_brushes.primary_bg;
94+
case BrushType::PrimaryBorder:
95+
return m_brushes.primary_border;
96+
default:
97+
return m_brushes.body_bg; // デフォルトは本文背景を返す
98+
}
99+
}
76100

77-
void ThemeRenderer::SetTheme(BOOL isDarkMode, Colors colors)
101+
void ThemeRenderer::SetTheme(BOOL isDarkMode, const ThemeColors& colors)
78102
{
79103
m_isDarkMode = isDarkMode;
80104
m_colors = colors;
81105

82-
m_brushes.face.CreateSolidBrush(colors.face);
83-
m_brushes.bg.CreateSolidBrush(colors.bg);
84-
m_brushes.hot.CreateSolidBrush(colors.hot);
85-
m_brushes.hotSelected.CreateSolidBrush(colors.hotSelected);
86-
m_brushes.selected.CreateSolidBrush(colors.selected);
87-
m_brushes.selectedNotFocus.CreateSolidBrush(colors.selectedNotFocus);
106+
m_brushes.body.CreateSolidBrush(colors.body);
107+
m_brushes.body_bg.CreateSolidBrush(colors.body_bg);
108+
m_brushes.secondary.CreateSolidBrush(colors.secondary);
109+
m_brushes.secondary_bg.CreateSolidBrush(colors.secondary_bg);
110+
m_brushes.border.CreateSolidBrush(colors.border);
111+
m_brushes.primary.CreateSolidBrush(colors.primary);
112+
m_brushes.primary_bg.CreateSolidBrush(colors.primary_bg);
113+
m_brushes.primary_border.CreateSolidBrush(colors.primary_border);
88114

89115
for (const auto& hwnd : m_windows) {
90116
ApplyTheme(hwnd);
@@ -106,6 +132,9 @@ void ThemeRenderer::Register(HWND hwnd)
106132
else if (className == WC_BUTTON) {
107133
::SetWindowSubclass(childWindow, DefaultSubclassProc, BUTTON_SUBCLASS_ID, reinterpret_cast<DWORD_PTR>(self));
108134
}
135+
else if (className == WC_EDIT) {
136+
::SetWindowSubclass(childWindow, DefaultSubclassProc, EDIT_SUBCLASS_ID, reinterpret_cast<DWORD_PTR>(self));
137+
}
109138
return TRUE;
110139
}, reinterpret_cast<LPARAM>(this));
111140

@@ -120,21 +149,21 @@ void ThemeRenderer::ApplyTheme(HWND hwnd)
120149
if (className == TOOLBARCLASSNAME) {
121150
COLORSCHEME scheme{
122151
.dwSize = sizeof(COLORSCHEME),
123-
.clrBtnHighlight = self->m_colors.selected,
124-
.clrBtnShadow = self->m_colors.face,
152+
.clrBtnHighlight = self->m_colors.primary_bg,
153+
.clrBtnShadow = self->m_colors.secondary_bg,
125154
};
126155
::SendMessage(childWindow, TB_SETCOLORSCHEME, 0, reinterpret_cast<LPARAM>(&scheme));
127156
}
128157
else if (className == WC_TREEVIEW) {
129-
TreeView_SetBkColor(childWindow, self->m_colors.bg);
130-
TreeView_SetTextColor(childWindow, self->m_colors.fg);
158+
TreeView_SetBkColor(childWindow, self->m_colors.secondary_bg);
159+
TreeView_SetTextColor(childWindow, self->m_colors.secondary);
131160
::SetWindowTheme(childWindow, self->m_isDarkMode ? L"DarkMode_Explorer" : L"Explorer", nullptr);
132161
}
133162
else if (className == WC_LISTVIEW) {
134-
ListView_SetBkColor(childWindow, self->m_colors.bg);
135-
ListView_SetTextColor(childWindow, self->m_colors.fg);
163+
ListView_SetBkColor(childWindow, self->m_colors.secondary_bg);
164+
ListView_SetTextColor(childWindow, self->m_colors.secondary);
136165
ListView_SetTextBkColor(childWindow, CLR_NONE);
137-
::InvalidateRect(childWindow, NULL, TRUE);
166+
::SetWindowTheme(childWindow, self->m_isDarkMode ? L"DarkMode_Explorer" : L"Explorer", nullptr);
138167
}
139168
return TRUE;
140169
}, reinterpret_cast<LPARAM>(this));
@@ -150,6 +179,8 @@ LRESULT CALLBACK ThemeRenderer::DefaultSubclassProc(HWND hWnd, UINT uMsg, WPARAM
150179
return self->RebarProc(hWnd, uMsg, wParam, lParam);
151180
case BUTTON_SUBCLASS_ID:
152181
return self->ButtonProc(hWnd, uMsg, wParam, lParam);
182+
case EDIT_SUBCLASS_ID:
183+
return self->EditProc(hWnd, uMsg, wParam, lParam);
153184
default:
154185
break;
155186
}
@@ -162,9 +193,16 @@ LRESULT ThemeRenderer::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP
162193
case WM_ERASEBKGND: {
163194
RECT rc{};
164195
::GetClientRect(hWnd, &rc);
165-
::FillRect((HDC)wParam, &rc, m_brushes.face);
196+
::FillRect((HDC)wParam, &rc, m_brushes.body_bg);
166197
return TRUE;
167198
}
199+
case WM_CTLCOLOREDIT:
200+
{
201+
HDC hdc = (HDC)wParam;
202+
::SetTextColor(hdc, m_colors.secondary);
203+
::SetBkColor(hdc, m_colors.secondary_bg);
204+
return (LRESULT)(HBRUSH)m_brushes.secondary_bg;
205+
}
168206
case WM_NCDESTROY:
169207
::RemoveWindowSubclass(hWnd, DefaultSubclassProc, REBAR_SUBCLASS_ID);
170208
m_windows.erase(hWnd);
@@ -179,7 +217,7 @@ LRESULT ThemeRenderer::RebarProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
179217
case WM_ERASEBKGND: {
180218
RECT rc{};
181219
::GetClientRect(hWnd, &rc);
182-
::FillRect((HDC)wParam, &rc, m_brushes.face);
220+
::FillRect((HDC)wParam, &rc, m_brushes.secondary_bg);
183221
return TRUE;
184222
}
185223
case WM_NCDESTROY:
@@ -196,7 +234,7 @@ LRESULT ThemeRenderer::ButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP
196234
case WM_ERASEBKGND: {
197235
RECT rc{};
198236
::GetClientRect(hWnd, &rc);
199-
::FillRect((HDC)wParam, &rc, m_brushes.face);
237+
::FillRect((HDC)wParam, &rc, m_brushes.body_bg);
200238
return TRUE;
201239
}
202240
case WM_NCDESTROY:
@@ -206,3 +244,30 @@ LRESULT ThemeRenderer::ButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP
206244
}
207245
return ::DefSubclassProc(hWnd, uMsg, wParam, lParam);
208246
}
247+
248+
LRESULT ThemeRenderer::EditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
249+
{
250+
switch (uMsg) {
251+
case WM_NCPAINT: {
252+
HDC hdc = GetWindowDC(hWnd);
253+
RECT rect;
254+
GetWindowRect(hWnd, &rect);
255+
OffsetRect(&rect, -rect.left, -rect.top);
256+
257+
HWND hFocusWnd = GetFocus();
258+
if (hFocusWnd == hWnd) {
259+
FrameRect(hdc, &rect, m_brushes.primary_border);
260+
} else {
261+
FrameRect(hdc, &rect, m_brushes.border);
262+
}
263+
264+
ReleaseDC(hWnd, hdc);
265+
return TRUE;
266+
}
267+
case WM_NCDESTROY:
268+
::RemoveWindowSubclass(hWnd, DefaultSubclassProc, EDIT_SUBCLASS_ID);
269+
m_windows.erase(hWnd);
270+
break;
271+
}
272+
return ::DefSubclassProc(hWnd, uMsg, wParam, lParam);
273+
}

0 commit comments

Comments
 (0)