Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF/C#: 'Slide to Unlock' feature from iPhone

I just want to ask for your opinion on how to achieve the 'Slide to Unlock' feature from iPhone using Windows Presentation Foundation.

I already came across to this article: iPhone slide to unlock progress bar (part 1), and wondering if you can give me some other resources for a good head start. Thank you.

like image 730
abramlimpin Avatar asked Mar 24 '11 09:03

abramlimpin


1 Answers

I would retemplate a Slider, as this is the closest control, functionality-wise.

You should catch the event of Value_Changed, and if Value == Maximum then the slider is "opened".

Retemplating the control would make it look like your "unlock control" with ease. I'll paste later an example.

-- EDIT -- Have free time at work, so I started it for you. The usage is as follows:

<Grid x:Name="LayoutRoot">
    <Slider Margin="185,193,145,199" Style="{DynamicResource SliderStyle1}"/>
</Grid>

and the ResourceDictionary:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">

    <LinearGradientBrush x:Key="MouseOverBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFF" Offset="0.0"/>
        <GradientStop Color="#AAA" Offset="1.0"/>
    </LinearGradientBrush>


    <LinearGradientBrush x:Key="LightBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFF" Offset="0.0"/>
        <GradientStop Color="#EEE" Offset="1.0"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="NormalBorderBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#CCC" Offset="0.0"/>
        <GradientStop Color="#444" Offset="1.0"/>
    </LinearGradientBrush>

    <Style x:Key="SimpleScrollRepeatButtonStyle" d:IsControlPart="True" TargetType="{x:Type RepeatButton}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Grid>
                        <Rectangle Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Style x:Key="ThumbStyle1" d:IsControlPart="True" TargetType="{x:Type Thumb}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <Grid Width="54">
                        <Ellipse x:Name="Ellipse" />
                        <Border CornerRadius="10" >
                            <Border.Background>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#FFFBFBFB" Offset="0.075"/>
                                    <GradientStop Color="Gainsboro" Offset="0.491"/>
                                    <GradientStop Color="#FFCECECE" Offset="0.509"/>
                                    <GradientStop Color="#FFA6A6A6" Offset="0.943"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Fill" Value="{StaticResource MouseOverBrush}" TargetName="Ellipse"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" Value="{StaticResource DisabledBackgroundBrush}" TargetName="Ellipse"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="SliderStyle1" TargetType="{x:Type Slider}">
        <Setter Property="Background" Value="{StaticResource LightBrush}"/>
        <Setter Property="BorderBrush" Value="{StaticResource NormalBorderBrush}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Slider}">
                    <Border CornerRadius="14" Padding="4">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FF252525" Offset="0"/>
                                <GradientStop Color="#FF5C5C5C" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.Background>
                        <Grid x:Name="GridRoot">
                        <TextBlock Text="Slide to unlock" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        <!-- TickBar shows the ticks for Slider -->

                        <!-- The Track lays out the repeat buttons and thumb -->
                            <Track x:Name="PART_Track" Height="Auto">
                                <Track.Thumb>
                                    <Thumb Style="{StaticResource ThumbStyle1}"/>
                                </Track.Thumb>
                                <Track.IncreaseRepeatButton>
                                    <RepeatButton Style="{StaticResource SimpleScrollRepeatButtonStyle}" Command="Slider.IncreaseLarge" Background="Transparent"/>
                                </Track.IncreaseRepeatButton>
                                <Track.DecreaseRepeatButton>
                                    <RepeatButton Style="{StaticResource SimpleScrollRepeatButtonStyle}" Command="Slider.DecreaseLarge" d:IsHidden="True"/>
                                </Track.DecreaseRepeatButton>
                            </Track>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="TickPlacement" Value="TopLeft"/>
                        <Trigger Property="TickPlacement" Value="BottomRight"/>
                        <Trigger Property="TickPlacement" Value="Both"/>
                        <Trigger Property="IsEnabled" Value="false"/>

                        <!-- Use a rotation to create a Vertical Slider form the default Horizontal -->
                        <Trigger Property="Orientation" Value="Vertical">
                            <Setter Property="LayoutTransform" TargetName="GridRoot">
                                <Setter.Value>
                                    <RotateTransform Angle="-90"/>
                                </Setter.Value>
                            </Setter>
                            <!-- Track rotates itself based on orientation so need to force it back -->
                            <Setter TargetName="PART_Track" Property="Orientation" Value="Horizontal"/>
                        </Trigger>

                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

Note that this is a very good start, but it's not everything. I would also define a custom control that derives from slider and that uses this style automatically. Also I would expose a SlideUnlocked event when the user slides all the way right. To finish it all i would also add an animation that moves the Thumb back left in case the user has dragged it right, but not all the way (to imitate iPhone's UX exactly.)

Good luck, and ask away if you don't know how to implement any of the stages i suggested.

like image 156
Elad Katz Avatar answered Oct 05 '22 12:10

Elad Katz