Skip to content

Commit

Permalink
add visual indicator for input sessions/devices
Browse files Browse the repository at this point in the history
- Also added colors & brushes
- Added WPF color converter properties to NotifyIcon
- Added try-catch around PersistentFileEndpoint.Dispose's Flush() call
- Updated some other UI elements
  • Loading branch information
radj307 committed Nov 10, 2023
1 parent 37437b4 commit 6741804
Show file tree
Hide file tree
Showing 12 changed files with 510 additions and 398 deletions.
2 changes: 1 addition & 1 deletion VolumeControl.CoreAudio/AudioDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal AudioDevice(MMDevice mmDevice)
if (MMDevice.AudioMeterInformation is null)
throw new NullReferenceException($"{nameof(AudioDevice)} '{Name}' has a null {nameof(MMDevice.AudioMeterInformation)} property!");

SessionManager = new(this); //< TODO: try-catch?
SessionManager = new(this);

AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;

Expand Down
10 changes: 7 additions & 3 deletions VolumeControl.CoreAudio/AudioDeviceSessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@ internal AudioDeviceSessionManager(AudioDevice audioDevice)

foreach (var audioSessionControl in AudioSessionManager2.Sessions)
{
if (audioSessionControl.State == AudioSessionState.AudioSessionStateExpired)
switch (audioSessionControl.State)
{
case AudioSessionState.AudioSessionStateExpired:
if (showTraceLogMessages)
FLog.Trace($"[{nameof(AudioDeviceSessionManager)}] Ignoring expired session with {nameof(audioSessionControl.ProcessID)} {audioSessionControl.ProcessID} and {nameof(audioSessionControl.SessionInstanceIdentifier)} \"{audioSessionControl.SessionInstanceIdentifier}\".");
continue;
break;
case AudioSessionState.AudioSessionStateInactive: //< add inactive sessions too
case AudioSessionState.AudioSessionStateActive:
CreateAndAddSessionIfUnique(audioSessionControl);
break;
}
CreateAndAddSessionIfUnique(audioSessionControl);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion VolumeControl.Log/Endpoints/PersistentFileEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ public override void Close()
/// </summary>
public new void Dispose()
{
Flush(); //< calls to Dispose() may expect that the stream is flushed
try
{
Flush(); //< calls to Dispose() may expect that the stream is flushed
}
catch { }
if (!CanClose) return;
base.Dispose();
GC.SuppressFinalize(this);
Expand Down
17 changes: 17 additions & 0 deletions VolumeControl.TypeExtensions/WinFormsInterop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace VolumeControl.TypeExtensions
{
/// <summary>
/// Extension methods for WinForms-WPF interoperation.
/// </summary>
public static class WinFormsInterop
{
/// <summary>
/// Converts the <see cref="System.Windows.Media.Color"/> to the equivalent <see cref="System.Drawing.Color"/>.
/// </summary>
public static System.Drawing.Color ToFormsColor(this System.Windows.Media.Color color) => System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B);
/// <summary>
/// Converts the <see cref="System.Drawing.Color"/> to the equivalent <see cref="System.Windows.Media.Color"/>.
/// </summary>
public static System.Windows.Media.Color ToWpfColor(this System.Drawing.Color color) => System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
}
}
41 changes: 34 additions & 7 deletions VolumeControl/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
<Thickness x:Key="WindowBorderThickness">3</Thickness>
<SolidColorBrush x:Key="UpdateIconBrush">Yellow</SolidColorBrush>
<SolidColorBrush x:Key="NotificationBackgroundBrush">#252525</SolidColorBrush>
<Color x:Key="ContextMenuBackgroundColor">#484848</Color>
<SolidColorBrush x:Key="ContextMenuBackgroundBrush" Color="{StaticResource ContextMenuBackgroundColor}" />
<SolidColorBrush x:Key="ContextMenuForegroundBrush">WhiteSmoke</SolidColorBrush>

<!-- Tabs -->
<SolidColorBrush x:Key="TabBackgroundBrush">#383838</SolidColorBrush>
Expand All @@ -64,16 +67,23 @@

<!-- TextBox Colors -->
<SolidColorBrush x:Key="TextBoxBackground">#1F1F1F</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxForeground">WhiteSmoke</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxForegroundDark">LightGray</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxBackgroundDisabled">#2F2F2F</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxBackgroundMouseOver">#282828</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxForeground">
<!-- #F5F5F5 is the hex code for WhiteSmoke -->
#F5F5F5
</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxForegroundColor">#C5C5FF</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxForegroundDark">LightGray</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxSelectionBrush">#569DE5</SolidColorBrush>
<SolidColorBrush x:Key="TextBoxWatermarkForeground">#9A9A9A</SolidColorBrush>

<!-- Data Grid Colors -->
<SolidColorBrush x:Key="HeaderBackgroundBrush">#222</SolidColorBrush>
<SolidColorBrush x:Key="GridRowBrush">#444</SolidColorBrush>
<SolidColorBrush x:Key="GridRowAltBrush">#555</SolidColorBrush>
<SolidColorBrush x:Key="GridSecondaryRowBrush">#445</SolidColorBrush>
<SolidColorBrush x:Key="GridSecondaryRowAltBrush">#556</SolidColorBrush>
<SolidColorBrush x:Key="GridHorizontalLineBrush">#222</SolidColorBrush>

<LinearGradientBrush x:Key="AccentGradient" StartPoint="0.05,0" EndPoint="0.95,1">
Expand Down Expand Up @@ -115,10 +125,16 @@
<Color x:Key="GrayForegroundColor">#B0B0B0</Color>
<Color x:Key="GrayForegroundFocusedColor">#909090</Color>

<SolidColorBrush x:Key="SelectionForegroundBrush" Color="#4CF" />
<Color x:Key="SelectionDimBackgroundColor">#54CF</Color>
<Color x:Key="SelectionBackgroundColor">#94CF</Color>
<Color x:Key="SelectionForegroundColor">#4CF</Color>
<Color x:Key="SelectionBorderGradientStartColor">#4AF</Color>
<Color x:Key="SelectionBorderGradientEndColor">#4CF</Color>

<SolidColorBrush x:Key="SelectionForegroundBrush" Color="{StaticResource SelectionForegroundColor}" />
<LinearGradientBrush x:Key="SelectionBorderBrush" StartPoint="0.2,0" EndPoint="0.8,1">
<GradientStop Offset="0" Color="#4AF" />
<GradientStop Offset="1" Color="#4CF" />
<GradientStop Offset="0" Color="{StaticResource SelectionBorderGradientStartColor}" />
<GradientStop Offset="1" Color="{StaticResource SelectionBorderGradientEndColor}" />
</LinearGradientBrush>
<Thickness x:Key="SelectionBorderThickness">1</Thickness>

Expand Down Expand Up @@ -284,6 +300,7 @@
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
<Style BasedOn="{StaticResource CheckBoxStyle}" TargetType="{x:Type CheckBox}" />
<!-- Button -->
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
Expand Down Expand Up @@ -912,12 +929,14 @@
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="WhiteSmoke" />
</Trigger>
<!-- Focused -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource SelectionBorderBrush}" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource SelectionBorderBrush}" />
<Setter Property="BorderThickness" Value="{StaticResource SelectionBorderThickness}" />
</Trigger>
</Style.Triggers>
<Setter Property="BorderThickness" Value="{StaticResource SelectionBorderThickness}" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
Expand Down Expand Up @@ -1047,6 +1066,14 @@
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type ScrollViewer}">
<EventSetter Event="Loaded" Handler="ScrollViewer_Loaded_AttachHorizontalScrollBehavior" />
</Style>
<Style x:Key="ContextMenuStyle" TargetType="{x:Type ContextMenu}">
<Setter Property="Background" Value="{StaticResource ContextMenuBackgroundBrush}" />
<Setter Property="Foreground" Value="{StaticResource ContextMenuForegroundBrush}" />
</Style>
<Style BasedOn="{StaticResource ContextMenuStyle}" TargetType="{x:Type ContextMenu}" />

