public void BackspaceOverPara() { XmlElement para = doc.CreateElement("para"); doc.DocumentElement.AppendChild(para); XmlText text = doc.CreateTextNode("testing..."); para.AppendChild(text); Assert.AreEqual(0, v.InvalidNodes.AllErrors.Length, "Errors before backspace"); TextSelectionPoint tsp = new TextSelectionPoint(text, 0); Selection sel = new Selection(tsp); SelectionManager selManager = new SelectionManager(new Stylesheet()); selManager.Backspace(sel); Assert.AreEqual(1, v.InvalidNodes.AllErrors.Length, "Expected error after backspace"); para = doc.CreateElement("para"); doc.DocumentElement.AppendChild(para); para.AppendChild(text); Assert.AreEqual(0, v.InvalidNodes.AllErrors.Length, "Errors still exist after undo"); }
public void WhitespaceHandling1() { string test = "aaaa bbbb cccc"; XmlDocument doc = new XmlDocument(); doc.LoadXml("<doc>" + test + "</doc>"); Stylesheet s = new Stylesheet(); s.BindStyles(doc.NameTable); // Rectangle rc=new Rectangle(0, 0, 480, int.MaxValue); Rectangle rc = new Rectangle(0, 0, 110, int.MaxValue); using (IGraphics gr = new DummyGraphics()) { DrawContext ctx = new DrawContext(gr, Point.Empty, rc, rc, null, new DocumentType(), null); LayoutEngine layoutEngine = new LayoutEngine(s); layoutEngine.Reflow(ctx, doc.DocumentElement); SelectionPoint start = new TextSelectionPoint(doc.DocumentElement.FirstChild, 11); Console.WriteLine("Getting caret pos for {0}", start); Rectangle c = layoutEngine.GetCaretPosition(gr, start, CaretDirection.None); Console.WriteLine("Char {0} at {1}", start.ToString(), c); } }
private static void RunTest(TextSelectionPoint tsp, int[] indexes, WhitespaceHandling ws, bool reverse) { if (reverse) { Array.Reverse(indexes); } Console.WriteLine("Running movement tests for {0}, ws={1}, reverse={2}", tsp, ws, reverse); TextSelectionHelper tsh = new TextSelectionHelper(tsp, ws); int n = 0; while (tsp != null) { Console.WriteLine("Scanning: '{0}' (={1})", tsp.Char, (int)tsp.Char); Assert.IsTrue(n < indexes.Length, "Too many iterations, expected {0}", indexes.Length); Assert.IsTrue(indexes[n] == tsp.Index, "Wrong value at iteration {0} (expected {1}, got {2}", n, indexes[n], tsp.Index); if (reverse) { tsp = tsh.Previous; } else { tsp = tsh.Next; } n++; } }
public override Widget buildToolbar(BuildContext context, Rect globalEditableRegion, float textLineHeight, Offset selectionMidpoint, List <TextSelectionPoint> endpoints, TextSelectionDelegate selectionDelegate) { D.assert(WidgetsD.debugCheckHasMediaQuery(context)); D.assert(material_.debugCheckHasMaterialLocalizations(context)); TextSelectionPoint startTextSelectionPoint = endpoints[0]; TextSelectionPoint endTextSelectionPoint = endpoints.Count > 1 ? endpoints[1] : endpoints[0]; const float closedToolbarHeightNeeded = MaterialUtils._kToolbarScreenPadding + MaterialUtils._kToolbarHeight + MaterialUtils._kToolbarContentDistance; float paddingTop = MediaQuery.of(context).padding.top; float availableHeight = globalEditableRegion.top + startTextSelectionPoint.point.dy - textLineHeight - paddingTop; bool fitsAbove = closedToolbarHeightNeeded <= availableHeight; Offset anchor = new Offset( globalEditableRegion.left + selectionMidpoint.dx, fitsAbove ? globalEditableRegion.top + startTextSelectionPoint.point.dy - textLineHeight - MaterialUtils._kToolbarContentDistance : globalEditableRegion.top + endTextSelectionPoint.point.dy + MaterialUtils._kToolbarContentDistanceBelow ); return(new Stack( children: new List <Widget>() { new CustomSingleChildLayout( layoutDelegate: new _TextSelectionToolbarLayout( anchor, MaterialUtils._kToolbarScreenPadding + paddingTop, fitsAbove ), child: new _TextSelectionToolbar( handleCut: canCut(selectionDelegate) ? () => handleCut(selectionDelegate) : (VoidCallback)null, handleCopy: canCopy(selectionDelegate) ? () => handleCopy(selectionDelegate) : (VoidCallback)null, handlePaste: canPaste(selectionDelegate) ? () => handlePaste(selectionDelegate) : (VoidCallback)null, handleSelectAll: canSelectAll(selectionDelegate) ? () => handleSelectAll(selectionDelegate) : (VoidCallback)null, isAbove: fitsAbove ) ), } )); }
public override void GetCaretPosition(IGraphics gr, int x, int y, SelectionPoint sp, ref CaretPositionInfo cpi) { // TODO: M: this is very innefficient since it is called for all text nodes during search if (!ContainsSelectionPoint(sp)) { cpi.UpdateLocation(x + Width, y, Height, CaretSetting.Fallback); return; } TextSelectionPoint tsp = (TextSelectionPoint)sp; CaretSetting mode = CaretSetting.Absolute; gr.PushFont(gr.GetFontHandle(style.FontDesc)); try { int n = tsp.Index - start; if (n < 0) { // position is not in visible part of the string, it's // in whitespace that has been trimmed. cpi.UseSecondary = true; return; } else if (tsp.Index == 0) { // caret can be put somewhere else if necessary // TODO: L: this is a bit simplistic - will be wrong if text nodes are // split and first node ends with space and ends a line (!) mode = CaretSetting.Accurate; } string text = Text; if (n > text.Length) { // TODO: L: not sure exactly when this happens n = text.Length; } text = ProcessText(text.Substring(0, n)); int w = gr.MeasureText(text).Width; cpi.UpdateLocation(x + w, y, Height, mode); } finally { gr.PopFont(); } }
public override bool ContainsSelectionPointInternal(SelectionPoint sp) { TextSelectionPoint tsp = sp as TextSelectionPoint; if (tsp == null) { return(false); } if (tsp.Node.NodeType == XmlNodeType.SignificantWhitespace) { return(true); } return(tsp.Index >= start - ignoreStart && tsp.Index < start + len + ignoreEnd); }
public void MoveNextAndPrevious() { XmlDocument doc = new XmlDocument(); doc.LoadXml("<doc/>"); XmlElement e = doc.CreateElement("p"); XmlText t = doc.CreateTextNode("\r\n\r\nabc\r\n"); e.AppendChild(t); t = doc.CreateTextNode("\r\n\r\n"); e.AppendChild(t); t = doc.CreateTextNode("\r\ndef\r\n"); e.AppendChild(t); doc.DocumentElement.AppendChild(e); t = e.FirstChild as XmlText; TextSelectionPoint tsp = new TextSelectionPoint(t, 0); RunTest(tsp, new int[] { 0, 4, 5, 6, 7, 2, 3, 4, 5 }, WhitespaceHandling.Default, false); RunTest(tsp, new int[] { 0, 2, 4, 5, 6, 7, 0, 2, 0, 2, 3, 4, 5 }, WhitespaceHandling.Preserve, false); t = e.LastChild as XmlText; tsp = new TextSelectionPoint(t, t.Value.Length - 1); RunTest(tsp, new int[] { 0, 4, 5, 6, 7, 2, 3, 4, 5 }, WhitespaceHandling.Default, true); RunTest(tsp, new int[] { 0, 2, 4, 5, 6, 7, 0, 2, 0, 2, 3, 4, 5 }, WhitespaceHandling.Preserve, true); e.RemoveAll(); t = doc.CreateTextNode("\n\nabc\n"); e.AppendChild(t); t = doc.CreateTextNode("\n\n"); e.AppendChild(t); t = doc.CreateTextNode("\ndef\n"); e.AppendChild(t); doc.DocumentElement.AppendChild(e); t = e.FirstChild as XmlText; tsp = new TextSelectionPoint(t, 0); RunTest(tsp, new int[] { 0, 2, 3, 4, 5, 1, 2, 3, 4 }, WhitespaceHandling.Default, false); RunTest(tsp, new int[] { 0, 1, 2, 3, 4, 5, 0, 1, 0, 1, 2, 3, 4 }, WhitespaceHandling.Preserve, false); t = e.LastChild as XmlText; tsp = new TextSelectionPoint(t, t.Value.Length - 1); RunTest(tsp, new int[] { 0, 2, 3, 4, 5, 1, 2, 3, 4 }, WhitespaceHandling.Default, true); RunTest(tsp, new int[] { 0, 1, 2, 3, 4, 5, 0, 1, 0, 1, 2, 3, 4 }, WhitespaceHandling.Preserve, true); }
public override HitTestInfo GetHitTestInfo(IGraphics gr, int x, int y, Point pt) { // caller will have tested if point is within bounding rect // taking into account additional ascent/descent on the line Debug.Assert(style != null, "No class attached to TextFragment!!"); string text = ProcessText(Text); gr.PushFont(gr.GetFontHandle(style.FontDesc)); try { BinaryChopper bc = new BinaryChopper(text); int w = 0; while (bc.CanMove) { // TODO: L: this could be optimised by calculating the shift // left and right in pixels rather than measuring from zero w = gr.MeasureText(bc.Text).Width; if (pt.X < x + w) { bc.TooLong(); } else { bc.TooShort(); } } int cw = gr.MeasureText(text[bc.Position].ToString()).Width; bool after = (float)1.0 * x + w - cw / 2 < pt.X; Debug.Assert(start + bc.Position < Node.Value.Length, "Invalid TextSelectionPoint!"); SelectionPoint sp = new TextSelectionPoint(Node, start + bc.Position); Line l = (Line)Parent; LineItemContext ili = new LineItemContext(l.Height, l.Baseline, this, new Point(x, y)); HitTestInfo ht = new HitTestInfo(sp, ili, after); return(ht); } finally { gr.PopFont(); } }
public override SelectionPoint GetSelectionPoint(bool atEnd) { if (!atEnd) { return(new TextSelectionPoint(Node, start)); } int index = start + len - 1; TextSelectionPoint tsp = new TextSelectionPoint(Node, index); if (tsp.Index > 0) { // we do this as this is only called when cursor is at end of line, // and we want to position the cursor in front of the line-end tsp = new TextSelectionPoint(Node, tsp.Index - 1); } Console.WriteLine("Returning {0}", tsp); return(tsp); }
TextSelectionHandleType _chooseType( TextSelectionPoint endpoint, TextSelectionHandleType ltrType, TextSelectionHandleType rtlType ) { if (this.widget.selection.isCollapsed) { return(TextSelectionHandleType.collapsed); } D.assert(endpoint.direction != null); switch (endpoint.direction) { case TextDirection.ltr: return(ltrType); case TextDirection.rtl: return(rtlType); } D.assert(() => throw new UIWidgetsError($"invalid endpoint.direction {endpoint.direction}")); return(ltrType); }
public override void Draw(DrawContext dc, int x, int y, int baseline, int height, Style c) { Debug.Assert(Height >= 0, "TextFragment is not composed!"); Rectangle rc = GetBoundingRect(x, y); rc.Height += height - Height; if (!dc.ClippingRectangle.IntersectsWith(rc)) { return; } string text = ProcessText(Text); // .Replace('\r', ' ').Replace('\t', ' ').Replace('\n', ' '); int startIndex = 0; int endIndex = 0; Color bkCol = c.Stylesheet.HighlightColor; bool inError = dc.InvalidInfo.Contains(Node); dc.Graphics.PushFont(dc.Graphics.GetFontHandle(style.FontDesc)); // dc.Graphics.PushFont(style.FontHandle); try { if (selection != null) { SelectionPoint startSel = selection.Start; SelectionPoint endSel = selection.End; // by default everything selected endIndex = text.Length; if (ContainsSelectionPoint(startSel)) { TextSelectionPoint sel = (TextSelectionPoint)startSel; startIndex = sel.Index - start; if (startIndex < 0) { startIndex = 0; } } if (ContainsSelectionPoint(endSel)) { TextSelectionPoint sel = (TextSelectionPoint)endSel; endIndex = sel.Index - start; if (endIndex < 0) { endIndex = text.Length; } } } int dx = dc.Graphics.MeasureText(text).Width; Rectangle rcText = new Rectangle(x, y, dx, height); DrawText(dc, rcText, baseline, text, bkCol, Color.White, startIndex, endIndex); if (inError) { DrawErrorIndicator(dc, x, x, dx, y + baseline, false); } } finally { dc.Graphics.PopFont(); } }
public override SelectionPoint GetSelectionPoint(bool atEnd) { if ( !atEnd ) return new TextSelectionPoint(Node, start); int index=start+len-1; TextSelectionPoint tsp=new TextSelectionPoint(Node, index); if ( tsp.Index > 0 ) // we do this as this is only called when cursor is at end of line, // and we want to position the cursor in front of the line-end tsp=new TextSelectionPoint(Node, tsp.Index-1); Console.WriteLine("Returning {0}", tsp); return tsp; }
public override HitTestInfo GetHitTestInfo(IGraphics gr, int x, int y, Point pt) { // caller will have tested if point is within bounding rect // taking into account additional ascent/descent on the line Debug.Assert(style != null, "No class attached to TextFragment!!"); string text=ProcessText(Text); gr.PushFont(gr.GetFontHandle(style.FontDesc)); try { BinaryChopper bc=new BinaryChopper(text); int w=0; while ( bc.CanMove ) { // TODO: L: this could be optimised by calculating the shift // left and right in pixels rather than measuring from zero w=gr.MeasureText(bc.Text).Width; if ( pt.X < x+w ) bc.TooLong(); else bc.TooShort(); } int cw=gr.MeasureText(text[bc.Position].ToString()).Width; bool after=(float) 1.0 * x + w - cw / 2 < pt.X; Debug.Assert(start+bc.Position < Node.Value.Length, "Invalid TextSelectionPoint!"); SelectionPoint sp=new TextSelectionPoint(Node, start+bc.Position); Line l=(Line) Parent; LineItemContext ili=new LineItemContext(l.Height, l.Baseline, this, new Point(x,y)); HitTestInfo ht=new HitTestInfo(sp, ili, after); return ht; } finally { gr.PopFont(); } }
public void WhitespaceHandling1() { string test="aaaa bbbb cccc"; XmlDocument doc=new XmlDocument(); doc.LoadXml("<doc>"+test+"</doc>"); Stylesheet s=new Stylesheet(); s.BindStyles(doc.NameTable); // Rectangle rc=new Rectangle(0, 0, 480, int.MaxValue); Rectangle rc=new Rectangle(0, 0, 110, int.MaxValue); using ( IGraphics gr=new DummyGraphics() ) { DrawContext ctx=new DrawContext(gr, Point.Empty, rc, rc, null, new DocumentType(), null); LayoutEngine layoutEngine=new LayoutEngine(s); layoutEngine.Reflow(ctx, doc.DocumentElement); SelectionPoint start=new TextSelectionPoint(doc.DocumentElement.FirstChild, 11); Console.WriteLine("Getting caret pos for {0}", start); Rectangle c=layoutEngine.GetCaretPosition(gr, start, CaretDirection.None); Console.WriteLine("Char {0} at {1}", start.ToString(), c); } }