private void onPenData(wgssSTU.IPenData penData) // Process incoming pen data { Point pt = tabletToScreen(penData); int btn = 0; // will be +ve if the pen is over a button. { for (int i = 0; i < m_btns.Length; ++i) { if (m_btns[i].Bounds.Contains(pt)) { btn = i + 1; break; } } } bool isDown = (penData.sw != 0); // This code uses a model of four states the pen can be in: // down or up, and whether this is the first sample of that state. if (isDown) { if (m_isDown == 0) { // transition to down if (btn > 0) { // We have put the pen down on a button. // Track the pen without inking on the client. m_isDown = btn; } else { // We have put the pen down somewhere else. // Treat it as part of the signature. m_isDown = -1; } } else { // already down, keep doing what we're doing! } // draw if (m_penData.Count != 0 && m_isDown == -1) { // Draw a line from the previous down point to this down point. // This is the simplist thing you can do; a more sophisticated program // can perform higher quality rendering than this! Graphics gfx = this.CreateGraphics(); gfx.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; gfx.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; wgssSTU.IPenData prevPenData = m_penData[m_penData.Count - 1]; PointF prev = tabletToClient(prevPenData); gfx.DrawLine(m_penInk, prev, tabletToClient(penData)); gfx.Dispose(); } // The pen is down, store it for use later. if (m_isDown == -1) { m_penData.Add(penData); } } else { if (m_isDown != 0) { // transition to up if (btn > 0) { // The pen is over a button if (btn == m_isDown) { // The pen was pressed down over the same button as is was lifted now. // Consider that as a click! m_btns[btn - 1].PerformClick(); } } m_isDown = 0; } else { // still up } // Add up data once we have collected some down data. if (m_penData != null) { if (m_penData.Count != 0) { m_penData.Add(penData); } } } }
// As per the file comment, there are three coordinate systems to deal with. // To help understand, we have left the calculations in place rather than optimise them. private PointF tabletToClient(wgssSTU.IPenData penData) { // Client means the Windows Form coordinates. return(new PointF((float)penData.x * this.ClientSize.Width / m_capability.tabletMaxX, (float)penData.y * this.ClientSize.Height / m_capability.tabletMaxY)); }
private Point tabletToScreen(wgssSTU.IPenData penData) { // Screen means LCD screen of the tablet. return(Point.Round(new PointF((float)penData.x * m_capability.screenWidth / m_capability.tabletMaxX, (float)penData.y * m_capability.screenHeight / m_capability.tabletMaxY))); }
private Point tabletToScreen(wgssSTU.IPenData penData, Rectangle customResolution) { // Screen means LCD screen of the tablet. return(Point.Round(new PointF(((float)customResolution.X) + ((float)penData.x * (customResolution.Width - customResolution.X) / m_capability.tabletMaxX), ((float)customResolution.Y) + ((float)penData.y * (customResolution.Height - customResolution.Y) / m_capability.tabletMaxY)))); }