218 lines
8.6 KiB
C#
218 lines
8.6 KiB
C#
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
// MTScratchpadRTStylus application.
|
|
// Description:
|
|
// Inside the application window, user can draw using multiple fingers
|
|
// at the same time. The trace of each finger is drawn using different
|
|
// color. The primary finger trace is always drawn in black, and the
|
|
// remaining traces are drawn by rotating through the following colors:
|
|
// red, blue, green, magenta, cyan and yellow.
|
|
//
|
|
// Purpose:
|
|
// This sample demonstrates handling of the multi-touch input inside
|
|
// a C# application using Real Time Stylus inking API:
|
|
// - Setting up minimal RTS object configuration that allows the window
|
|
// to be inking-enabled (this is not multi-touch specific);
|
|
// Construction and initialization of RealTimeStylus object and
|
|
// DynamicRenderer object.
|
|
// - Registering RTS object for multi-touch;
|
|
// - Deriving and initializing synchronous RTS plugin that receives
|
|
// inking notifications that are multi-touch aware.
|
|
// - Handling multi-touch aware pen-down/up/move notifications: changing
|
|
// stroke color on pen-down.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
|
|
// Microsoft Tablet PC namespaces
|
|
using Microsoft.StylusInput;
|
|
using Microsoft.StylusInput.PluginData;
|
|
|
|
namespace Microsoft.Samples.Touch.MTScratchpadRTStylus
|
|
{
|
|
public partial class MTScratchpadRTStylusForm : Form
|
|
{
|
|
// MTScratchpadRTStylusForm constructor
|
|
public MTScratchpadRTStylusForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
// Setup event handlers
|
|
Load += new System.EventHandler(this.OnLoadHandler);
|
|
Paint += new PaintEventHandler(this.OnPaintHandler);
|
|
}
|
|
|
|
// OnLoad window event handler
|
|
// in:
|
|
// sender object that has sent the event
|
|
// e event arguments
|
|
private void OnLoadHandler(Object sender, EventArgs e)
|
|
{
|
|
// Create RealTimeStylus object and enable it for multi-touch
|
|
realTimeStylus = new RealTimeStylus(this);
|
|
realTimeStylus.MultiTouchEnabled = true;
|
|
|
|
// Create DynamicRenderer and event handler, and add them to the RTS object as synchronous plugins
|
|
dynamicRenderer = new DynamicRenderer(this);
|
|
eventHandler = new EventHandlerPlugIn(this.CreateGraphics(), dynamicRenderer);
|
|
realTimeStylus.SyncPluginCollection.Add(eventHandler);
|
|
realTimeStylus.SyncPluginCollection.Add(dynamicRenderer);
|
|
|
|
// Enable RTS and DynamicRenderer object, and enable auto-redraw of the DynamicRenderer
|
|
realTimeStylus.Enabled = true;
|
|
dynamicRenderer.Enabled = true;
|
|
dynamicRenderer.EnableDataCache = true;
|
|
}
|
|
|
|
// OnPaint window event handler
|
|
// in:
|
|
// sender object that has sent the event
|
|
// e event arguments
|
|
private void OnPaintHandler(object sender, PaintEventArgs e)
|
|
{
|
|
// Erase the background
|
|
Brush brush = new SolidBrush(SystemColors.Window);
|
|
e.Graphics.FillRectangle(brush, ClientRectangle);
|
|
|
|
// Ask DynamicRenderer to redraw itself
|
|
dynamicRenderer.Refresh();
|
|
}
|
|
|
|
// Attributes
|
|
private RealTimeStylus realTimeStylus; // RealTimeStylus object
|
|
private DynamicRenderer dynamicRenderer; // DynamicRenderer object
|
|
private EventHandlerPlugIn eventHandler; // Event handler object
|
|
}
|
|
|
|
// Notification receiver that changes pen color.
|
|
public class EventHandlerPlugIn : IStylusSyncPlugin
|
|
{
|
|
// EventHandlerPlugIn constructor
|
|
public EventHandlerPlugIn(Graphics graph, DynamicRenderer render)
|
|
{
|
|
graphics = graph;
|
|
cntContacts = 0;
|
|
touchColor = new TouchColor();
|
|
dynamicRenderer = render;
|
|
}
|
|
|
|
// Pen-down notification handler.
|
|
// Sets the color for the newly started stroke and increments finger-down counter.
|
|
// sender RTS event sender object
|
|
// data event arguments
|
|
public void StylusDown(RealTimeStylus sender, StylusDownData data)
|
|
{
|
|
// Set new stroke color to the DrawingAttributes of the DynamicRenderer
|
|
// If there are no fingers down, this is a primary contact
|
|
dynamicRenderer.DrawingAttributes.Color = touchColor.GetColor(cntContacts == 0);
|
|
|
|
++cntContacts; // Increment finger-down counter
|
|
}
|
|
|
|
// Pen-move notification handler
|
|
// In this case, does nothing, but likely to be used in a more complex application.
|
|
// RTS framework does stroke collection and rendering for us.
|
|
// sender RTS event sender object
|
|
// data event arguments
|
|
public void Packets(RealTimeStylus sender, PacketsData data)
|
|
{
|
|
}
|
|
|
|
// Pen-up notification handler.
|
|
// Decrements finger-down counter.
|
|
// sender RTS event sender object
|
|
// data event arguments
|
|
public void StylusUp(RealTimeStylus sender, StylusUpData data)
|
|
{
|
|
--cntContacts; // Decrement finger-down counter
|
|
}
|
|
|
|
// Defines which handlers are called by the framework. We set the flags for pen-down, pen-up and pen-move.
|
|
public DataInterestMask DataInterest
|
|
{
|
|
get
|
|
{
|
|
return DataInterestMask.StylusDown |
|
|
DataInterestMask.Packets |
|
|
DataInterestMask.StylusUp;
|
|
}
|
|
}
|
|
|
|
// The remaining interface methods are not used in this sample application.
|
|
public void RealTimeStylusDisabled(RealTimeStylus sender, RealTimeStylusDisabledData data) { }
|
|
public void RealTimeStylusEnabled(RealTimeStylus sender, RealTimeStylusEnabledData data) { }
|
|
public void StylusOutOfRange(RealTimeStylus sender, StylusOutOfRangeData data) { }
|
|
public void StylusInRange(RealTimeStylus sender, StylusInRangeData data) { }
|
|
public void StylusButtonDown(RealTimeStylus sender, StylusButtonDownData data) { }
|
|
public void StylusButtonUp(RealTimeStylus sender, StylusButtonUpData data) { }
|
|
public void CustomStylusDataAdded(RealTimeStylus sender, CustomStylusData data) { }
|
|
public void SystemGesture(RealTimeStylus sender, SystemGestureData data) { }
|
|
public void InAirPackets(RealTimeStylus sender, InAirPacketsData data) { }
|
|
public void TabletAdded(RealTimeStylus sender, TabletAddedData data) { }
|
|
public void TabletRemoved(RealTimeStylus sender, TabletRemovedData data) { }
|
|
public void Error(RealTimeStylus sender, ErrorData data) { }
|
|
|
|
// Attributes
|
|
private Graphics graphics; // graphics object of the window this plugin is attached to
|
|
private int cntContacts; // number of fingers currently in the contact with the touch digitizer
|
|
private TouchColor touchColor; // color generator
|
|
private DynamicRenderer dynamicRenderer; // dynamic renderer
|
|
}
|
|
|
|
// Color generator: assigns a color to the new stroke.
|
|
public class TouchColor
|
|
{
|
|
public TouchColor()
|
|
{
|
|
}
|
|
|
|
// Returns color for the newly started stroke.
|
|
// in:
|
|
// primary flag, whether the contact is the primary contact
|
|
// returns:
|
|
// color of the stroke
|
|
public Color GetColor(bool primary)
|
|
{
|
|
if (primary)
|
|
{
|
|
// The primary contact is drawn in black.
|
|
return Color.Black;
|
|
}
|
|
else
|
|
{
|
|
// Take current secondary color.
|
|
Color color = secondaryColors[idx];
|
|
|
|
// Move to the next color in the array.
|
|
idx = (idx + 1) % secondaryColors.Length;
|
|
|
|
return color;
|
|
}
|
|
}
|
|
|
|
// Attributes
|
|
static private Color[] secondaryColors = // secondary colors
|
|
{
|
|
Color.Red,
|
|
Color.LawnGreen,
|
|
Color.Blue,
|
|
Color.Cyan,
|
|
Color.Magenta,
|
|
Color.Yellow
|
|
};
|
|
private int idx = 0; // rotating secondary color index
|
|
}
|
|
}
|