Kinect – Create Buttons

23/06/2011

4 comments


In my previous posts about Kinect I’ve showed how to get started, how to change Angles and more cool stuff, but now it’s time to start working on the real things, how to KinectButtonenable Kinect to your environment, I’m talking about PC.

You may say Kinect is not yet perfect and the precision of the Skeleton Tracking system isn’t 100% accurate, and if you have to stand at least 1 meter from the screen how you will be able to see something from that distance? even more how to perform a Click? (Raise the other hand isn’t a good solution but checking the distance of the hand can help us to do that – I’ll show more later.)

Several posts ago I’ve talked about Masking in WPF and showed how to create WP7 The Mask Way– Rating Control and More, in this post I’ll use the same concept to Create Kinect Buttons that can fit for PC.

Download Control Kit

How?

There are several ways to accomplish that, the one I’m going to show is by Timer – same as the XBox Kinect concept you will move the Kinect Cursor over the Button then based on the Time you want the user has to hold the cursor in the same position and if he complete the time period then a Click event will be fired.

Step 1: Create New Control

Create Xaml: I’ve used the same concept as the Rating Control Mask and define the Border Path, Mask and the Fill and also added a Text Block to display the Text on the button.

<Grid x:Name="LayoutRoot">
    <Path x:Name="FillPath" Stretch="Fill" Data="F1 M 113.302,91.7188C 113.302,103.641 103.642,113.299 91.7213,113.299L 21.582,113.299C 9.66146,113.299 7.62939e-006,103.641
            7.62939e-006,91.7188L 7.62939e-006,21.5821C 7.62939e-006,9.66148 9.66146,2.47955e-005 21.582,2.47955e-005L 91.7213,2.47955e-005C 103.642,2.47955e-005 113.302,9.66148
            113.302,21.5821L 113.302,91.7188 Z " Margin="8,8,0,0" Height="113" HorizontalAlignment="Left" Width="113" VerticalAlignment="Top" Fill="{Binding PathFill}">            
    </Path>
 
    <Rectangle x:Name="Mask" Fill="White" Height="121" VerticalAlignment="Top" HorizontalAlignment="Left" Width="129" RenderTransformOrigin="0.5,0.5" >
    </Rectangle>
 
    <Path x:Name="BorderPath" Stretch="Fill" StrokeThickness="0.591467" StrokeLineJoin="Round" Stroke="#FF777677" Data="F1 M 121.384,99.8022C 121.384,111.724 111.724,121.383
            99.8035,121.383L 29.6642,121.383C 17.7436,121.383 8.08218,111.724 8.08218,99.8022L 8.08218,29.6655C 8.08218,17.745 17.7436,8.0835 29.6642,8.0835L 99.8035,8.0835C
            111.724,8.0835 121.384,17.745 121.384,29.6655L 121.384,99.8022 Z M 104.624,0.295738L 24.8439,0.295738C 11.2853,0.295738 0.295734,11.2866 0.295734,24.8439L
            0.295734,104.624C 0.295734,118.181 11.2853,129.172 24.8439,129.172L 104.624,129.172C 118.181,129.172 129.172,118.181 129.172,104.624L 129.172,24.8439C
            129.172,11.2866 118.181,0.295738 104.624,0.295738 Z " HorizontalAlignment="Left" Width="129" Height="129" VerticalAlignment="Top">
        <Path.Fill>
            <LinearGradientBrush StartPoint="0.5,6.51193e-007" EndPoint="0.5,1">
                <LinearGradientBrush.GradientStops>
                    <GradientStop Color="#FFDED9D2" Offset="0" />
                    <GradientStop Color="#FF858681" Offset="0.154192" />
                    <GradientStop Color="#FF2D3330" Offset="0.26404" />
                    <GradientStop Color="#FF969997" Offset="0.383313" />
                    <GradientStop Color="#FFFFFFFF" Offset="0.57303" />
                    <GradientStop Color="#FF7F7F7F" Offset="0.735806" />
                    <GradientStop Color="#FF000000" Offset="1" />
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Path.Fill>
    </Path>
        
    <TextBlock Name="txtHeader" Text="{Binding DisplayText}" Foreground="{Binding DisplayTextColor}" TextAlignment="Center" TextWrapping="WrapWithOverflow" FontSize="38"
VerticalAlignment="Center" HorizontalAlignment="Center" /> </Grid
>

Define the basic properties for your button control, for example I’ve defined some DependencyProperty  for Time Interval, Fill Path Color and Display Text etc…

/// <summary>
/// Timer Interval
/// </summary>
public int Time
{
    get { return (int)this.GetValue(TimeProperty); }
    set { this.SetValue(TimeProperty, value); }
}
public static readonly DependencyProperty TimeProperty = DependencyProperty.Register(
    "Time"typeof(int), typeof(KinectButton), new PropertyMetadata((int)3));
 
/// <summary>
/// Fill Color
/// </summary>
public Brush PathFill
{
    get { return (Brush)this.GetValue(PathFillProperty); }
    set { this.SetValue(PathFillProperty, value); }
}
public static readonly DependencyProperty PathFillProperty = DependencyProperty.Register(
    "PathFill"typeof(Brush), typeof(KinectButton), new PropertyMetadata(Brushes.Yellow));
 
/// <summary>
/// Display Text Color
/// </summary>
public Brush DisplayTextColor
{
    get { return (Brush)this.GetValue(DisplayTextColorProperty); }
    set { this.SetValue(DisplayTextColorProperty, value); }
}
public static readonly DependencyProperty DisplayTextColorProperty = DependencyProperty.Register(
    "DisplayTextColor"typeof(Brush), typeof(KinectButton), new PropertyMetadata(Brushes.Black));
 
/// <summary>
/// Display Text
/// </summary>
public string DisplayText
{
    get { return (string)this.GetValue(TextProperty); }
    set { this.SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "DisplayText"typeof(string), typeof(KinectButton), new PropertyMetadata("Display Text"));

Step 2: Enter , Leave and Simulate Click Event

Register for MouseEnter and MouseLeave event and define new event for you KinectButton called – ClickHandler

public delegate void ClickHandler(object sender, EventArgs eventArgs);
public event ClickHandler Click;
Now, when the mouse enter to the KinectButton we going to start Fill the button with Color and when the button leave the KinectButton we will remove the fill.
private void SrKinectButtonMouseEnter(object sender, MouseEventArgs e)
{
    StartFill();
}
 
private void SrKinectButtonMouseLeave(object sender, MouseEventArgs e)
{
    RemoveFill();
}
You can put counter and several other technics to show the count down for the user I did a Animation to fill the KinectButton, like that:
void StartFill()
{
    da = new DoubleAnimation(Mask.ActualHeight, MinFillHeight, _duration);
    da.Completed += new EventHandler(da_Completed);
    Mask.BeginAnimation(Canvas.HeightProperty, da);
}
 
void da_Completed(object sender, EventArgs e)
{
    if (Click != null)
        Click(sender, e);
    Mask.BeginAnimation(Canvas.HeightProperty, null);
}
 
void RemoveFill()
{
    da.Completed -= da_Completed;
    da = new DoubleAnimation(Mask.ActualHeight, MaxFillHeight, ReverseDuration);
    Mask.BeginAnimation(Canvas.HeightProperty, da);
}

Step 3: Use It

 <Kit:KinectButton Canvas.Left="565" Canvas.Top="158" DisplayTextColor="Black" PathFill="Red" DisplayText="C" Time="2" Name="btnPlus" Click="btnPlus_Click" />


Download Control Kit


Add comment
facebook linkedin twitter email

Leave a Reply

4 comments

  1. CristiR07/09/2011 ב 22:48

    Hi, can you explain briefly how can I use the Control Kit? I’m having problems creating my own application using you’re buttons. I have to add this as a reference to my project? and how do I connect them together?

  2. Basic Stuff07/09/2011 ב 23:31

    How can I add 3 such buttons in a WPF window ? Can you provide source code for a Calculator Demo on Youtube?

  3. noidea20/09/2011 ב 08:12

    Hi, I have no idea how to use the control kit. Can you provide more help for using it :)

  4. Pokey08/11/2011 ב 12:53

    What a joy to find someone else who tnhkis this way.