2
0

refactor(ci): rename DellMonitorControl to MonitorControl
All checks were successful
Build / build (push) Successful in 9h0m26s
Build and Release / build (push) Successful in 8h0m15s

Rename project from DellMonitorControl to MonitorControl to reflect broader monitor compatibility beyond Dell hardware. Update all references in solution file, workflow, and project paths.

Add DDC/CI rate limiting and throttling logic to prevent command failures:
- Minimum 50ms interval between commands to same monitor
- 8-second grace period after system resume before sending commands
- 3-second cooldown after timeout to allow monitor recovery
- Global semaphore to prevent command collisions

Replace old icon with new generic monitor icon (ico and png formats).
This commit is contained in:
2026-01-29 18:14:58 -05:00
parent 3c6cc15281
commit 404e6f42da
24 changed files with 262 additions and 53 deletions

View File

@@ -0,0 +1,243 @@
<Window x:Class="MonitorControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Monitor Control"
Width="300" MinHeight="200" MaxHeight="500"
SizeToContent="Height"
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
ResizeMode="NoResize"
ShowInTaskbar="False"
Topmost="True"
Deactivated="Window_Deactivated">
<Window.Resources>
<!-- Dark Button Style with proper hover -->
<Style x:Key="DarkButton" TargetType="Button">
<Setter Property="Background" Value="#464646"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="#646464"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="8,4"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
CornerRadius="3">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#0056A0"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#004080"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dark ComboBox Style -->
<Style x:Key="DarkComboBox" TargetType="ComboBox">
<Setter Property="Background" Value="#3A3A3A"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="#555"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="6,4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton x:Name="ToggleButton"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"/>
<Path Grid.Column="1" Data="M0,0 L4,4 L8,0" Stroke="White" StrokeThickness="1.5"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#4A4A4A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter x:Name="ContentSite"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
Margin="8,4,28,4"
VerticalAlignment="Center"
HorizontalAlignment="Left"
IsHitTestVisible="False"/>
<Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Border x:Name="DropDown" Background="#3A3A3A" BorderBrush="#555" BorderThickness="1"
MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
CornerRadius="3" Margin="0,2,0,0">
<ScrollViewer SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True"/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dark ComboBoxItem Style -->
<Style x:Key="DarkComboBoxItem" TargetType="ComboBoxItem">
<Setter Property="Background" Value="#3A3A3A"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="8,4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" Value="#0056A0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#4A4A4A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Quick Switch Button Style -->
<Style x:Key="QuickSwitchButton" TargetType="Button">
<Setter Property="Background" Value="#3C3C3C"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="#0078D4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="10,5"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
CornerRadius="3">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#0056A0"/>
<Setter Property="BorderBrush" Value="#0078D4"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#004080"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Spinner Animation -->
<Storyboard x:Key="SpinnerAnimation" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="SpinnerRotate"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:1"/>
</Storyboard>
</Window.Resources>
<Border Background="#F0333333" CornerRadius="8" BorderBrush="#555" BorderThickness="1" Margin="5">
<Border.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="2" Opacity="0.5"/>
</Border.Effect>
<Grid MinHeight="180">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Header -->
<Border Grid.Row="0" Background="#444" CornerRadius="8,8,0,0" Padding="12,10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="Monitor Control" Foreground="White" FontSize="14" FontWeight="SemiBold" VerticalAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="About" Margin="0,0,6,0" Click="AboutButton_Click"
Style="{StaticResource DarkButton}" FontSize="11"/>
<Button Content="Exit" Click="ExitButton_Click"
Style="{StaticResource DarkButton}" FontSize="11"/>
</StackPanel>
</Grid>
<!-- Update Banner -->
<Border Name="updateBanner" Grid.Row="1" Background="#0078D4" CornerRadius="3"
Padding="8,4" Margin="0,8,0,0" Visibility="Collapsed" Cursor="Hand"
MouseLeftButtonUp="UpdateBanner_Click">
<TextBlock Name="updateText" Text="Update available!" Foreground="White"
FontSize="11" HorizontalAlignment="Center"/>
</Border>
</Grid>
</Border>
<!-- Quick Switch Toolbar -->
<WrapPanel Name="quickSwitchPanel" Grid.Row="1" Margin="8,8,8,0" Visibility="Collapsed"/>
<!-- Content -->
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto" Padding="12">
<StackPanel Name="sp" VerticalAlignment="Center">
<!-- Loading indicator with spinner -->
<StackPanel Name="loadingPanel" HorizontalAlignment="Center" Margin="0,30,0,30">
<Ellipse Width="24" Height="24" StrokeThickness="3" HorizontalAlignment="Center" Margin="0,0,0,10"
RenderTransformOrigin="0.5,0.5">
<Ellipse.Stroke>
<LinearGradientBrush>
<GradientStop Color="#0078D4" Offset="0"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.RenderTransform>
<RotateTransform x:Name="SpinnerRotate" Angle="0"/>
</Ellipse.RenderTransform>
</Ellipse>
<TextBlock Name="loadingText" Text="Loading..." Foreground="LightGray" FontSize="12"
HorizontalAlignment="Center"/>
<Button Name="showLogButton" Content="Show Log" Margin="0,10,0,0"
Style="{StaticResource DarkButton}" FontSize="10"
Click="ShowLogButton_Click" Visibility="Collapsed"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
</Window>