</ResourceDictionary>
</Application.Resources>
Expand Down
18 changes: 16 additions & 2 deletions VolumeControl/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public App()
// setup the tray icon
TrayIcon = new(() => this.MainWindow.Visibility == Visibility.Visible)
{
Tooltip = $"Volume Control {version}"
Tooltip = $"Volume Control {version}",
Background = (System.Windows.Media.Color)FindResource("ContextMenuBackgroundColor"),
};
TrayIcon.DoubleClick += (s, e) =>
{
Expand Down Expand Up @@ -103,7 +104,9 @@ private void App_DispatcherUnhandledException(object sender, System.Windows.Thre
$"Sender: \"{sender}\" ({sender.GetType()})",
$"Thread: \"{e.Dispatcher.Thread.Name}\"",
e.Exception);
e.Handled = true;
#if DEBUG
throw new Exception("Unhandled dispatcher exception!", e.Exception);
#endif
}
#endregion App

Expand Down Expand Up @@ -162,6 +165,17 @@ private void TextBox_Loaded_AttachEscapeBehavior(object sender, RoutedEventArgs
}
#endregion TextBox

#region ScrollViewer
private void ScrollViewer_Loaded_AttachHorizontalScrollBehavior(object sender, RoutedEventArgs e)
{
var scrollViewer = (ScrollViewer)sender;

WPF.Behaviors.ScrollViewerHorizontalScrollBehavior behavior = new();
behavior.Attach(scrollViewer);
Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(scrollViewer).Add(behavior);
}
#endregion ScrollViewer

