merge niels changes

This commit is contained in:
Yu Leng
2025-11-27 15:21:14 +08:00
5 changed files with 260 additions and 162 deletions

View File

@@ -4,18 +4,19 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animatedVisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals" xmlns:animatedVisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
xmlns:animations="using:CommunityToolkit.WinUI.Animations" xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:local="using:PowerDisplay"
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls" xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
xmlns:ui="using:CommunityToolkit.WinUI" xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:vm="using:PowerDisplay.ViewModels" xmlns:vm="using:PowerDisplay.ViewModels"
xmlns:winuiex="using:WinUIEx" xmlns:winuiex="using:WinUIEx"
MinWidth="0"
MinHeight="0"
IsAlwaysOnTop="True" IsAlwaysOnTop="True"
IsMaximizable="False" IsMaximizable="False"
IsMinimizable="False" IsMinimizable="False"
IsResizable="False" IsResizable="False"
IsShownInSwitchers="False" IsShownInSwitchers="False"
IsTitleBarVisible="False" IsTitleBarVisible="False">
MinHeight="0"
MinWidth="0">
<winuiex:WindowEx.SystemBackdrop> <winuiex:WindowEx.SystemBackdrop>
<DesktopAcrylicBackdrop /> <DesktopAcrylicBackdrop />
</winuiex:WindowEx.SystemBackdrop> </winuiex:WindowEx.SystemBackdrop>
@@ -81,10 +82,10 @@
<ScrollViewer <ScrollViewer
x:Name="MainScrollViewer" x:Name="MainScrollViewer"
Padding="16,16,16,16" Padding="16,16,16,16"
VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled"
HorizontalScrollMode="Disabled" HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
VerticalAlignment="Stretch"
ZoomMode="Disabled"> ZoomMode="Disabled">
<!-- Monitors List with modern card design --> <!-- Monitors List with modern card design -->
<ItemsRepeater <ItemsRepeater
@@ -98,85 +99,56 @@
<ItemsRepeater.ItemTemplate> <ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="vm:MonitorViewModel"> <DataTemplate x:DataType="vm:MonitorViewModel">
<StackPanel HorizontalAlignment="Stretch" Spacing="4"> <StackPanel HorizontalAlignment="Stretch" Spacing="4">
<!-- Monitor Name with Icon and More Actions --> <!-- Monitor Name with Icon -->
<Grid HorizontalAlignment="Stretch"> <Grid Margin="2,0,0,0" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="16" /> <ColumnDefinition Width="22" />
<ColumnDefinition Width="16" /> <ColumnDefinition Width="16" />
<!-- Spacing --> <!-- Spacing -->
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<!-- More Actions Button -->
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<FontIcon <local:MonitorIcon
x:Uid="MonitorTooltip"
VerticalAlignment="Center" VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw" IsBuiltIn="{x:Bind IsInternal, Mode=OneWay}"
FontSize="14" MonitorNumber="{x:Bind MonitorNumber, Mode=OneWay}" />
Glyph="{x:Bind MonitorIconGlyph, Mode=OneWay}" />
<TextBlock <TextBlock
Grid.Column="2" Grid.Column="2"
Margin="0,0,0,2"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="SemiBold"
Text="{x:Bind DisplayName, Mode=OneWay}" /> Text="{x:Bind DisplayName, Mode=OneWay}" />
<!-- More Actions Button (only visible when input source switching is supported) -->
<Button <Button
x:Name="MoreActionsButton" Grid.Column="2"
Grid.Column="3" HorizontalAlignment="Right"
Padding="4" Content="{ui:FontIcon Glyph=&#xE712;,
VerticalAlignment="Center" FontSize=16}"
Background="Transparent" Style="{StaticResource SubtleButtonStyle}">
BorderThickness="0"
Visibility="{x:Bind ConvertBoolToVisibility(SupportsInputSource), Mode=OneWay}">
<ToolTipService.ToolTip>
<TextBlock Text="More actions" />
</ToolTipService.ToolTip>
<FontIcon FontSize="12" Glyph="&#xE712;" />
<Button.Flyout> <Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight"> <Flyout>
<StackPanel MinWidth="160" Spacing="4"> <StackPanel Orientation="Vertical">
<ListView SelectedIndex="2">
<ListView.Header>
<TextBlock <TextBlock
Margin="12,4,12,8" Margin="16,0,8,0"
FontWeight="SemiBold" FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Input source" /> Text="Input source" />
<ItemsRepeater ItemsSource="{x:Bind AvailableInputSources, Mode=OneWay}"> </ListView.Header>
<ItemsRepeater.Layout> <ListViewItem Content="Source 1" />
<StackLayout Orientation="Vertical" Spacing="0" /> <ListViewItem Content="Source 2" />
</ItemsRepeater.Layout> <ListViewItem Content="Source 3" />
<ItemsRepeater.ItemTemplate> </ListView>
<DataTemplate x:DataType="vm:InputSourceItem">
<Button
Padding="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Style="{StaticResource SubtleButtonStyle}"
Tag="{x:Bind}"
Click="InputSourceItem_Click">
<Grid MinHeight="32" MinWidth="140">
<!-- Selection indicator (left blue bar) -->
<Border
Width="3"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Background="{ThemeResource AccentFillColorDefaultBrush}"
CornerRadius="1.5"
Visibility="{x:Bind SelectionVisibility}" />
<TextBlock
Margin="12,0,12,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Bind Name}" />
</Grid>
</Button>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel> </StackPanel>
</Flyout> </Flyout>
</Button.Flyout> </Button.Flyout>
</Button> </Button>
</Grid> </Grid>
<StackPanel
Margin="0,8,0,0"
Padding="8,0,16,8"
Background="{ThemeResource LayerOnAcrylicFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}">
<!-- Brightness Control --> <!-- Brightness Control -->
<Grid Margin="0,8,0,0" HorizontalAlignment="Stretch"> <Grid Margin="0,8,0,0" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -189,14 +161,14 @@
x:Uid="BrightnessTooltip" x:Uid="BrightnessTooltip"
VerticalAlignment="Center" VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
FontSize="14" FontSize="18"
Glyph="&#xE706;" /> Glyph="&#xEC8A;" />
<Slider <Slider
x:Uid="BrightnessAutomation" x:Uid="BrightnessAutomation"
DataContext="{x:Bind}"
Grid.Column="2" Grid.Column="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" VerticalAlignment="Center"
DataContext="{x:Bind}"
IsEnabled="{x:Bind IsInteractionEnabled, Mode=OneWay}" IsEnabled="{x:Bind IsInteractionEnabled, Mode=OneWay}"
Maximum="{x:Bind MaxBrightness, Mode=OneWay}" Maximum="{x:Bind MaxBrightness, Mode=OneWay}"
Minimum="{x:Bind MinBrightness, Mode=OneWay}" Minimum="{x:Bind MinBrightness, Mode=OneWay}"
@@ -206,11 +178,11 @@
Value="{x:Bind Brightness, Mode=OneWay}" /> Value="{x:Bind Brightness, Mode=OneWay}" />
</Grid> </Grid>
<!-- Contrast Control --> <!-- Contrast Control {x:Bind ConvertBoolToVisibility(ShowContrast), Mode=OneWay}" -->
<Grid <Grid
Margin="0,8,0,0" Margin="0,8,0,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Visibility="{x:Bind ConvertBoolToVisibility(ShowContrast), Mode=OneWay}"> Visibility="Visible">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="16" /> <ColumnDefinition Width="16" />
<ColumnDefinition Width="16" /> <ColumnDefinition Width="16" />
@@ -222,14 +194,14 @@
x:Uid="ContrastTooltip" x:Uid="ContrastTooltip"
VerticalAlignment="Center" VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
FontSize="14" FontSize="12"
Glyph="&#xE7A1;" /> Glyph="&#xE7A1;" />
<Slider <Slider
x:Uid="ContrastAutomation" x:Uid="ContrastAutomation"
DataContext="{x:Bind}"
Grid.Column="2" Grid.Column="2"
VerticalAlignment="Center" VerticalAlignment="Center"
DataContext="{x:Bind}"
IsEnabled="{x:Bind IsInteractionEnabled, Mode=OneWay}" IsEnabled="{x:Bind IsInteractionEnabled, Mode=OneWay}"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
@@ -239,11 +211,8 @@
Value="{x:Bind ContrastPercent, Mode=OneWay}" /> Value="{x:Bind ContrastPercent, Mode=OneWay}" />
</Grid> </Grid>
<!-- Volume Control --> <!-- Volume Control Visibility="{x:Bind ConvertBoolToVisibility(ShowVolume), Mode=OneWay}" -->
<Grid <Grid Margin="0,8,0,0" HorizontalAlignment="Stretch">
Margin="0,8,0,0"
HorizontalAlignment="Stretch"
Visibility="{x:Bind ConvertBoolToVisibility(ShowVolume), Mode=OneWay}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="16" /> <ColumnDefinition Width="16" />
<ColumnDefinition Width="16" /> <ColumnDefinition Width="16" />
@@ -253,16 +222,17 @@
<FontIcon <FontIcon
x:Uid="VolumeTooltip" x:Uid="VolumeTooltip"
Margin="2,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw" AutomationProperties.AccessibilityView="Raw"
FontSize="14" FontSize="16"
Glyph="&#xE767;" /> Glyph="&#xE993;" />
<Slider <Slider
x:Uid="VolumeAutomation" x:Uid="VolumeAutomation"
DataContext="{x:Bind}"
Grid.Column="2" Grid.Column="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" VerticalAlignment="Center"
DataContext="{x:Bind}"
IsEnabled="{x:Bind IsInteractionEnabled, Mode=OneWay}" IsEnabled="{x:Bind IsInteractionEnabled, Mode=OneWay}"
Maximum="{x:Bind MaxVolume, Mode=OneWay}" Maximum="{x:Bind MaxVolume, Mode=OneWay}"
Minimum="{x:Bind MinVolume, Mode=OneWay}" Minimum="{x:Bind MinVolume, Mode=OneWay}"
@@ -272,20 +242,40 @@
Value="{x:Bind Volume, Mode=OneWay}" /> Value="{x:Bind Volume, Mode=OneWay}" />
</Grid> </Grid>
</StackPanel> </StackPanel>
</StackPanel>
</DataTemplate> </DataTemplate>
</ItemsRepeater.ItemTemplate> </ItemsRepeater.ItemTemplate>
</ItemsRepeater> </ItemsRepeater>
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>
</Border> </Border>
<!-- Status Bar with modern design -->
<Grid x:Name="StatusBar" Grid.Row="1" Padding="12,8,12,8" MaxHeight="48"> <Grid x:Name="StatusBar" Grid.Row="1">
<!-- Action Buttons --> <!-- Action Buttons -->
<StackPanel <StackPanel
Margin="0,0,8,8"
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
Orientation="Horizontal" Orientation="Horizontal"
Spacing="8"> Spacing="8">
<Button Content="{ui:FontIcon Glyph=&#xE748;, FontSize=16}" Style="{StaticResource SubtleButtonStyle}">
<Button.Flyout>
<Flyout>
<ListView SelectedIndex="2">
<ListView.Header>
<TextBlock
Margin="16,0,8,0"
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Profiles" />
</ListView.Header>
<ListViewItem Content="Profile 1" />
<ListViewItem Content="Profile 2" />
<ListViewItem Content="Profile 3" />
</ListView>
</Flyout>
</Button.Flyout>
</Button>
<Button <Button
x:Name="LinkButton" x:Name="LinkButton"
x:Uid="SyncAllMonitorsTooltip" x:Uid="SyncAllMonitorsTooltip"

