Skip to content

Commit

Permalink
Complete implementation of 'System Default' for the Staus Color Set s…
Browse files Browse the repository at this point in the history
…etting
  • Loading branch information
djp952 committed Jan 12, 2022
1 parent bfcdeb5 commit 65a1a53
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 70 deletions.
2 changes: 2 additions & 0 deletions src/hdhomeruntray/ApplicationTheme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ namespace zuki.hdhomeruntray

internal static class ApplicationTheme
{
// Static Constructor
//
static ApplicationTheme()
{
if(Settings.Default.AppTheme == Theme.System) s_darkmode = (GetSystemTheme() == Theme.Dark);
Expand Down
20 changes: 19 additions & 1 deletion src/hdhomeruntray/MainApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public MainApplication()
catch(Exception) { /* DON'T CARE FOR NOW */ }

m_colorfiltermonitor = new RegistryKeyValueChangeMonitor(Registry.CurrentUser, @"Software\Microsoft\ColorFiltering");
m_colorfiltermonitor.ValueChanged += new EventHandler(OnSystemThemesChanged);
m_colorfiltermonitor.ValueChanged += new EventHandler(OnColorFilterChanged);

try { m_colorfiltermonitor.Start(); }
catch(Exception) { /* DON'T CARE FOR NOW */ }
Expand Down Expand Up @@ -168,6 +168,24 @@ private void OnApplicationExit(object sender, EventArgs args)
m_notifyicon.Visible = false; // Remove the tray icon
}

// OnColorFilterChanged
//
// Invoked when the color filter has changed
private void OnColorFilterChanged(object sender, EventArgs args)
{
// Refresh the status icon if would be different than it already is
Icon statusicon = StatusIcons.Get(m_status);
if(!m_notifyicon.Icon.Equals(statusicon)) m_notifyicon.Icon = statusicon;

// The StatusColor class exists in the WindowsFormsSynchronizationContext
// but also needs to know about this event to inform listeners
m_context.Post(new SendOrPostCallback((o) =>
{
StatusColor.ColorFilterChanged(this, EventArgs.Empty);

}), null);
}

// OnDiscoveryCompleted
//
// Invoked when a discovery operation has completed
Expand Down
41 changes: 26 additions & 15 deletions src/hdhomeruntray/PopupItemDeviceControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@
//---------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

using zuki.hdhomeruntray.discovery;
using zuki.hdhomeruntray.Properties;

namespace zuki.hdhomeruntray
{
Expand Down Expand Up @@ -68,9 +66,6 @@ public PopupItemDeviceControl(Device device, SizeF scalefactor) : base(PopupItem
int numdots = 1;
if(m_device is TunerDevice tunerdevice) numdots = tunerdevice.Tuners.Count;

// Wire up a handler for property changes as the color of the dot(s) may need to change dynamically
Settings.Default.PropertyChanged += new PropertyChangedEventHandler(OnPropertyChanged);

// Create the dot labels
m_dots = new Label[numdots];
for(int index = 0; index < numdots; index++)
Expand All @@ -90,6 +85,26 @@ public PopupItemDeviceControl(Device device, SizeF scalefactor) : base(PopupItem
// Add the dot label to the layout panel
base.LayoutPanel.Controls.Add(m_dots[index]);
}

// COLOR FILTER (Initialize after m_dots)
//
m_statuscolorschanged = new EventHandler(OnStatusColorsChanged);
StatusColor.Changed += m_statuscolorschanged;
OnStatusColorsChanged(this, EventArgs.Empty);
}

// Dispose
//
// Releases unmanaged resources and optionally releases managed resources
protected override void Dispose(bool disposing)
{
if(disposing)
{
// Dispose managed state
if(m_statuscolorschanged != null) StatusColor.Changed -= m_statuscolorschanged;
}

base.Dispose(disposing);
}

//-------------------------------------------------------------------------
Expand Down Expand Up @@ -183,18 +198,13 @@ public void SetDeviceColor(int index, Color color)
// Event Handlers
//-------------------------------------------------------------------

// OnPropertyChanged
// OnStatusColorsChanged
//
// Invoked when a settings property has been changed
private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
// Invoked when the application status colors have changed
private void OnStatusColorsChanged(object sender, EventArgs args)
{
// StatusColorSet
//
if(args.PropertyName == nameof(Settings.Default.StatusColorSet))
{
// Rebase the dot colors appropriately for the new color set
for(int index = 0; index < m_dots.Length; index++) m_dots[index].ForeColor = StatusColor.Rebase(m_dots[index].ForeColor);
}
// Rebase the dot colors appropriately for the new color set
for(int index = 0; index < m_dots.Length; index++) m_dots[index].ForeColor = StatusColor.Rebase(m_dots[index].ForeColor);
}

//-------------------------------------------------------------------
Expand All @@ -204,5 +214,6 @@ private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
private readonly Device m_device = null;
private readonly Label[] m_dots;
private DeviceStatus m_status = DeviceStatus.Idle;
private readonly EventHandler m_statuscolorschanged;
}
}
148 changes: 95 additions & 53 deletions src/hdhomeruntray/StatusColor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
// SOFTWARE.
//---------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Drawing;

