Browse Source

Merge pull request #5545 from AvaloniaUI/fixes/4205-slider-keyboard

Fix slider keyboard interaction and add IsDirectionReversed
pull/5546/head
Jumar Macato 6 years ago
committed by GitHub
parent
commit
10075e34af
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      samples/ControlCatalog/Pages/AcrylicPage.xaml
  2. 15
      samples/ControlCatalog/Pages/SliderPage.xaml
  3. 47
      src/Avalonia.Controls/Slider.cs
  4. 5
      src/Avalonia.Themes.Default/Slider.xaml
  5. 12
      src/Avalonia.Themes.Fluent/Controls/Slider.xaml

8
samples/ControlCatalog/Pages/AcrylicPage.xaml

@ -16,13 +16,13 @@
<StackPanel Spacing="5" Margin="40 10">
<StackPanel Orientation="Horizontal">
<TextBlock Text="TintOpacity" Foreground="Black" />
<Slider Name="TintOpacitySlider" Minimum="0" Maximum="1" Value="0.9" Width="400" />
<TextBlock Text="{Binding #TintOpacitySlider.Value}" Foreground="Black" />
<Slider Name="TintOpacitySlider" Minimum="0" Maximum="1" Value="0.9" SmallChange="0.1" LargeChange="0.2" Width="400" />
<TextBlock Text="{Binding #TintOpacitySlider.Value, StringFormat=\{0:0.#\}}" Foreground="Black" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="MaterialOpacity" Foreground="Black" />
<Slider Name="MaterialOpacitySlider" Minimum="0" Maximum="1" Value="0.8" Width="400" />
<TextBlock Text="{Binding #MaterialOpacitySlider.Value}" Foreground="Black" />
<Slider Name="MaterialOpacitySlider" Minimum="0" Maximum="1" Value="0.8" SmallChange="0.1" LargeChange="0.2" Width="400" />
<TextBlock Text="{Binding #MaterialOpacitySlider.Value, StringFormat=\{0:0.#\}}" Foreground="Black" />
</StackPanel>
</StackPanel>
</ExperimentalAcrylicBorder>

15
samples/ControlCatalog/Pages/SliderPage.xaml

@ -45,6 +45,12 @@
<sys:Exception />
</DataValidationErrors.Error>
</Slider>
<Slider Value="0"
IsDirectionReversed="True"
Minimum="0"
Maximum="100"
TickFrequency="10"
Width="300" />
</StackPanel>
<Slider Value="0"
Minimum="0"
@ -54,6 +60,15 @@
TickPlacement="Outside"
TickFrequency="10"
Height="300"/>
<Slider Value="0"
IsDirectionReversed="True"
Minimum="0"
Maximum="100"
Orientation="Vertical"
IsSnapToTickEnabled="True"
TickPlacement="Outside"
TickFrequency="10"
Height="300"/>
</StackPanel>
</StackPanel>

47
src/Avalonia.Controls/Slider.cs

@ -49,6 +49,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty<Orientation> OrientationProperty =
ScrollBar.OrientationProperty.AddOwner<Slider>();
/// <summary>
/// Defines the <see cref="IsDirectionReversed"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsDirectionReversedProperty =
Track.IsDirectionReversedProperty.AddOwner<Slider>();
/// <summary>
/// Defines the <see cref="IsSnapToTickEnabled"/> property.
/// </summary>
@ -83,7 +89,6 @@ namespace Avalonia.Controls
private IDisposable _increaseButtonSubscription;
private IDisposable _increaseButtonReleaseDispose;
private IDisposable _pointerMovedDispose;
private IDisposable _trackOnKeyDownDispose;
private const double Tolerance = 0.0001;
@ -93,6 +98,7 @@ namespace Avalonia.Controls
static Slider()
{
PressedMixin.Attach<Slider>();
FocusableProperty.OverrideDefaultValue<Slider>(true);
OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
Thumb.DragStartedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragCompleted(e),
@ -127,6 +133,19 @@ namespace Avalonia.Controls
set { SetValue(OrientationProperty, value); }
}
/// <summary>
/// Gets or sets the direction of increasing value.
/// </summary>
/// <value>
/// true if the direction of increasing value is to the left for a horizontal slider or
/// down for a vertical slider; otherwise, false. The default is false.
/// </value>
public bool IsDirectionReversed
{
get { return GetValue(IsDirectionReversedProperty); }
set { SetValue(IsDirectionReversedProperty, value); }
}
/// <summary>
/// Gets or sets a value that indicates whether the <see cref="Slider"/> automatically moves the <see cref="Thumb"/> to the closest tick mark.
/// </summary>
@ -165,7 +184,6 @@ namespace Avalonia.Controls
_increaseButtonSubscription?.Dispose();
_increaseButtonReleaseDispose?.Dispose();
_pointerMovedDispose?.Dispose();
_trackOnKeyDownDispose?.Dispose();
_decreaseButton = e.NameScope.Find<Button>("PART_DecreaseButton");
_track = e.NameScope.Find<Track>("PART_Track");
@ -174,7 +192,6 @@ namespace Avalonia.Controls
if (_track != null)
{
_track.IsThumbDragHandled = true;
_trackOnKeyDownDispose = _track.AddDisposableHandler(KeyDownEvent, TrackOnKeyDown);
}
if (_decreaseButton != null)
@ -192,26 +209,32 @@ namespace Avalonia.Controls
_pointerMovedDispose = this.AddDisposableHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel);
}
private void TrackOnKeyDown(object sender, KeyEventArgs e)
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyModifiers != KeyModifiers.None) return;
base.OnKeyDown(e);
if (e.Handled || e.KeyModifiers != KeyModifiers.None) return;
var handled = true;
switch (e.Key)
{
case Key.Down:
case Key.Left:
MoveToNextTick(-SmallChange);
MoveToNextTick(IsDirectionReversed ? SmallChange : -SmallChange);
break;
case Key.Up:
case Key.Right:
MoveToNextTick(SmallChange);
MoveToNextTick(IsDirectionReversed ? -SmallChange : SmallChange);
break;
case Key.PageUp:
MoveToNextTick(-LargeChange);
MoveToNextTick(IsDirectionReversed ? -LargeChange : LargeChange);
break;
case Key.PageDown:
MoveToNextTick(LargeChange);
MoveToNextTick(IsDirectionReversed ? LargeChange : -LargeChange);
break;
case Key.Home:
@ -221,7 +244,13 @@ namespace Avalonia.Controls
case Key.End:
Value = Maximum;
break;
default:
handled = false;
break;
}
e.Handled = handled;
}
private void MoveToNextTick(double direction)

