Clean up and polish release
- Nice popup UI with proper positioning - Professional README with badges - Remove debug logging - Add .claude/ to .gitignore 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,19 +14,20 @@ namespace DellMonitorControl
|
||||
_trayIcon.TrayLeftMouseUp += TrayIcon_Click;
|
||||
|
||||
_mainWindow = new MainWindow();
|
||||
_mainWindow.Show();
|
||||
}
|
||||
|
||||
private void TrayIcon_Click(object sender, RoutedEventArgs e)
|
||||
private async void TrayIcon_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_mainWindow == null) return;
|
||||
|
||||
if (_mainWindow.IsVisible)
|
||||
{
|
||||
_mainWindow.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
_mainWindow.Show();
|
||||
_mainWindow.Activate();
|
||||
_mainWindow.ShowNearTray();
|
||||
await _mainWindow.LoadMonitors();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
<Window x:Class="DellMonitorControl.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="Monitor Control" Height="400" Width="320"
|
||||
WindowStyle="ToolWindow"
|
||||
ResizeMode="CanResize"
|
||||
Background="#333333">
|
||||
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">
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="10">
|
||||
<StackPanel Name="sp">
|
||||
<TextBlock Text="Monitor Control" Foreground="White" FontSize="16" FontWeight="Bold"/>
|
||||
<TextBlock Text="Loading..." Foreground="LightGray" FontSize="12" Margin="0,10,0,0"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<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="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Border Grid.Row="0" Background="#444" CornerRadius="8,8,0,0" Padding="12,10">
|
||||
<TextBlock Text="Monitor Control" Foreground="White" FontSize="14" FontWeight="SemiBold"/>
|
||||
</Border>
|
||||
|
||||
<!-- Content -->
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" Padding="12">
|
||||
<StackPanel Name="sp" VerticalAlignment="Center">
|
||||
<TextBlock Name="loadingText" Text="Loading..." Foreground="LightGray" FontSize="12"
|
||||
HorizontalAlignment="Center" Margin="0,40,0,40"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
|
||||
@@ -15,70 +15,67 @@ public partial class MainWindow : Window
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
PositionWindowNearTray();
|
||||
Loaded += async (s, e) => await LoadMonitors();
|
||||
}
|
||||
|
||||
private void PositionWindowNearTray()
|
||||
public void ShowNearTray()
|
||||
{
|
||||
var workArea = SystemParameters.WorkArea;
|
||||
Left = workArea.Right - Width - 10;
|
||||
Top = workArea.Bottom - Height - 10;
|
||||
// Use estimated height since ActualHeight is 0 before render
|
||||
Top = workArea.Bottom - 350;
|
||||
Show();
|
||||
Activate();
|
||||
|
||||
// Reposition after layout is complete
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
Top = workArea.Bottom - ActualHeight - 10;
|
||||
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
private static readonly string LogFile = System.IO.Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "MonitorControl.log");
|
||||
|
||||
private static void Log(string msg)
|
||||
private void Window_Deactivated(object sender, EventArgs e)
|
||||
{
|
||||
try { System.IO.File.AppendAllText(LogFile, $"{DateTime.Now:HH:mm:ss.fff} {msg}\n"); }
|
||||
catch { }
|
||||
Hide();
|
||||
}
|
||||
|
||||
private async Task LoadMonitors()
|
||||
public async Task LoadMonitors()
|
||||
{
|
||||
var newChildren = new List<UIElement>();
|
||||
Log("LoadMonitors started");
|
||||
|
||||
try
|
||||
{
|
||||
Log("Calling ScanMonitor...");
|
||||
await CMMCommand.ScanMonitor();
|
||||
Log("ScanMonitor complete");
|
||||
|
||||
Log("Calling ReadMonitorsData...");
|
||||
var monitors = (await CMMCommand.ReadMonitorsData()).ToList();
|
||||
Log($"ReadMonitorsData complete, found {monitors.Count} monitors");
|
||||
|
||||
if (!monitors.Any())
|
||||
{
|
||||
Log("No monitors found");
|
||||
newChildren.Add(new TextBlock { Text = "No DDC/CI monitors detected", Foreground = Brushes.White, FontSize = 14 });
|
||||
newChildren.Add(new TextBlock
|
||||
{
|
||||
Text = "No DDC/CI monitors detected",
|
||||
Foreground = Brushes.LightGray,
|
||||
FontSize = 12,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Margin = new Thickness(0, 30, 0, 30)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var m in monitors)
|
||||
{
|
||||
Log($"Processing monitor: {m.MonitorName} ({m.SerialNumber})");
|
||||
|
||||
var brightness = await CMMCommand.GetBrightness(m.SerialNumber) ?? 50;
|
||||
Log($" Brightness: {brightness}");
|
||||
var contrast = await CMMCommand.GetContrast(m.SerialNumber) ?? 50;
|
||||
Log($" Contrast: {contrast}");
|
||||
var inputSource = await CMMCommand.GetInputSource(m.SerialNumber);
|
||||
Log($" InputSource: {inputSource}");
|
||||
var inputOptions = await CMMCommand.GetInputSourceOptions(m.SerialNumber);
|
||||
Log($" InputOptions count: {inputOptions.Count}");
|
||||
var powerStatus = await CMMCommand.GetMonPowerStatus(m.SerialNumber) ?? "Unknown";
|
||||
Log($" PowerStatus: {powerStatus}");
|
||||
|
||||
// Monitor name header
|
||||
newChildren.Add(new TextBlock
|
||||
{
|
||||
Text = m.MonitorName,
|
||||
Foreground = Brushes.White,
|
||||
FontSize = 14,
|
||||
FontWeight = FontWeights.Bold,
|
||||
Margin = new Thickness(0, 10, 0, 5)
|
||||
FontSize = 13,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Margin = new Thickness(0, 8, 0, 6)
|
||||
});
|
||||
|
||||
newChildren.Add(CreateSliderRow("Brightness", brightness, m.SerialNumber, CMMCommand.SetBrightness));
|
||||
@@ -88,22 +85,33 @@ public partial class MainWindow : Window
|
||||
newChildren.Add(CreateInputRow(inputSource, inputOptions, m.SerialNumber));
|
||||
|
||||
newChildren.Add(CreatePowerRow(powerStatus, m.SerialNumber));
|
||||
|
||||
// Separator
|
||||
newChildren.Add(new Border { Height = 1, Background = new SolidColorBrush(Color.FromRgb(80, 80, 80)), Margin = new Thickness(0, 10, 0, 2) });
|
||||
}
|
||||
|
||||
// Remove last separator
|
||||
if (newChildren.Count > 0 && newChildren.Last() is Border)
|
||||
newChildren.RemoveAt(newChildren.Count - 1);
|
||||
}
|
||||
Log($"Built {newChildren.Count} UI elements");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"ERROR: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}");
|
||||
newChildren.Clear();
|
||||
newChildren.Add(new TextBlock { Text = $"Error: {ex.Message}", Foreground = Brushes.Red, FontSize = 12, TextWrapping = TextWrapping.Wrap });
|
||||
newChildren.Add(new TextBlock { Text = $"Error: {ex.Message}", Foreground = Brushes.OrangeRed, FontSize = 11, TextWrapping = TextWrapping.Wrap });
|
||||
}
|
||||
|
||||
Log("Updating UI...");
|
||||
sp.VerticalAlignment = VerticalAlignment.Top;
|
||||
sp.Children.Clear();
|
||||
foreach (var child in newChildren)
|
||||
sp.Children.Add(child);
|
||||
Log($"UI updated with {sp.Children.Count} children");
|
||||
|
||||
// Reposition after content changes
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
var workArea = SystemParameters.WorkArea;
|
||||
Top = workArea.Bottom - ActualHeight - 10;
|
||||
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
private StackPanel CreateSliderRow(string label, int value, string serialNumber, Func<string, int, Task> setCommand)
|
||||
|
||||
Reference in New Issue
Block a user