|
|||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionMouse gesture commands enrich the UI of an application. They are very easy to learn and intuitive for the user. There are some postings on CodeProject that address mouse gestures in one way or the other way (unfortunately, I didn't get the AI ones running), so I thought to offer my solution to the CP community. I first saw a mouse gestures functionality in the very early 90s in a CAD kernel package written in C that I used in a project. This article gives you the possibility to add mouse gesture functionality in your .NET project in a very easy way. It offers the following advanteges:
The IdeaIt doesn't really need to be said but first we have to capture the mouse movement/position. Once done, these x/y positions can be analysed to find an appropriate mouse gesture command. The idea of finding a mouse gesture is as follows:
Example:
Path: 0, 1, 2, 3, 4, 5, 4, 10, 9, 15, 14, 20, 19, 18, 24, 30, 31, 32, 33, 34, 35 With this solution a specific command has several keys — one key for every possible path for a mouse gesture. That means the more fields we divide the bounding rectangle into, the more keys a command needs to be found. A more complicated mouse gesture consists of a longer path which ends in more possible keys. As we can see, a very important point is the number of rectangles we divide the bounding rectangle into. If the number is too small, we will not have enough fields to differentiate similar mouse gestures. To illustrate this, imagine the smallest possible divider equal to 1 to divide each side of the bounding rectangle; in other words, not to divide the bounding rectangle. So every mouse gesture's path is 0, no matter if it's just a point or millions of movements. On the other side, if we divide the rectangle into too many fields, there are lots of path's which are very similar. I made several tests with different dividers for the bounding rectangle and finaly used 6 as the best avarage which gets 36 fields. The key should be as short as possible, because we will have many of them for one command as more complex a mouse gesture is. Because mouse gestures are not limited to a certain length or movements, we don't know how long the key can get. The simplest solution is to use a string that consists of the Base64 encoded field numbers — the path. The ImplementationClass MouseGestureDataClass Class MouseGestureClass In the class private void OnMouseDown( object sender, MouseEventArgs e )
{
// only enter capturing if...
if( !_bCapturing && // ...not capturing in
// progress
e.Button == _data.MouseButtonTrigger && // ...the button pressed last
// to trigger
Control.MouseButtons == _data.MouseButtonMask && // ...this/these button/s
// pressed together
Control.ModifierKeys == _data.ModifierKeyMask // ...this/these modifier
// key/s (shift/ctrl/alt)
)
{
// capturing mouse positions starts here
...
}
}
The default is only the right mouse button to be pressed. But with the additional properties MouseButtonTrigger = MouseButtons.Right;
MouseButtonMask = MouseBottons.Left | MouseButtons.Right
Or the ctrl-key plus the right mouse botton is pressed: MouseButtonTrigger = MouseButtons.Right;
MouseButtonMask = MouseButtons.Right
ModifierKeyMask = Keys.Control;
It is possible to give the user a visual feedback when the mouse positions are captured. It is done in three levels. The first level is that we show a window on which we draw the mouse gesture. This window has no frame, but we setup the
The second level for the visual feedback is drawing the mouse positions and is defined in property The third level is some properties that define if the bounding rectangle, the grid and the path of the mouse gesture should be drawn and its colors. There is also a property that defines for how much longer the capturing window should be shown after capturing the mouse position is finished. The analysis of the captured mouse positions is straightforward, there isn't really any tricky code behind it. But there are two properties to mention. Property Once capturing in the mouse positions is started and the
These values of the last Class CommandsThis class holds a Class MouseGestureManagerYou can draw mouse gestures on the manager form on all "container controls" (as explained above) plus the list control on the second tab. The allowed controls are set to default. When an event raises, it is visualized in the group box bellow the tabs: Red means no valid mouse gesture, green means a valied mouse gesture was entered and its key generated, but no appropriate command was found, whereas blue means that a command was found. Tab Parameter allows the setting of all the possible properties of
Tab Keys & Commands allows you to manage everything around keys and commands. Select or type in a command in the drop down combo box Commands to see all appropriate keys in the list bellow it. Group box Selected key shows the current/selected key as a stretched thumb and lets you delete it from the list. Button Delete all asks for a confirmation before deleting all keys/commands from the list.
Probably the most important button is the Add Mouse Gesture at the top right border of the tab. It is a button style check box and when pressed, every valid mouse gesture you draw on tab Keys & Commands (must be visible) is added to the current command. It is immediately selected on the list box, so you can delete if right afterwards if you are not happy with it. If you want to add a new command, just enter its name in the drop down combo box and start drawing the mouse gestures. (Unfortunately, the first character typed in the combo box is not acceppted, IMO a .NET problem). Consecutive cmd in group box Total counters is increased everytime a valid command is found and is set to 0 if not. It can be used while teaching new mouse gestures to get an idea of how god the system already is. How to Use the CodeUsing the
That's it! Here is an example with the minimum of steps needed (unnecessary VS code deleted): // a) Refer to namespace "DcamMouseGesture"
using DcamMouseGesture;
namespace WindowsFormsApplication
{
public partial class Form1 : Form
{
MouseGesture _mg;
public Form1()
{
InitializeComponent();
// b) Load a file with the commands and keys once in your application
MouseGestureData.Instance.Commands.ReadFile(
Environment.CurrentDirectory + @"\MouseGestureCommands.xml" );
// c) For each Form you want to use mouse gestures...
_mg = new MouseGesture( this, null );
_mg.MouseGestureEntered += new MouseGestureEventHandler(
OnMouseGestureEntered );
}
private void OnMouseGestureEntered( object sender, MouseGestureEventArgs e )
{
// d) In your registered MouseGestureEventHandler, handle the commands
// you want
MessageBox.Show( string.Format( "OnMouseGestureEntered:\n" +
" Command:\t{0}\n" +
" Key:\t\t{1}\n" +
" Control:\t\t{2}\n" +
" Bounds:\t\t{3}",
e.Command, e.Key, e.Control,
e.Bounds.ToString() ) );
}
}
}
The downloadable source code is a .NET 2.0 solution created in Visual Studion 2008 Standard Edition. I used the new feature auto-implemented proberties wherever possible. So if you want to use the source code in an older version of Visual Studio, you have to declare these as member variables and it's appropriate properties. History2008-05-12 - V1.0
|
||||||||||||||||||||||||||||||