This project is read-only.

Tutorial 1: A Simple Painting Program

In this tutorial, we will introduce how to create a simple painting application using uTableSDK step by step. uTableSDK is based on WPF, so please make sure you’re familiar with WPF before read this tutorial.

1. Environment Setup

a) Operating system required:

      · Windows XP, Vista or 7

b) Prerequisite software:

      · Visual Studio 2008 SP1 or Visual Studio 2010

c) Install uTableSDK:

      · Download uTableSDK from http://utablesdk.codeplex.com/

      · Unzip uTableSDK package

      · Run uTableSDK/install/install.exe (If your operating system is Vista or 7, please run the program as administrator).

 

2. Create the uTable project

a) Open Visual Studio 2008

b) Select File-> New-> Project. In the “New Project” dialog, select Visual C#/UTable entry in the “Project types” column, and select UTableApplication in the “Templates” column.

image

a) Give a name to the project (uTablePaint, for example), and click the OK button.

b) Now, we’ve created a uTable Project. There are four files in the project:

      · App.xaml.cs: set up operating environment of the application before the application starts up.

      · NLog.config: configure log of the application. Please see http://nlog-project.org/ for more information.

      · Microsoft.MultiPoint.MultiPointSDK.dll.config: this file takes effect only when you are using MultiMouseProvider2 as InputProvider.

      · UTable.config: configure the application.

      · UObject1.xaml/UObject1.xaml.cs: similar to Window1.xaml/Window1.xaml.cs in a standard WPF application, these two files define the look and feel of the application, which will be the main work place.

 

(Note: if you are using Visual Studio 2010 as IDE, and you also upgrade the project to .NET 4.0, then you should use UTable.Input.MultiMouseProvider2 instead of MultiMouseProvider in the file UTable.config. MultiMouseProvider does not work under .NET 4.0)

 

3. Write the code

After an uTable project created, we now can do some real work. The application we’re creating is very simple; it only supports two functions: 1) display the traces of fingers; 2) eraser the traces when clicking a button. Yet this application reveals several key issues you must know when developing using uTableSDK. In the following subsections, I’ll show you how to create this application step by step.

 

3.1. Create a customized control

Firstly, we should create a control that can display the finger trace when touched. We call this control PaintCanvas. It can be created using UTableUserControl template:

      a) Right click the project item in Solution Explorer view, select Add/New item tab

      b) In the Visual C#/UTable category, choose UTableUserControl template

      c) Set name PaintCanvas.xaml, and click Add button.

image

However, the content of PaintCanvas is empty after created. Thus we should rewrite the view in PaintCanvas.xaml:

<u:UUserControl x:Class="uTablePaint.PaintCanvas"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:u="clr-namespace:UTable.Objects.Controls;assembly=UTable.Core"

        Height="300" Width="300">

       <u:UCanvas Background="White" x:Name="PCanvas">

       </u:UCanvas>

</u:UUserControl>

 

3.2. Handle Multi-touch events

Now we will handle the multi-touch input on PaintCanvas control, and display the trace.

In uTableSDK, any control that implements IInputNode interface will have InputReceived event. This event will be triggered when any input such as multi-touch or keyboard is sent to the control. Therefore, we should handle the InputReceived event in PaintCanvas, and only deal with the multi-touch input:

public PaintCanvas()

{

        InitializeComponent();

        this.InputReceived +=

        new InputEventHandler(PaintCanvas_InputReceived);

}

private void PaintCanvas_InputReceived(InputEventArgs args)

{

        if (args is MultiTouchEventArgs)

        {

                HandleMultiTouchInput(args as MultiTouchEventArgs);

        }

}

private void HandleMultiTouchInput(MultiTouchEventArgs args)

{

//...

}

 

The MultiTouchEventArgs contains several FingerEventArgs, and we should take different actions for different event types:

private void HandleMultiTouchInput(MultiTouchEventArgs args)

{

        foreach (FingerEventArgs f in args.FingerEvents)

        {

                switch (f.EventType)

                {

                        case FingerEventType.FINGER_DOWN_EVENT:

                                //handle finger down event

                                break;

                        case FingerEventType.FINGER_MOVE_EVENT:

                                //handle finger move event

                                break;

                        case FingerEventType.FINGER_UP_EVENT:

                                //handle finger up event

                                break;

                }

        }

}

 

