Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / game / Kinect

Kinect – Create Buttons

5.00/5 (5 votes)
24 Jul 2011Ms-PL2 min read 20.9K  
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 enable Kinect to your environment, I'm talking about PC.

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? (Raising 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.

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 completes the time period, then a Click event will be fired.

Step 1: Create a 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.

XML
<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…

C#
/// <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.

C#
public delegate void ClickHandler(object sender, EventArgs eventArgs);
public event ClickHandler Click;

Now, when the mouse enters to the KinectButton, we going to start Fill the button with Color and when the button leaves the KinectButton, we will remove the fill.

C#
private void SrKinectButtonMouseEnter(object sender, MouseEventArgs e)
{
    StartFill();
}
 
private void SrKinectButtonMouseLeave(object sender, MouseEventArgs e)
{
    RemoveFill();
}

You can put counter and several other techniques to show the count down for the user. I did an Animation to fill the KinectButton, like that:

C#
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

XML
<Kit:KinectButton Canvas.Left="565" Canvas.Top="158"
   DisplayTextColor="Black" PathFill="Red"
   DisplayText="C" Time="2" Name="btnPlus" Click="btnPlus_Click" />
<object type="application/x-shockwave-flash" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=3,0,0,0" width="512" height="370" data="http://www.youtube.com/v/fTLIxtE06c0"><param name="movie" value="http://www.youtube.com/v/fTLIxtE06c0" /><param name="quality" value="high" /><param name="wmode" value="transparent" />

Download Control Kit

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)