Community
    • Login

    Darkmode doesn't stylize all plugin controls on docked window (groupbox, panel, labels etc)

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    14 Posts 4 Posters 1.1k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Bas de ReuverB
      Bas de Reuver
      last edited by

      @Alan-Kilborn Okay I’ve submitted them as two separate issues here 13572 and 13574

      Alan KilbornA 1 Reply Last reply Reply Quote 2
      • Alan KilbornA
        Alan Kilborn @Bas de Reuver
        last edited by

        @Bas-de-Reuver

        I tried my own quick test using the N++ plugin demo, found HERE.

        I created a groupbox and an edit control on the docking dialog. I ran it and both were “dark” in dark mode (so good so far). Then in the code, I changed the parent of the edit control to be the groupbox. Rerunning that, the edit control ended up not being “dark”.

        So, not much new to add, but basically I can confirm/duplicate your results…

        1 Reply Last reply Reply Quote 2
        • Mark OlsonM
          Mark Olson
          last edited by Mark Olson

          FWIW, I worked on recursively applying dark mode styling to all my forms in JsonTools a while back, just using C# code in the tree view controls.

          I was able to do it, but I came to the conclusion that while docking forms like my JSON tree and the CSV Lint window look much better when they have the same styling as the editor window, non-docking forms like the find/replace form don’t necessarily look better.

          So I’d cast a weak tentative vote in favor of allowing people to opt out of this, although I recognize that adding yet another knob that people can turn has downsides.

          Alan KilbornA 1 Reply Last reply Reply Quote 1
          • Alan KilbornA
            Alan Kilborn @Mark Olson
            last edited by

            @Mark-Olson said in Darkmode doesn’t stylize all plugin controls on docked window (groupbox, panel, labels etc):

            …don’t necessarily look better

            Do you have a specific example you can show?

            Mark OlsonM 1 Reply Last reply Reply Quote 0
            • Mark OlsonM
              Mark Olson @Alan Kilborn
              last edited by

              @Alan-Kilborn
              No, I never took pictures and I reverted the code to get rid of the recursive application of Notepad++ theme to anything other than my tree viewer. I just decided in my purely subjective opinion that while the tree view looked better sharing the NPP theme, the non-docking forms didn’t.

              Admittedly the not-so-great result might have been mainly due to my hand-coded attempt to make the controls look similar to Notepad++, and this proposal might look better. I won’t stand in the way of progress.

              Bas de ReuverB 1 Reply Last reply Reply Quote 0
              • Bas de ReuverB
                Bas de Reuver @Mark Olson
                last edited by

                @Mark-Olson I wouldn’t want to bother the user with unnecessary extra options for something like this, imho it should either be all in lightmode or all in darkmode. Wether it looks better or not is subjective and up to the enduser.

                As far as I’m concerned it’s just a matter of consistency. So making the plug-in look seemlessly integrated with Notepad++. As it is now, when a user is working with Notepad++ in darkmode, the sudden lightmode dialogs from the plug-in just look out of place.

                Alan KilbornA 1 Reply Last reply Reply Quote 1
                • Alan KilbornA
                  Alan Kilborn @Bas de Reuver
                  last edited by Alan Kilborn

                  @Bas-de-Reuver said in Darkmode doesn’t stylize all plugin controls on docked window (groupbox, panel, labels etc):

                  … it should either be all in lightmode or all in darkmode…As far as I’m concerned it’s just a matter of consistency.

                  I agree.

                  Even for my simple test:

                  …I changed the parent of the edit control to be the groupbox. Rerunning that, the edit control ended up not being “dark”.

                  It was ridiculous to see the white edit box on the otherwise dark dialog.

                  1 Reply Last reply Reply Quote 0
                  • rdipardoR
                    rdipardo @Bas de Reuver
                    last edited by

                    This will probably have to be implemented on the plugin’s end. The minimum required infrastructure would be, roughly:

                    • definitions for the Npp API messages added in v8.4.1, i.e.:

                       NPPM_ISDARKMODEENABLED
                       NPPM_GETDARKMODECOLORS
                       NPPN_DARKMODECHANGED
                      
                    • a type equivalent to the NppDarkMode::Colors structure, for collecting the active palette of dark mode styles

                    • a method implementing the NPPM_GETDARKMODECOLORS API, taking a pointer to the ersatz NppDarkMode::Colors struct and filling each member with the corresponding color for the active theme (black, cyan, olive, etc.)

                    • a callback inside beNotified that hooks NPPN_DARKMODECHANGED, where the plugin calls the NPPM_GETDARKMODECOLORS method, iterates the form’s components, and changes their color to whatever the NppDarkMode::Colors instance was initialized with

                    Of course none of these features are provided by the still-popular .NET plugin template, and most likely never will be, until somebody with lots of spare time makes an updated fork.

                    Some components (e.g. scroll bars) may not be customizable without hacking into the WM_NCPAINT message or, in the case of buttons, using style flags like BS_OWNERDRAW. All of which is at least possible in C#, if you don’t mind getting your hands dirty.

                    1 Reply Last reply Reply Quote 5
                    • rdipardoR
                      rdipardo
                      last edited by rdipardo

                      This will probably have to be implemented on the plugin’s end.

                      From what @ozone10 says here and here, looks like I was on the right track.

                      @Bas-de-Reuver, here’s a quick patch you can build your own proof-of-concept from. It doesn’t touch the form components, but it’s just a matter of exposing the controls and setting the colors however you want.

                      The NPPN_DARKMODECHANGED hook I added to Main.OnNotification is where you collect the currently active dark mode colors. Notice how the RGB values change when switching tones to red, blue, cyan, etc.

                      csvlint-nppn_darkmodechanged-hook


                      WIP: Integrate Npp’s dark mode API
                      diff --git a/CSVLintNppPlugin/CsvLintNppPlugin.csproj b/CSVLintNppPlugin/CsvLintNppPlugin.csproj
                      index 2a169a6..f81bebc 100644
                      --- a/CSVLintNppPlugin/CsvLintNppPlugin.csproj
                      +++ b/CSVLintNppPlugin/CsvLintNppPlugin.csproj
                      @@ -139,6 +139,7 @@
                           <Compile Include="PluginInfrastructure\ScintillaStreams.cs" />
                           <Compile Include="PluginInfrastructure\Win32.cs" />
                           <Compile Include="Main.cs" />
                      +    <Compile Include="PluginInfrastructure\DarkMode.cs" />    
                           <Compile Include="PluginInfrastructure\GatewayDomain.cs" />
                           <Compile Include="PluginInfrastructure\NotepadPPGateway.cs" />
                           <Compile Include="PluginInfrastructure\ScintillaGateway.cs" />
                      diff --git a/CSVLintNppPlugin/Main.cs b/CSVLintNppPlugin/Main.cs
                      index 9f97846..1efd612 100644
                      --- a/CSVLintNppPlugin/Main.cs
                      +++ b/CSVLintNppPlugin/Main.cs
                      @@ -124,6 +124,31 @@ public static void OnNotification(ScNotification notification)
                                       Main.RemoveCSVdef(notification.Header.IdFrom);
                                   }
                       
                      +            // dark mode (de-)activated
                      +            if (code == (uint)NppMsg.NPPN_DARKMODECHANGED)
                      +            {
                      +                NotepadPPGateway notepad = new NotepadPPGateway();
                      +                if (notepad.IsDarkModeEnabled())
                      +                {
                      +                    IntPtr theme_ptr = notepad.GetDarkModeColors();
                      +                    if (theme_ptr != IntPtr.Zero)
                      +                    {
                      +                        DarkModeColors theme = (DarkModeColors)Marshal.PtrToStructure(theme_ptr, typeof(DarkModeColors));
                      +                        // TODO: set component colors to `theme.Background`, `theme.SofterBackground`, etc.
                      +#if DEBUG
                      +                        // show the active palette's RBG values
                      +                        var msg = new StringBuilder();
                      +                        foreach (var style in typeof(DarkModeColors).GetFields(BindingFlags.Instance |BindingFlags.Public))
                      +                        {
                      +                            msg.AppendLine($"{style.Name}: 0x{style.GetValue(theme):X6}");
                      +                        }
                      +                        System.Windows.Forms.MessageBox.Show($"{msg}");
                      +#endif
                      +                    }
                      +                    Marshal.FreeHGlobal(theme_ptr);
                      +                }
                      +            }
                      +
                                   if (code > int.MaxValue) // windows messages
                                   {
                                       int wm = -(int)code;
                      diff --git a/CSVLintNppPlugin/PluginInfrastructure/DarkMode.cs b/CSVLintNppPlugin/PluginInfrastructure/DarkMode.cs
                      new file mode 100644
                      index 0000000..70e54d3
                      --- /dev/null
                      +++ b/CSVLintNppPlugin/PluginInfrastructure/DarkMode.cs
                      @@ -0,0 +1,46 @@
                      +// Types, methods for interacing with Npp's dark mode API
                      +using System;
                      +using System.Runtime.InteropServices;
                      +
                      +namespace Kbg.NppPluginNET.PluginInfrastructure
                      +{
                      +    /// <see href "https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/NppDarkMode.h"/>
                      +    [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;
                      +    }
                      +
                      +    /// <summary>
                      +    /// Implements dark mode APIs for plugins.
                      +    /// </summary>
                      +    public partial class NotepadPPGateway : INotepadPPGateway
                      +    {
                      +        /// Returns a pointer so that callees can deallocate it.
                      +        public IntPtr GetDarkModeColors()
                      +       {
                      +            DarkModeColors darkModeColors = new DarkModeColors();
                      +            IntPtr _size = new IntPtr(Marshal.SizeOf(darkModeColors));
                      +            IntPtr _ptrDarkModeColors = Marshal.AllocHGlobal(_size);
                      +           Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_GETDARKMODECOLORS, _size, _ptrDarkModeColors);
                      +            return _ptrDarkModeColors;
                      +        }
                      +
                      +        public bool IsDarkModeEnabled()
                      +        {
                      +            IntPtr result = Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_ISDARKMODEENABLED, Unused, Unused);
                      +            return ((int)result == 1);
                      +       }
                      +    }
                      +}
                      diff --git a/CSVLintNppPlugin/PluginInfrastructure/Msgs_h.cs b/CSVLintNppPlugin/PluginInfrastructure/Msgs_h.cs
                      index 3319ce2..4363fa1 100644
                      --- a/CSVLintNppPlugin/PluginInfrastructure/Msgs_h.cs
                      +++ b/CSVLintNppPlugin/PluginInfrastructure/Msgs_h.cs
                      @@ -565,6 +565,45 @@ public enum NppMsg : uint
                               /// </summary>
                               NPPM_ADDTOOLBARICON_FORDARKMODE = Constants.NPPMSG + 101,
                       
                      +        /// <summary>
                      +        /// bool NPPM_ISDARKMODEENABLED(0, 0)
                      +        /// Returns true when Notepad++ Dark Mode is enable, false when it is not.
                      +        /// <see href="https://github.com/notepad-plus-plus/notepad-plus-plus/commit/1eb5b10e41d7ab92b60aa32b28d4fe7739d15b53"/>
                      +        /// </summary>
                      +        NPPM_ISDARKMODEENABLED = (Constants.NPPMSG + 107),
                      +
                      +        /// <summary>
                      +        /// 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.
                      +        /// You need to uncomment the following code to use NppDarkMode::Colors structure:
                      +        /// <code>
                      +        /// 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;
                      +        ///  };
                      +        /// }
                      +        /// </code>
                      +        /// Note: in the case of calling failure ("false" is returned), you may need to change NppDarkMode::Colors structure to:
                      +        /// https:///github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/NppDarkMode.h#L32
                      +        /// <see href="https://github.com/notepad-plus-plus/notepad-plus-plus/commit/1eb5b10e41d7ab92b60aa32b28d4fe7739d15b53"/>
                      +        /// </summary>
                      +        NPPM_GETDARKMODECOLORS = (Constants.NPPMSG + 108),
                      +
                               RUNCOMMAND_USER = Constants.WM_USER + 3000,
                               NPPM_GETFULLCURRENTPATH = RUNCOMMAND_USER + FULL_CURRENT_PATH,
                               NPPM_GETCURRENTDIRECTORY = RUNCOMMAND_USER + CURRENT_DIRECTORY,
                      @@ -810,6 +849,14 @@ public enum NppMsg : uint
                               /// </summary>
                               NPPN_FILEDELETED = NPPN_FIRST + 26,
                       
                      +        /// <summary>
                      +        /// To notify plugins that Dark Mode was enabled/disabled
                      +        /// scnNotification->nmhdr.code = NPPN_DARKMODECHANGED;
                      +        /// scnNotification->nmhdr.hwndFrom = hwndNpp;
                      +        /// scnNotification->nmhdr.idFrom = 0;
                      +        /// </summary>
                      +        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/CSVLintNppPlugin/PluginInfrastructure/NotepadPPGateway.cs b/CSVLintNppPlugin/PluginInfrastructure/NotepadPPGateway.cs
                      index 7b599a0..d3e0467 100644
                      --- a/CSVLintNppPlugin/PluginInfrastructure/NotepadPPGateway.cs
                      +++ b/CSVLintNppPlugin/PluginInfrastructure/NotepadPPGateway.cs
                      @@ -18,7 +18,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.
                       	/// </summary>
                      -	public class NotepadPPGateway : INotepadPPGateway
                      +	public partial class NotepadPPGateway : INotepadPPGateway
                       	{
                       		private const int Unused = 0;
                       
                      
                      rdipardoR 1 Reply Last reply Reply Quote 4
                      • rdipardoR
                        rdipardo @rdipardo
                        last edited by

                        Submitted my implementation upstream, with a real usage example: https://github.com/kbilsted/NotepadPlusPlusPluginPack.Net/pull/104

                        Mark OlsonM 1 Reply Last reply Reply Quote 4
                        • Mark OlsonM
                          Mark Olson @rdipardo
                          last edited by

                          @rdipardo
                          Cool! I’m going to run with your example and see about writing something that just automatically applies good dark mode styling to all the controls in any arbitrary WinForm rather than having to specify which controls get which colors.

                          1 Reply Last reply Reply Quote 3
                          • First post
                            Last post
                          The Community of users of the Notepad++ text editor.
                          Powered by NodeBB | Contributors