Browse Source

Added implementation of Slider

pull/448/head
Artsiom Herasimchuk 10 years ago
parent
commit
8c22f3bf3b
  1. 1
      src/Perspex.Controls/Perspex.Controls.csproj
  2. 146
      src/Perspex.Controls/Slider.cs
  3. 1
      src/Perspex.Themes.Default/DefaultTheme.paml
  4. 3
      src/Perspex.Themes.Default/Perspex.Themes.Default.csproj
  5. 78
      src/Perspex.Themes.Default/Slider.paml

1
src/Perspex.Controls/Perspex.Controls.csproj

@ -72,6 +72,7 @@
<Compile Include="Shapes\Line.cs" />
<Compile Include="Shapes\Polygon.cs" />
<Compile Include="Shapes\Polyline.cs" />
<Compile Include="Slider.cs" />
<Compile Include="SystemDialog.cs" />
<Compile Include="Generators\ITreeItemContainerGenerator.cs" />
<Compile Include="Generators\ItemContainerEventArgs.cs" />

146
src/Perspex.Controls/Slider.cs

@ -0,0 +1,146 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Perspex.Controls.Primitives;
using Perspex.Controls.Templates;
using Perspex.Input;
using Perspex.Interactivity;
namespace Perspex.Controls
{
/// <summary>
/// A control that lets the user select from a range of values by moving a Thumb control along a Track.
/// </summary>
public class Slider : RangeBase
{
/// <summary>
/// Defines the <see cref="Orientation"/> property.
/// </summary>
public static readonly StyledProperty<Orientation> OrientationProperty =
PerspexProperty.Register<Slider, Orientation>(nameof(Orientation), Orientation.Horizontal);
/// <summary>
/// Defines the <see cref="IsSnapToTickEnabled"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsSnapToTickEnabledProperty =
PerspexProperty.Register<Slider, bool>(nameof(IsSnapToTickEnabled), false);
/// <summary>
/// Defines the <see cref="TickFrequency"/> property.
/// </summary>
public static readonly StyledProperty<double> TickFrequencyProperty =
PerspexProperty.Register<Slider, double>(nameof(TickFrequencyProperty), 0.0);
// Slider required parts
private Track _track;
/// <summary>
/// Initializes static members of the <see cref="Slider"/> class.
/// </summary>
static Slider()
{
Thumb.DragStartedEvent.AddClassHandler<Slider>(x => x.OnThumbDragStarted, RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>(x => x.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>(x => x.OnThumbDragCompleted, RoutingStrategies.Bubble);
}
/// <summary>
/// Instantiates a new instance of the <see cref="Slider"/> class.
/// </summary>
public Slider()
{
}
/// <summary>
/// Gets or sets the orientation of a <see cref="Slider"/>.
/// </summary>
public Orientation Orientation
{
get { return GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, 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>
public bool IsSnapToTickEnabled
{
get { return GetValue(IsSnapToTickEnabledProperty); }
set { SetValue(IsSnapToTickEnabledProperty, value); }
}
/// <summary>
/// Gets or sets the interval between tick marks.
/// </summary>
public double TickFrequency
{
get { return GetValue(TickFrequencyProperty); }
set { SetValue(TickFrequencyProperty, value); }
}
/// <inheritdoc/>
protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
{
_track = e.NameScope.Get<Track>("PART_Track");
}
/// <summary>
/// Called when user start dragging the <see cref="Thumb"/>.
/// </summary>
/// <param name="e"></param>
protected virtual void OnThumbDragStarted(VectorEventArgs e)
{
}
/// <summary>
/// Called when user dragging the <see cref="Thumb"/>.
/// </summary>
/// <param name="e"></param>
protected virtual void OnThumbDragDelta(VectorEventArgs e)
{
Thumb thumb = e.Source as Thumb;
if (thumb != null && _track.Thumb == thumb)
{
MoveToNextTick(_track.Value);
}
}
/// <summary>
/// Called when user stop dragging the <see cref="Thumb"/>.
/// </summary>
/// <param name="e"></param>
protected virtual void OnThumbDragCompleted(VectorEventArgs e)
{
}
/// <summary>
/// Searches for the closest tick and sets Value to that tick.
/// </summary>
/// <param name="value">Value that want to snap to closest Tick.</param>
private void MoveToNextTick(double value)
{
double next = SnapToTick(Math.Max(Minimum, Math.Min(Maximum, value)));
if (next != value)
{
Value = next;
}
}
/// <summary>
/// Snap the input 'value' to the closest tick.
/// </summary>
/// <param name="value">Value that want to snap to closest Tick.</param>
private double SnapToTick(double value)
{
if (IsSnapToTickEnabled && TickFrequency > 0.0)
{
double previous = Minimum + (Math.Round(((value - Minimum) / TickFrequency)) * TickFrequency);
double next = Math.Min(Maximum, previous + TickFrequency);
value = value > (previous + next) * 0.5 ? next : previous;
}
return value;
}
}
}

1
src/Perspex.Themes.Default/DefaultTheme.paml

@ -17,6 +17,7 @@
<StyleInclude Source="resm:Perspex.Themes.Default.ProgressBar.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.RadioButton.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Separator.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Slider.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ScrollBar.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ScrollViewer.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TabStrip.paml?assembly=Perspex.Themes.Default"/>

3
src/Perspex.Themes.Default/Perspex.Themes.Default.csproj

@ -193,6 +193,9 @@
<EmbeddedResource Include="Separator.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Slider.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

78
src/Perspex.Themes.Default/Slider.paml

@ -0,0 +1,78 @@
<Styles xmlns="https://github.com/perspex">
<Style Selector="Slider[Orientation=Horizontal]">
<Setter Property="MinWidth" Value="104"/>
<Setter Property="MinHeight" Value="21"/>
<Setter Property="Template">
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"
MinHeight="26" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Name="TrackBackground"
Grid.Row="1"
Height="4"
Margin="10,0"
VerticalAlignment="Center"/>
<Track Name="PART_Track" Grid.Row="1">
<Thumb MinWidth="26" MinHeight="26">
<Thumb.Template>
<ControlTemplate>
<Grid>
<Ellipse Width="26" Height="26" Fill="#5534b4e3"/>
<Ellipse Width="10" Height="10" Fill="#FF34b4e3"/>
</Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="Slider[Orientation=Vertical]">
<Setter Property="MinWidth" Value="21" />
<Setter Property="MinHeight" Value="104"/>
<Setter Property="Template">
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"
MinWidth="26"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Name="TrackBackground"
Grid.Column="1"
Width="4"
Margin="0,10"
HorizontalAlignment="Center"/>
<Track Name="PART_Track" Grid.Column="1">
<Thumb MinWidth="26" MinHeight="26">
<Thumb.Template>
<ControlTemplate>
<Grid>
<Ellipse Width="26" Height="26" Fill="#5534b4e3"/>
<Ellipse Width="10" Height="10" Fill="#FF34b4e3"/>
</Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="Slider /template/ Track#PART_Track">
<Setter Property="Minimum" Value="{TemplateBinding Minimum}"/>
<Setter Property="Maximum" Value="{TemplateBinding Maximum}"/>
<Setter Property="Value" Value="{TemplateBinding Path=Value, Mode=TwoWay}"/>
<Setter Property="Orientation" Value="{TemplateBinding Orientation}"/>
</Style>
<Style Selector="Slider /template/ Border#TrackBackground">
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="LightGray"/>
</Style>
</Styles>
Loading…
Cancel
Save