Friday, May 29, 2009

Tablet Programming Part 4: Advanced Gesture Control

Interfaces have made a huge leap forward in products such as the iPhone that allows you to navigate using gestures, your programs can do this too, and its not as difficult as you might expect.
The tutorial that follows will utilize several concepts from tableadapters to inkoverlays and I will not go too far into detail on them while creating them, but each of these is discussed in-depth with samples in this blog, you just need to do a quick find if you get a little lost. If there are several comments on this being an issue i can dig further, but i am trying to get away from re-creating the wheel with every post. With that, lets get going already.

I have a datagrid on a form and using it is a pain, you can increase the size of the grid and the font of the text etc., but that scroll bar is a huge issue. I don't know exactly what the solution is yet, but this is an attempt at using gestures to control scrolling.

First I am going to add a split container control to my form (I do this a lot for testing, one screen for input, the other for textboxes, label etc to test outputs). Next, create a datasource linking to a database, I am going with the Customer table of the Northwind.mdb. To follow along in this post you will need to accomplish this all in design view (should take 20 seconds) if you don't know how, read the section on table adapters. Drag the table to the left side of your screen and dock it there. As usual i deleted the bindingsource bar. Add a listbox control and a textbox to the right have of the splitter. You should now have a listbox, textbox, datagrid, TableAdapterManager, CustomersTableAdapter, CustomersBindingSource, and a NorthwindDataSet.
Now we need to set up our inkoverlay, start with the imports statement:

Imports Microsoft.Ink

and the squiggly line tells me i forgot to do the reference, d'oh! Add a reference to Microsoft Tablet PC API (near the top of the .NET tab).

Next, add the WithEvents statement below Class but before Sub:

Private WithEvents inkOverlay As New InkOverlay

After the Tableadapter fill method in the load event place the code for the inkOverlay

inkOverlay.CollectionMode = CollectionMode.GestureOnly
inkOverlay.SetGestureStatus(ApplicationGesture.Down, True)
inkOverlay.SetGestureStatus(ApplicationGesture.Up, True)
AddHandler InkOverlay.Gesture, AddressOf Gesture_Event
InkOverlay.Enabled = True

For this sample i want gesture only, no ink, and for now i only want to recognize the up and down gestures. We still have an event handler to Gesture_Event so I will copy the event from the other sample and change it up a bit.

Dim theGesture As Gesture = e.Gestures(0)
If theGesture.Id = ApplicationGesture.Down Then
Me.CustomersDataGridView.FirstDisplayedScrollingRowIndex += 10
End If
If theGesture.Id = ApplicationGesture.Up Then
Me.CustomersDataGridView.FirstDisplayedScrollingRowIndex -= 10
End If

What this does, is when we flick down with the pen, the datagrid scrolls up 10 rows, and vice-versa. Give it a try. I know its a little slow, I'll work on a different method, but for now this works fine.
This next step may not work on a small datagrid or for people with shaky movements, but you can use it as a 'what's possible'. To your Up and Down declerations, add a Right. Then in the Gesture_Event add this

If theGesture.Id = ApplicationGesture.Right Then
Me.ListBox1.Items.Add(Me.CustomersBindingSource.Current("CustomerID"))
End If

This means that a flick of the pen to the right will add the data in the CustomerID column of the selected row to the listbox.
Add 'Circle' to your gestures and add this bit:

If theGesture.Id = ApplicationGesture.Circle Then
Me.CustomersBindingSource.RemoveCurrent()
Me.CustomersDataGridView.Refresh()
End If

Now when you draw a circle the selected row is deleted. If you draw outside of the row unintended things could happen. The best way that i have found to handle many of these gesture issues is to create a little area where they can perform the gestures. I put a small panel somewhere and tie the inkoverlay to that.

That's all for now on tablet programming, thanks for reading.

No comments: