mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +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})");
|
||||
|
||||
// Apply brightness
|
||||
if (setting.Brightness >= monitorVm.MinBrightness && setting.Brightness <= monitorVm.MaxBrightness)
|
||||
// Apply brightness if included in profile
|
||||
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
|
||||
@@ -622,10 +623,10 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
updateTasks.Add(monitorVm.SetVolumeAsync(setting.Volume.Value, immediate: true, fromProfile: true));
|
||||
}
|
||||
|
||||
// Apply color temperature
|
||||
if (setting.ColorTemperature > 0)
|
||||
// Apply color temperature if included in profile
|
||||
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; }
|
||||
|
||||
[JsonPropertyName("brightness")]
|
||||
public int Brightness { get; set; }
|
||||
public int? Brightness { get; set; }
|
||||
|
||||
[JsonPropertyName("contrast")]
|
||||
public int? Contrast { get; set; }
|
||||
@@ -24,16 +24,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public int? Volume { get; set; }
|
||||
|
||||
[JsonPropertyName("colorTemperature")]
|
||||
public int ColorTemperature { get; set; }
|
||||
public int? ColorTemperature { get; set; }
|
||||
|
||||
public ProfileMonitorSetting()
|
||||
{
|
||||
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;
|
||||
Brightness = brightness;
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsClickEnabled="True" />
|
||||
|
||||
|
||||
|
||||
<tkcontrols:SettingsCard
|
||||
x:Uid="PowerDisplay_RestoreSettingsOnStartup"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
@@ -78,11 +80,11 @@
|
||||
<Button.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem
|
||||
Text="Rename"
|
||||
Click="RenameProfile_Click"
|
||||
Text="Edit"
|
||||
Click="EditProfile_Click"
|
||||
Tag="{x:Bind}">
|
||||
<MenuFlyoutItem.Icon>
|
||||
<FontIcon Glyph=""/>
|
||||
<FontIcon Glyph=""/>
|
||||
</MenuFlyoutItem.Icon>
|
||||
</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;
|
||||
if (menuItem?.Tag is PowerDisplayProfile profile)
|
||||
|
||||
@@ -15,144 +15,261 @@
|
||||
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
|
||||
CloseButtonClick="ContentDialog_CloseButtonClick">
|
||||
|
||||
<ScrollViewer MaxHeight="600" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="16">
|
||||
<!-- Profile Name -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock
|
||||
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>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Monitors Selection -->
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock
|
||||
Text="Select Monitors to Include"
|
||||
<!-- Profile Name Section -->
|
||||
<StackPanel Grid.Row="0" Spacing="4" Margin="0,0,0,24">
|
||||
<TextBlock
|
||||
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}" />
|
||||
<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.ItemTemplate>
|
||||
<DataTemplate x:DataType="viewmodels:MonitorSelectionItem">
|
||||
<Expander
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsExpanded="{x:Bind IsSelected, Mode=TwoWay}"
|
||||
Margin="0,0,0,8">
|
||||
<Expander.Header>
|
||||
<Grid>
|
||||
<Grid Margin="0,0,0,12">
|
||||
<!-- Unselected State -->
|
||||
<Border
|
||||
CornerRadius="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
|
||||
Visibility="{x:Bind IsSelected, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
|
||||
<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" />
|
||||
<StackPanel Grid.Column="1" Orientation="Vertical">
|
||||
Margin="0,0,12,0"
|
||||
VerticalAlignment="Center"/>
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock
|
||||
Text="{x:Bind Monitor.Name}"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
Text="{x:Bind Monitor.Name}"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||
<TextBlock
|
||||
Text="{x:Bind Monitor.HardwareId}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
Text="{x:Bind Monitor.HardwareId}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Foreground="{ThemeResource TextFillColorTertiaryBrush}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
</Border>
|
||||
|
||||
<StackPanel Spacing="12" Padding="32,8,8,8">
|
||||
<!-- Brightness -->
|
||||
<StackPanel Spacing="4">
|
||||
<Grid>
|
||||
<TextBlock Text="Brightness" />
|
||||
<TextBlock
|
||||
Text="{x:Bind Brightness, Mode=OneWay}"
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
||||
<!-- Selected State -->
|
||||
<Border
|
||||
CornerRadius="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{ThemeResource AccentControlElevationBorderBrush}"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
Visibility="{x:Bind IsSelected, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<StackPanel>
|
||||
<!-- 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>
|
||||
<Slider
|
||||
Value="{x:Bind Brightness, Mode=TwoWay}"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
StepFrequency="1"
|
||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Color Temperature -->
|
||||
<StackPanel
|
||||
Spacing="4"
|
||||
Visibility="{x:Bind SupportsColorTemperature, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<TextBlock Text="Color Temperature" />
|
||||
<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>
|
||||
<!-- Content: Settings -->
|
||||
<StackPanel
|
||||
Padding="20,0,20,20"
|
||||
Spacing="0">
|
||||
|
||||
<MenuFlyoutSeparator Margin="-20,0,-20,16" />
|
||||
|
||||
<!-- Contrast -->
|
||||
<StackPanel
|
||||
Spacing="4"
|
||||
Visibility="{x:Bind SupportsContrast, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<TextBlock Text="Contrast" />
|
||||
<TextBlock
|
||||
Text="{x:Bind Contrast, Mode=OneWay}"
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
||||
</Grid>
|
||||
<Slider
|
||||
Value="{x:Bind Contrast, Mode=TwoWay}"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
StepFrequency="1"
|
||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<!-- Brightness Row -->
|
||||
<Grid Margin="0,0,0,12" Visibility="{x:Bind Monitor.SupportsBrightness, 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="Brightness" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<Slider
|
||||
Grid.Column="1"
|
||||
Value="{x:Bind Brightness, Mode=TwoWay}"
|
||||
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 -->
|
||||
<StackPanel
|
||||
Spacing="4"
|
||||
Visibility="{x:Bind SupportsVolume, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<TextBlock Text="Volume" />
|
||||
<TextBlock
|
||||
Text="{x:Bind Volume, Mode=OneWay}"
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
||||
</Grid>
|
||||
<Slider
|
||||
Value="{x:Bind Volume, Mode=TwoWay}"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
StepFrequency="1"
|
||||
IsEnabled="{x:Bind IsSelected, Mode=OneWay}" />
|
||||
<!-- Contrast Row -->
|
||||
<Grid Margin="0,0,0,12" Visibility="{x:Bind Monitor.SupportsContrast, 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="Contrast" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<Slider
|
||||
Grid.Column="1"
|
||||
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>
|
||||
</Expander>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
|
||||
@@ -61,16 +61,32 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
if (monitorItem != null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
monitorItem.IncludeContrast = true;
|
||||
monitorItem.Contrast = monitorSetting.Contrast.Value;
|
||||
}
|
||||
|
||||
// Set volume if included in profile
|
||||
if (monitorSetting.Volume.HasValue)
|
||||
{
|
||||
monitorItem.IncludeVolume = true;
|
||||
monitorItem.Volume = monitorSetting.Volume.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private int _contrast = 50;
|
||||
private int _volume = 50;
|
||||
private int _colorTemperature = 6500;
|
||||
private bool _includeBrightness;
|
||||
private bool _includeContrast;
|
||||
private bool _includeVolume;
|
||||
private bool _includeColorTemperature;
|
||||
|
||||
public required MonitorInfo Monitor { get; set; }
|
||||
|
||||
public bool SuppressAutoSelection { get; set; }
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
@@ -45,6 +51,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
_brightness = value;
|
||||
OnPropertyChanged();
|
||||
if (!SuppressAutoSelection)
|
||||
{
|
||||
IncludeBrightness = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,6 +68,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
_contrast = value;
|
||||
OnPropertyChanged();
|
||||
if (!SuppressAutoSelection)
|
||||
{
|
||||
IncludeContrast = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,6 +85,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
_volume = value;
|
||||
OnPropertyChanged();
|
||||
if (!SuppressAutoSelection)
|
||||
{
|
||||
IncludeVolume = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,6 +102,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
_colorTemperature = value;
|
||||
OnPropertyChanged();
|
||||
if (!SuppressAutoSelection)
|
||||
{
|
||||
IncludeColorTemperature = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +116,58 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
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;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
|
||||
@@ -30,19 +30,33 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
var item = new MonitorSelectionItem
|
||||
{
|
||||
SuppressAutoSelection = true,
|
||||
Monitor = monitor,
|
||||
IsSelected = false,
|
||||
Brightness = monitor.CurrentBrightness,
|
||||
Contrast = 50, // Default value (MonitorInfo doesn't store contrast)
|
||||
Volume = 50, // Default value (MonitorInfo doesn't store volume)
|
||||
ColorTemperature = monitor.ColorTemperature,
|
||||
};
|
||||
|
||||
// Subscribe to selection changes
|
||||
item.SuppressAutoSelection = false;
|
||||
|
||||
// Subscribe to selection and checkbox changes
|
||||
item.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(MonitorSelectionItem.IsSelected))
|
||||
{
|
||||
OnPropertyChanged(nameof(CanSave));
|
||||
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 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()
|
||||
{
|
||||
@@ -87,10 +105,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
.Where(m => m.IsSelected)
|
||||
.Select(m => new ProfileMonitorSetting(
|
||||
m.Monitor.HardwareId,
|
||||
m.Brightness,
|
||||
m.ColorTemperature,
|
||||
m.SupportsContrast ? (int?)m.Contrast : null,
|
||||
m.SupportsVolume ? (int?)m.Volume : null))
|
||||
m.IncludeBrightness ? (int?)m.Brightness : null,
|
||||
m.IncludeColorTemperature && m.SupportsColorTemperature ? (int?)m.ColorTemperature : null,
|
||||
m.IncludeContrast && m.SupportsContrast ? (int?)m.Contrast : null,
|
||||
m.IncludeVolume && m.SupportsVolume ? (int?)m.Volume : null))
|
||||
.ToList();
|
||||
|
||||
return new PowerDisplayProfile(_profileName, settings);
|
||||
|
||||
Reference in New Issue
Block a user