private void InkAnalyzer_ResultsUpdated(object sender, ResultsUpdatedEventArgs e) { running = false; InkUtils.MergeParagraphs(inkAnalyzer); if (processor < inkProcessors.Count) { InkProcessor proc = inkProcessors[processor]; proc.process(inkAnalyzer); processor++; fireoff(); return; } if (adds.Count > 0 || removes.Count > 0) { //Flush adds and removes while (adds.Count > 0) { Stroke stroke = adds.Dequeue(); inkAnalyzer.AddStroke(stroke); } while (removes.Count > 0) { Stroke stroke = removes.Dequeue(); inkAnalyzer.RemoveStroke(stroke); } fireoff(); return; } if (PipelineComplete != null) { PipelineComplete(this, new EventArgs()); } processor = 0; processing = false; if (queued) { queued = false; processor = 0; processing = true; fireoff(); } }
void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e) { foreach (Stroke stroke in e.Added) { if (!graphAnalyzer.newStroke(stroke)) { inkAnalyzer.AddStroke(stroke); } AutocorrectHandleAddStroke(stroke); } double ymax = InkUtils.StrokeYMax(e.Added); if (ymax > MainInkCanvas.ActualHeight - 300.0) { MainInkCanvas.Height = ymax + 800.0; } foreach (Stroke stroke in e.Removed) { graphAnalyzer.removeStroke(stroke); // If we erase a word and try to replace it with autocorrect // suggestions, there's no good way to define the behavior // so just hide the suggestions. suggestionsBox.Visibility = Visibility.Collapsed; inkAnalyzer.RemoveStroke(stroke); } }
/// <summary> /// Analyze a new stroke. /// </summary> /// <param name="stroke"></param> /// <returns>true if the stroke was recognized as belonging to a graph (and so should be excluded from InkAnalyzer)</returns> public bool newStroke(Stroke stroke) { if (strokes.ContainsKey(stroke)) { // already have it! return(true); } foreach (Graph g in graphs) { if (g.containsStroke(stroke) && g.takeStroke(stroke)) { strokes.Add(stroke, g); return(true); } } Stroke copy = stroke.Clone(); analyzer.AddStroke(copy); analyzer.Analyze(); StrokeCollection sc = new StrokeCollection(new Stroke[] { copy }); ContextNodeCollection ctxNodes = analyzer.FindInkLeafNodes(sc); foreach (ContextNode ctxNode in ctxNodes) { if (ctxNode is InkDrawingNode && (ctxNode as InkDrawingNode).GetShapeName() == "Rectangle") { Graph g = new XYGraph(this, stroke); graphs.Add(g); strokes.Add(stroke, g); analyzer.RemoveStroke(copy); return(true); } } analyzer.RemoveStroke(copy); return(false); }
public void process(InkAnalyzer inkAnalyzer) { ContextNodeCollection nodeCollection = inkAnalyzer.FindLeafNodes(); foreach (ContextNode childNodes in nodeCollection) { foreach (Stroke stroke in childNodes.Strokes) { if (strokeIsCaret(stroke)) { insertionBox.Visibility = Visibility.Visible; Canvas.SetLeft(insertionBox, stroke.StylusPoints[0].X - 140); Canvas.SetTop(insertionBox, stroke.StylusPoints[1].Y); inkAnalyzer.RemoveStroke(stroke); strokeToBeReplaced = stroke; } } } }
private void CanvasTinta_StrokeErasing(object sender, InkCanvasStrokeErasingEventArgs e) { m_analyzer.RemoveStroke(e.Stroke); }
private void findAndDeleteStrikethrough(InkAnalyzer inkAnalyzer, InkCanvas canvas, List <Stroke> horizontalLines, ContextNodeCollection contextNodeCollection) { List <ContextNode> deletedNodes = new List <ContextNode>(); List <Stroke> removedHorizontalLines = new List <Stroke>(); //Find things to apply gestures to foreach (ContextNode node in contextNodeCollection) { if (node.Strokes.Count == 0) { continue; } Rect strikethroughBounds = node.Strokes.GetBounds(); strikethroughBounds.Height *= 0.75d; if (node is InkWordNode) { PointCollection bl = (node as InkWordNode).GetBaseline(); if (bl != null && bl.Count() > 0) { double baseline = bl[0].Y; strikethroughBounds.Height = baseline - strikethroughBounds.Y; } } for (int j = 0; j < horizontalLines.Count; j++) { if (node.Strokes[0] == horizontalLines[j]) { break; } Stroke horizontalLine = horizontalLines[j]; Rect horizontalLineBounds = horizontalLine.GetBounds(); double sideBuffer = (1 - Constants.LINE_WORD_OVERLAPSE_RATIO) / 2; double strikethroughBoundLeft = strikethroughBounds.X + strikethroughBounds.Width * sideBuffer; double strikethroughBoundRight = strikethroughBounds.X + strikethroughBounds.Width * (1 - sideBuffer); if (strikethroughBounds.IntersectsWith(horizontalLineBounds) && strikethroughBoundLeft > horizontalLineBounds.X && strikethroughBoundRight < horizontalLineBounds.X + horizontalLineBounds.Width) { //Delete strikethrough deletedNodes.Add(node); removedHorizontalLines.Add(horizontalLine); } } } foreach (Stroke stroke in removedHorizontalLines) { horizontalLines.Remove(stroke); canvas.Strokes.Remove(stroke); inkAnalyzer.RemoveStroke(stroke); } //Final step to apply the gestures, commit changes for (int i = deletedNodes.Count - 1; i >= 0; i--) { ContextNode node = deletedNodes[i]; try { Rect bounds = node.Strokes.GetBounds(); double nodeX = bounds.X; ContextNode parent = node.ParentNode; double closestX = double.MaxValue; foreach (ContextNode sibling in parent.SubNodes) { double siblingX = sibling.Strokes.GetBounds().X; if (siblingX > nodeX && siblingX < closestX) { closestX = siblingX; } } double dx = nodeX - closestX; foreach (ContextNode sibling in parent.SubNodes) { //Nodes right side of current if (sibling.Strokes.GetBounds().X > nodeX) { InkUtils.transposeStrokes(inkAnalyzer, sibling.Strokes, dx, 0d); } } canvas.Strokes.Remove(node.Strokes); inkAnalyzer.RemoveStrokes(node.Strokes); } catch (Exception e) { //Ignore already deleted error } } }
private void findAndDeleteStrikethrough(InkAnalyzer inkAnalyzer, InkCanvas canvas, List<Stroke> horizontalLines, ContextNodeCollection contextNodeCollection) { List<ContextNode> deletedNodes = new List<ContextNode>(); List<Stroke> removedHorizontalLines = new List<Stroke>(); //Find things to apply gestures to foreach (ContextNode node in contextNodeCollection) { if (node.Strokes.Count == 0) { continue; } Rect strikethroughBounds = node.Strokes.GetBounds(); strikethroughBounds.Height *= 0.75d; if (node is InkWordNode) { PointCollection bl = (node as InkWordNode).GetBaseline(); if (bl != null && bl.Count() > 0) { double baseline = bl[0].Y; strikethroughBounds.Height = baseline - strikethroughBounds.Y; } } for (int j = 0; j < horizontalLines.Count; j++) { if (node.Strokes[0] == horizontalLines[j]) { break; } Stroke horizontalLine = horizontalLines[j]; Rect horizontalLineBounds = horizontalLine.GetBounds(); double sideBuffer = (1 - Constants.LINE_WORD_OVERLAPSE_RATIO) / 2; double strikethroughBoundLeft = strikethroughBounds.X + strikethroughBounds.Width * sideBuffer; double strikethroughBoundRight = strikethroughBounds.X + strikethroughBounds.Width * (1 - sideBuffer); if (strikethroughBounds.IntersectsWith(horizontalLineBounds) && strikethroughBoundLeft > horizontalLineBounds.X && strikethroughBoundRight < horizontalLineBounds.X + horizontalLineBounds.Width) { //Delete strikethrough deletedNodes.Add(node); removedHorizontalLines.Add(horizontalLine); } } } foreach (Stroke stroke in removedHorizontalLines) { horizontalLines.Remove(stroke); canvas.Strokes.Remove(stroke); inkAnalyzer.RemoveStroke(stroke); } //Final step to apply the gestures, commit changes for (int i = deletedNodes.Count - 1; i >= 0; i--) { ContextNode node = deletedNodes[i]; try { Rect bounds = node.Strokes.GetBounds(); double nodeX = bounds.X; ContextNode parent = node.ParentNode; double closestX = double.MaxValue; foreach (ContextNode sibling in parent.SubNodes) { double siblingX = sibling.Strokes.GetBounds().X; if (siblingX > nodeX && siblingX < closestX) { closestX = siblingX; } } double dx = nodeX - closestX; foreach (ContextNode sibling in parent.SubNodes) { //Nodes right side of current if (sibling.Strokes.GetBounds().X > nodeX) { InkUtils.transposeStrokes(inkAnalyzer, sibling.Strokes, dx, 0d); } } canvas.Strokes.Remove(node.Strokes); inkAnalyzer.RemoveStrokes(node.Strokes); } catch (Exception e) { //Ignore already deleted error } } }