View File

@@ -157,7 +157,7 @@ namespace PowerDisplay
// Auto-hide window when it loses focus (deactivated) // Auto-hide window when it loses focus (deactivated)
if (args.WindowActivationState == WindowActivationState.Deactivated) if (args.WindowActivationState == WindowActivationState.Deactivated)
{ {
HideWindow(); // HideWindow();
} }
} }

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="PowerDisplay.MonitorIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:PowerDisplay"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Viewbox>
<Grid>
<Grid x:Name="MonitorGrid">
<FontIcon
x:Uid="MonitorTooltip"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontSize="22"
Glyph="&#xE7F4;" />
<TextBlock
Margin="0,0,0,4"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="10"
FontWeight="SemiBold"
Text="{x:Bind MonitorNumber, Mode=OneWay}" />
</Grid>
<Grid
x:Name="BuiltInDisplayGrid"
Padding="0,0,0,-4"
Visibility="Collapsed">
<FontIcon
x:Uid="MonitorTooltip"
Margin="0,0,0,0"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontSize="22"
Glyph="&#xE7FB;" />
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="10"
FontWeight="SemiBold"
Text="{x:Bind MonitorNumber, Mode=OneWay}" />
</Grid>
</Grid>
</Viewbox>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Monitor" />
<VisualState x:Name="BuiltIn">
<VisualState.Setters>
<Setter Target="BuiltInDisplayGrid.Visibility" Value="Visible" />
<Setter Target="MonitorGrid.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>

