Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

text renderer : it is now possible to use the keyboard up/down arrows…

… to navigate in multiline text
  • Loading branch information...
commit 9b90041ad3635b4a9486fbd080f3d62791570da4 1 parent 1669fe3
Michael Villar authored
2  lib/Support/CoreText+Additions.h
@@ -30,5 +30,7 @@ extern CGSize AB_CTFrameGetSize(CTFrameRef frame, BOOL shouldAddOneLine);
30 30 extern CGFloat AB_CTFrameGetHeight(CTFrameRef frame);
31 31 extern CFIndex AB_CTFrameGetStringIndexForPosition(CTFrameRef frame, CGPoint p);
32 32
  33 +extern void AB_CTFrameGetIndexForPositionInLine(NSString *string, CTFrameRef frame, CFIndex lineIndex, float xPosition, CFIndex *index);
  34 +extern void AB_CTFrameGetLinePositionOfIndex(NSString *string, CTFrameRef frame, int index, CFIndex *lineIndex, float *xPosition);
33 35 extern void AB_CTFrameGetRectsForRange(NSString *string, CTFrameRef frame, CFRange range, CGRect rects[], CFIndex *rectCount);
34 36 extern void AB_CTFrameGetRectsForRangeWithAggregationType(NSString *string, CTFrameRef frame, CFRange range, AB_CTLineRectAggregationType aggregationType, CGRect rects[], CFIndex *rectCount);
36 lib/Support/CoreText+Additions.m
@@ -142,6 +142,42 @@ static inline BOOL RangeContainsIndex(CFRange range, CFIndex index)
142 142 return (a && b);
143 143 }
144 144
  145 +void AB_CTFrameGetIndexForPositionInLine(NSString *string, CTFrameRef frame, CFIndex lineIndex, float xPosition, CFIndex *index)
  146 +{
  147 + NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
  148 + CFIndex linesCount = [lines count];
  149 + if(lineIndex < linesCount)
  150 + {
  151 + CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:lineIndex];
  152 + *index = CTLineGetStringIndexForPosition(line, CGPointMake(xPosition, 0));
  153 + }
  154 + else
  155 + *index = 0;
  156 +}
  157 +
  158 +void AB_CTFrameGetLinePositionOfIndex(NSString *string, CTFrameRef frame, int index, CFIndex *lineIndex, float *xPosition)
  159 +{
  160 + NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
  161 + CFIndex linesCount = [lines count];
  162 + CFIndex charCount = 0;
  163 + CFIndex count = 0;
  164 +
  165 + for(CFIndex i = 0; i < linesCount; ++i) {
  166 + CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:i];
  167 + count = CTLineGetGlyphCount(line);
  168 + if((index >= charCount && index < charCount + count) || i == linesCount - 1)
  169 + {
  170 + CGFloat offset = CTLineGetOffsetForStringIndex(line, index, NULL);
  171 + *lineIndex = i;
  172 + *xPosition = offset;
  173 + return;
  174 + }
  175 + charCount += count;
  176 + }
  177 + *lineIndex = -1;
  178 + *xPosition = 0;
  179 +}
  180 +
145 181 void AB_CTFrameGetRectsForRange(NSString *string, CTFrameRef frame, CFRange range, CGRect rects[], CFIndex *rectCount)
146 182 {
147 183 AB_CTFrameGetRectsForRangeWithAggregationType(string, frame, range, AB_CTLineRectAggregationTypeInline, rects, rectCount);
1  lib/UIKit/TUITextEditor.m
@@ -194,6 +194,7 @@ text with distinguishing appearance (i.e. NSTextView renders with -markedTextAtt
194 194 */
195 195 - (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection replacementRange:(NSRange)replacementRange
196 196 {
  197 + NSLog(@"set selected range : %@",NSStringFromRange(newSelection));
197 198 NSRange selectedRange = [self selectedRange];
198 199
199 200 if(replacementRange.location == NSNotFound) {
70 lib/UIKit/TUITextRenderer+KeyBindings.m
@@ -17,6 +17,13 @@
17 17 #import "TUITextRenderer.h"
18 18 #import "TUITextEditor.h"
19 19 #import "TUIView.h"
  20 +#import "CoreText+Additions.h"
  21 +
  22 +@interface TUITextRenderer ()
  23 +
  24 +- (CTFrameRef)ctFrame;
  25 +
  26 +@end
20 27
21 28 @interface NSString (ABTokenizerAdditions)
22 29 @end
@@ -73,6 +80,69 @@ - (TUITextEditor *)_textEditor
73 80 return nil;
74 81 }
75 82
  83 +- (int)_indexByMovingIndex:(int)index
  84 + by:(int)incr
  85 +{
  86 + CFIndex lineIndex;
  87 + float xPosition;
  88 + AB_CTFrameGetLinePositionOfIndex(TEXT, [self ctFrame], index, &lineIndex, &xPosition);
  89 + if(lineIndex >= 0)
  90 + {
  91 + NSArray *lines = (__bridge NSArray *)CTFrameGetLines([self ctFrame]);
  92 + CFIndex linesCount = [lines count];
  93 + if(incr < 0 && lineIndex == 0)
  94 + {
  95 + return 0;
  96 + }
  97 + else if(lineIndex + incr >= linesCount)
  98 + {
  99 + return (int)[TEXT length];
  100 + }
  101 + else if(lineIndex + incr >= 0) {
  102 + CFIndex index;
  103 + AB_CTFrameGetIndexForPositionInLine(TEXT, [self ctFrame], lineIndex + incr, xPosition, &index);
  104 + return (int)index;
  105 + }
  106 + }
  107 + return -1;
  108 +}
  109 +
  110 +- (void)moveUp:(id)sender
  111 +{
  112 + NSInteger selectionLength = abs((int)(_selectionStart - _selectionEnd));
  113 + if(selectionLength)
  114 + _selectionStart = _selectionEnd = (MIN(_selectionEnd,_selectionStart));
  115 + else
  116 + _selectionEnd = _selectionStart = [self _indexByMovingIndex:(int)MIN(_selectionStart,_selectionEnd)
  117 + by:-1];
  118 + [self.view setNeedsDisplay];
  119 +}
  120 +
  121 +- (void)moveUpAndModifySelection:(id)sender
  122 +{
  123 + _selectionEnd = [self _indexByMovingIndex:(int)MIN(_selectionStart,_selectionEnd)
  124 + by:-1];
  125 + [self.view setNeedsDisplay];
  126 +}
  127 +
  128 +- (void)moveDown:(id)sender
  129 +{
  130 + NSInteger selectionLength = abs((int)(_selectionStart - _selectionEnd));
  131 + if(selectionLength)
  132 + _selectionStart = _selectionEnd = (MAX(_selectionEnd,_selectionStart));
  133 + else
  134 + _selectionEnd = _selectionStart = [self _indexByMovingIndex:(int)MAX(_selectionStart,_selectionEnd)
  135 + by:1];
  136 + [self.view setNeedsDisplay];
  137 +}
  138 +
  139 +- (void)moveDownAndModifySelection:(id)sender
  140 +{
  141 + _selectionEnd = [self _indexByMovingIndex:(int)MAX(_selectionStart,_selectionEnd)
  142 + by:1];
  143 + [self.view setNeedsDisplay];
  144 +}
  145 +
76 146 - (void)moveRight:(id)sender
77 147 {
78 148 NSInteger selectionLength = abs((int)(_selectionStart - _selectionEnd));

0 comments on commit 9b90041

Please sign in to comment.
Something went wrong with that request. Please try again.