using Microsoft.Win32;
Expand All @@ -35,6 +37,18 @@ namespace zuki.hdhomeruntray

internal static class StatusColor
{
// Static Constructor
//
static StatusColor()
{
if(Settings.Default.StatusColorSet == StatusColorSet.System) s_filteractive = GetColorFilterActive();
else if(Settings.Default.StatusColorSet == StatusColorSet.GreenRed) s_filteractive = false;
else if(Settings.Default.StatusColorSet == StatusColorSet.BlueOrange) s_filteractive = true;

// Wire up a handler to watch for property changes
Settings.Default.PropertyChanged += new PropertyChangedEventHandler(OnPropertyChanged);
}

//-------------------------------------------------------------------
// Fields
//-------------------------------------------------------------------
Expand Down Expand Up @@ -63,32 +77,43 @@ internal static class StatusColor
//
public static readonly Color Yellow = Color.FromArgb(0xFF, 0xE9, 0x00);

//-------------------------------------------------------------------------
// Events
//-------------------------------------------------------------------------

// Changed
//
// Invoked when the status color set has changed
public static event EventHandler Changed;

//-------------------------------------------------------------------
// Member Functions
//-------------------------------------------------------------------

// Rebase (static)
// ColorFilterChanged (static)
//
// Resets a color due to a color set switch
public static Color Rebase(Color color)
// Invoked when the color filter has been changed
public static void ColorFilterChanged(object sender, EventArgs args)
{
StatusColorSet colorset = Settings.Default.StatusColorSet;

// The "System" colorset depends on if the user has a color filter enabled or not
if(colorset == StatusColorSet.System)
// This is only applicable if the setting is set to System
if(Settings.Default.StatusColorSet == StatusColorSet.System)
{
colorset = StatusColorSet.GreenRed; // Default to green/red

// If on Windows 10 / Windows 11, change the color set to blue/orange if the user
// has any color filtering setting applied at the operating system level
if(VersionHelper.IsWindows10OrGreater())
// Get a new color filter flag for the system, and if it changed inform listeners
bool filteractive = GetColorFilterActive();
if(filteractive != s_filteractive)
{
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\ColorFiltering", "Active", 0);
if((value is int @int) && (@int != 0)) colorset = StatusColorSet.BlueOrange;
s_filteractive = filteractive;
Changed?.Invoke(typeof(ApplicationTheme), EventArgs.Empty);
}
}
}

if(colorset == StatusColorSet.BlueOrange)
// Rebase (static)
//
// Resets a color due to a color set switch
public static Color Rebase(Color color)
{
if(s_filteractive)
{
if(color == Green) return Blue;
if(color == Red) return Orange;
Expand All @@ -108,30 +133,10 @@ public static Color Rebase(Color color)
// Retrieves the correct GUI color based on a DeviceStatus
public static Color FromDeviceStatus(DeviceStatus status)
{
Color result = Gray;
StatusColorSet colorset = Settings.Default.StatusColorSet;

// The "System" colorset depends on if the user has a color filter enabled or not
if(colorset == StatusColorSet.System)
{
colorset = StatusColorSet.GreenRed; // Default to green/red

// If on Windows 10 / Windows 11, change the color set to blue/orange if the user
// has any color filtering setting applied at the operating system level
if(VersionHelper.IsWindows10OrGreater())
{
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\ColorFiltering", "Active", 0);
if((value is int @int) && (@int != 0)) colorset = StatusColorSet.BlueOrange;
}
}

// Active = Green/Blue
//
if(status == DeviceStatus.Active) result = (colorset == StatusColorSet.BlueOrange) ? Blue : Green;
Color result = Gray; // Default to gray

// ActiveAndRecording = Red/Orange
//
else if(status == DeviceStatus.ActiveAndRecording) result = (colorset == StatusColorSet.BlueOrange) ? Orange : Red;
if(status == DeviceStatus.Active) result = s_filteractive ? Blue : Green;
else if(status == DeviceStatus.ActiveAndRecording) result = s_filteractive ? Orange : Red;

return result;
}
Expand All @@ -141,29 +146,66 @@ public static Color FromDeviceStatus(DeviceStatus status)
// Retrieves the correct GUI color based on a DeviceStatusColor
public static Color FromDeviceStatusColor(DeviceStatusColor devicestatuscolor)
{
Color result = Gray;
StatusColorSet colorset = Settings.Default.StatusColorSet;
Color result = Gray; // Default to gray

// The "System" colorset depends on if the user has a color filter enabled or not
if(colorset == StatusColorSet.System)
if(devicestatuscolor == DeviceStatusColor.Green) result = s_filteractive ? Blue : Green;
else if(devicestatuscolor == DeviceStatusColor.Red) result = s_filteractive ? Orange : Red;
else if(devicestatuscolor == DeviceStatusColor.Yellow) result = s_filteractive ? Blue : Yellow;

return result;
}

//-------------------------------------------------------------------
// Event Handlers
//-------------------------------------------------------------------

// OnPropertyChanged
//
// Invoked when a settings property has been changed
private static void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
// StatusColorSet
//
if(args.PropertyName == nameof(Settings.Default.StatusColorSet))
{
colorset = StatusColorSet.GreenRed; // Default to green/red
bool filteractive = GetColorFilterActive();

// Override for specific settings
if(Settings.Default.StatusColorSet == StatusColorSet.GreenRed) filteractive = false;
else if(Settings.Default.StatusColorSet == StatusColorSet.BlueOrange) filteractive = true;

// If on Windows 10 / Windows 11, change the color set to blue/orange if the user
// has any color filtering setting applied at the operating system level
if(VersionHelper.IsWindows10OrGreater())
// If the setting has changed, invoke the event to inform
if(filteractive != s_filteractive)
{
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\ColorFiltering", "Active", 0);
if((value is int @int) && (@int != 0)) colorset = StatusColorSet.BlueOrange;
s_filteractive = filteractive;
Changed?.Invoke(typeof(StatusColor), EventArgs.Empty);
}
}
}

if(devicestatuscolor == DeviceStatusColor.Neutral) result = Gray;
else if(devicestatuscolor == DeviceStatusColor.Green) result = (colorset == StatusColorSet.BlueOrange) ? Blue : Green;
else if(devicestatuscolor == DeviceStatusColor.Red) result = (colorset == StatusColorSet.BlueOrange) ? Orange : Red;
else if(devicestatuscolor == DeviceStatusColor.Yellow) result = (colorset == StatusColorSet.BlueOrange) ? Blue : Yellow;
//-------------------------------------------------------------------
// Private Member Functions
//-------------------------------------------------------------------

return result;
// GetColorFilterActive
//
// Gets the flag indicating if color filtering is active
private static bool GetColorFilterActive()
{
// On Windows 10 / Windows 11, check if filtering is currently active
if(VersionHelper.IsWindows10OrGreater())
{
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\ColorFiltering", "Active", 0);
if((value is int @int) && (@int != 0)) return true;
}

return false; // Default to no filtering
}

//-------------------------------------------------------------------
// Member Variables
//-------------------------------------------------------------------

private static bool s_filteractive = false;
}
}
17 changes: 17 additions & 0 deletions src/hdhomeruntray/StorageDeviceLiveBufferControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ private StorageDeviceLiveBufferControl(SizeF scalefactor)
ApplicationTheme.Changed += m_appthemechanged;
OnApplicationThemeChanged(this, EventArgs.Empty);