#endregion EventHandlers
}
}
11 changes: 11 additions & 0 deletions VolumeControl/Controls/NotifyIcon.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Windows.Media;
using VolumeControl.TypeExtensions;

namespace VolumeControl.Controls
Expand Down Expand Up @@ -107,11 +108,21 @@ public System.Drawing.Color BackColor
get => _contextMenuStrip.BackColor;
set => _contextMenuStrip.BackColor = value;
}
public Color Background
{
get => BackColor.ToWpfColor();
set => BackColor = value.ToFormsColor();
}
public System.Drawing.Color ForeColor
{
get => _contextMenuStrip.ForeColor;
set => _contextMenuStrip.ForeColor = value;
}
public Color Foreground
{
get => ForeColor.ToWpfColor();
set => ForeColor = value.ToFormsColor();
}
public bool DropShadowEnabled
{
get => _contextMenuStrip.DropShadowEnabled;
Expand Down
25 changes: 22 additions & 3 deletions VolumeControl/DeviceListNotification.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
<conv:BooleanInverter x:Key="InvertConverter" />

<!-- Styles -->
<Style BasedOn="{StaticResource CheckBoxStyle}" TargetType="{x:Type CheckBox}" />
<Style BasedOn="{StaticResource TextBoxStyle}" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="#0000" />
<Setter Property="BorderThickness" Value="0" />
Expand Down Expand Up @@ -137,7 +136,17 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Foreground="{Binding DeviceConfigVM.ForegroundBrush, Source={StaticResource Settings}}"
Text="{Binding Name}" />
Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding AudioDevice.DataFlow}" Value="Capture">
<Setter Property="FontStyle" Value="Oblique" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DeviceDisplayAlwaysBoldWidthDataTemplate" DataType="{x:Type vm:AudioDeviceVM}">
Expand All @@ -163,7 +172,17 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Foreground="{Binding DeviceConfigVM.ForegroundBrush, Source={StaticResource Settings}}"
Text="{Binding Name}" />
Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding AudioDevice.DataFlow}" Value="Capture">
<Setter Property="FontStyle" Value="Oblique" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<!-- Always Bold TextBlock (Keeps correct width) -->
<TextBlock
Grid.Column="1"
Expand Down
Loading

0 comments on commit 6741804

Please sign in to comment.