In our current scenario, the logic is:

      · Add a new polyline element to the canvas when a finger put down

      · Adjust the polyline to record the trace when the finger is moving

      · Stop recording when the finger is up

Since we need to know the relationship between a finger and the line it is drawing, we use a dictionary to achieve this.

The following code contains all the business logics discussed above:

Dictionary<int, Polyline> fingerMap = new Dictionary<int, Polyline>();

private void HandleMultiTouchInput(MultiTouchEventArgs args)

{

       foreach (FingerEventArgs f in args.FingerEvents)

       {

                switch (f.EventType)

                {

                        case FingerEventType.FINGER_DOWN_EVENT:

                                Polyline line = new Polyline();

                                line.Stroke = Brushes.Black;

                                line.StrokeThickness = 3;

                                line.Points.Add(f.Position);

                                fingerMap.Add(f.FingerID, line);

                                PCanvas.Children.Add(line);

                                this.CaptureFinger(f.FingerID);

                                break;

                        case FingerEventType.FINGER_MOVE_EVENT:

                                if (fingerMap.ContainsKey(f.FingerID))

                                {

                                        fingerMap[f.FingerID].Points.Add(f.Position);

                                }

                                break;

                        case FingerEventType.FINGER_UP_EVENT:

                                if (fingerMap.ContainsKey(f.FingerID))

                                {

                                        fingerMap.Remove(f.FingerID);

                                }

                                break;

                }

        }

        args.Handled = true; // do not route down the event

}

 

To test PaintCanvas control, add it to UObject1.xaml:

<u:UObject x:Class="uTablePaint.UObject1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       xmlns:u="clr-namespace:UTable.Objects.Controls;assembly=UTable.Core"

       xmlns:local="clr-namespace:uTablePaint"

       Height="300" Width="300" Position="500, 300">

       <Grid>

               <local:PaintCanvas/>

       </Grid>

</u:UObject>

 

Then run the application, you should see a full-screen tabletop, and UObject1 is just located at the center of the tabletop. If you have more than one mice connected to PC, you can draw two lines simultaneously on the object:

image

 

3.3. Use UTableSDK standard controls

uTableSDK provides a rich set controls under UTable.Objects.Controls namespace that you can use directly:

      · Basic controls: UButton, UCheckBox, UToggleButton, URadioBox, USlider, UTextBox, …

      · Advanced controls: UListBox, UDialog, UScrollViewer, UPopup, UGridView, UBookView, UScanView, UInkCanvas…

In our paint application, we only use UButton to add ClearScreen functionality. You can check examples in uTableSDK to understand the use of other controls.

Firstly, let’s add a button to UObject1.xaml:

<u:UObject x:Class="uTablePaint.UObject1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:u="clr- namespace:UTable.Objects.Controls;assembly=UTable.Core"

        xmlns:local="clr-namespace:uTablePaint"

        Height="350" Width="350" Position="500, 300">

        <Grid>

                <local:PaintCanvas Margin="10, 20, 10, 50" x:Name="Paint" />

                <u:UButton Height="42" Width="207" Margin="73,0,68,1"

                        VerticalAlignment="Bottom" Foreground="White" FontSize="15"

                        Pressed="UButton_Pressed">Clear</u:UButton>

        </Grid>

</u:UObject>

 

Notice that we add a handler to the Pressed event of the button. This event will be triggered when you click the button.

In our case, the handler just removes all the lines in the PaintCanvas:

Private void Ubutton_Pressed(object sender, ButtonEventArgs args)

{

        Paint.PCanvas.Children.Clear();

}

 

Now run the application again to check the effects:

image

 

4. Configure the application

You can edit the UTable.config file of the project to configure the environment of the application, such as display mode and inputs. By default, the application only uses UTable.Input.MultiMouseProvider as its multi-touch input provider. You can add other providers such as TuioProvider when the application is to be deployed on a real tabletop.

 

5. Further reading

      · The uTableSDK\examples\basics category provides several examples to reveals the important issues you should know when using uTableSDK.

      · The uTableSDK\examples\applications\note example shows how to create a better painting application by using InkCanvas and control templates.

 

Download source code: uTablePaint.rar

Last edited Dec 1, 2010 at 2:55 PM by anwing, version 7

Comments

No comments yet.