From 9a638ea47abee22578b29b7a099fbeeb456c9f41 Mon Sep 17 00:00:00 2001 From: Robert Di Pardo <59004801+rdipardo@users.noreply.github.com> Date: Tue, 25 Apr 2023 23:40:34 -0400 Subject: [PATCH 1/3] Integrate Npp's dark mode APIs Exposes the APIs available since Npp v8.4.1 This lets plugins customize WinForm controls that can't be reached by Npp's native dark mode theming --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 34 +++++++++++ .../Forms/frmGoToLine.designer.cs | 4 +- .../NppManagedPluginDemo.csproj | 3 + .../$projectname$.csproj | 1 + .../PluginInfrastructure/DarkMode.cs | 56 +++++++++++++++++++ .../PluginInfrastructure/Docking_h.cs | 1 + .../PluginInfrastructure/Msgs_h.cs | 23 ++++++++ .../PluginInfrastructure/NotepadPPGateway.cs | 4 +- 8 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 96bae70..596af0b 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -40,6 +40,13 @@ public static void OnNotification(ScNotification notification) { Kbg.Demo.Namespace.Main.doInsertHtmlCloseTag((char)notification.Character); } + + // dark mode (de-)activated + if (notification.Header.Code == (uint)NppMsg.NPPN_DARKMODECHANGED) + { + INotepadPPGateway notepad = new NotepadPPGateway(); + Kbg.Demo.Namespace.Main.ToggleDarkMode(notepad.IsDarkModeEnabled()); + } } internal static string PluginName { get { return Kbg.Demo.Namespace.Main.PluginName; }} @@ -177,6 +184,32 @@ static internal void PluginCleanUp() { Win32.WritePrivateProfileString(sectionName, keyName, doCloseTag ? "1" : "0", iniFilePath); } + + static internal void ToggleDarkMode(bool isDark) + { + if (frmGoToLine != null) + { + if (isDark) + { + IntPtr theme_ptr = notepad.GetDarkModeColors(); + if (theme_ptr != IntPtr.Zero) + { + var theme = (DarkModeColors)Marshal.PtrToStructure(theme_ptr, typeof(DarkModeColors)); + frmGoToLine.label1.BackColor = NppDarkMode.BGRToColor(theme.PureBackground); + frmGoToLine.label1.ForeColor = NppDarkMode.BGRToColor(theme.Text); + frmGoToLine.button1.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); + frmGoToLine.button1.ForeColor = NppDarkMode.BGRToColor(theme.Text); + } + } + else + { + frmGoToLine.label1.BackColor = Label.DefaultBackColor; + frmGoToLine.label1.ForeColor = Label.DefaultForeColor; + frmGoToLine.button1.BackColor = Color.FromKnownColor(KnownColor.ButtonFace); + frmGoToLine.button1.ForeColor = Button.DefaultForeColor; + } + } + } #endregion #region " Menu functions " @@ -441,6 +474,7 @@ static void DockableDlgDemo() Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[idFrmGotToLine]._cmdID, 0); } } + ToggleDarkMode(notepad.IsDarkModeEnabled()); frmGoToLine.textBox1.Focus(); } #endregion diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs index 0caa768..f6fa606 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs +++ b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs @@ -84,8 +84,8 @@ private void InitializeComponent() #endregion - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Button button1; + internal System.Windows.Forms.Label label1; + internal System.Windows.Forms.Button button1; internal System.Windows.Forms.TextBox textBox1; diff --git a/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj b/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj index f71a267..a7d5500 100644 --- a/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj +++ b/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj @@ -72,6 +72,9 @@ PluginInfrastructure\ClikeStringArray.cs + + PluginInfrastructure\DarkMode.cs + PluginInfrastructure\NotepadPPGateway.cs diff --git a/Visual Studio Project Template C#/$projectname$.csproj b/Visual Studio Project Template C#/$projectname$.csproj index 974ba5c..bd69539 100644 --- a/Visual Studio Project Template C#/$projectname$.csproj +++ b/Visual Studio Project Template C#/$projectname$.csproj @@ -74,6 +74,7 @@ + diff --git a/Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs b/Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs new file mode 100644 index 0000000..874c893 --- /dev/null +++ b/Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs @@ -0,0 +1,56 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace Kbg.NppPluginNET.PluginInfrastructure +{ + /// + /// Holds the BGR values of the active dark mode theme. + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct DarkModeColors + { + public int Background; + public int SofterBackground; + public int HotBackground; + public int PureBackground; + public int ErrorBackground; + public int Text; + public int DarkerText; + public int DisabledText; + public int LinkText; + public int Edge; + public int HotEdge; + public int DisabledEdge; + } + + /// + /// Extends with methods implementing Npp's dark mode API. + /// + public partial class NotepadPPGateway : INotepadPPGateway + { + public IntPtr GetDarkModeColors() + { + DarkModeColors darkModeColors = new DarkModeColors(); + IntPtr _cbSize = new IntPtr(Marshal.SizeOf(darkModeColors)); + IntPtr _ptrDarkModeColors = Marshal.AllocHGlobal(_cbSize); + Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_GETDARKMODECOLORS, _cbSize, _ptrDarkModeColors); + return _ptrDarkModeColors; + } + + public bool IsDarkModeEnabled() + { + IntPtr result = Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_ISDARKMODEENABLED, Unused, Unused); + return ((int)result == 1); + } + } + + static class NppDarkMode + { + public static Color BGRToColor(int bgr) + { + return Color.FromArgb((bgr & 0xFF), ((bgr >> 8) & 0xFF), ((bgr >> 16) & 0xFF)); + } + } +} diff --git a/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs b/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs index bb256da..1f11089 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs @@ -29,6 +29,7 @@ public enum NppTbMsg : uint DWS_ICONTAB = 0x00000001, // Icon for tabs are available DWS_ICONBAR = 0x00000002, // Icon for icon bar are available (currently not supported) DWS_ADDINFO = 0x00000004, // Additional information are in use + DWS_USEOWNDARKMODE = 0x00000008, // Use plugin's own dark mode DWS_PARAMSALL = (DWS_ICONTAB | DWS_ICONBAR | DWS_ADDINFO), // default docking values for first call of plugin diff --git a/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs b/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs index 214a73c..241ef45 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs @@ -560,6 +560,21 @@ public enum NppMsg : uint /// NPPM_ADDTOOLBARICON_FORDARKMODE = Constants.NPPMSG + 101, + /// + /// bool NPPM_ISDARKMODEENABLED(0, 0) + /// Returns true when Notepad++ Dark Mode is enabled, false when it is not. + /// + /// + NPPM_ISDARKMODEENABLED = (Constants.NPPMSG + 107), + + /// + /// bool NPPM_GETDARKMODECOLORS (size_t cbSize, NppDarkMode::Colors* returnColors) + /// - cbSize must be filled with sizeof(NppDarkMode::Colors). + /// - returnColors must be a pre-allocated NppDarkMode::Colors struct. + /// Returns true when successful, false otherwise. + /// + NPPM_GETDARKMODECOLORS = (Constants.NPPMSG + 108), + RUNCOMMAND_USER = Constants.WM_USER + 3000, NPPM_GETFULLCURRENTPATH = RUNCOMMAND_USER + FULL_CURRENT_PATH, NPPM_GETCURRENTDIRECTORY = RUNCOMMAND_USER + CURRENT_DIRECTORY, @@ -805,6 +820,14 @@ public enum NppMsg : uint /// NPPN_FILEDELETED = NPPN_FIRST + 26, + /// + /// To notify plugins that Dark Mode was enabled/disabled + /// scnNotification->nmhdr.code = NPPN_DARKMODECHANGED; + /// scnNotification->nmhdr.hwndFrom = hwndNpp; + /// scnNotification->nmhdr.idFrom = 0; + /// + NPPN_DARKMODECHANGED = (NPPN_FIRST + 27) + /* --Autogenerated -- end of section automatically generated from notepad-plus-plus\PowerEditor\src\MISC\PluginsManager\Notepad_plus_msgs.h * */ } } diff --git a/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs b/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs index ff11162..eb0ced6 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs @@ -13,6 +13,8 @@ public interface INotepadPPGateway void AddToolbarIcon(int funcItemsIndex, toolbarIcons icon); void AddToolbarIcon(int funcItemsIndex, Bitmap icon); + bool IsDarkModeEnabled(); + IntPtr GetDarkModeColors(); string GetNppPath(); string GetPluginConfigPath(); string GetCurrentFilePath(); @@ -25,7 +27,7 @@ public interface INotepadPPGateway /// This class holds helpers for sending messages defined in the Msgs_h.cs file. It is at the moment /// incomplete. Please help fill in the blanks. /// - public class NotepadPPGateway : INotepadPPGateway + public partial class NotepadPPGateway : INotepadPPGateway { private const int Unused = 0; From 9954abdd52837dcdfa93820a4b9630a1bc5eef9e Mon Sep 17 00:00:00 2001 From: Robert Di Pardo <59004801+rdipardo@users.noreply.github.com> Date: Wed, 26 Apr 2023 00:43:11 -0400 Subject: [PATCH 2/3] Remember to deallocate pointer --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 596af0b..0594516 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -199,6 +199,7 @@ static internal void ToggleDarkMode(bool isDark) frmGoToLine.label1.ForeColor = NppDarkMode.BGRToColor(theme.Text); frmGoToLine.button1.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); frmGoToLine.button1.ForeColor = NppDarkMode.BGRToColor(theme.Text); + Marshal.FreeHGlobal(theme_ptr); } } else From 8f3490b0c33648afcc43719dfd6ae671ab7dcf38 Mon Sep 17 00:00:00 2001 From: Robert Di Pardo <59004801+rdipardo@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:48:24 -0400 Subject: [PATCH 3/3] Simplify rollback to default control style --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 0594516..55fa551 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -204,10 +204,10 @@ static internal void ToggleDarkMode(bool isDark) } else { - frmGoToLine.label1.BackColor = Label.DefaultBackColor; - frmGoToLine.label1.ForeColor = Label.DefaultForeColor; - frmGoToLine.button1.BackColor = Color.FromKnownColor(KnownColor.ButtonFace); - frmGoToLine.button1.ForeColor = Button.DefaultForeColor; + frmGoToLine.label1.ResetBackColor(); + frmGoToLine.label1.ResetForeColor(); + frmGoToLine.button1.ResetBackColor(); + frmGoToLine.button1.ResetForeColor(); } } }