View File

@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace PowerDisplay;
public sealed partial class MonitorIcon : UserControl
{
public MonitorIcon()
{
InitializeComponent();
}
public bool IsBuiltIn
{
get => (bool)GetValue(IsBuiltInProperty);
set => SetValue(IsBuiltInProperty, value);
}
public static readonly DependencyProperty IsBuiltInProperty = DependencyProperty.Register(nameof(IsBuiltIn), typeof(bool), typeof(MonitorIcon), new PropertyMetadata(false, OnPropertyChanged));
public int MonitorNumber
{
get => (int)GetValue(MonitorNumberProperty);
set => SetValue(MonitorNumberProperty, value);
}
public static readonly DependencyProperty MonitorNumberProperty = DependencyProperty.Register(nameof(MonitorNumber), typeof(int), typeof(MonitorIcon), new PropertyMetadata(0, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var monIcon = (MonitorIcon)d;
if (monIcon.IsBuiltIn)
{
VisualStateManager.GoToState(monIcon, "BuiltIn", true);
}
else
{
VisualStateManager.GoToState(monIcon, "Monitor", true);
}
}
}

View File

@@ -283,10 +283,10 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable
{ {
// Check if there's more than one visible monitor and MonitorNumber is valid // Check if there's more than one visible monitor and MonitorNumber is valid
// Set the limit to zero for debugging. // Set the limit to zero for debugging.
if (_mainViewModel != null && _mainViewModel.Monitors.Count > 0 && MonitorNumber > 0) /* if (_mainViewModel != null && _mainViewModel.Monitors.Count > 0 && MonitorNumber > 0)
{ {
return $"{Name} {MonitorNumber}"; return $"{Name} {MonitorNumber}";
} } */
return Name; return Name;
} }