5
src/Avalonia.Themes.Default/Slider.xaml

@ -11,7 +11,7 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Name="TrackBackground" Grid.Row="1" Height="4" Margin="6,0" VerticalAlignment="Center"/>
<Track Name="PART_Track" Grid.Row="1" Orientation="Horizontal">
<Track Name="PART_Track" Grid.Row="1" IsDirectionReversed="{TemplateBinding IsDirectionReversed}" Orientation="Horizontal">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton"
Classes="repeattrack" />
@ -46,7 +46,7 @@
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Name="TrackBackground" Grid.Column="1" Width="4" Margin="0,6" HorizontalAlignment="Center"/>
<Track Name="PART_Track" Grid.Column="1" Orientation="Vertical">
<Track Name="PART_Track" Grid.Column="1" IsDirectionReversed="{TemplateBinding IsDirectionReversed}" Orientation="Vertical">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton"
Classes="repeattrack" />
@ -80,6 +80,7 @@
</Style>
<Style Selector="Slider /template/ RepeatButton.repeattrack">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeBorderLowBrush}"/>
<Setter Property="Template">
<ControlTemplate>

12
src/Avalonia.Themes.Fluent/Controls/Slider.xaml

@ -62,9 +62,9 @@
<TickBar Name="TopTickBar" Placement="Top" Height="{DynamicResource SliderOutsideTickBarThemeHeight}" VerticalAlignment="Bottom" Margin="0,0,0,4" Grid.ColumnSpan="3" />
<!-- <TickBar Name="HorizontalInlineTickBar" Placement="Top" Fill="{DynamicResource SliderInlineTickBarFill}" Height="{DynamicResource SliderTrackThemeHeight}" Grid.Row="1" Grid.ColumnSpan="3" /> -->
<TickBar Name="BottomTickBar" Placement="Bottom" Height="{DynamicResource SliderOutsideTickBarThemeHeight}" VerticalAlignment="Top" Margin="0,4,0,0" Grid.Row="2" Grid.ColumnSpan="3" />
<Track Name="PART_Track" Grid.Row="1" Grid.ColumnSpan="3" Orientation="Horizontal">
<Track Name="PART_Track" Grid.Row="1" Grid.ColumnSpan="3" IsDirectionReversed="{TemplateBinding IsDirectionReversed}" Orientation="Horizontal">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton" Background="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<RepeatButton Name="PART_DecreaseButton" Background="{TemplateBinding Foreground}" Focusable="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Grid>
@ -76,7 +76,7 @@
</RepeatButton>
</Track.DecreaseButton>
<Track.IncreaseButton>
<RepeatButton Name="PART_IncreaseButton" Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<RepeatButton Name="PART_IncreaseButton" Background="{TemplateBinding Background}" Focusable="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Grid>
@ -124,9 +124,9 @@
<TickBar Name="LeftTickBar" Placement="Left" Width="{DynamicResource SliderOutsideTickBarThemeHeight}" HorizontalAlignment="Right" Margin="0,0,4,0" Grid.RowSpan="3" />
<!-- <TickBar Name="VerticalInlineTickBar" Placement="Inline" Fill="{DynamicResource SliderInlineTickBarFill}" Width="{DynamicResource SliderTrackThemeHeight}" Grid.Column="1" Grid.RowSpan="3" /> -->
<TickBar Name="RightTickBar" Placement="Right" Width="{DynamicResource SliderOutsideTickBarThemeHeight}" HorizontalAlignment="Left" Margin="4,0,0,0" Grid.Column="2" Grid.RowSpan="3" />
<Track Name="PART_Track" Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="3" Orientation="Vertical">
<Track Name="PART_Track" Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="3" IsDirectionReversed="{TemplateBinding IsDirectionReversed}" Orientation="Vertical">
<Track.DecreaseButton>
<RepeatButton Name="PART_DecreaseButton" Background="{TemplateBinding Foreground}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<RepeatButton Name="PART_DecreaseButton" Background="{TemplateBinding Foreground}" Focusable="False" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Grid>
@ -138,7 +138,7 @@
</RepeatButton>
</Track.DecreaseButton>
<Track.IncreaseButton>
<RepeatButton Name="PART_IncreaseButton" Background="{TemplateBinding Background}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<RepeatButton Name="PART_IncreaseButton" Background="{TemplateBinding Background}" Focusable="False" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<RepeatButton.Template>
<ControlTemplate>
<Grid>

Loading…
Cancel
Save