diff --git a/NppTaskList.vcxproj b/NppTaskList.vcxproj index 83faf06..9f21970 100644 --- a/NppTaskList.vcxproj +++ b/NppTaskList.vcxproj @@ -253,6 +253,7 @@ + @@ -269,6 +270,7 @@ + diff --git a/include/DockingDlgInterface.h b/include/DockingDlgInterface.h index 7a32d11..ecfd005 100644 --- a/include/DockingDlgInterface.h +++ b/include/DockingDlgInterface.h @@ -24,6 +24,7 @@ #include #include "Common.h" #include "StaticDialog.h" +#include "NppDarkMode.h" @@ -93,9 +94,21 @@ protected : generic_string _pluginName; bool _isClosed = false; - virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM , LPARAM lParam) { + virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { + case WM_ERASEBKGND: + { + if (!NppDarkMode::isEnabled()) + { + break; + } + + RECT rc = {}; + getClientRect(rc); + ::FillRect(reinterpret_cast(wParam), &rc, NppDarkMode::getDarkerBackgroundBrush()); + return TRUE; + } case WM_NOTIFY: { LPNMHDR pnmh = reinterpret_cast(lParam); diff --git a/include/NppDarkMode.h b/include/NppDarkMode.h new file mode 100644 index 0000000..b95d09b --- /dev/null +++ b/include/NppDarkMode.h @@ -0,0 +1,220 @@ +// This file is part of Notepad++ project +// Copyright (c) 2021 adzm / Adam D. Walling + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// at your option any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include + +constexpr COLORREF HEXRGB(DWORD rrggbb) { + // from 0xRRGGBB like natural #RRGGBB + // to the little-endian 0xBBGGRR + return + ((rrggbb & 0xFF0000) >> 16) | + ((rrggbb & 0x00FF00) ) | + ((rrggbb & 0x0000FF) << 16); +} + +namespace NppDarkMode +{ + struct Colors + { + COLORREF background = 0; + COLORREF softerBackground = 0; + COLORREF hotBackground = 0; + COLORREF pureBackground = 0; + COLORREF errorBackground = 0; + COLORREF text = 0; + COLORREF darkerText = 0; + COLORREF disabledText = 0; + COLORREF linkText = 0; + COLORREF edge = 0; + COLORREF hotEdge = 0; + COLORREF disabledEdge = 0; + }; + + struct Options + { + bool enable = false; + bool enableMenubar = false; + bool enablePlugin = false; + }; + + struct NppDarkModeParams + { + const wchar_t* _themeClassName = nullptr; + bool _subclass = false; + bool _theme = false; + }; + + enum class ToolTipsType + { + tooltip, + toolbar, + listview, + treeview, + tabbar + }; + + enum ColorTone { + blackTone = 0, + redTone = 1, + greenTone = 2, + blueTone = 3, + purpleTone = 4, + cyanTone = 5, + oliveTone = 6, + customizedTone = 32 + }; + + enum class TreeViewStyle + { + classic = 0, + light = 1, + dark = 2 + }; + + void initDarkMode(); // pulls options from NppParameters + void refreshDarkMode(HWND hwnd, bool forceRefresh = false); // attempts to apply new options from NppParameters, sends NPPM_INTERNAL_REFRESHDARKMODE to hwnd's top level parent + + bool isEnabled(); + bool isDarkMenuEnabled(); + bool isEnabledForPlugins(); + bool isExperimentalSupported(); + + bool isWindows10(); + bool isWindows11(); + + COLORREF invertLightness(COLORREF c); + COLORREF invertLightnessSofter(COLORREF c); + double calculatePerceivedLighness(COLORREF c); + + void setDarkTone(ColorTone colorToneChoice); + + COLORREF getBackgroundColor(); + COLORREF getSofterBackgroundColor(); + COLORREF getHotBackgroundColor(); + COLORREF getDarkerBackgroundColor(); + COLORREF getErrorBackgroundColor(); + + COLORREF getTextColor(); + COLORREF getDarkerTextColor(); + COLORREF getDisabledTextColor(); + COLORREF getLinkTextColor(); + + COLORREF getEdgeColor(); + COLORREF getHotEdgeColor(); + COLORREF getDisabledEdgeColor(); + + HBRUSH getBackgroundBrush(); + HBRUSH getDarkerBackgroundBrush(); + HBRUSH getSofterBackgroundBrush(); + HBRUSH getHotBackgroundBrush(); + HBRUSH getErrorBackgroundBrush(); + + HBRUSH getEdgeBrush(); + HBRUSH getHotEdgeBrush(); + HBRUSH getDisabledEdgeBrush(); + + HPEN getDarkerTextPen(); + HPEN getEdgePen(); + HPEN getHotEdgePen(); + HPEN getDisabledEdgePen(); + + COLORREF getIndividualTabColour(int colourIndex, bool themeDependant, bool saturated); + + void setBackgroundColor(COLORREF c); + void setSofterBackgroundColor(COLORREF c); + void setHotBackgroundColor(COLORREF c); + void setDarkerBackgroundColor(COLORREF c); + void setErrorBackgroundColor(COLORREF c); + void setTextColor(COLORREF c); + void setDarkerTextColor(COLORREF c); + void setDisabledTextColor(COLORREF c); + void setLinkTextColor(COLORREF c); + void setEdgeColor(COLORREF c); + void setHotEdgeColor(COLORREF c); + void setDisabledEdgeColor(COLORREF c); + + Colors getDarkModeDefaultColors(); + void changeCustomTheme(const Colors& colors); + + // handle events + void handleSettingChange(HWND hwnd, LPARAM lParam); + + // processes messages related to UAH / custom menubar drawing. + // return true if handled, false to continue with normal processing in your wndproc + bool runUAHWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* lr); + void drawUAHMenuNCBottomLine(HWND hWnd); + + // from DarkMode.h + void initExperimentalDarkMode(); + void setDarkMode(bool useDark, bool fixDarkScrollbar); + void allowDarkModeForApp(bool allow); + bool allowDarkModeForWindow(HWND hWnd, bool allow); + void setTitleBarThemeColor(HWND hWnd); + + // enhancements to DarkMode.h + void enableDarkScrollBarForWindowAndChildren(HWND hwnd); + + inline void paintRoundFrameRect(HDC hdc, const RECT rect, const HPEN hpen, int width = 0, int height = 0); + + void subclassButtonControl(HWND hwnd); + void subclassGroupboxControl(HWND hwnd); + void subclassTabControl(HWND hwnd); + void subclassComboBoxControl(HWND hwnd); + + void subclassAndThemeButton(HWND hwnd, NppDarkModeParams p); + void subclassAndThemeComboBox(HWND hwnd, NppDarkModeParams p); + void subclassAndThemeListBoxOrEditControl(HWND hwnd, NppDarkModeParams p, bool isListBox); + void subclassAndThemeListView(HWND hwnd, NppDarkModeParams p); + void themeTreeView(HWND hwnd, NppDarkModeParams p); + void themeToolbar(HWND hwnd, NppDarkModeParams p); + void themeRichEdit(HWND hwnd, NppDarkModeParams p); + + void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass = true, bool theme = true); + void autoThemeChildControls(HWND hwndParent); + + LRESULT darkToolBarNotifyCustomDraw(LPARAM lParam); + LRESULT darkListViewNotifyCustomDraw(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool isPlugin); + LRESULT darkTreeViewNotifyCustomDraw(LPARAM lParam); + + void autoSubclassAndThemePluginDockWindow(HWND hwnd); + void autoSubclassAndThemeWindowNotify(HWND hwnd); + + bool subclassTabUpDownControl(HWND hwnd); + + void setDarkTitleBar(HWND hwnd); + void setDarkExplorerTheme(HWND hwnd); + void setDarkScrollBar(HWND hwnd); + void setDarkTooltips(HWND hwnd, ToolTipsType type); + void setDarkLineAbovePanelToolbar(HWND hwnd); + void setDarkListView(HWND hwnd); + + void disableVisualStyle(HWND hwnd, bool doDisable); + void calculateTreeViewStyle(); + void setTreeViewStyle(HWND hwnd); + void setBorder(HWND hwnd, bool border = true); + + BOOL CALLBACK enumAutocompleteProc(HWND hwnd, LPARAM lParam); + void setDarkAutoCompletion(); + + LRESULT onCtlColor(HDC hdc); + LRESULT onCtlColorSofter(HDC hdc); + LRESULT onCtlColorDarker(HDC hdc); + LRESULT onCtlColorError(HDC hdc); + LRESULT onCtlColorDarkerBGStaticText(HDC hdc, bool isTextEnabled); + INT_PTR onCtlColorListbox(WPARAM wParam, LPARAM lParam); +} diff --git a/include/TaskListDlg.h b/include/TaskListDlg.h index dca4289..f592367 100644 --- a/include/TaskListDlg.h +++ b/include/TaskListDlg.h @@ -74,15 +74,7 @@ public : return; //clear list LB_RESETCONTENT ::SendMessage( _hList, LB_RESETCONTENT, NULL, NULL ); - if ( !todoItems.empty() ) - { - // "if" branch replaces previous todoItems.clear(); to address the following issue: - // https://community.notepad-plus-plus.org/topic/23236/npp-task-list-plugin-window-overwrites/5 - todoItems.clear(); - todoItemsFingerprint = ""; - findTasks(); - return; - } + todoItems.clear(); //add list items LB_ADDSTRING diff --git a/src/NppDarkModeDummy.cpp b/src/NppDarkModeDummy.cpp new file mode 100644 index 0000000..62d2d87 --- /dev/null +++ b/src/NppDarkModeDummy.cpp @@ -0,0 +1,31 @@ +#include "NppDarkMode.h" +#include "PluginInterface.h" + +extern NppData nppData; + +namespace NppDarkMode +{ + bool isEnabled() + { + return ::SendMessage(nppData._nppHandle, NPPM_ISDARKMODEENABLED, 0, 0); + } + + HBRUSH getDarkerBackgroundBrush() + { + return ::CreateSolidBrush(HEXRGB(0x202020)); + } + + COLORREF getDarkerTextColor() + { + return HEXRGB(0xC0C0C0); + } + + COLORREF getLinkTextColor() + { + return HEXRGB(0xFFFF00); + } + + void setDarkTitleBar(HWND /*hwnd*/) + { + } +} diff --git a/src/StaticDialog.cpp b/src/StaticDialog.cpp index 3270c39..367776a 100644 --- a/src/StaticDialog.cpp +++ b/src/StaticDialog.cpp @@ -18,6 +18,7 @@ #include #include "StaticDialog.h" #include "Common.h" +#include "NppDarkMode.h" StaticDialog::~StaticDialog() { @@ -227,6 +228,8 @@ void StaticDialog::create(int dialogID, bool isRTL, bool msgDestParent) return; } + NppDarkMode::setDarkTitleBar(_hSelf); + // if the destination of message NPPM_MODELESSDIALOG is not its parent, then it's the grand-parent ::SendMessage(msgDestParent ? _hParent : (::GetParent(_hParent)), NPPM_MODELESSDIALOG, MODELESSDIALOGADD, reinterpret_cast(_hSelf)); } @@ -237,6 +240,8 @@ intptr_t CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, { case WM_INITDIALOG: { + NppDarkMode::setDarkTitleBar(hwnd); + StaticDialog *pStaticDlg = reinterpret_cast(lParam); pStaticDlg->_hSelf = hwnd; ::SetWindowLongPtr(hwnd, GWLP_USERDATA, static_cast(lParam));