2025-11-28 00:35:46 +09:00

1673 lines
69 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.
//
// File: InkClipboard.cs
// Simple Ink Clipboard with Selection Sample Application
//
// This program demonstrates how to copy and paste ink into
// another application such as Microsoft Word or Microsoft Paint.
// It also allows the user to copy a selection of strokes and
// paste the result into this application's existing ink object.
//
// The following clipboard formats are available:
//
// Metafile
// Enhanced Metafile
// Bitmap
// Ink Serialized Format
// Text Ink
// Sketch Ink
// TextInk and SketchInk are two flavors of Ink OLE Embeddable Objects
// that Microsoft Word uses for ink that represents text or drawing
// respectively.
// It is possible to paste Ink Serialized Format, Text Ink, and
// Sketch Ink into existing ink.
//
// In addition to the clipboard, this sample also illustrates how
// to select strokes with a lasso. The user can move selected
// strokes and modify their drawing attributes. This functionality
// is a subset of the selection functionality already provided by
// the InkOverlay control; it is implemented here for illustrative
// purposes.
//
// The features used are: InkCollector, Ink Clipboard support, and
// HitTest with lasso.
//
//--------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Windows.Forms;
// The Ink namespace, which contains the Tablet PC Platform API
using Microsoft.Ink;
namespace Microsoft.Samples.TabletPC.InkClipboard
{
/// <summary>
/// Enumeration of all possible application modes:
///
/// Ink: The user is drawing new strokes
/// LassoSelection: The user is selecting strokes with a lasso
/// MoveInk: The user is moving selected strokes (this is not a menu item)
///
/// </summary>
public enum ApplicationMode
{
Ink,
LassoSelection,
MoveInk
}
/// <summary>
/// The InkClipboard with Selection Sample Application form class
/// </summary>
public class InkClipboard : System.Windows.Forms.Form
{
// --------------- Constants ---------------
// Declare constants for the pen widths used by this application.
// Note that these constants are in high metric units (1 unit = .01mm)
private const float ThinInkWidth = 10;
private const float MediumInkWidth = 100;
private const float ThickInkWidth = 200;
// Declare constant for the size of the border around selected strokes
private const int SelectedInkWidthIncrease = 105;
// Declare constant for the size of a lasso point
private const int DotSize = 6;
// Declare constant for the spacing between lasso points
private const int DotSpacing = 7;
// Declare constant for the padding size of the rectangle that bounds
// the selected strokes.
private const int SelectionRectBuffer = 8;
// Declare constant for the lasso hit test percent (specifies how much
// of the stroke must fall within the lasso in order to be selected).
private const float LassoPercent = 50;
// The index for the x and y packet values. This index is used
// to retrieve the lasso point data in the Packets event handler.
private const int XPacketIndex = 0;
private const int YPacketIndex = 1;
// --------------- Fields ---------------
// Declare the Ink Collector object
private InkCollector myInkCollector = null;
// The current application mode: inking, selecting, or moving the selection
private ApplicationMode applicationMode = ApplicationMode.Ink;
// The points in the selection lasso
private ArrayList lassoPoints = null;
// The array of rectangle selection handles
private PictureBox[] selectionHandles;
// The rectangle that bounds the selected strokes
private Rectangle selectionRect = Rectangle.Empty;
// The strokes that have been selected by the lasso
private Strokes selectedStrokes = null;
// The location where the move started (used when moving selected strokes)
private Point startMoveLocation = Point.Empty;
// The coordinates of the last lasso point drawn (empty if no dot has been drawn)
private Point lastDrawnLassoDot = Point.Empty;
// Declare the colors used in the selection lasso
private Color dotEdgeColor = Color.White;
private Color dotColor = SystemColors.Highlight;
private Color connectorColor = Color.Black;
// Declare the pens used to draw the selection lasso
private Pen connectorPen = null;
private Pen dotEdgePen = null;
private Pen dotPen = null;
// --------------- Constructor ---------------
#region Standard Template Code
private System.Windows.Forms.MenuItem miClear;
private System.Windows.Forms.MenuItem miExit;
private System.Windows.Forms.MenuItem miMainEdit;
private System.Windows.Forms.MenuItem miCut;
private System.Windows.Forms.MenuItem miCopy;
private System.Windows.Forms.MenuItem miPaste;
private System.Windows.Forms.MenuItem miInk;
private System.Windows.Forms.MenuItem miMainFormat;
private System.Windows.Forms.MenuItem miISF;
private System.Windows.Forms.MenuItem miMetafile;
private System.Windows.Forms.MenuItem miBMP;
private System.Windows.Forms.MenuItem miEMF;
private System.Windows.Forms.MenuItem miSInk;
private System.Windows.Forms.MenuItem miTInk;
private System.Windows.Forms.MenuItem miNoOLE;
private System.Windows.Forms.MenuItem miThin;
private System.Windows.Forms.MenuItem miMedium;
private System.Windows.Forms.MenuItem miThick;
private System.Windows.Forms.MenuItem miRed;
private System.Windows.Forms.MenuItem miGreen;
private System.Windows.Forms.MenuItem miBlue;
private System.Windows.Forms.MenuItem miBlack;
private System.Windows.Forms.PictureBox rightBottomHandle;
private System.Windows.Forms.PictureBox centerBottomHandle;
private System.Windows.Forms.PictureBox leftBottomHandle;
private System.Windows.Forms.PictureBox rightCenterHandle;
private System.Windows.Forms.PictureBox leftCenterHandle;
private System.Windows.Forms.PictureBox rightTopHandle;
private System.Windows.Forms.PictureBox centerTopHandle;
private System.Windows.Forms.PictureBox leftTopHandle;
private System.Windows.Forms.MenuItem miLassoSelect;
private System.Windows.Forms.MainMenu mainMenu;
private System.Windows.Forms.MenuItem miInkSeparator;
private System.Windows.Forms.MenuItem miEditSeparator;
private System.Windows.Forms.MenuItem miFormatSeparator;
private System.Windows.Forms.MenuItem miStyle;
private System.Windows.Forms.MenuItem miWidth;
private System.Windows.Forms.MenuItem miColor;
private System.Windows.Forms.MenuItem miMainAction;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
#endregion
public InkClipboard()
{
#region Standard Template Code
//
// Required for Windows Form Designer support
//
InitializeComponent();
#endregion
}
#region Standard Template Code
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
if (myInkCollector != null)
{
myInkCollector.Dispose();
}
}
base.Dispose( disposing );
}
#endregion
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(InkClipboard));
this.mainMenu = new System.Windows.Forms.MainMenu();
this.miMainAction = new System.Windows.Forms.MenuItem();
this.miClear = new System.Windows.Forms.MenuItem();
this.miInkSeparator = new System.Windows.Forms.MenuItem();
this.miExit = new System.Windows.Forms.MenuItem();
this.miMainEdit = new System.Windows.Forms.MenuItem();
this.miCut = new System.Windows.Forms.MenuItem();
this.miCopy = new System.Windows.Forms.MenuItem();
this.miPaste = new System.Windows.Forms.MenuItem();
this.miEditSeparator = new System.Windows.Forms.MenuItem();
this.miLassoSelect = new System.Windows.Forms.MenuItem();
this.miInk = new System.Windows.Forms.MenuItem();
this.miMainFormat = new System.Windows.Forms.MenuItem();
this.miISF = new System.Windows.Forms.MenuItem();
this.miMetafile = new System.Windows.Forms.MenuItem();
this.miEMF = new System.Windows.Forms.MenuItem();
this.miBMP = new System.Windows.Forms.MenuItem();
this.miFormatSeparator = new System.Windows.Forms.MenuItem();
this.miSInk = new System.Windows.Forms.MenuItem();
this.miTInk = new System.Windows.Forms.MenuItem();
this.miNoOLE = new System.Windows.Forms.MenuItem();
this.miStyle = new System.Windows.Forms.MenuItem();
this.miWidth = new System.Windows.Forms.MenuItem();
this.miThin = new System.Windows.Forms.MenuItem();
this.miMedium = new System.Windows.Forms.MenuItem();
this.miThick = new System.Windows.Forms.MenuItem();
this.miColor = new System.Windows.Forms.MenuItem();
this.miRed = new System.Windows.Forms.MenuItem();
this.miGreen = new System.Windows.Forms.MenuItem();
this.miBlue = new System.Windows.Forms.MenuItem();
this.miBlack = new System.Windows.Forms.MenuItem();
this.rightBottomHandle = new System.Windows.Forms.PictureBox();
this.centerBottomHandle = new System.Windows.Forms.PictureBox();
this.leftBottomHandle = new System.Windows.Forms.PictureBox();
this.rightCenterHandle = new System.Windows.Forms.PictureBox();
this.leftCenterHandle = new System.Windows.Forms.PictureBox();
this.rightTopHandle = new System.Windows.Forms.PictureBox();
this.centerTopHandle = new System.Windows.Forms.PictureBox();
this.leftTopHandle = new System.Windows.Forms.PictureBox();
this.SuspendLayout();
//
// mainMenu
//
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miMainAction,
this.miMainEdit,
this.miMainFormat,
this.miStyle});
//
// miMainAction
//
this.miMainAction.Index = 0;
this.miMainAction.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miClear,
this.miInkSeparator,
this.miExit});
this.miMainAction.Text = "&Action";
//
// miClear
//
this.miClear.Index = 0;
this.miClear.Text = "&Clear";
this.miClear.Click += new System.EventHandler(this.miClear_Click);
//
// miInkSeparator
//
this.miInkSeparator.Index = 1;
this.miInkSeparator.Text = "-";
//
// miExit
//
this.miExit.Index = 2;
this.miExit.Text = "&Exit";
this.miExit.Click += new System.EventHandler(this.miExit_Click);
//
// miMainEdit
//
this.miMainEdit.Index = 1;
this.miMainEdit.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miCut,
this.miCopy,
this.miPaste,
this.miEditSeparator,
this.miLassoSelect,
this.miInk});
this.miMainEdit.Text = "&Edit";
this.miMainEdit.Popup += new System.EventHandler(this.miMainEdit_Popup);
//
// miCut
//
this.miCut.Index = 0;
this.miCut.Shortcut = System.Windows.Forms.Shortcut.CtrlX;
this.miCut.Text = "Cu&t";
this.miCut.Click += new System.EventHandler(this.miCut_Click);
//
// miCopy
//
this.miCopy.Index = 1;
this.miCopy.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
this.miCopy.Text = "&Copy";
this.miCopy.Click += new System.EventHandler(this.miCopy_Click);
//
// miPaste
//
this.miPaste.Index = 2;
this.miPaste.Shortcut = System.Windows.Forms.Shortcut.CtrlV;
this.miPaste.Text = "&Paste";
this.miPaste.Click += new System.EventHandler(this.miPaste_Click);
//
// miEditSeparator
//
this.miEditSeparator.Index = 3;
this.miEditSeparator.Text = "-";
//
// miLassoSelect
//
this.miLassoSelect.Index = 4;
this.miLassoSelect.RadioCheck = true;
this.miLassoSelect.Text = "&Select";
this.miLassoSelect.Click += new System.EventHandler(this.miLassoSelect_Click);
//
// miInk
//
this.miInk.Checked = true;
this.miInk.Index = 5;
this.miInk.RadioCheck = true;
this.miInk.Text = "&Ink";
this.miInk.Click += new System.EventHandler(this.miInk_Click);
//
// miMainFormat
//
this.miMainFormat.Index = 2;
this.miMainFormat.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miISF,
this.miMetafile,
this.miEMF,
this.miBMP,
this.miFormatSeparator,
this.miSInk,
this.miTInk,
this.miNoOLE});
this.miMainFormat.Text = "&Format";
//
// miISF
//
this.miISF.Checked = true;
this.miISF.Index = 0;
this.miISF.Text = "&Ink Serialized Format (ISF)";
this.miISF.Click += new System.EventHandler(this.miISF_Click);
//
// miMetafile
//
this.miMetafile.Checked = true;
this.miMetafile.Index = 1;
this.miMetafile.Text = "&Metafile";
this.miMetafile.Click += new System.EventHandler(this.miMetafile_Click);
//
// miEMF
//
this.miEMF.Checked = true;
this.miEMF.Index = 2;
this.miEMF.Text = "&Enhanced Metafile";
this.miEMF.Click += new System.EventHandler(this.miEMF_Click);
//
// miBMP
//
this.miBMP.Checked = true;
this.miBMP.Index = 3;
this.miBMP.Text = "&Bitmap";
this.miBMP.Click += new System.EventHandler(this.miBMP_Click);
//
// miFormatSeparator
//
this.miFormatSeparator.Index = 4;
this.miFormatSeparator.Text = "-";
//
// miSInk
//
this.miSInk.Index = 5;
this.miSInk.RadioCheck = true;
this.miSInk.Text = "&Sketch Ink";
this.miSInk.Click += new System.EventHandler(this.miSInk_Click);
//
// miTInk
//
this.miTInk.Checked = true;
this.miTInk.Index = 6;
this.miTInk.RadioCheck = true;
this.miTInk.Text = "&Text Ink";
this.miTInk.Click += new System.EventHandler(this.miTInk_Click);
//
// miNoOLE
//
this.miNoOLE.Index = 7;
this.miNoOLE.RadioCheck = true;
this.miNoOLE.Text = "&No OLE Object Format";
this.miNoOLE.Click += new System.EventHandler(this.miNoOLE_Click);
//
// miStyle
//
this.miStyle.Index = 3;
this.miStyle.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miWidth,
this.miColor});
this.miStyle.Text = "&Style";
//
// miWidth
//
this.miWidth.Index = 0;
this.miWidth.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miThin,
this.miMedium,
this.miThick});
this.miWidth.Text = "&Width";
//
// miThin
//
this.miThin.Index = 0;
this.miThin.Text = "Thin";
this.miThin.Click += new System.EventHandler(this.miThin_Click);
//
// miMedium
//
this.miMedium.Index = 1;
this.miMedium.Text = "Medium";
this.miMedium.Click += new System.EventHandler(this.miMedium_Click);
//
// miThick
//
this.miThick.Index = 2;
this.miThick.Text = "Thick";
this.miThick.Click += new System.EventHandler(this.miThick_Click);
//
// miColor
//
this.miColor.Index = 1;
this.miColor.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miRed,
this.miGreen,
this.miBlue,
this.miBlack});
this.miColor.Text = "&Color";
//
// miRed
//
this.miRed.Index = 0;
this.miRed.Text = "Red";
this.miRed.Click += new System.EventHandler(this.miRed_Click);
//
// miGreen
//
this.miGreen.Index = 1;
this.miGreen.Text = "Green";
this.miGreen.Click += new System.EventHandler(this.miGreen_Click);
//
// miBlue
//
this.miBlue.Index = 2;
this.miBlue.Text = "Blue";
this.miBlue.Click += new System.EventHandler(this.miBlue_Click);
//
// miBlack
//
this.miBlack.Index = 3;
this.miBlack.Text = "Black";
this.miBlack.Click += new System.EventHandler(this.miBlack_Click);
//
// rightBottomHandle
//
this.rightBottomHandle.BackColor = System.Drawing.Color.Gray;
this.rightBottomHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.rightBottomHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("rightBottomHandle.Image")));
this.rightBottomHandle.Location = new System.Drawing.Point(281, 256);
this.rightBottomHandle.Name = "rightBottomHandle";
this.rightBottomHandle.Size = new System.Drawing.Size(11, 11);
this.rightBottomHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.rightBottomHandle.TabIndex = 20;
this.rightBottomHandle.TabStop = false;
this.rightBottomHandle.Visible = false;
//
// centerBottomHandle
//
this.centerBottomHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.centerBottomHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("centerBottomHandle.Image")));
this.centerBottomHandle.Location = new System.Drawing.Point(137, 256);
this.centerBottomHandle.Name = "centerBottomHandle";
this.centerBottomHandle.Size = new System.Drawing.Size(9, 9);
this.centerBottomHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.centerBottomHandle.TabIndex = 19;
this.centerBottomHandle.TabStop = false;
this.centerBottomHandle.Visible = false;
//
// leftBottomHandle
//
this.leftBottomHandle.BackColor = System.Drawing.Color.Gray;
this.leftBottomHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.leftBottomHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("leftBottomHandle.Image")));
this.leftBottomHandle.Location = new System.Drawing.Point(1, 256);
this.leftBottomHandle.Name = "leftBottomHandle";
this.leftBottomHandle.Size = new System.Drawing.Size(11, 11);
this.leftBottomHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.leftBottomHandle.TabIndex = 18;
this.leftBottomHandle.TabStop = false;
this.leftBottomHandle.Visible = false;
//
// rightCenterHandle
//
this.rightCenterHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.rightCenterHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("rightCenterHandle.Image")));
this.rightCenterHandle.Location = new System.Drawing.Point(281, 128);
this.rightCenterHandle.Name = "rightCenterHandle";
this.rightCenterHandle.Size = new System.Drawing.Size(9, 9);
this.rightCenterHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.rightCenterHandle.TabIndex = 17;
this.rightCenterHandle.TabStop = false;
this.rightCenterHandle.Visible = false;
//
// leftCenterHandle
//
this.leftCenterHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.leftCenterHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("leftCenterHandle.Image")));
this.leftCenterHandle.Location = new System.Drawing.Point(1, 128);
this.leftCenterHandle.Name = "leftCenterHandle";
this.leftCenterHandle.Size = new System.Drawing.Size(9, 9);
this.leftCenterHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.leftCenterHandle.TabIndex = 16;
this.leftCenterHandle.TabStop = false;
this.leftCenterHandle.Visible = false;
//
// rightTopHandle
//
this.rightTopHandle.BackColor = System.Drawing.Color.Gray;
this.rightTopHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.rightTopHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("rightTopHandle.Image")));
this.rightTopHandle.Location = new System.Drawing.Point(281, 0);
this.rightTopHandle.Name = "rightTopHandle";
this.rightTopHandle.Size = new System.Drawing.Size(11, 11);
this.rightTopHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.rightTopHandle.TabIndex = 15;
this.rightTopHandle.TabStop = false;
this.rightTopHandle.Visible = false;
//
// centerTopHandle
//
this.centerTopHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.centerTopHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("centerTopHandle.Image")));
this.centerTopHandle.Location = new System.Drawing.Point(137, 0);
this.centerTopHandle.Name = "centerTopHandle";
this.centerTopHandle.Size = new System.Drawing.Size(9, 9);
this.centerTopHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.centerTopHandle.TabIndex = 14;
this.centerTopHandle.TabStop = false;
this.centerTopHandle.Visible = false;
//
// leftTopHandle
//
this.leftTopHandle.BackColor = System.Drawing.Color.Gray;
this.leftTopHandle.Cursor = System.Windows.Forms.Cursors.Default;
this.leftTopHandle.Image = ((System.Drawing.Bitmap)(resources.GetObject("leftTopHandle.Image")));
this.leftTopHandle.Location = new System.Drawing.Point(1, 0);
this.leftTopHandle.Name = "leftTopHandle";
this.leftTopHandle.Size = new System.Drawing.Size(11, 11);
this.leftTopHandle.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.leftTopHandle.TabIndex = 13;
this.leftTopHandle.TabStop = false;
this.leftTopHandle.Visible = false;
//
// InkClipboard
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.rightBottomHandle,
this.centerBottomHandle,
this.leftBottomHandle,
this.rightCenterHandle,
this.leftCenterHandle,
this.rightTopHandle,
this.centerTopHandle,
this.leftTopHandle});
this.Menu = this.mainMenu;
this.Name = "InkClipboard";
this.Text = "InkClipboard";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.InkClipboard_MouseDown);
this.Load += new System.EventHandler(this.InkClipboard_Load);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.InkClipboard_MouseUp);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.InkClipboard_Paint);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.InkClipboard_MouseMove);
this.ResumeLayout(false);
}
#endregion
#region Standard Template Code
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new InkClipboard());
}
#endregion
// --------------- Form Events ---------------
/// <summary>
/// Event Handler from Form Load Event
/// Setup the ink collector for collection
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void InkClipboard_Load(object sender, System.EventArgs e)
{
// Set the application mode to inking
applicationMode = ApplicationMode.Ink;
// Initialize the selection data
lassoPoints = new ArrayList();
selectionHandles = new PictureBox[] {leftTopHandle,centerTopHandle,rightTopHandle,leftCenterHandle,rightCenterHandle,leftBottomHandle,centerBottomHandle,rightBottomHandle};
selectionRect = new Rectangle();
selectedStrokes = null;
// Create the pens used to draw the lasso selection
connectorPen = new Pen(connectorColor); // Pen used to draw dotted lasso connector line
connectorPen.DashStyle = DashStyle.Dash;
dotEdgePen = new Pen(dotEdgeColor); // Pen used to draw the outer edge of the lasso dot
dotPen = new Pen(dotColor); // Pen used to draw the center of the lasso dot
// Create a new ink collector and assign it to this form's window
myInkCollector = new InkCollector(this.Handle);
// Set the ink collector's pen width
myInkCollector.DefaultDrawingAttributes.Width = MediumInkWidth;
// Turn the ink collector on
myInkCollector.Enabled = true;
}
/// <summary>
/// Event Handler from Form Paint Event
///
/// When no ink is selected, autoredrawing is turned on and
/// this method doesn't need to do anything. However, if
/// there is a selection, autoredrawing is turned off and
/// it is necessary to draw the strokes manually
/// (in order to display the strokes as selected).
///
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void InkClipboard_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// If AutoRedraw is turned off, perform the drawing manually.
if (!myInkCollector.AutoRedraw)
{
DrawStrokes(e.Graphics);
e.Graphics.DrawRectangle(connectorPen,selectionRect);
}
// If the user is drawing a lasso, repaint the lasso points.
if (ApplicationMode.LassoSelection == applicationMode)
{
DrawLasso(e.Graphics, 0);
}
}
/// <summary>
/// Event Handler from Form Mouse Down Event
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void InkClipboard_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
// If the mouse button was pressed down within the
// current selection area, update the application mode
// to indicate that the user is moving ink and record
// the starting location of the move. This value will
// be used in MouseMove to determine how much the selected
// ink should be moved.
if (selectionRect.Contains(e.X,e.Y))
{
applicationMode = ApplicationMode.MoveInk;
startMoveLocation = new Point(e.X, e.Y);
}
// Otherwise, if there is a selection and the mouse
// is pressed, clear the selection.
else if (HasSelection())
{
SetSelection(null);
}
}
/// <summary>
/// Event Handler from Form Mouse Move Event
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void InkClipboard_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
// If the selected ink is currently being moved...
if (applicationMode == ApplicationMode.MoveInk && HasSelection())
{
// Compute the ink space distance the mouse has moved and
// move the selected strokes correspondingly.
Point moveAmount = new Point(e.X-startMoveLocation.X,e.Y-startMoveLocation.Y);
using (Graphics g = CreateGraphics())
{
myInkCollector.Renderer.PixelToInkSpace(g, ref moveAmount);
}
selectedStrokes.Move(moveAmount.X, moveAmount.Y);
// Record the location of the mouse since the next
// move should be relative to it.
startMoveLocation.X = e.X;
startMoveLocation.Y = e.Y;
// Update the selection rectangle
SetSelection(selectedStrokes);
}
else
{
// If the mouse has entered the rectangular selection
// region, disable ink collection and update the cursor
// to show that the user can move this region. It is
// necessary to disable ink collection since ink should not
// flow from the pen while the user is moving the selection.
if ( selectionRect.Contains(e.X,e.Y) )
{
if (myInkCollector.Enabled && !myInkCollector.CollectingInk)
{
myInkCollector.Enabled = false;
Cursor = System.Windows.Forms.Cursors.SizeAll;
}
}
// Otherwise, enable ink collection and set the cursor
// to its default value (if necessary).
else if (!myInkCollector.Enabled)
{
myInkCollector.Enabled = true;
Cursor = System.Windows.Forms.Cursors.Arrow;
}
}
}
/// <summary>
/// Event Handler from Form Mouse Up Event
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void InkClipboard_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
// If the user was moving selected ink and the
// mouse is raised, set the application mode back to
// its original value.
if (applicationMode == ApplicationMode.MoveInk)
{
if (miLassoSelect.Checked)
{
applicationMode = ApplicationMode.LassoSelection;
}
else
{
applicationMode = ApplicationMode.Ink;
}
}
}
/// <summary>
/// Event Handler from Ink->Clear Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miClear_Click(object sender, System.EventArgs e)
{
// Clear the selection and delete all strokes from the ink
myInkCollector.Ink.DeleteStrokes();
SetSelection(null);
}
/// <summary>
/// Event Handler from Ink->Exit Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miExit_Click(object sender, System.EventArgs e)
{
// Although not required, it is good practice to disable
// ink collection before exiting
myInkCollector.Enabled = false;
Application.Exit();
}
/// <summary>
/// Event Handler from Edit Select Event
///
/// If the Edit menu is selected, check whether the object
/// that is currently on the clipboard can be pasted into
/// the ink. Disable the Paste item if it can't be pasted.
/// Also, disable Copy and Cut if no ink is selected.
///
///
/// Allowable formats: Ink Serialized Format or Embeddable OLE
/// Object (Text Ink or Sketch Ink).
///
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miMainEdit_Popup(object sender, System.EventArgs e)
{
miPaste.Enabled = myInkCollector.Ink.CanPaste();
miCopy.Enabled = HasSelection();
miCut.Enabled = HasSelection();
}
/// <summary>
/// Event Handler from Edit->Cut Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miCut_Click(object sender, System.EventArgs e)
{
// Use helper method to cut the selection
CopyInkToClipboard(InkClipboardModes.Cut);
SetSelection(null);
}
/// <summary>
/// Event Handler from Edit->Copy Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miCopy_Click(object sender, System.EventArgs e)
{
// Use helper method to copy the selection
CopyInkToClipboard(InkClipboardModes.Copy);
}
/// <summary>
/// Event Handler from Edit->Paste Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miPaste_Click(object sender, System.EventArgs e)
{
if (myInkCollector.Ink.CanPaste())
{
// Compute the location where the ink should be pasted;
// this location should be shifted from the origin
// to account for the width of the selection rectangle's handle.
Point offset = new Point(leftTopHandle.Width+1,leftTopHandle.Height+1);
using (Graphics g = CreateGraphics())
{
myInkCollector.Renderer.PixelToInkSpace(g, ref offset);
}
// Use Ink API to paste the clipboard data into the Ink
Strokes pastedStrokes = myInkCollector.Ink.ClipboardPaste(offset);
// If the contents of the clipboard were a valid format
// (Ink Serialized Format or Embeddable OLE Object) and at
// least one stroke was pasted into the ink, use a helper
// method to update the stroke selection. Otherwise,
// the result will be null and this paste becomes a no-op.
if (null != pastedStrokes)
{
SetSelection(pastedStrokes);
}
}
else
{
MessageBox.Show("Unable to paste ink.");
}
}
/// <summary>
/// Event Handler from Edit->Select Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miLassoSelect_Click(object sender, System.EventArgs e)
{
if (ApplicationMode.LassoSelection != applicationMode)
{
// Set the application mode to lasso selection
applicationMode = ApplicationMode.LassoSelection;
// Lasso strokes should be transparent
myInkCollector.DefaultDrawingAttributes.Transparency = 255;
// Use helper method to clear the selection
SetSelection(null);
// Update menu item state
miLassoSelect.Checked = true;
miInk.Checked = false;
// Hook the new packets and stroke events since
// these events are needed to implement lasso selection.
// These events are only hooked when they are needed to improve
// performance.
myInkCollector.NewPackets += new InkCollectorNewPacketsEventHandler(myInkCollector_NewPackets);
myInkCollector.Stroke += new InkCollectorStrokeEventHandler(myInkCollector_Stroke);
}
}
/// <summary>
/// Event Handler from Edit->Ink Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miInk_Click(object sender, System.EventArgs e)
{
if (applicationMode != ApplicationMode.Ink)
{
// Set the application mode to ink collection
applicationMode = ApplicationMode.Ink;
// Ink strokes should be opaque
myInkCollector.DefaultDrawingAttributes.Transparency = 0;
// Use helper method to clear the selection
SetSelection(null);
// Update menu item state
miLassoSelect.Checked = false;
miInk.Checked = true;
// Unhook the new packets and stroke events since
// these events are only needed to implement lasso selection.
// These events are only hooked when they are needed to improve
// performance.
myInkCollector.NewPackets -= new InkCollectorNewPacketsEventHandler(myInkCollector_NewPackets);
myInkCollector.Stroke -= new InkCollectorStrokeEventHandler(myInkCollector_Stroke);
}
}
/// <summary>
/// Event Handler from Format->ISF Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miISF_Click(object sender, System.EventArgs e)
{
miISF.Checked = !miISF.Checked;
}
/// <summary>
/// Event Handler from Metafile->ISF Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miMetafile_Click(object sender, System.EventArgs e)
{
miMetafile.Checked = !miMetafile.Checked;
}
/// <summary>
/// Event Handler from Format->EMF Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miEMF_Click(object sender, System.EventArgs e)
{
miEMF.Checked = !miEMF.Checked;
}
/// <summary>
/// Event Handler from Format->BMP Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miBMP_Click(object sender, System.EventArgs e)
{
miBMP.Checked = !miBMP.Checked;
}
/// <summary>
/// Event Handler from Format->Text Ink Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miTInk_Click(object sender, System.EventArgs e)
{
miSInk.Checked = false;
miTInk.Checked = true;
miNoOLE.Checked = false;
}
/// <summary>
/// Event Handler from Format->Sketch Ink Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miSInk_Click(object sender, System.EventArgs e)
{
miSInk.Checked = true;
miTInk.Checked = false;
miNoOLE.Checked = false;
}
/// <summary>
/// Event Handler from Format->No OLE Object Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miNoOLE_Click(object sender, System.EventArgs e)
{
miSInk.Checked = false;
miTInk.Checked = false;
miNoOLE.Checked = true;
}
/// <summary>
/// Event Handler from Style->Color->Red Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miRed_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected color.
SetColor(Color.Red);
}
/// <summary>
/// Event Handler from Style->Color->Green Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miGreen_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected color.
SetColor(Color.Green);
}
/// <summary>
/// Event Handler from Style->Color->Blue Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miBlue_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected color.
SetColor(Color.Blue);
}
/// <summary>
/// Event Handler from Style->Color->Black Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miBlack_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected color.
SetColor(Color.Black);
}
/// <summary>
/// Event Handler from Style->Width->Thin Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miThin_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected pen width.
SetWidth(ThinInkWidth);
}
/// <summary>
/// Event Handler from Style->Width->Medium Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miMedium_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected pen width.
SetWidth(MediumInkWidth);
}
/// <summary>
/// Event Handler from Style->Width->Thick Menu Item
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void miThick_Click(object sender, System.EventArgs e)
{
// Use helper method to set the InkCollector and the
// selected strokes to the selected pen width.
SetWidth(ThickInkWidth);
}
// --------------- Ink Collector Events ---------------
/// <summary>
/// Event Handler from Ink Collector's NewPackets event
///
/// This event is fired when the Ink Collector receives
/// new packet data and the user is drawing a lasso.
/// In this case, it is necessary to intercept the new packets
/// and use them to draw the selection lasso.
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void myInkCollector_NewPackets(object sender, InkCollectorNewPacketsEventArgs e)
{
// retrieve the size of each packet
int packetDescriptionLength = e.Stroke.PacketDescription.Length;
// the index where the new lasso points will be added
int newPacketIndex = lassoPoints.Count;
using (Graphics g = CreateGraphics())
{
// Add each new packet into the lasso points collection
for (int i = 0; i < e.PacketCount; i++)
{
// retrieve the x and y packet values
Point pt = new Point(e.PacketData[i * packetDescriptionLength + XPacketIndex],
e.PacketData[i * packetDescriptionLength + YPacketIndex]);
myInkCollector.Renderer.InkSpaceToPixel(g, ref pt);
// If the x or y packet values fall outside of
// the drawing area , update them to the nearest
// location on the drawing area. This adjustment
// prevents the lasso's boundaries from going
// beyond the drawing area.
if (pt.X<0)
{
pt.X = 0;
}
if (pt.X>ClientSize.Width)
{
pt.X = ClientSize.Width;
}
if (pt.Y<0)
{
pt.Y = 0;
}
if (pt.Y>this.ClientSize.Height)
{
pt.Y = ClientSize.Height;
}
// Add the new point into the lasso points collection
lassoPoints.Add(pt);
}
// Draw the updated lasso. In order to improve performance,
// only the new lasso packets will be drawn.
DrawLasso(g,newPacketIndex);
}
}
/// <summary>
/// Event Handler from Ink Collector's Stroke event
///
/// This event is fired when a new lasso stroke is drawn.
/// In this case, it is necessary to update the selected
/// strokes information.
/// </summary>
/// <param name="sender">The control that raised the event.</param>
/// <param name="e">The event arguments.</param>
private void myInkCollector_Stroke(object sender, InkCollectorStrokeEventArgs e )
{
// This stroke corresponds to the lasso -
// cancel it so that it is not added into the ink
e.Cancel = true;
Strokes hitStrokes = null;
// If there are enough lasso points, perform a hit test
// to determine which strokes were selected.
if (lassoPoints.Count > 2)
{
// Convert the lasso points from pixels to ink space
Point[] inkLassoPoints = (Point[])lassoPoints.ToArray(typeof(Point));
using (Graphics g = CreateGraphics())
{
myInkCollector.Renderer.PixelToInkSpace(g, ref inkLassoPoints);
}
// Perform a hit test on this ink collector's ink to
// determine which points were selected by the lasso stroke.
//
// Note that there is a slight inefficiency here since the
// lasso stroke is part of the ink and, therefore, part of the
// hit test - even though we don't need it. It would have
// been more efficient to remove the stroke from the ink before
// calling HitTest. However, it is not good practice to modify
// the stroke inside of its own event handler.
hitStrokes = myInkCollector.Ink.HitTest(inkLassoPoints, LassoPercent);
hitStrokes.Remove(e.Stroke);
}
// Reset the lasso points
lassoPoints.Clear();
lastDrawnLassoDot = Point.Empty;
// Use helper method to set the selection
SetSelection(hitStrokes);
}
// --------------- Helper Methods ---------------
/// <summary>
/// Helper method to convert a rectangle in pixel coordinates
/// to ink space coordinates. (1 ink space unit = .01mm)
///
/// Note that this method works since there is guaranteed not
/// to be any rotation in this sample.
/// </summary>
/// <param name="g">The graphics display</param>
/// <param name="r">The rectangle to convert</param>
private void PixelToInkSpace(Graphics g, ref Rectangle r)
{
Point leftTop = new Point(r.X,r.Y);
Point widthHeight = new Point (r.Width, r.Height);
myInkCollector.Renderer.PixelToInkSpace(g, ref leftTop);
myInkCollector.Renderer.PixelToInkSpace(g, ref widthHeight);
r.Location = leftTop;
r.Size = new Size(widthHeight);
}
/// <summary>
/// Helper method to convert a rectangle in ink space
/// coordinates to pixel coordinates. (1 ink space unit = .01mm)
///
/// Note that this method works since there is guaranteed not
/// to be any rotation in this sample.
/// </summary>
/// <param name="g">The graphics display</param>
/// <param name="r">The rectangle to convert</param>
private void InkSpaceToPixel(Graphics g, ref Rectangle r)
{
Point leftTop = new Point(r.X,r.Y);
Point widthHeight = new Point (r.Width, r.Height);
myInkCollector.Renderer.InkSpaceToPixel(g, ref leftTop);
myInkCollector.Renderer.InkSpaceToPixel(g, ref widthHeight);
r.Location = leftTop;
r.Size = new Size(widthHeight);
}
/// <summary>
/// This method uses the Ink API to copy ink onto
/// the clipboard.
/// </summary>
/// <param name="clipboardModes">The clipboard modes (such as copy or paste)</param>
private void CopyInkToClipboard(InkClipboardModes clipboardModes)
{
// Declare the ink clipboard formats to put on the clipboard
InkClipboardFormats formats = new InkClipboardFormats();
// Use selected format menu items to set the clipboard formats
if (miISF.Checked)
{
formats |= InkClipboardFormats.InkSerializedFormat;
}
if (miMetafile.Checked)
{
formats |= InkClipboardFormats.Metafile;
}
if (miEMF.Checked)
{
formats |= InkClipboardFormats.EnhancedMetafile;
}
if (miBMP.Checked)
{
formats |= InkClipboardFormats.Bitmap;
}
if (miSInk.Checked)
{
formats |= InkClipboardFormats.SketchInk;
}
if (miTInk.Checked)
{
formats |= InkClipboardFormats.TextInk;
}
// If at least one format was selected, invoke the Ink
// API's ClipboardCopy method. Note that selectedStrokes
// could be null, but that this is ok - if selectedStrokes
// is null, all of the ink is copied.
if (formats != InkClipboardFormats.None)
{
myInkCollector.Ink.ClipboardCopy(selectedStrokes,formats,clipboardModes);
}
else
{
MessageBox.Show("No clipboard formats selected");
}
}
/// <summary>
/// Sets the selected strokes and selection rectangle.
/// </summary>
/// <param name="strokes">The strokes that should be selected. If null, the selection becomes empty</param>
private void SetSelection(Strokes strokes)
{
// Tracks whether the rectangle that bounds the selected
// strokes should be displayed
bool isSelectionVisible = false;
// Update the selected strokes collection
selectedStrokes = strokes;
// If no strokes are selected, set the selection rectangle
// to empty
if (!HasSelection())
{
selectionRect = Rectangle.Empty;
}
// Otherwise, at least one stroke is selected and it is necessary
// to display the selection rectangle.
else
{
isSelectionVisible = true;
// Retrieve the bounding box of the strokes
selectionRect = selectedStrokes.GetBoundingBox();
using (Graphics g = CreateGraphics())
{
InkSpaceToPixel(g, ref selectionRect);
}
// Pad the selection rectangle so that the selected ink
// doesn't overlap with the selection rectangle's handles.
selectionRect.Inflate(SelectionRectBuffer, SelectionRectBuffer);
// compute the center of the rectangle that bounds the
// selected strokes
int xAvg = (selectionRect.Right+selectionRect.Left)/2;
int yAvg = (selectionRect.Top+selectionRect.Bottom)/2;
// Draw the resize handles
// top left
SetLocation(selectionHandles[0],selectionRect.Left, selectionRect.Top);
// top
SetLocation(selectionHandles[1],xAvg, selectionRect.Top);
// top right
SetLocation(selectionHandles[2],selectionRect.Right, selectionRect.Top);
// left
SetLocation(selectionHandles[3],selectionRect.Left, yAvg);
// right
SetLocation(selectionHandles[4],selectionRect.Right, yAvg);
// bottom left
SetLocation(selectionHandles[5],selectionRect.Left, selectionRect.Bottom);
// bottom
SetLocation(selectionHandles[6],xAvg, selectionRect.Bottom);
// bottom right
SetLocation(selectionHandles[7],selectionRect.Right, selectionRect.Bottom);
}
// Set the visibility of each selection handle in the
// selection rectangle. If there is no selection, all
// handles should be hidden. Otherwise, all handles should
// be visible.
foreach(PictureBox pb in selectionHandles)
{
pb.Visible = isSelectionVisible;
}
// Turn off autoredrawing if there is a selection - otherwise,
// the selected ink will not be displayed as selected.
myInkCollector.AutoRedraw = !isSelectionVisible;
// Since the selection has changed, repaint the screen.
Refresh();
}
/// <summary>
/// Helper method to set the location of the selection rectangle
/// handle.
/// </summary>
/// <param name="pb">The handle's picture box</param>
/// <param name="xCenter">The desired x coordinate of the center</param>
/// <param name="yCenter">The desired y coordinate of the center</param>
public void SetLocation(PictureBox pb, int xCenter, int yCenter)
{
Point location = new Point();
location.X = xCenter - pb.Width/2;
location.Y = yCenter - pb.Height/2;
pb.Location = location;
}
/// <summary>
/// Helper method to determine if there is a selection
/// </summary>
/// <returns>True if there is a selection</returns>
public bool HasSelection()
{
return selectedStrokes!=null && selectedStrokes.Count > 0;
}
/// <summary>
/// Draws the selection lasso.
///
/// Note that this method does NOT draw a point for every piece
/// of packet data. Instead, it draws evenly spaced dots that
/// fall along the lasso path.
/// </summary>
/// <param name="g">The graphics device</param>
/// <param name="newPacketIndex">The index where the new packets begin</param>
public void DrawLasso(Graphics g, int newPacketIndex)
{
// The distance between the current point and the next point
int dx, dy;
// The distance and angle of the line connecting the current
// point and the next point
double lineLength;
double angle;
// The horizontal and vertical spacing between the dots
double segSpaceX, segSpaceY;
// The total number of dots to draw
int totalSegments;
// For each lasso point, draw the corresponding lasso dots.
// Note that this method does NOT draw a point for every piece
// of packet data. Instead, it draws evenly spaced dots that
// fall along the lasso path.
for (int i = newPacketIndex; i < lassoPoints.Count; i++)
{
// Always draw the first packet...
if (0 == i)
{
// Update the last drawn lasso dot to this packet
lastDrawnLassoDot.X = ((Point)lassoPoints[i]).X;
lastDrawnLassoDot.Y = ((Point)lassoPoints[i]).Y;
// use a helper method to draw the lasso dot
DrawSelectionInkDot(g, lastDrawnLassoDot.X, lastDrawnLassoDot.Y);
}
else
{
// Compute the x and y distance between this point and the last drawn
// lasso dot
dx = ((Point)lassoPoints[i]).X - lastDrawnLassoDot.X;
dy = ((Point)lassoPoints[i]).Y - lastDrawnLassoDot.Y;
// Compute length of the line between this point and the last drawn
// lasso dot
lineLength = Math.Sqrt(dx*dx + dy*dy);
// If the spacing between this packet and the last drawn lasso
// dot is greater than the desired DotSpacing, draw as many
// evently spaced lasso points as needed to fill the distance...
if (DotSpacing <= lineLength)
{
// Calculate the angle of the line connecting this point
// to the last drawn lasso point.
angle = Math.Atan2(dy, dx);
// Calculate the x and y components of the dot spacing
segSpaceX = DotSpacing * Math.Cos(angle);
segSpaceY = DotSpacing * Math.Sin(angle);
// Calculate the number of dots we will need to draw.
totalSegments = (int)(lineLength/ (double)DotSpacing);
// draw the lasso dots...
for (int j = 0; j < totalSegments; j++)
{
// The coordinates of the lasso dot are determined by the
// previous lasso dot plus the x and y components of the
// dot spacing (computed above).
lastDrawnLassoDot.X = (int)(lastDrawnLassoDot.X + segSpaceX);
lastDrawnLassoDot.Y = (int)(lastDrawnLassoDot.Y + segSpaceY);
// use a helper method to draw the lasso dot
DrawSelectionInkDot(g, lastDrawnLassoDot.X, lastDrawnLassoDot.Y);
}
}
}
}
}
/// <summary>
/// Helper method to draw a lasso seletion dot
/// </summary>
/// <param name="g">The graphics device</param>
/// <param name="x">The x coordinate of the center of the dot</param>
/// <param name="y">The y coordinate of the center of the dot</param>
private void DrawSelectionInkDot(Graphics g, int x, int y)
{
//
// Offset the x and y by 1/2 the dot size (biasing lower-right)
//
x = x-(DotSize/2);
y = y-(DotSize/2);
// Draw the inside of the lasso dot
g.FillEllipse(dotPen.Brush,x,y,DotSize,DotSize);
// Draw the outside edge of the lasso dot
g.DrawEllipse(dotEdgePen, x,y, DotSize, DotSize);
}
/// <summary>
/// This method is used to render ink when there is
/// a selection.
/// </summary>
/// <param name="g">The graphics device</param>
private void DrawStrokes(Graphics g)
{
// First, draw the strokes that are not part of the
// selection. These strokes will appear the same
// as the InkCollector would normally draw them.
Strokes unselectedStrokes = myInkCollector.Ink.Strokes;
unselectedStrokes.Remove(selectedStrokes);
myInkCollector.Renderer.Draw(g, unselectedStrokes);
// Next, draw each selected stroke. A selected stroke
// is rendered in white with a selection border.
foreach (Stroke selectedStroke in selectedStrokes)
{
DrawingAttributes da = selectedStroke.DrawingAttributes.Clone();
da.Color = SystemColors.WindowText;
da.Width = da.Width+SelectedInkWidthIncrease;
myInkCollector.Renderer.Draw(g, selectedStroke, da);
da.Color = Color.White;
da.Width = da.Width-SelectedInkWidthIncrease;
myInkCollector.Renderer.Draw(g, selectedStroke, da);
}
}
/// <summary>
/// Helper method to set the InkCollector and the
/// selected stroke color.
/// </summary>
/// <param name="newColor">The new color</param>
private void SetColor(Color newColor)
{
myInkCollector.DefaultDrawingAttributes.Color = newColor;
// In addition to updating the ink collector, also update
// the drawing attributes of all selected strokes.
if (HasSelection())
{
foreach (Stroke s in selectedStrokes)
{
s.DrawingAttributes.Color = newColor;
}
}
Refresh();
}
/// <summary>
/// Helper method to set the InkCollector and the
/// selected stroke pen width.
/// </summary>
/// <param name="newWidth">The new pen width</param>
private void SetWidth(float newWidth)
{
myInkCollector.DefaultDrawingAttributes.Width = newWidth;
// In addition to updating the ink collector, also update
// the drawing attributes of all selected strokes.
if (HasSelection())
{
foreach (Stroke s in selectedStrokes)
{
s.DrawingAttributes.Width = newWidth;
}
}
Refresh();
}
}
}