Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color picker fixes #4134

Merged
merged 8 commits into from
Aug 30, 2021
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,43 @@
</controls:ColorPickerButton.ColorPickerStyle>
</controls:ColorPickerButton>
</StackPanel>
<!-- Example 5 -->
<StackPanel Grid.Row="3"
robloo marked this conversation as resolved.
Show resolved Hide resolved
Orientation="Vertical"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="20">
<Border Background="{ThemeResource SystemChromeMediumColor}"
CornerRadius="4"
Height="100"
Width="300"
Padding="10">
<TextBlock TextAlignment="Center"
VerticalAlignment="Center">
Ring-shaped spectrum <LineBreak />
Alpha channel enabled <LineBreak />
Only Color Palette Shown
</TextBlock>
</Border>
<controls:ColorPickerButton x:Name="ColorPickerButton5"
SelectedColor="Teal">
<controls:ColorPickerButton.ColorPickerStyle>
<Style TargetType="controls:ColorPicker">
<Setter Property="ColorSpectrumShape"
Value="Ring"/>
<Setter Property="IsAlphaEnabled"
Value="True"/>
<Setter Property="IsHexInputVisible"
Value="True"/>
<Setter Property="IsColorSpectrumVisible"
Value="False"/>
<Setter Property="IsColorPaletteVisible"
Value="True"/>
<Setter Property="IsColorChannelTextInputVisible"
Value="False"/>
</Style>
</controls:ColorPickerButton.ColorPickerStyle>
</controls:ColorPickerButton>
</StackPanel>
</Grid>
</Page>
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
Alpha channel enabled
</TextBlock>
</Border>
<controls:ColorPicker x:Name="ColorPickerButton3"
<controls:ColorPicker x:Name="ColorPicker3"
Color="Transparent"
ColorSpectrumShape="Ring"
IsAlphaEnabled="True"
Expand All @@ -78,12 +78,33 @@
Saturation+Value spectrum channels
</TextBlock>
</Border>
<controls:ColorPicker x:Name="ColorPickerButton4"
<controls:ColorPicker x:Name="ColorPicker4"
Color="Maroon"
ColorSpectrumShape="Ring"
ColorSpectrumComponents="SaturationValue"
IsAlphaEnabled="True"
IsHexInputVisible="True"/>
<!-- Example 5 -->
<Border Background="{ThemeResource SystemChromeMediumColor}"
CornerRadius="4"
Height="100"
Width="300"
Padding="10">
<TextBlock TextAlignment="Center"
VerticalAlignment="Center">
Ring-shaped spectrum <LineBreak />
Alpha channel enabled <LineBreak />
Only Color Palette Shown
</TextBlock>
</Border>
<controls:ColorPicker x:Name="ColorPicker5"
Color="Teal"
ColorSpectrumShape="Ring"
IsAlphaEnabled="True"
IsHexInputVisible="True"
IsColorSpectrumVisible="False"
IsColorPaletteVisible="True"
IsColorChannelTextInputVisible="False"/>
</StackPanel>
</ScrollViewer>
</Page>
47 changes: 47 additions & 0 deletions Microsoft.Toolkit.Uwp.UI.Controls.Input/ColorPicker/ColorPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
[TemplatePart(Name = nameof(ColorPicker.CheckeredBackground8Border), Type = typeof(Border))]
[TemplatePart(Name = nameof(ColorPicker.CheckeredBackground9Border), Type = typeof(Border))]
[TemplatePart(Name = nameof(ColorPicker.CheckeredBackground10Border), Type = typeof(Border))]
[TemplatePart(Name = nameof(ColorPicker.ColorPanelSelector), Type = typeof(ListBox))]
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumControl), Type = typeof(ColorSpectrum))]
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumAlphaSlider), Type = typeof(ColorPickerSlider))]
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumThirdDimensionSlider), Type = typeof(ColorPickerSlider))]
Expand Down Expand Up @@ -78,6 +79,7 @@ public partial class ColorPicker : Microsoft.UI.Xaml.Controls.ColorPicker
private Color? updatedRgbColor = null;
private DispatcherQueueTimer dispatcherQueueTimer = null;

private ListBox ColorPanelSelector;
private ColorSpectrum ColorSpectrumControl;
private ColorPickerSlider ColorSpectrumAlphaSlider;
private ColorPickerSlider ColorSpectrumThirdDimensionSlider;
Expand Down Expand Up @@ -177,6 +179,8 @@ protected override void OnApplyTemplate()
// We need to disconnect old events first
this.ConnectEvents(false);

this.ColorPanelSelector = this.GetTemplateChild<ListBox>(nameof(ColorPanelSelector));

this.ColorSpectrumControl = this.GetTemplateChild<ColorSpectrum>(nameof(ColorSpectrumControl));
this.ColorSpectrumAlphaSlider = this.GetTemplateChild<ColorPickerSlider>(nameof(ColorSpectrumAlphaSlider));
this.ColorSpectrumThirdDimensionSlider = this.GetTemplateChild<ColorPickerSlider>(nameof(ColorSpectrumThirdDimensionSlider));
Expand Down Expand Up @@ -216,6 +220,7 @@ protected override void OnApplyTemplate()

base.OnApplyTemplate();
this.UpdateVisualState(false);
this.ValidateSelectedPanel();
Copy link
Contributor Author

@robloo robloo Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an issue with validating and updating the selected panel only here. If the IsColorSpectrumVisible or IsColorChannelTextInputVisible properties are changed after the template is applied the selected tab may become invalid. This is because the base WinUI ColorPicker is currenlty responsible for updating the visual state that actually applies tab visibility for these two (it is all done in the style). Only IsColorPaletteVisible is managed by the derived toolkit ColorPicker. To fix this:

  1. Need to monitor for property changes on these properties as well, or
  2. Need to connect to VisualState changed events -- there are more than one and this is a bit ugly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an existing issue, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was waiting to see if its considered enough of an issue to fix. The changes now will work as long as the properties are updated in XAML which is by far the largest use case.

this.isInitialized = true;
this.SetActiveColorRepresentation(ColorRepresentation.Rgba);
this.UpdateColorControlValues(); // TODO: This will also connect events after, can we optimize vs. doing it twice with the ConnectEvents above?
Expand Down Expand Up @@ -1065,6 +1070,48 @@ private void SetDefaultPalette()
return;
}

/// <summary>
/// Validates and updates the current 'tab' or 'panel' selection.
/// If the currently selected tab is collapsed, the next visible tab will be selected.
/// </summary>
private void ValidateSelectedPanel()
{
object selectedItem = null;

if (this.ColorPanelSelector != null)
{
if (this.ColorPanelSelector.SelectedItem == null &&
this.ColorPanelSelector.Items.Count > 0)
{
// As a failsafe, forcefully select the first item
selectedItem = this.ColorPanelSelector.Items[0];
}
else
{
selectedItem = this.ColorPanelSelector.SelectedItem;
}

if (selectedItem is UIElement selectedElement &&
selectedElement.Visibility == Visibility.Collapsed)
{
// Select the first visible item instead
foreach (object item in this.ColorPanelSelector.Items)
{
if (item is UIElement element &&
element.Visibility == Visibility.Visible)
{
selectedItem = item;
break;
}
}
}

this.ColorPanelSelector.SelectedItem = selectedItem;
}

return;
}

/***************************************************************************************
*
* Color Update Timer
Expand Down