/// <summary> /// 将inkspace中的Point转换成像素坐标 /// </summary> /// <param name="inkpicture"></param> /// <param name="pt"></param> /// <returns></returns> public Point InkSpaceToPixelPoint(InkPicture inkpicture, Point pt) { Graphics g = inkpicture.CreateGraphics(); Point p = new Point(pt.X, pt.Y); inkpicture.Renderer.InkSpaceToPixel(g, ref p); return p; }
/// <summary> /// 将inkspace中的Points转换成为像素空间的坐标 /// </summary> /// <param name="inkpicture"></param> /// <param name="points"></param> /// <returns></returns> public Point[] InkSpaceToPixelPoints(InkPicture inkpicture, Point[] points) { Graphics g = inkpicture.CreateGraphics(); Point[] pts = (Point[])(points.Clone()); inkpicture.Renderer.InkSpaceToPixel(g, ref pts); return pts; }
/// <summary> /// 将inkspace中的rectangle转换成像素的坐标 /// </summary> /// <param name="inkpicture"></param> /// <param name="rect"></param> /// <returns></returns> public Rectangle InkSpaceToPixelRect(InkPicture inkpicture, Rectangle rect) { Graphics g = inkpicture.CreateGraphics(); Point p1 = rect.Location; Point p2 = new Point(rect.Width, rect.Height); inkpicture.Renderer.InkSpaceToPixel(g, ref p1); inkpicture.Renderer.InkSpaceToPixel(g, ref p2); return(new Rectangle(p1.X, p1.Y, p2.X, p2.Y)); }
/// <summary> /// <see cref="InvalidateStroke"/> /// </summary> /// <param name="iStroke">The Ink stroke to invalidate</param> /// <param name="padding">Number of pixels to pad invalidation /// rectangle in Ink space pixels</param> public void InvalidateStroke(Microsoft.Ink.Stroke iStroke, int padding) { using (Graphics g = InkPicture.CreateGraphics()) { Rectangle bb = iStroke.GetBoundingBox(); System.Drawing.Point upperLeft = new System.Drawing.Point(bb.X - padding, bb.Y - padding); System.Drawing.Point lowerRight = new System.Drawing.Point(bb.Right + padding, bb.Bottom + padding); InkPicture.Renderer.InkSpaceToPixel(g, ref upperLeft); InkPicture.Renderer.InkSpaceToPixel(g, ref lowerRight); InkPicture.Invalidate(new Rectangle(upperLeft.X, upperLeft.Y, lowerRight.X, lowerRight.Y)); } }
/// <summary> /// Displays a tooltip based on the label of the nearest stroke. /// </summary> /// <param name="sender">event sender</param> /// <param name="e">event information, includign mouse location</param> private void sketchPicture_MouseMove(object sender, MouseEventArgs e) { /// /// HACK: turn off tooptip /// return; // Get the current mouse position and convert it into InkSpace System.Drawing.Point mousePt = new System.Drawing.Point(e.X, e.Y); Graphics graphics = sketchPicture.CreateGraphics(); sketchPicture.Renderer.PixelToInkSpace(graphics, ref mousePt); // Get the Microsoft Stroke closest to the mouse pointer float strokePt, distance; Microsoft.Ink.Stroke closestMSubstroke = sketchPicture.Ink.NearestPoint(mousePt, out strokePt, out distance); if (closestMSubstroke == null) { return; } // Fire tooltip if the mouse pointer is close enough if (distance < UIConstants.ColorFeedbackMechanismTooltipDistanceThreshold) { // Get the stroke's label, if it has one if (!ink2sketchLabelTable.Contains(closestMSubstroke.Id)) { return; } string label = (string)ink2sketchLabelTable[closestMSubstroke.Id]; // Show the ToolTip this.toolTip.SetToolTip(sketchPicture, label); this.toolTip.Active = true; } else { // Don't show the ToolTip if the mouse pointer is not close this.toolTip.Active = false; } }
/// <summary> /// Set Ink stroke text labels based upon domain /// </summary> public override void FireFeedbackMechanism(Sketch.Sketch sketch, InkPicture inkPicture, Hashtable ink2sketchIdTable, FeedbackContext context) { // // Preprocessing // // Remove all current textboxes from the inkPicture // and clear the table of textboxes; start out fresh foreach (Label currentLabel in textboxList) { inkPicture.Controls.Remove(currentLabel); } textboxList.Clear(); // Build hashtable of sketch substroke Ids to ink strokes Hashtable substroke2InkTable = new Hashtable(); System.Guid currentGuid; foreach (Microsoft.Ink.Stroke iStroke in inkPicture.Ink.Strokes) { // If this ink stroke does not have a // corresponding sketch stroke, skip it if (!ink2sketchIdTable.Contains(iStroke.Id)) { continue; } currentGuid = (System.Guid)ink2sketchIdTable[iStroke.Id]; substroke2InkTable.Add(currentGuid, iStroke); } // // Iterate through shapes // Graphics g = inkPicture.CreateGraphics(); foreach (Sketch.Shape shape in sketch.Shapes) { // Get label of this shape string label = shape.Substrokes[0].GetFirstLabel(); // // Color wires and don't label them // if (label == "Wire") { foreach (Sketch.Substroke substroke in shape.Substrokes) { if (!substroke2InkTable.Contains(substroke.XmlAttrs.Id)) { // If, for some reason, there is no ink stroke // that corresponds to this substroke, skip it continue; } Microsoft.Ink.Stroke iStroke = (Microsoft.Ink.Stroke)substroke2InkTable[substroke.XmlAttrs.Id]; iStroke.DrawingAttributes.Color = UIConstants.TextFeedbackMechanismWireColor; } } // // Draw boxes over input/output labels // else if (label == "Label") { // For efficiency's sake, we color the strokes while calculating the bounding box. Rectangle boundingBox = calculateBoundingBox(shape, substroke2InkTable, true); // Devise the (x,y) location of the text label on the screen System.Drawing.Point upperLeft = new System.Drawing.Point(boundingBox.X, boundingBox.Y); System.Drawing.Point lowerRight = new System.Drawing.Point(boundingBox.Right, boundingBox.Bottom); inkPicture.Renderer.InkSpaceToPixel(g, ref upperLeft); inkPicture.Renderer.InkSpaceToPixel(g, ref lowerRight); upperLeft.X -= 10; upperLeft.Y -= 10; lowerRight.X += 10; lowerRight.Y += 10; int bwidth = lowerRight.X - upperLeft.X; int bheight = lowerRight.Y - upperLeft.Y; // Create bounding box for label // HACK!! TODO: draw a transparent label // instead of four labels to make // a box around the symbol Label topLabel = new Label(); Label bottomLabel = new Label(); Label leftLabel = new Label(); Label rightLabel = new Label(); topLabel.UseMnemonic = false; bottomLabel.UseMnemonic = false; leftLabel.UseMnemonic = false; rightLabel.UseMnemonic = false; topLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; bottomLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; leftLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; rightLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; // Set label positions topLabel.Location = upperLeft; topLabel.Height = 1; topLabel.Width = bwidth; bottomLabel.Location = new System.Drawing.Point(upperLeft.X, upperLeft.Y + bheight); bottomLabel.Height = 1; bottomLabel.Width = bwidth; leftLabel.Location = new System.Drawing.Point(upperLeft.X, upperLeft.Y); leftLabel.Height = bheight; leftLabel.Width = 1; rightLabel.Location = new System.Drawing.Point(upperLeft.X + bwidth, upperLeft.Y); rightLabel.Height = bheight; rightLabel.Width = 1; topLabel.Enabled = true; bottomLabel.Enabled = true; leftLabel.Enabled = true; rightLabel.Enabled = true; inkPicture.Controls.Add(topLabel); inkPicture.Controls.Add(bottomLabel); inkPicture.Controls.Add(leftLabel); inkPicture.Controls.Add(rightLabel); textboxList.Add(topLabel); textboxList.Add(bottomLabel); textboxList.Add(leftLabel); textboxList.Add(rightLabel); } // // Draw labels for other symbols // else { // For efficiency's sake, we color the strokes while calculating the bounding box. Rectangle boundingBox = calculateBoundingBox(shape, substroke2InkTable, true); // Devise the (x,y) location of the text label on the screen System.Drawing.Point center = new System.Drawing.Point(boundingBox.Width / 2 + boundingBox.Left, boundingBox.Height / 2 + boundingBox.Top); System.Drawing.Point upperLeft = new System.Drawing.Point(boundingBox.X, boundingBox.Y); System.Drawing.Point lowerRight = new System.Drawing.Point(boundingBox.Right, boundingBox.Bottom); inkPicture.Renderer.InkSpaceToPixel(g, ref center); inkPicture.Renderer.InkSpaceToPixel(g, ref upperLeft); inkPicture.Renderer.InkSpaceToPixel(g, ref lowerRight); center.X += inkPicture.Bounds.X; center.Y += inkPicture.Bounds.Y; // Create textbox for label Label textLabel = new Label(); textLabel.UseMnemonic = false; textLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; textLabel.Text = label; textLabel.TextAlign = ContentAlignment.MiddleCenter; textLabel.AutoSize = true; // Position label so that it is either on top of the symbol, // or, if the symbol is very small, along side the symbol int bwidth = lowerRight.X - upperLeft.X; int bheight = lowerRight.Y - upperLeft.Y; if (textLabel.Width < bwidth && textLabel.Height < bheight) { center.X -= textLabel.Width / 2; center.Y -= textLabel.Height / 2; } else { // If taller than is wide, place label to the right; // else place label just above symbol if (boundingBox.Height > boundingBox.Width) { center.Y -= textLabel.Height / 2; center.X += bwidth / 2; } else { center.Y += bheight / 2; center.X -= textLabel.Width / 2; } } textLabel.Location = center; textLabel.Enabled = true; inkPicture.Controls.Add(textLabel); textboxList.Add(textLabel); } } }