Jump to content

[Guide] Dark Theme support for custom EffectConfigDialog


Recommended Posts

Adding support for the Dark Theme is very easy, and only takes a few minutes.

 

The first step is to set the UseAppThemeColors property in your EffectConfigDialog to true.

This can be done using the Properties pane in Visual Studio:

UseThemeColors.png

 

This will automatically set the ForeColor and BackColor of your Form based on the active PDN theme, and most of the child controls will simply inherit those color values.

 

There are some special cases though.

 

For Buttons (ex: OK, Cancel), you'll want to set their FlatStyle property to FlatStyle.System.

FlatStyle.png

 

 

For TextBoxes and NumericUpDowns, you'll need to set the colors manually.

For example:

myTextBox.ForeColor = this.ForeColor;
myTextBox.BackColor = this.BackColor;

or if you have many in your form, you may want to use a foreach loop:

public MyConfigDialog()
{
    InitializeComponent();

    foreach (Control control in this.Controls)
    {
        if (control is TextBox || control is NumericUpDown)
        {
            control.ForeColor = this.ForeColor;
            control.BackColor = this.BackColor;
        }
    }
}

 

Edited by toe_head2001
typo
  • Like 1
  • Thanks 1
  • Upvote 1
Link to comment
Share on other sites

3 hours ago, toe_head2001 said:

For Buttons (ex: OK, Cancel), you'll want to set their FlatStyle property to System.

 

That is less work than resetting the button colors when using FlatStyle.Standard.

 

If your dialog uses a LinkLabel you can use the following code to change the link color.

if (control is LinkLabel link)
{
    if (this.ForeColor != Control.DefaultForeColor)
    {
        link.LinkColor = this.ForeColor;
    }
    else
    {
        // If the control is using the default foreground color set the link color
        // to Color.Empty so the LinkLabel will use its default colors.
        link.LinkColor = Color.Empty;
    }
}

 

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

  • toe_head2001 changed the title to [Guide] Dark Theme support for custom EffectConfigDialog
  • 4 months later...

If you have a few tabs on your Form:

InitializeComponent();

            UseAppThemeColors = true;

            TabControl.TabPageCollection pages = tabControl1.TabPages;
            foreach (TabPage page in pages)
            {
                if (page is TabPage)
                {
                    page.ForeColor = ForeColor;
                    page.BackColor = BackColor;
                }
            }

But TabpageHeader will not change its color.

 

 

 

Edited by NSD
typo
Link to comment
Share on other sites

  • 1 month later...

I don't know how to enable Dark Theme for labels.
I tried a lot of variants for Enabled / Disabled labels.
If the control whose name is a label is Enabled everything is OK, but if it is Disabled the text turns black and is not visible.
It's about a group of controls placed on a panel. In fact the panel is Enabled / Disabled.
What's the trick?

Link to comment
Share on other sites

50 minutes ago, toe_head2001 said:

The dark theme code in CodeLab is a bit overkill for general use.

 

On second thought, it looks fine.

https://github.com/BoltBait/CodeLab/blob/master/Theming.cs

 

Take a look at our ThemeRenderer class. It derives from ToolStripProfessionalRenderer, and mostly consists of a custom ProfessionalColorTable.

 

 

You'll also see our TabRenderer class in that file, but you can ignore it. We use that for the document tabs in CodeLab.

  • Upvote 1
Link to comment
Share on other sites

  • 3 weeks later...

If Dark theme is active then the focus cues of RadioButtons and CheckBoxes are Black in 4.2.15 (nearly invisible). IMHO is would be better to use the ForeColor.

ShowFocusCues is true if the keyboard is used to tab through the properties in the dialog.

 

            if (ShowFocusCues && Focused)
            {
                ControlPaint.DrawFocusRectangle(pevent.Graphics, textBounds, ForeColor, BackColor);
            }

 

BTW: Using the arrow keys in the RadioButtons to scroll through the buttons seems to focus nothing if you cross the bottom or top button. Pressing the arrow a second time then went from top to bottom (or vice versa).

Edited by midora

midoras signature.gif

Link to comment
Share on other sites

  • 3 months later...

Windows 10 allows to set the color of the active window title bar (AccentColor).

The issue is that in dark mode the inactive title bars are much to light.

 

To solve this you may add the AccentColorInactive key to the registry

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\DWM\

 

I'm using AccentColorInactive=0xff595448 (together with an pale dark blue accent color).

The value has to be provided in ABGR. So 0xffff0000 is blue.

No reboot is required. Just activate and deactivate your windows.

 

midoras signature.gif

Link to comment
Share on other sites

  • 4 weeks later...

Just a hint:

SetWindowTheme(xxx.Handle, "DarkMode_Explorer", null);

allows to switch on dark mode of forms and controls (i.e. buttons). Is also adapts scrollbars (i.e. of richtextbox or form).

You still have to set BackColor  and ForeColor.

 

image.png.8bc42c331516b1858a3173c54a1e5e0f.png

 

using System.Runtime.InteropServices;
[DllImport("uxtheme.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
public static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);

 

 

midoras signature.gif

Link to comment
Share on other sites

  • 2 months later...
  • 4 months later...
  • 4 months later...
6 hours ago, NinthDesertDude said:

I know it's possible to inherit values, but can you directly check if PDN is in dark or light mode?

 

Currently, the only way a plugin can detect whether PDN is int dark or light mode is to guess based on the RGB values of the background color.

CodeLab will use dark mode when the RGB values of the background color are less than 128, see https://github.com/BoltBait/CodeLab/blob/50e99f202cd2cecce3119b04c7a06f10855ad57c/Theming.cs#L184.

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

I'll look into adding something simple for 4.3.12. I've had enough pain trying to second guess things through the Win32 APIs, I understand how un-fun that can be.

 

Inside the app, it's more complicated than just asking Win32 for theming details though because the user can override the OS configured theme in the app Settings.

  • Like 2

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

  • 2 weeks later...

Alright I'm adding a PdnBaseForm.IsAppThemeDark property. You'll be able to use it in 4.3.12.

 

Also, in 4.3.11, title bars automatically use the "immersive dark theme" mode as long as you're on a supported version of Windows (10 v20H1+, or 11 of course)

  • Like 1
  • Upvote 1

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

  • 1 month later...

tl;dr I'm doing a bunch of things on my main plugin again, and I've themed everything except scrollbars and title bars. Winforms doesn't play well with those whatsoever. If anyone has themed versions of those for Winforms, I'd love to get a copy for Dynamic Draw -- I've looked into both and I know titlebar themeing is P/Invoke while scrollbars have to be fully rebuilt. Tips or pointers to anything simpler would be helpful. Thanks for reading

Edit: I should add that yes, I've definitely tried Midora's suggestions above. They were the first

Link to comment
Share on other sites

10 hours ago, NinthDesertDude said:

I've themed everything except scrollbars

 

CodeLab uses this code for dark scrollbars:

 

        [DllImport("uxtheme.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);

        /// <summary>
        /// Use to set dark scroll bars
        /// </summary>
        internal static void EnableUxThemeDarkMode(this Control control, bool enable)
        {
            if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17763)) // Win 10 1809
            {
                return;
            }

            string themeName = enable ? "DarkMode_Explorer" : null;
            SetWindowTheme(control.Handle, themeName, null);
        }

 

 

Just call the extension method on your control. For example:

 

myListBox.EnableUxThemeDarkMode(true); // enable dark scrollbar

myListBox.EnableUxThemeDarkMode(false); // disable dark scrollbar

 

  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...