Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions SteamShutdown/ColorUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Microsoft.Win32;
using System;
using System.Drawing;

namespace SteamShutdown
{
public static class ColorUtils
{
public static bool SystemUsesLightTheme()
{
int sult = (Int32)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", null);
return sult == 1;
}

public static Color GetAccentColor()
{
const String DWM_KEY = @"Software\Microsoft\Windows\DWM";
using (RegistryKey dwmKey = Registry.CurrentUser.OpenSubKey(DWM_KEY, RegistryKeyPermissionCheck.ReadSubTree))
{
const String KEY_EX_MSG = "The \"HKCU\\" + DWM_KEY + "\" registry key does not exist.";
if (dwmKey is null) throw new InvalidOperationException(KEY_EX_MSG);

Object accentColorObj = dwmKey.GetValue("AccentColor");
if (accentColorObj is Int32 accentColorDword)
{
return ParseDWordColor(accentColorDword);
}
else
{
const String VALUE_EX_MSG = "The \"HKCU\\" + DWM_KEY + "\\AccentColor\" registry key value could not be parsed as an ABGR color.";
throw new InvalidOperationException(VALUE_EX_MSG);
}
}
}

private static Color ParseDWordColor(Int32 color)
{
return Color.FromArgb((color >> 24) & 0xFF, (color >> 0) & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF);
}
}
}
6 changes: 5 additions & 1 deletion SteamShutdown/CustomApplicationContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using SteamShutdown.Actions;
using SteamShutdown.Actions;
using System;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -171,6 +171,10 @@ private void InitializeContext()
};
NotifyIcon.MouseUp += NotifyIcon_MouseUp;
NotifyIcon.ContextMenuStrip.Opening += ContextMenuStrip_Opening;
NotifyIcon.ContextMenuStrip.RenderMode = ToolStripRenderMode.Professional;
if(!ColorUtils.SystemUsesLightTheme())
NotifyIcon.ContextMenuStrip.Renderer = new DarkRenderer(ColorUtils.GetAccentColor());

NotifyIcon.ShowBalloonTip(2000, "Hello", "You find me in the taskbar.", ToolTipIcon.Info);
}

Expand Down
111 changes: 111 additions & 0 deletions SteamShutdown/DarkRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace SteamShutdown
{
internal class DarkColorTable : ProfessionalColorTable
{
private Color _backColor = Color.FromArgb(43, 43, 43),
_itemSelectedColor = Color.FromArgb(65, 65, 65),
_borderColor = Color.FromArgb(128, 128, 128),
_separatorColor = Color.FromArgb(128, 128, 128),
_btnPressedColor = Color.FromArgb(110, 160, 230);

//Border color
public override Color ToolStripBorder => _borderColor;
public override Color MenuBorder => _borderColor;

//Background color
public override Color ToolStripDropDownBackground => _backColor;
public override Color MenuStripGradientBegin => _backColor;
public override Color MenuStripGradientEnd => _backColor;
public override Color CheckBackground => _backColor;
public override Color CheckSelectedBackground => _backColor;
public override Color CheckPressedBackground => _backColor;
public override Color ImageMarginGradientBegin => _backColor;
public override Color ImageMarginGradientMiddle => _backColor;
public override Color ImageMarginGradientEnd => _backColor;

//Seperator color
public override Color SeparatorDark => _separatorColor;
public override Color SeparatorLight => _separatorColor;

//MenuItem selected color
public override Color MenuItemSelected => _itemSelectedColor;
public override Color MenuItemBorder => _itemSelectedColor;

//Item pressed color
public override Color ButtonPressedBorder => _btnPressedColor;
public override Color ButtonPressedGradientBegin => _btnPressedColor;
public override Color ButtonPressedGradientMiddle => _btnPressedColor;
public override Color ButtonPressedGradientEnd => _btnPressedColor;

//StatusStrip color
public override Color StatusStripGradientBegin => _backColor;
public override Color StatusStripGradientEnd => _backColor;
}

public class DarkRenderer : ToolStripProfessionalRenderer
{
private Color _accentColor;

public DarkRenderer(Color accentColor) : base(new DarkColorTable())
{
_accentColor = accentColor;
}

//Make sure the text is rendered with white text color
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
e.TextColor = Color.White;
base.OnRenderItemText(e);
}

//Rendering the arrow for the actions submenu
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

//Rectangle for the arrows bounding box, a smaller box for a cleaner menu look
var r = new Rectangle(e.ArrowRectangle.Location, e.ArrowRectangle.Size);
r.Inflate(-3, -6);

//The arrow consists of two lines, defined by 3 points
e.Graphics.DrawLines(Pens.White, new Point[3] {
new Point(r.Left, r.Top),
new Point(r.Right, r.Top + r.Height /2),
new Point(r.Left, r.Top+ r.Height)
});
}

//Rendering the checkmark and its surrounding box
protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e)
{
if (e != null)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

var rectImage = new Rectangle(e.ImageRectangle.Location, e.ImageRectangle.Size);
rectImage.X += 4;
//rectImage.Inflate(-1, -1);

using (var p = new Pen(_accentColor, 1))
e.Graphics.DrawRectangle(p, rectImage);

rectImage.Width -= 6;
rectImage.Height -= 8;

rectImage.X += 3;
rectImage.Y += 4;

using (var p = new Pen(Color.White, 1))
{
e.Graphics.DrawLines(p, new Point[] { new Point(rectImage.Left, rectImage.Bottom - (int)(rectImage.Height / 2)), new Point(rectImage.Left + (int)(rectImage.Width / 3), rectImage.Bottom), new Point(rectImage.Right, rectImage.Top) });
}
}
else
base.OnRenderItemCheck(e);
}
}
}