// COLOR FILTER
//
m_statuscolorschanged = new EventHandler(OnStatusColorsChanged);
StatusColor.Changed += m_statuscolorschanged;
OnStatusColorsChanged(this, EventArgs.Empty);

m_layoutpanel.EnableDoubleBuferring();

Padding = Padding.ScaleDPI(scalefactor);
Expand Down Expand Up @@ -83,6 +89,7 @@ protected override void Dispose(bool disposing)
if(disposing)
{
// Dispose managed state
if(m_statuscolorschanged != null) StatusColor.Changed -= m_statuscolorschanged;
if(m_appthemechanged != null) ApplicationTheme.Changed -= m_appthemechanged;
if(components != null) components.Dispose();
}
Expand All @@ -103,10 +110,20 @@ private void OnApplicationThemeChanged(object sender, EventArgs args)
m_layoutpanel.ForeColor = ApplicationTheme.PanelForeColor;
}

// OnStatusColorsChanged
//
// Invoked when the application status colors have changed
private void OnStatusColorsChanged(object sender, EventArgs args)
{
// Rebase the colors for the new color set
m_activedot.ForeColor = StatusColor.Rebase(m_activedot.ForeColor);
}

//-------------------------------------------------------------------
// Member Variables
//-------------------------------------------------------------------

private readonly EventHandler m_appthemechanged;
private readonly EventHandler m_statuscolorschanged;
}
}
Loading

0 comments on commit 65a1a53

Please sign in to comment.