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 Bas de Reuver

      Btw also, it would be nice to be able to somehow call the autoSubclassAndThemeChildControls from within the plugin, is that possible at the moment? I couldn’t find any API calls. That way the plugin can use the default Notepad++ functions to apply darkmode colors to all its dialogs.

      Currently most plugins display any dialogs in normal/lightmode colors even when Notepad++ is set to darkmode. I know there is DWS_USEOWNDARKMODE but for simple Settings/About forms when there are no special controls or anything, it would imho be better to just let Notepad++ uniformly change these to darkmode. See an example plug-in dialog and a mockup dialog below.

      csvquery_example_dialog.png

      notepad_plugin_darkmode.png

      1 Reply Last reply Reply Quote 2
      • 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):

        Is it possible to have Notepad++ apply darkmode colors also to labels and the container controls with its childcontrols?

        I think it would be very reasonable for you to open an official issue on github concerning this. See HERE.

        If you do that, you will likely have very much luck if you put @ozone10 in your issue text so that he for sure doesn’t miss your issue. He is the one that added dark mode support to N++ and would be very interested in – and probably quick to action on – such an issue (IMO).

        1 Reply Last reply Reply Quote 3
        • 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