Skip to content

Commit

Permalink
Use Mica for prettier dark theme
Browse files Browse the repository at this point in the history
  • Loading branch information
t1m0thyj committed Jan 16, 2023
1 parent 8b370f4 commit a88d156
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 183 deletions.
2 changes: 1 addition & 1 deletion src/AboutDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public partial class AboutDialog : Form
public AboutDialog()
{
InitializeComponent();
DarkUI.ThemeForm(this);
AcrylicUI.ThemeForm(this);
Localization.TranslateForm(this);
}

Expand Down
85 changes: 85 additions & 0 deletions src/AcrylicUI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

using Dark.Net;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WinDynamicDesktop
{
internal class AcrylicUI
{
public static bool IsDark
{
get { return IsSupported && DarkNet.Instance.UserDefaultAppThemeIsDark; }
}

public static void ThemeForm(Form form, bool onInit = true)
{
if (!IsSupported)
{
return;
}

COM.WinBlur.BlurType blurType = IsDark ? COM.WinBlur.BlurType.Mica : COM.WinBlur.BlurType.None;
COM.WinBlur.SetBlurStyle(form, blurType, COM.WinBlur.Mode.DarkMode);
form.ForeColor = IsDark ? Color.White : Control.DefaultForeColor;

foreach (Control childControl in GetControls(form))
{
COM.WinBlur.SetBlurStyle(childControl, blurType, COM.WinBlur.Mode.DarkMode);
childControl.ForeColor = IsDark ? Color.White : Control.DefaultForeColor;

if (childControl is LinkLabel)
{
((LinkLabel)childControl).LinkColor = IsDark ? Color.LightBlue : Color.Blue;
}

if (onInit)
{
childControl.Paint += (object sender, PaintEventArgs e) =>
{
if (!childControl.Enabled)
{
TextRenderer.DrawText(e.Graphics, childControl.Text, childControl.Font,
childControl.ClientRectangle, Color.Gray);
}
};
}
}
}

public static void UserDefaultAppThemeIsDarkChanged(object sender, bool isDark)
{
AppContext.notifyIcon.ContextMenuStrip.BeginInvoke(() =>
{
foreach (Form form in Application.OpenForms)
{
ThemeForm(form, false);
}
});
}

// Code from https://stackoverflow.com/a/664083/5504760
internal static IEnumerable<Control> GetControls(Control form)
{
foreach (Control childControl in form.Controls)
{
foreach (Control grandChild in GetControls(childControl))
{
yield return grandChild;
}

yield return childControl;
}
}

private static bool IsSupported
{
get { return Environment.OSVersion.Version.Major >= 10 && Environment.OSVersion.Version.Build >= 22000; }
}
}
}
2 changes: 1 addition & 1 deletion src/AppContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private void HandleMultiInstance()
private void InitializeTrayIcon()
{
Application.ApplicationExit += OnApplicationExit;
Dark.Net.DarkNet.Instance.UserDefaultAppThemeIsDarkChanged += DarkUI.UserDefaultAppThemeIsDarkChanged;
Dark.Net.DarkNet.Instance.UserDefaultAppThemeIsDarkChanged += AcrylicUI.UserDefaultAppThemeIsDarkChanged;

notifyIcon = new NotifyIcon
{
Expand Down
108 changes: 108 additions & 0 deletions src/COM/WinBlur.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WinDynamicDesktop.COM
{
// https://github.com/Pronner/WinBlur/blob/70384557eab3fb00a83360de24a18a620f086cfa/src/WinBlur/PInvoke.cs
public class WinBlur
{
public class ParameterTypes
{
[Flags]
public enum DWMWINDOWATTRIBUTE
{
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
DWMWA_SYSTEMBACKDROP_TYPE = 38
}

public struct MARGINS
{
public int cxLeftWidth;

public int cxRightWidth;

public int cyTopHeight;

public int cyBottomHeight;
}
}

public class Methods
{
[DllImport("DwmApi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref ParameterTypes.MARGINS pMarInset);

[DllImport("dwmapi.dll")]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIBUTE dwAttribute, ref int pvAttribute, int cbAttribute);

public static int ExtendFrame(IntPtr hwnd, ParameterTypes.MARGINS margins)
{
return DwmExtendFrameIntoClientArea(hwnd, ref margins);
}

public static int SetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIBUTE attribute, int parameter)
{
return DwmSetWindowAttribute(hwnd, attribute, ref parameter, Marshal.SizeOf<int>());
}
}

public static void SetBlurStyle(Control cntrl, BlurType blurType, Mode designMode)
{
ParameterTypes.MARGINS bounds = default(ParameterTypes.MARGINS);
IntPtr hwnd = cntrl.Handle;
bounds.cxLeftWidth = 0;
bounds.cxRightWidth = 0;
checked
{
bounds.cyTopHeight = cntrl.Height + 10000000;
bounds.cyBottomHeight = 0;
int result = Methods.DwmExtendFrameIntoClientArea(hwnd, ref bounds);
cntrl.BackColor = blurType != BlurType.None ? System.Drawing.Color.Black : Control.DefaultBackColor;
}

if (blurType == BlurType.None)
{
Methods.SetWindowAttribute(cntrl.Handle, ParameterTypes.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 1);
}
if (blurType == BlurType.Mica)
{
Methods.SetWindowAttribute(cntrl.Handle, ParameterTypes.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 2);
}
if (blurType == BlurType.Acrylic)
{
Methods.SetWindowAttribute(cntrl.Handle, ParameterTypes.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3);
}
if (blurType == BlurType.Tabbed)
{
Methods.SetWindowAttribute(cntrl.Handle, ParameterTypes.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 4);
}
if (designMode == Mode.LightMode)
{
Methods.SetWindowAttribute(cntrl.Handle, ParameterTypes.DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0);
}
if (designMode == Mode.DarkMode)
{
Methods.SetWindowAttribute(cntrl.Handle, ParameterTypes.DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1);
}
}

public enum BlurType
{
None,
Acrylic,
Mica,
Tabbed
}

public enum Mode
{
LightMode,
DarkMode
}
}
}
172 changes: 0 additions & 172 deletions src/DarkUI.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/DownloadDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public partial class DownloadDialog : Form
public DownloadDialog()
{
InitializeComponent();
DarkUI.ThemeForm(this);
AcrylicUI.ThemeForm(this);
Localization.TranslateForm(this);

this.FormClosing += OnFormClosing;
Expand Down
Loading

0 comments on commit a88d156

Please sign in to comment.