mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Enhance profile settings and UI for monitor controls
Refactor logic to support optional inclusion of brightness, contrast, volume, and color temperature in monitor profiles. Updated `Brightness` and `ColorTemperature` to nullable types and adjusted related logic in `MainViewModel.cs` and `ProfileMonitorSetting.cs`. Improved the UI in `PowerDisplayPage.xaml` and `ProfileEditorDialog.xaml`: - Added toggle switches for selectively including settings in profiles. - Enhanced layout and styling for better user experience. - Updated context menu and monitor selection visuals. Enhanced `MonitorSelectionItem.cs` with new `Include` flags and auto-selection suppression. Updated `ProfileEditorViewModel.cs` to validate profiles and ensure at least one setting is included for selected monitors. Performed general code cleanup for readability and maintainability.
This commit is contained in:
@@ -602,10 +602,11 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
|||||||
|
|
||||||
Logger.LogInfo($"[Profile] Applying settings to monitor '{monitorVm.Name}' (HardwareId: {setting.HardwareId})");
|
Logger.LogInfo($"[Profile] Applying settings to monitor '{monitorVm.Name}' (HardwareId: {setting.HardwareId})");
|
||||||
|
|
||||||
// Apply brightness
|
// Apply brightness if included in profile
|
||||||
if (setting.Brightness >= monitorVm.MinBrightness && setting.Brightness <= monitorVm.MaxBrightness)
|
if (setting.Brightness.HasValue &&
|
||||||
|
setting.Brightness.Value >= monitorVm.MinBrightness && setting.Brightness.Value <= monitorVm.MaxBrightness)
|
||||||
{
|
{
|
||||||
updateTasks.Add(monitorVm.SetBrightnessAsync(setting.Brightness, immediate: true, fromProfile: true));
|
updateTasks.Add(monitorVm.SetBrightnessAsync(setting.Brightness.Value, immediate: true, fromProfile: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply contrast if supported and value provided
|
// Apply contrast if supported and value provided
|
||||||
@@ -622,10 +623,10 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
|||||||
updateTasks.Add(monitorVm.SetVolumeAsync(setting.Volume.Value, immediate: true, fromProfile: true));
|
updateTasks.Add(monitorVm.SetVolumeAsync(setting.Volume.Value, immediate: true, fromProfile: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply color temperature
|
// Apply color temperature if included in profile
|
||||||
if (setting.ColorTemperature > 0)
|
if (setting.ColorTemperature.HasValue && setting.ColorTemperature.Value > 0)
|
||||||
{
|
{
|
||||||
updateTasks.Add(monitorVm.SetColorTemperatureAsync(setting.ColorTemperature, fromProfile: true));
|
updateTasks.Add(monitorVm.SetColorTemperatureAsync(setting.ColorTemperature.Value, fromProfile: true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
public string HardwareId { get; set; }
|
public string HardwareId { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("brightness")]
|
[JsonPropertyName("brightness")]
|
||||||
public int Brightness { get; set; }
|
public int? Brightness { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("contrast")]
|
[JsonPropertyName("contrast")]
|
||||||
public int? Contrast { get; set; }
|
public int? Contrast { get; set; }
|
||||||
@@ -24,16 +24,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
public int? Volume { get; set; }
|
public int? Volume { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("colorTemperature")]
|
[JsonPropertyName("colorTemperature")]
|
||||||
public int ColorTemperature { get; set; }
|
public int? ColorTemperature { get; set; }
|
||||||
|
|
||||||
public ProfileMonitorSetting()
|
public ProfileMonitorSetting()
|
||||||
{
|
{
|
||||||
HardwareId = string.Empty;
|
HardwareId = string.Empty;
|
||||||
Brightness = 100;
|
|
||||||
ColorTemperature = 6500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileMonitorSetting(string hardwareId, int brightness, int colorTemperature, int? contrast = null, int? volume = null)
|
public ProfileMonitorSetting(string hardwareId, int? brightness = null, int? colorTemperature = null, int? contrast = null, int? volume = null)
|
||||||
{
|
{
|
||||||
HardwareId = hardwareId;
|
HardwareId = hardwareId;
|
||||||
Brightness = brightness;
|
Brightness = brightness;
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||||
IsClickEnabled="True" />
|
IsClickEnabled="True" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tkcontrols:SettingsCard
|
<tkcontrols:SettingsCard
|
||||||
x:Uid="PowerDisplay_RestoreSettingsOnStartup"
|
x:Uid="PowerDisplay_RestoreSettingsOnStartup"
|
||||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||||
@@ -78,11 +80,11 @@
|
|||||||
<Button.ContextFlyout>
|
<Button.ContextFlyout>
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
<MenuFlyoutItem
|
<MenuFlyoutItem
|
||||||
Text="Rename"
|
Text="Edit"
|
||||||
Click="RenameProfile_Click"
|
Click="EditProfile_Click"
|
||||||
Tag="{x:Bind}">
|
Tag="{x:Bind}">
|
||||||
<MenuFlyoutItem.Icon>
|
<MenuFlyoutItem.Icon>
|
||||||
<FontIcon Glyph=""/>
|
<FontIcon Glyph=""/>
|
||||||
</MenuFlyoutItem.Icon>
|
</MenuFlyoutItem.Icon>
|
||||||
</MenuFlyoutItem>
|
</MenuFlyoutItem>
|
||||||
<MenuFlyoutItem
|
<MenuFlyoutItem
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void RenameProfile_Click(object sender, RoutedEventArgs e)
|
private async void EditProfile_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var menuItem = sender as MenuFlyoutItem;
|
var menuItem = sender as MenuFlyoutItem;
|
||||||
if (menuItem?.Tag is PowerDisplayProfile profile)
|
if (menuItem?.Tag is PowerDisplayProfile profile)
|
||||||
|
|||||||
@@ -15,144 +15,261 @@
|
|||||||
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
|
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
|
||||||
CloseButtonClick="ContentDialog_CloseButtonClick">
|
CloseButtonClick="ContentDialog_CloseButtonClick">
|
||||||
|
|
||||||
<ScrollViewer MaxHeight="600" VerticalScrollBarVisibility="Auto">
|
<Grid>
|
||||||
<StackPanel Spacing="16">
|
<Grid.RowDefinitions>
|
||||||
<!-- Profile Name -->
|
<RowDefinition Height="Auto" />
|
||||||
<StackPanel Spacing="4">
|
<RowDefinition Height="*" />
|
||||||
<TextBlock
|
</Grid.RowDefinitions>
|
||||||
Text="Profile Name"
|
|
||||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
|
||||||
<TextBox
|
|
||||||
x:Name="ProfileNameTextBox"
|
|
||||||
Text="{x:Bind ViewModel.ProfileName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
|
||||||
PlaceholderText="Enter profile name (e.g., 'Work Setup', 'Gaming')"
|
|
||||||
MaxLength="50" />
|
|
||||||
<TextBlock
|
|
||||||
Text="Leave empty to auto-generate (Profile1, Profile2, etc.)"
|
|
||||||
Style="{StaticResource CaptionTextBlockStyle}"
|
|
||||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- Monitors Selection -->
|
<!-- Profile Name Section -->
|
||||||
<StackPanel Spacing="8">
|
<StackPanel Grid.Row="0" Spacing="4" Margin="0,0,0,24">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="Select Monitors to Include"
|
Text="Profile Name"
|
||||||
|
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="ProfileNameTextBox"
|
||||||
|
Text="{x:Bind ViewModel.ProfileName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
PlaceholderText="Enter profile name (e.g., 'Gaming Mode', 'Work')"
|
||||||
|
MaxLength="50" />
|
||||||
|
<TextBlock
|
||||||
|
Text="Leave empty to auto-generate"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Monitors List -->
|
||||||
|
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" Padding="0,0,16,0">
|
||||||
|
<StackPanel Spacing="16">
|
||||||
|
<TextBlock
|
||||||
|
Text="Select Monitors"
|
||||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||||
<TextBlock
|
|
||||||
Text="At least one monitor must be selected"
|
|
||||||
Style="{StaticResource CaptionTextBlockStyle}"
|
|
||||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
|
||||||
Visibility="{x:Bind ViewModel.HasSelectedMonitors, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}" />
|
|
||||||
|
|
||||||
<ItemsControl ItemsSource="{x:Bind ViewModel.Monitors, Mode=OneWay}">
|
<ItemsControl ItemsSource="{x:Bind ViewModel.Monitors, Mode=OneWay}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate x:DataType="viewmodels:MonitorSelectionItem">
|
<DataTemplate x:DataType="viewmodels:MonitorSelectionItem">
|
||||||
<Expander
|
<Grid Margin="0,0,0,12">
|
||||||
HorizontalAlignment="Stretch"
|
<!-- Unselected State -->
|
||||||
HorizontalContentAlignment="Stretch"
|
<Border
|
||||||
IsExpanded="{x:Bind IsSelected, Mode=TwoWay}"
|
CornerRadius="8"
|
||||||
Margin="0,0,0,8">
|
BorderThickness="1"
|
||||||
<Expander.Header>
|
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||||
<Grid>
|
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
|
||||||
|
Visibility="{x:Bind IsSelected, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
|
||||||
|
<Grid Padding="16,12">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
IsChecked="{x:Bind IsSelected, Mode=TwoWay}"
|
IsChecked="{x:Bind IsSelected, Mode=TwoWay}"
|
||||||
Margin="0,0,12,0" />
|
Margin="0,0,12,0"
|
||||||
<StackPanel Grid.Column="1" Orientation="Vertical">
|
VerticalAlignment="Center"/>
|
||||||
|
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{x:Bind Monitor.Name}"
|
Text="{x:Bind Monitor.Name}"
|
||||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{x:Bind Monitor.HardwareId}"
|
Text="{x:Bind Monitor.HardwareId}"
|
||||||
Style="{StaticResource CaptionTextBlockStyle}"
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
Foreground="{ThemeResource TextFillColorTertiaryBrush}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Expander.Header>
|
</Border>
|
||||||
|
|
||||||
<StackPanel Spacing="12" Padding="32,8,8,8">
|
<!-- Selected State -->
|
||||||
<!-- Brightness -->
|
<Border
|
||||||
<StackPanel Spacing="4">
|
CornerRadius="8"
|
||||||
<Grid>
|
BorderThickness="1"
|
||||||
<TextBlock Text="Brightness" />
|
BorderBrush="{ThemeResource AccentControlElevationBorderBrush}"
|
||||||
<TextBlock
|
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||||
Text="{x:Bind Brightness, Mode=OneWay}"
|
Visibility="{x:Bind IsSelected, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
HorizontalAlignment="Right"
|
<StackPanel>
|
||||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
<!-- Header: Monitor Selection -->
|
||||||
|
<Grid Padding="16,12">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<CheckBox
|
||||||
|
IsChecked="{x:Bind IsSelected, Mode=TwoWay}"
|
||||||
|
Margin="0,0,12,0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||||
|
<TextBlock
|
||||||
|
Text="{x:Bind Monitor.Name}"
|
||||||
|
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||||
|
<TextBlock
|
||||||
|
Text="{x:Bind Monitor.HardwareId}"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||||
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Slider
|
|
||||||
Value="{x:Bind Brightness, Mode=TwoWay}"
|
|
||||||
Minimum="0"
|
|
||||||
Maximum="100"
|
|
||||||
StepFrequency="1"
|
|
||||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- Color Temperature -->
|
<!-- Content: Settings -->
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Spacing="4"
|
Padding="20,0,20,20"
|
||||||
Visibility="{x:Bind SupportsColorTemperature, Converter={StaticResource BoolToVisibilityConverter}}">
|
Spacing="0">
|
||||||
<Grid>
|
|
||||||
<TextBlock Text="Color Temperature" />
|
<MenuFlyoutSeparator Margin="-20,0,-20,16" />
|
||||||
<TextBlock
|
|
||||||
Text="{x:Bind ColorTemperature, Mode=OneWay}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
|
||||||
</Grid>
|
|
||||||
<Slider
|
|
||||||
Value="{x:Bind ColorTemperature, Mode=TwoWay}"
|
|
||||||
Minimum="4000"
|
|
||||||
Maximum="10000"
|
|
||||||
StepFrequency="100"
|
|
||||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- Contrast -->
|
<!-- Brightness Row -->
|
||||||
<StackPanel
|
<Grid Margin="0,0,0,12" Visibility="{x:Bind Monitor.SupportsBrightness, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
Spacing="4"
|
<Grid.ColumnDefinitions>
|
||||||
Visibility="{x:Bind SupportsContrast, Converter={StaticResource BoolToVisibilityConverter}}">
|
<ColumnDefinition Width="140" />
|
||||||
<Grid>
|
<ColumnDefinition Width="*" />
|
||||||
<TextBlock Text="Contrast" />
|
<ColumnDefinition Width="40" />
|
||||||
<TextBlock
|
<ColumnDefinition Width="50" />
|
||||||
Text="{x:Bind Contrast, Mode=OneWay}"
|
</Grid.ColumnDefinitions>
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Spacing="12">
|
||||||
</Grid>
|
<FontIcon Glyph="" FontSize="16" Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
<Slider
|
<TextBlock Text="Brightness" VerticalAlignment="Center"/>
|
||||||
Value="{x:Bind Contrast, Mode=TwoWay}"
|
</StackPanel>
|
||||||
Minimum="0"
|
|
||||||
Maximum="100"
|
<Slider
|
||||||
StepFrequency="1"
|
Grid.Column="1"
|
||||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
Value="{x:Bind Brightness, Mode=TwoWay}"
|
||||||
</StackPanel>
|
Minimum="0" Maximum="100"
|
||||||
|
Margin="12,0,12,0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="2"
|
||||||
|
Text="{x:Bind Brightness, Mode=OneWay}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
TextAlignment="Right"
|
||||||
|
Margin="0,0,8,0"/>
|
||||||
|
|
||||||
|
<ToggleSwitch
|
||||||
|
Grid.Column="3"
|
||||||
|
IsOn="{x:Bind IncludeBrightness, Mode=TwoWay}"
|
||||||
|
OnContent="" OffContent=""
|
||||||
|
MinWidth="0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<!-- Volume -->
|
<!-- Contrast Row -->
|
||||||
<StackPanel
|
<Grid Margin="0,0,0,12" Visibility="{x:Bind Monitor.SupportsContrast, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
Spacing="4"
|
<Grid.ColumnDefinitions>
|
||||||
Visibility="{x:Bind SupportsVolume, Converter={StaticResource BoolToVisibilityConverter}}">
|
<ColumnDefinition Width="140" />
|
||||||
<Grid>
|
<ColumnDefinition Width="*" />
|
||||||
<TextBlock Text="Volume" />
|
<ColumnDefinition Width="40" />
|
||||||
<TextBlock
|
<ColumnDefinition Width="50" />
|
||||||
Text="{x:Bind Volume, Mode=OneWay}"
|
</Grid.ColumnDefinitions>
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Spacing="12">
|
||||||
</Grid>
|
<FontIcon Glyph="" FontSize="16" Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
<Slider
|
<TextBlock Text="Contrast" VerticalAlignment="Center"/>
|
||||||
Value="{x:Bind Volume, Mode=TwoWay}"
|
</StackPanel>
|
||||||
Minimum="0"
|
|
||||||
Maximum="100"
|
<Slider
|
||||||
StepFrequency="1"
|
Grid.Column="1"
|
||||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
Value="{x:Bind Contrast, Mode=TwoWay}"
|
||||||
|
Minimum="0" Maximum="100"
|
||||||
|
Margin="12,0,12,0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="2"
|
||||||
|
Text="{x:Bind Contrast, Mode=OneWay}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
TextAlignment="Right"
|
||||||
|
Margin="0,0,8,0"/>
|
||||||
|
|
||||||
|
<ToggleSwitch
|
||||||
|
Grid.Column="3"
|
||||||
|
IsOn="{x:Bind IncludeContrast, Mode=TwoWay}"
|
||||||
|
OnContent="" OffContent=""
|
||||||
|
MinWidth="0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Volume Row -->
|
||||||
|
<Grid Margin="0,0,0,12" Visibility="{x:Bind Monitor.SupportsVolume, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="140" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="40" />
|
||||||
|
<ColumnDefinition Width="50" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Spacing="12">
|
||||||
|
<FontIcon Glyph="" FontSize="16" Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
|
<TextBlock Text="Volume" VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Slider
|
||||||
|
Grid.Column="1"
|
||||||
|
Value="{x:Bind Volume, Mode=TwoWay}"
|
||||||
|
Minimum="0" Maximum="100"
|
||||||
|
Margin="12,0,12,0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="2"
|
||||||
|
Text="{x:Bind Volume, Mode=OneWay}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
TextAlignment="Right"
|
||||||
|
Margin="0,0,8,0"/>
|
||||||
|
|
||||||
|
<ToggleSwitch
|
||||||
|
Grid.Column="3"
|
||||||
|
IsOn="{x:Bind IncludeVolume, Mode=TwoWay}"
|
||||||
|
OnContent="" OffContent=""
|
||||||
|
MinWidth="0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Color Temperature Row -->
|
||||||
|
<Grid Margin="0,0,0,0" Visibility="{x:Bind Monitor.SupportsColorTemperature, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="140" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="40" />
|
||||||
|
<ColumnDefinition Width="50" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Spacing="12">
|
||||||
|
<FontIcon Glyph="" FontSize="16" Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
|
<TextBlock Text="Color Temp" VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Margin="12,0,12,0"
|
||||||
|
MinWidth="160"
|
||||||
|
ItemsSource="{x:Bind Monitor.ColorPresetsForDisplay, Mode=OneWay}"
|
||||||
|
SelectedValue="{x:Bind ColorTemperature, Mode=TwoWay}"
|
||||||
|
SelectedValuePath="VcpValue"
|
||||||
|
DisplayMemberPath="DisplayName"
|
||||||
|
PlaceholderText="Select..."
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
|
||||||
|
<!-- Spacer to match layout -->
|
||||||
|
<Grid Grid.Column="2" />
|
||||||
|
|
||||||
|
<ToggleSwitch
|
||||||
|
Grid.Column="3"
|
||||||
|
IsOn="{x:Bind IncludeColorTemperature, Mode=TwoWay}"
|
||||||
|
OnContent="" OffContent=""
|
||||||
|
MinWidth="0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</Border>
|
||||||
</Expander>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</ScrollViewer>
|
||||||
</ScrollViewer>
|
</Grid>
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
|
|||||||
@@ -61,16 +61,32 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
|||||||
if (monitorItem != null)
|
if (monitorItem != null)
|
||||||
{
|
{
|
||||||
monitorItem.IsSelected = true;
|
monitorItem.IsSelected = true;
|
||||||
monitorItem.Brightness = monitorSetting.Brightness;
|
|
||||||
monitorItem.ColorTemperature = monitorSetting.ColorTemperature;
|
|
||||||
|
|
||||||
|
// Set brightness if included in profile
|
||||||
|
if (monitorSetting.Brightness.HasValue)
|
||||||
|
{
|
||||||
|
monitorItem.IncludeBrightness = true;
|
||||||
|
monitorItem.Brightness = monitorSetting.Brightness.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set color temperature if included in profile
|
||||||
|
if (monitorSetting.ColorTemperature.HasValue)
|
||||||
|
{
|
||||||
|
monitorItem.IncludeColorTemperature = true;
|
||||||
|
monitorItem.ColorTemperature = monitorSetting.ColorTemperature.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set contrast if included in profile
|
||||||
if (monitorSetting.Contrast.HasValue)
|
if (monitorSetting.Contrast.HasValue)
|
||||||
{
|
{
|
||||||
|
monitorItem.IncludeContrast = true;
|
||||||
monitorItem.Contrast = monitorSetting.Contrast.Value;
|
monitorItem.Contrast = monitorSetting.Contrast.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set volume if included in profile
|
||||||
if (monitorSetting.Volume.HasValue)
|
if (monitorSetting.Volume.HasValue)
|
||||||
{
|
{
|
||||||
|
monitorItem.IncludeVolume = true;
|
||||||
monitorItem.Volume = monitorSetting.Volume.Value;
|
monitorItem.Volume = monitorSetting.Volume.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
private int _contrast = 50;
|
private int _contrast = 50;
|
||||||
private int _volume = 50;
|
private int _volume = 50;
|
||||||
private int _colorTemperature = 6500;
|
private int _colorTemperature = 6500;
|
||||||
|
private bool _includeBrightness;
|
||||||
|
private bool _includeContrast;
|
||||||
|
private bool _includeVolume;
|
||||||
|
private bool _includeColorTemperature;
|
||||||
|
|
||||||
public required MonitorInfo Monitor { get; set; }
|
public required MonitorInfo Monitor { get; set; }
|
||||||
|
|
||||||
|
public bool SuppressAutoSelection { get; set; }
|
||||||
|
|
||||||
public bool IsSelected
|
public bool IsSelected
|
||||||
{
|
{
|
||||||
get => _isSelected;
|
get => _isSelected;
|
||||||
@@ -45,6 +51,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
{
|
{
|
||||||
_brightness = value;
|
_brightness = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
|
if (!SuppressAutoSelection)
|
||||||
|
{
|
||||||
|
IncludeBrightness = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,6 +68,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
{
|
{
|
||||||
_contrast = value;
|
_contrast = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
|
if (!SuppressAutoSelection)
|
||||||
|
{
|
||||||
|
IncludeContrast = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,6 +85,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
{
|
{
|
||||||
_volume = value;
|
_volume = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
|
if (!SuppressAutoSelection)
|
||||||
|
{
|
||||||
|
IncludeVolume = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,6 +102,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
{
|
{
|
||||||
_colorTemperature = value;
|
_colorTemperature = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
|
if (!SuppressAutoSelection)
|
||||||
|
{
|
||||||
|
IncludeColorTemperature = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,6 +116,58 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
|
|
||||||
public bool SupportsColorTemperature => Monitor?.SupportsColorTemperature ?? false;
|
public bool SupportsColorTemperature => Monitor?.SupportsColorTemperature ?? false;
|
||||||
|
|
||||||
|
public bool IncludeBrightness
|
||||||
|
{
|
||||||
|
get => _includeBrightness;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_includeBrightness != value)
|
||||||
|
{
|
||||||
|
_includeBrightness = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IncludeContrast
|
||||||
|
{
|
||||||
|
get => _includeContrast;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_includeContrast != value)
|
||||||
|
{
|
||||||
|
_includeContrast = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IncludeVolume
|
||||||
|
{
|
||||||
|
get => _includeVolume;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_includeVolume != value)
|
||||||
|
{
|
||||||
|
_includeVolume = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IncludeColorTemperature
|
||||||
|
{
|
||||||
|
get => _includeColorTemperature;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_includeColorTemperature != value)
|
||||||
|
{
|
||||||
|
_includeColorTemperature = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler? PropertyChanged;
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||||
|
|||||||
@@ -30,19 +30,33 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
{
|
{
|
||||||
var item = new MonitorSelectionItem
|
var item = new MonitorSelectionItem
|
||||||
{
|
{
|
||||||
|
SuppressAutoSelection = true,
|
||||||
Monitor = monitor,
|
Monitor = monitor,
|
||||||
IsSelected = false,
|
IsSelected = false,
|
||||||
Brightness = monitor.CurrentBrightness,
|
Brightness = monitor.CurrentBrightness,
|
||||||
|
Contrast = 50, // Default value (MonitorInfo doesn't store contrast)
|
||||||
|
Volume = 50, // Default value (MonitorInfo doesn't store volume)
|
||||||
ColorTemperature = monitor.ColorTemperature,
|
ColorTemperature = monitor.ColorTemperature,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Subscribe to selection changes
|
item.SuppressAutoSelection = false;
|
||||||
|
|
||||||
|
// Subscribe to selection and checkbox changes
|
||||||
item.PropertyChanged += (s, e) =>
|
item.PropertyChanged += (s, e) =>
|
||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(MonitorSelectionItem.IsSelected))
|
if (e.PropertyName == nameof(MonitorSelectionItem.IsSelected))
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(CanSave));
|
OnPropertyChanged(nameof(CanSave));
|
||||||
OnPropertyChanged(nameof(HasSelectedMonitors));
|
OnPropertyChanged(nameof(HasSelectedMonitors));
|
||||||
|
OnPropertyChanged(nameof(HasValidSettings));
|
||||||
|
}
|
||||||
|
else if (e.PropertyName == nameof(MonitorSelectionItem.IncludeBrightness) ||
|
||||||
|
e.PropertyName == nameof(MonitorSelectionItem.IncludeContrast) ||
|
||||||
|
e.PropertyName == nameof(MonitorSelectionItem.IncludeVolume) ||
|
||||||
|
e.PropertyName == nameof(MonitorSelectionItem.IncludeColorTemperature))
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(CanSave));
|
||||||
|
OnPropertyChanged(nameof(HasValidSettings));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,7 +93,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
|
|
||||||
public bool HasSelectedMonitors => _monitors?.Any(m => m.IsSelected) ?? false;
|
public bool HasSelectedMonitors => _monitors?.Any(m => m.IsSelected) ?? false;
|
||||||
|
|
||||||
public bool CanSave => !string.IsNullOrWhiteSpace(_profileName) && HasSelectedMonitors;
|
public bool HasValidSettings => _monitors != null &&
|
||||||
|
_monitors.Any(m => m.IsSelected) &&
|
||||||
|
_monitors.Where(m => m.IsSelected).All(m => m.IncludeBrightness || m.IncludeContrast || m.IncludeVolume || m.IncludeColorTemperature);
|
||||||
|
|
||||||
|
public bool CanSave => !string.IsNullOrWhiteSpace(_profileName) && HasSelectedMonitors && HasValidSettings;
|
||||||
|
|
||||||
public PowerDisplayProfile CreateProfile()
|
public PowerDisplayProfile CreateProfile()
|
||||||
{
|
{
|
||||||
@@ -87,10 +105,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
.Where(m => m.IsSelected)
|
.Where(m => m.IsSelected)
|
||||||
.Select(m => new ProfileMonitorSetting(
|
.Select(m => new ProfileMonitorSetting(
|
||||||
m.Monitor.HardwareId,
|
m.Monitor.HardwareId,
|
||||||
m.Brightness,
|
m.IncludeBrightness ? (int?)m.Brightness : null,
|
||||||
m.ColorTemperature,
|
m.IncludeColorTemperature && m.SupportsColorTemperature ? (int?)m.ColorTemperature : null,
|
||||||
m.SupportsContrast ? (int?)m.Contrast : null,
|
m.IncludeContrast && m.SupportsContrast ? (int?)m.Contrast : null,
|
||||||
m.SupportsVolume ? (int?)m.Volume : null))
|
m.IncludeVolume && m.SupportsVolume ? (int?)m.Volume : null))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return new PowerDisplayProfile(_profileName, settings);
|
return new PowerDisplayProfile(_profileName, settings);
|
||||||
|
|||||||
Reference in New Issue
Block a user