Exemplo n.º 1
0
        // Public method to create a rect for a given range in the text contents
        // Called by our EditableTextRange to implement the required
        // UITextInput:firstRectForRange method
        public CGRect FirstRect(NSRange range)
        {
            int index = (int)range.Location;

            // Iterate over our CTLines, looking for the line that encompasses the given range
            var lines = frame.GetLines();

            for (int i = 0; i < lines.Length; i++)
            {
                CTLine  line       = lines [i];
                NSRange lineRange  = line.StringRange;
                int     localIndex = index - (int)lineRange.Location;
                if (localIndex >= 0 && localIndex < lineRange.Length)
                {
                    // For this sample, we use just the first line that intersects range
                    int finalIndex = (int)Math.Min(lineRange.Location + lineRange.Length, range.Location + range.Length);
                    // Create a rect for the given range within this line
                    nfloat xStart  = line.GetOffsetForStringIndex(index);
                    nfloat xEnd    = line.GetOffsetForStringIndex(finalIndex);
                    var    origins = new CGPoint [lines.Length];
                    frame.GetLineOrigins(new NSRange(i, 0), origins);
                    nfloat ascent, descent, leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);

                    return(new CGRect(xStart, origins [0].Y - descent, xEnd - xStart, ascent + descent));
                }
            }

            return(CGRect.Empty);
        }
Exemplo n.º 2
0
        // Helper method for drawing the current selection range (as a simple filled rect)
        void DrawRangeAsSelection(NSRange selectionRange)
        {
            // If not in editing mode, we do not draw selection rects
            if (!IsEditing)
            {
                return;
            }

            // If selection range empty, do not draw
            if (selectionRange.Length == 0 || selectionRange.Location == NSRange.NotFound)
            {
                return;
            }

            // set the fill color to the selection color
            SelectionColor.SetFill();

            // Iterate over the lines in our CTFrame, looking for lines that intersect
            // with the given selection range, and draw a selection rect for each intersection
            var lines = frame.GetLines();

            for (int i = 0; i < lines.Length; i++)
            {
                CTLine  line         = lines [i];
                NSRange lineRange    = line.StringRange;
                NSRange range        = new NSRange(lineRange.Location, lineRange.Length);
                NSRange intersection = RangeIntersection(range, selectionRange);
                if (intersection.Location != NSRange.NotFound && intersection.Length > 0)
                {
                    // The text range for this line intersects our selection range
                    nfloat xStart = line.GetOffsetForStringIndex(intersection.Location);
                    nfloat xEnd   = line.GetOffsetForStringIndex(intersection.Location + intersection.Length);
                    var    origin = new CGPoint [lines.Length];
                    // Get coordinate and bounds information for the intersection text range
                    frame.GetLineOrigins(new NSRange(i, 0), origin);
                    nfloat ascent, descent, leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);
                    // Create a rect for the intersection and draw it with selection color
                    CGRect selectionRect = new CGRect(xStart, origin [0].Y - descent, xEnd - xStart, ascent + descent);
                    UIGraphics.RectFill(selectionRect);
                }
            }
        }
Exemplo n.º 3
0
        // Public method to determine the CGRect for the insertion point or selection, used
        // when creating or updating our SimpleCaretView instance
        public CGRect CaretRect(int index)
        {
            var lines = frame.GetLines();

            // Special case, no text
            if (text.Length == 0)
            {
                CGPoint origin = new CGPoint(Bounds.GetMinX(), Bounds.GetMinY() - font.Leading);
                // Note: using fabs() for typically negative descender from fonts
                return(new CGRect(origin.X, origin.Y - (nfloat)Math.Abs(font.Descender), 3, font.Ascender + (nfloat)Math.Abs(font.Descender)));
            }

            // Special case, insertion point at final position in text after newline
            if (index == text.Length && text.EndsWith("\n"))
            {
                CTLine  line = lines [lines.Length - 1];
                NSRange range = line.StringRange;
                nfloat  xPos = line.GetOffsetForStringIndex(range.Location);
                var     origins = new CGPoint [lines.Length];
                nfloat  ascent, descent, leading;
                line.GetTypographicBounds(out ascent, out descent, out leading);
                frame.GetLineOrigins(new NSRange(lines.Length - 1, 0), origins);
                // Place point after last line, including any font leading spacing if applicable
                origins[0].Y -= font.Leading;
                return(new CGRect(xPos, origins [0].Y - descent, 3, ascent + descent));
            }

            // Regular case, caret somewhere within our text content range
            for (int i = 0; i < lines.Length; i++)
            {
                CTLine  line       = lines [i];
                NSRange range      = line.StringRange;
                int     localIndex = index - (int)range.Location;
                if (localIndex >= 0 && localIndex <= range.Length)
                {
                    // index is in the range for this line
                    nfloat xPos = line.GetOffsetForStringIndex(index);
                    var    origins = new CGPoint [lines.Length];
                    nfloat ascent, descent, leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);
                    frame.GetLineOrigins(new NSRange(i, 0), origins);
                    // Make a small "caret" rect at the index position
                    return(new CGRect(xPos, origins [0].Y - descent, 3, ascent + descent));
                }
            }

            return(CGRect.Empty);
        }