1
0
Эх сурвалжийг харах

Added implementation of Slider

Artsiom Herasimchuk 9 жил өмнө
parent
commit
8c22f3bf3b

+ 1 - 0
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 - 0
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 - 0
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 - 0
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 - 0
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>