Browse DevX
Sign up for e-mail newsletters from DevX


Get Control and Performance with the Real Time Stylus API : Page 4

The Real Time Stylus API provides an alternate way to receive pen input pen. This high performance API provides a great level of control to developers for a small penalty in added effort.

Rendering Collected Information
One of the simplest things to do with the information you get from the plug-in is custom rendering of the received information. The following example draws a small circle at the pen coordinates you received. Pressure information is used to determine the radius of the circle.

   Public Sub Packets(ByVal s As RealTimeStylus, _
      ByVal data As PluginData.PacketsData) _
      Implements IStylusSyncPlugin.Packets
      Dim g As Graphics = _
      Dim packetCounter As Integer
      For packetCounter = 0 To _
         data.Count - data.PacketPropertyCount _
         Step data.PacketPropertyCount
         Dim iX As Integer
Figure 1: Custom Rendering: The figure shows custom circles being rendered at the point of pen contact with the screen, using pressure information to determine the radius of the circle.
Dim iY As Integer Dim iPressure As Integer = 10 iX = g.DpiX * data(packetCounter) / 2540 iY = g.DpiY * data(packetCounter+1) / 2540 If data.PacketPropertyCount > 2 Then iPressure = data(packetCounter+2) / 20 End If g.DrawEllipse(Pens.Red, _ iX - iPressure, iY - iPressure, _ iPressure * 2, iPressure * 2) Next End Sub
You can see the results of the preceding code in Figure 1. At this point, you have reproduced many of the features a normal InkCollector provides, replacing them with custom functionality. The advantage of this approach is that you have full control and can thus create completely different renderings of Ink "written" or "drawn" with the stylus.

This can be used for much more sophisticated effects than drawing circles of different sizes. Charles Petzold has a nice example, where the "Ink" automatically has a drop-shadow. A similar example adds a glow effect to the Ink. Larry O'Brien has an interesting example that uses pen information to draw Ink in 3D space, using pressure or elapsed time as the third dimension. Limits are set only by your imagination.

Figure 2: Beyond Ink: This figure shows a kaleidoscopic effect produced by mirroring the drawing actions on three different axes.
Another option is to go beyond drawing "Ink" wherever the pen touches the display. The example in Listing 6 shows a simple kaleidoscope, where the drawing is automatically mirrored on three axes. The code change in this example is that you now store references to four controls rather than just one. The first is the one you actually draw on. It is a panel on a form, rather than the form itself, as in the previous examples. The other three controls are simply used to draw each drawing point at a mirrored position. Figure 2 shows the result.

Modifying Collected Information
One of the great advantages of the Real Time Stylus is that you have full control over the data received from the API. This includes the ability to modify data as it is being received. A simple example that demonstrates that capability is the restriction of Inking to a specific area within a control. To keep this example simple, use a rectangle as the allowed Ink area, although the same concept can be used for any shape. Figure 3 shows the example at work.

Figure 3: Restricting the Ink Area: Here's an example of restricting the rectangle within which Ink appears.
Listing 7 shows the implementation of that functionality. The main difference between this example and the version that collected data and drew circles at the pen position is the ModifyData() method. This method is called from the Packet() method before any other processing happens. It compared the X and Y coordinates received from the stylus plug-in and checks whether they fall within the boundaries of a rectangle you define in the constructor of the plug-in (that's what I did to keep things simple for this example-the confining rectangle could be created or modified anywhere).

The tricky part is that in most scenarios, the inkable area is more easily defined in screen coordinates. You first need to map the X and Y coordinates from digitizer resolution to screen resolution, then check whether they are in a valid area; if not, move them into a valid area and translate them back to digitizer resolution. Luckily, this sounds more difficult than it really is, as you can see in Listing 7.

Note that you didn't just translate the values before you drew on the screen, but you changed the data in the actual packet data object. This means that other code (plug-ins) using the same data gets the modified version.

Thanks for your registration, follow us on our social networks to keep up-to-date