From 604ec8c8c618a9e71ffe88d9ef683f74c4110a13 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Mon, 3 Sep 2012 16:32:40 -0700 Subject: [PATCH 01/18] TUITextRenderer automatically scrolls when inside a TUIScrollView. And I've added a few keybindings. No undo support yet :( --- lib/Support/CoreText+Additions.h | 2 + lib/Support/CoreText+Additions.m | 36 +++++++ lib/UIKit/TUITextEditor.m | 8 ++ lib/UIKit/TUITextRenderer+KeyBindings.m | 138 ++++++++++++++++++++++++ 4 files changed, 184 insertions(+) diff --git a/lib/Support/CoreText+Additions.h b/lib/Support/CoreText+Additions.h index b9f73521..5835d4ae 100644 --- a/lib/Support/CoreText+Additions.h +++ b/lib/Support/CoreText+Additions.h @@ -30,6 +30,8 @@ extern CGSize AB_CTFrameGetSize(CTFrameRef frame); extern CGFloat AB_CTFrameGetHeight(CTFrameRef frame); extern CFIndex AB_CTFrameGetStringIndexForPosition(CTFrameRef frame, CGPoint p); +extern void AB_CTFrameGetIndexForPositionInLine(NSString *string, CTFrameRef frame, CFIndex lineIndex, float xPosition, CFIndex *index); +extern void AB_CTFrameGetLinePositionOfIndex(NSString *string, CTFrameRef frame, int index, CFIndex *lineIndex, float *xPosition); extern void AB_CTFrameGetRectsForRange(CTFrameRef frame, CFRange range, CGRect rects[], CFIndex *rectCount); extern void AB_CTFrameGetRectsForRangeWithAggregationType(CTFrameRef frame, CFRange range, AB_CTLineRectAggregationType aggregationType, CGRect rects[], CFIndex *rectCount); extern void AB_CTLinesGetRectsForRangeWithAggregationType(NSArray *lines, CGPoint *lineOrigins, CGRect bounds, CFRange range, AB_CTLineRectAggregationType aggregationType, CGRect rects[], CFIndex *rectCount); diff --git a/lib/Support/CoreText+Additions.m b/lib/Support/CoreText+Additions.m index 1591e0ab..5ed1f4f1 100644 --- a/lib/Support/CoreText+Additions.m +++ b/lib/Support/CoreText+Additions.m @@ -145,6 +145,42 @@ static inline BOOL RangeContainsIndex(CFRange range, CFIndex index) return (a && b); } +void AB_CTFrameGetIndexForPositionInLine(NSString *string, CTFrameRef frame, CFIndex lineIndex, float xPosition, CFIndex *index) +{ + NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame); + CFIndex linesCount = [lines count]; + if(lineIndex < linesCount) + { + CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:lineIndex]; + *index = CTLineGetStringIndexForPosition(line, CGPointMake(xPosition, 0)); + } + else + *index = 0; +} + +void AB_CTFrameGetLinePositionOfIndex(NSString *string, CTFrameRef frame, int index, CFIndex *lineIndex, float *xPosition) +{ + NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame); + CFIndex linesCount = [lines count]; + CFIndex charCount = 0; + CFIndex count = 0; + + for(CFIndex i = 0; i < linesCount; ++i) { + CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:i]; + count = CTLineGetGlyphCount(line); + if((index >= charCount && index < charCount + count) || i == linesCount - 1) + { + CGFloat offset = CTLineGetOffsetForStringIndex(line, index, NULL); + *lineIndex = i; + *xPosition = offset; + return; + } + charCount += count; + } + *lineIndex = -1; + *xPosition = 0; +} + void AB_CTFrameGetRectsForRange(CTFrameRef frame, CFRange range, CGRect rects[], CFIndex *rectCount) { AB_CTFrameGetRectsForRangeWithAggregationType(frame, range, AB_CTLineRectAggregationTypeInline, rects, rectCount); diff --git a/lib/UIKit/TUITextEditor.m b/lib/UIKit/TUITextEditor.m index ee35c0bb..a34c684c 100644 --- a/lib/UIKit/TUITextEditor.m +++ b/lib/UIKit/TUITextEditor.m @@ -18,6 +18,10 @@ #import "TUINSView.h" #import "TUINSWindow.h" +@interface TUITextRenderer () +- (void)_scrollToIndex:(long)index; +@end + @implementation TUITextEditor @synthesize defaultAttributes; @@ -103,6 +107,8 @@ - (void)paste:(id)sender if (self.editable) { [self insertText:[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]]; } + [self insertText:[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } - (void)patchMenuWithStandardEditingMenuItems:(NSMenu *)menu @@ -175,6 +181,7 @@ - (void)deleteCharactersInRange:(NSRange)range // designated delete selectedRange.length = 0; self.selectedRange = selectedRange; [self _textDidChange]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } @@ -237,6 +244,7 @@ - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange // des [self unmarkText]; self.selectedRange = selectedRange; [self _textDidChange]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } /* The receiver inserts aString replacing the content specified by replacementRange. diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index 39f408e5..0452e768 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -17,6 +17,10 @@ #import "TUITextRenderer.h" #import "TUITextEditor.h" #import "TUIView.h" +#import "CoreText+Additions.h" +#import "TUIScrollView.h" + +static NSAttributedString *killBuffer = nil; @interface NSString (ABTokenizerAdditions) @end @@ -61,6 +65,10 @@ - (CFIndex)ab_beginningOfWordGivenCursor:(CFIndex)cursor // if cursor is in word @end +@interface TUITextRenderer (Private) +- (CTFrameRef)ctFrame; +- (void)_scrollToIndex:(long)index; +@end @implementation TUITextRenderer (KeyBindings) @@ -73,12 +81,92 @@ - (TUITextEditor *)_textEditor return nil; } +- (void)_scrollToIndex:(long)index { + if(self.view && [self.view.superview isKindOfClass:[TUIScrollView class]]) { + TUIScrollView *scrollView = (TUIScrollView*)self.view.superview; + CFRange r = { index, 0 }; + CFIndex nRects = 1; + CGRect rects[nRects]; + AB_CTFrameGetRectsForRange([self ctFrame], r, rects, &nRects); + if(nRects == 1) + [scrollView scrollRectToVisible:rects[0] animated:YES]; + } +} + +- (int)_indexByMovingIndex:(int)index + by:(int)incr +{ + CFIndex lineIndex; + float xPosition; + AB_CTFrameGetLinePositionOfIndex(TEXT, [self ctFrame], index, &lineIndex, &xPosition); + if(lineIndex >= 0) + { + NSArray *lines = (__bridge NSArray *)CTFrameGetLines([self ctFrame]); + CFIndex linesCount = [lines count]; + if(incr < 0 && lineIndex == 0) + { + return 0; + } + else if(lineIndex + incr >= linesCount) + { + return (int)[TEXT length]; + } + else if(lineIndex + incr >= 0) { + CFIndex index; + AB_CTFrameGetIndexForPositionInLine(TEXT, [self ctFrame], lineIndex + incr, xPosition, &index); + return (int)index; + } + } + return -1; +} + +- (void)moveUp:(id)sender +{ + NSInteger selectionLength = abs((int)(_selectionStart - _selectionEnd)); + if(selectionLength) + _selectionStart = _selectionEnd = (MIN(_selectionEnd,_selectionStart)); + else + _selectionEnd = _selectionStart = [self _indexByMovingIndex:(int)MIN(_selectionStart,_selectionEnd) + by:-1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; +} + +- (void)moveUpAndModifySelection:(id)sender +{ + _selectionEnd = [self _indexByMovingIndex:(int)MIN(_selectionStart,_selectionEnd) + by:-1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; +} + +- (void)moveDown:(id)sender +{ + NSInteger selectionLength = abs((int)(_selectionStart - _selectionEnd)); + if(selectionLength) + _selectionStart = _selectionEnd = (MAX(_selectionEnd,_selectionStart)); + else + _selectionEnd = _selectionStart = [self _indexByMovingIndex:(int)MAX(_selectionStart,_selectionEnd) + by:1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; +} + +- (void)moveDownAndModifySelection:(id)sender +{ + _selectionEnd = [self _indexByMovingIndex:(int)MAX(_selectionStart,_selectionEnd) + by:1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; +} + - (void)moveRight:(id)sender { NSInteger selectionLength = abs((int)(_selectionStart - _selectionEnd)); NSInteger max = [TEXT length]; _selectionStart = _selectionEnd = MIN(MAX(_selectionStart, _selectionEnd) + (selectionLength?0:1), max); [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveLeft:(id)sender @@ -87,6 +175,7 @@ - (void)moveLeft:(id)sender NSInteger min = 0; _selectionStart = _selectionEnd = MAX(MIN(_selectionStart, _selectionEnd) - (selectionLength?0:1), min); [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveRightAndModifySelection:(id)sender @@ -94,6 +183,7 @@ - (void)moveRightAndModifySelection:(id)sender NSInteger max = [TEXT length]; _selectionEnd = MIN(_selectionEnd + 1, max); [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveLeftAndModifySelection:(id)sender @@ -101,59 +191,75 @@ - (void)moveLeftAndModifySelection:(id)sender NSInteger min = 0; _selectionEnd = MAX(_selectionEnd - 1, min); [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordRight:(id)sender { _selectionStart = _selectionEnd = [TEXT ab_endOfWordGivenCursor:MAX(_selectionStart, _selectionEnd)]; [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordLeft:(id)sender { _selectionStart = _selectionEnd = [TEXT ab_beginningOfWordGivenCursor:MIN(_selectionStart, _selectionEnd)]; [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordRightAndModifySelection:(id)sender { _selectionEnd = [TEXT ab_endOfWordGivenCursor:_selectionEnd]; [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordLeftAndModifySelection:(id)sender { _selectionEnd = [TEXT ab_beginningOfWordGivenCursor:_selectionEnd]; [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfLineAndModifySelection:(id)sender { _selectionEnd = 0; // fixme for multiline [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToEndOfLineAndModifySelection:(id)sender { _selectionEnd = [TEXT length]; // fixme for multiline [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfLine:(id)sender { _selectionStart = _selectionEnd = 0; [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToEndOfLine:(id)sender { _selectionStart = _selectionEnd = [TEXT length]; [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)insertNewline:(id)sender { [[self _textEditor] insertText:@"\n"]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; +} + +- (void)insertNewlineIgnoringFieldEditor:(id)sender +{ + [[self _textEditor] insertText:@"\n"]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)deleteBackward:(id)sender @@ -170,6 +276,7 @@ - (void)deleteBackward:(id)sender } [[self _textEditor] deleteCharactersInRange:deleteRange]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)deleteForward:(id)sender @@ -185,6 +292,7 @@ - (void)deleteForward:(id)sender } [[self _textEditor] deleteCharactersInRange:deleteRange]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } @@ -196,6 +304,7 @@ - (void)deleteToBeginningOfLine:(id)sender } else { [self deleteBackward:nil]; } + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)deleteWordBackward:(id)sender @@ -207,6 +316,7 @@ - (void)deleteWordBackward:(id)sender } else { [self deleteBackward:nil]; } + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfParagraph:(id)sender @@ -264,5 +374,33 @@ - (void)moveToEndOfDocument:(id)sender [self.view setNeedsDisplay]; } +- (void)deleteToBeginningOfParagraph:(id)sender +{ + [self deleteToBeginningOfLine:sender]; +} + +- (void)deleteToEndOfLine:(id)sender +{ + NSRange deleteRange = [self selectedRange]; + if(deleteRange.length == 0) + deleteRange.length = [TEXT length] - deleteRange.location; + killBuffer = [[self _textEditor].backingStore attributedSubstringFromRange:deleteRange]; + [[self _textEditor] deleteCharactersInRange:deleteRange]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; +} + +- (void)deleteToEndOfParagraph:(id)sender +{ + [self deleteToEndOfLine:sender]; +} + +- (void)yank:(id)sender +{ + if(killBuffer) + { + [[self _textEditor] insertText:killBuffer]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + } +} @end From 29267ffffbb60eefbdfb4d01100d7fe2ca01bd86 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Mon, 3 Sep 2012 16:33:26 -0700 Subject: [PATCH 02/18] Fixed auto-scroll for single line. --- lib/UIKit/TUITextRenderer+KeyBindings.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index 0452e768..49d48fa0 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -90,6 +90,9 @@ - (void)_scrollToIndex:(long)index { AB_CTFrameGetRectsForRange([self ctFrame], r, rects, &nRects); if(nRects == 1) [scrollView scrollRectToVisible:rects[0] animated:YES]; + else if(nRects == 0) + [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) + animated:YES]; } } From 67cfe3979fa70e25fd458e0e8605f17bac43e4d1 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Mon, 1 Oct 2012 16:03:51 -0700 Subject: [PATCH 03/18] Fixed tabbing issues. --- lib/UIKit/TUITextEditor.m | 50 ++++----- lib/UIKit/TUITextRenderer+KeyBindings.m | 128 ++++++++++++------------ 2 files changed, 89 insertions(+), 89 deletions(-) diff --git a/lib/UIKit/TUITextEditor.m b/lib/UIKit/TUITextEditor.m index dd21a98c..ceb918ad 100644 --- a/lib/UIKit/TUITextEditor.m +++ b/lib/UIKit/TUITextEditor.m @@ -37,7 +37,7 @@ - (id)init markedRange = NSMakeRange(NSNotFound, 0); inputContext = [[NSTextInputContext alloc] initWithClient:self]; inputContext.acceptsGlyphInfo = YES; - + _secure = NO; self.attributedString = backingStore; } @@ -54,19 +54,19 @@ - (void)setSecure:(BOOL)secured { } - (NSAttributedString*)drawingAttributedString { - if(_secure) { - NSString *placeholder = @"\u2022"; - NSUInteger backingStoreLength = backingStore.length; - NSMutableString *string = [NSMutableString string]; - for(int i = 0; i < backingStoreLength; i++) { - [string appendString:placeholder]; - } - - NSAttributedString *securePlaceHolder = [[NSAttributedString alloc] initWithString:string attributes:defaultAttributes]; - return securePlaceHolder; - } - - return [super drawingAttributedString]; + if(_secure) { + NSString *placeholder = @"\u2022"; + NSUInteger backingStoreLength = backingStore.length; + NSMutableString *string = [NSMutableString string]; + for(int i = 0; i < backingStoreLength; i++) { + [string appendString:placeholder]; + } + + NSAttributedString *securePlaceHolder = [[NSAttributedString alloc] initWithString:string attributes:defaultAttributes]; + return securePlaceHolder; + } + + return [super drawingAttributedString]; } - (NSTextInputContext *)inputContext @@ -125,18 +125,18 @@ - (void)setText:(NSString *)aString - (BOOL)respondsToSelector:(SEL)aSelector { - if(aSelector == @selector(copy:) || aSelector == @selector(cut:)) - return !_secure; - return [super respondsToSelector:aSelector]; + if(aSelector == @selector(copy:) || aSelector == @selector(cut:)) + return !_secure; + return [super respondsToSelector:aSelector]; } - (void)copy:(id)sender { - if(_secure) { - return; - } - - [super copy:sender]; + if(_secure) { + return; + } + + [super copy:sender]; } - (void)cut:(id)sender @@ -151,7 +151,7 @@ - (void)paste:(id)sender [self insertText:[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]]; } [self insertText:[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]]; - [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } - (void)patchMenuWithStandardEditingMenuItems:(NSMenu *)menu @@ -224,7 +224,7 @@ - (void)deleteCharactersInRange:(NSRange)range // designated delete selectedRange.length = 0; self.selectedRange = selectedRange; [self _textDidChange]; - [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } @@ -285,7 +285,7 @@ - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange // des [self unmarkText]; self.selectedRange = selectedRange; [self _textDidChange]; - [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } /* The receiver inserts aString replacing the content specified by replacementRange. diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index b305c3f3..963a8be0 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -78,18 +78,18 @@ - (TUITextEditor *)_textEditor } - (void)_scrollToIndex:(long)index { - if(self.view && [self.view.superview isKindOfClass:[TUIScrollView class]]) { - TUIScrollView *scrollView = (TUIScrollView*)self.view.superview; - CFRange r = { index, 0 }; - CFIndex nRects = 1; - CGRect rects[nRects]; - AB_CTFrameGetRectsForRange([self ctFrame], r, rects, &nRects); - if(nRects == 1) - [scrollView scrollRectToVisible:rects[0] animated:YES]; - else if(nRects == 0) - [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) - animated:YES]; - } + if(self.view && [self.view.superview isKindOfClass:[TUIScrollView class]]) { + TUIScrollView *scrollView = (TUIScrollView*)self.view.superview; + CFRange r = { index, 0 }; + CFIndex nRects = 1; + CGRect rects[nRects]; + AB_CTFrameGetRectsForRange([self ctFrame], r, rects, &nRects); + if(nRects == 1) + [scrollView scrollRectToVisible:rects[0] animated:YES]; + else if(nRects == 0) + [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) + animated:YES]; + } } - (CFIndex)_indexByMovingIndex:(CFIndex)index @@ -128,41 +128,41 @@ - (CFIndex)_indexByMovingIndex:(CFIndex)index - (void)moveUp:(id)sender { NSInteger selectionLength = labs(_selectionStart - _selectionEnd); - if(selectionLength) - _selectionStart = _selectionEnd = MIN(_selectionEnd,_selectionStart); - else - _selectionEnd = _selectionStart = [self _indexByMovingIndex:MIN(_selectionStart,_selectionEnd) - by:-1]; - [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + if(selectionLength) + _selectionStart = _selectionEnd = MIN(_selectionEnd,_selectionStart); + else + _selectionEnd = _selectionStart = [self _indexByMovingIndex:MIN(_selectionStart,_selectionEnd) + by:-1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveUpAndModifySelection:(id)sender { _selectionEnd = [self _indexByMovingIndex:MIN(_selectionStart,_selectionEnd) - by:-1]; - [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + by:-1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveDown:(id)sender { NSInteger selectionLength = labs(_selectionStart - _selectionEnd); - if(selectionLength) - _selectionStart = _selectionEnd = MAX(_selectionEnd,_selectionStart); - else - _selectionEnd = _selectionStart = [self _indexByMovingIndex:MAX(_selectionStart,_selectionEnd) - by:1]; - [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + if(selectionLength) + _selectionStart = _selectionEnd = MAX(_selectionEnd,_selectionStart); + else + _selectionEnd = _selectionStart = [self _indexByMovingIndex:MAX(_selectionStart,_selectionEnd) + by:1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveDownAndModifySelection:(id)sender { _selectionEnd = [self _indexByMovingIndex:MAX(_selectionStart,_selectionEnd) - by:1]; - [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + by:1]; + [self.view setNeedsDisplay]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveRight:(id)sender @@ -171,7 +171,7 @@ - (void)moveRight:(id)sender NSInteger max = [TEXT length]; _selectionStart = _selectionEnd = MIN(MAX(_selectionStart, _selectionEnd) + (selectionLength?0:1), max); [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveLeft:(id)sender @@ -180,7 +180,7 @@ - (void)moveLeft:(id)sender NSInteger min = 0; _selectionStart = _selectionEnd = MAX(MIN(_selectionStart, _selectionEnd) - (selectionLength?0:1), min); [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveRightAndModifySelection:(id)sender @@ -188,7 +188,7 @@ - (void)moveRightAndModifySelection:(id)sender NSInteger max = [TEXT length]; _selectionEnd = MIN(_selectionEnd + 1, max); [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveLeftAndModifySelection:(id)sender @@ -196,63 +196,63 @@ - (void)moveLeftAndModifySelection:(id)sender NSInteger min = 0; _selectionEnd = MAX(_selectionEnd - 1, min); [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordRight:(id)sender { _selectionStart = _selectionEnd = [TEXT ab_endOfWordGivenCursor:MAX(_selectionStart, _selectionEnd)]; [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordLeft:(id)sender { _selectionStart = _selectionEnd = [TEXT ab_beginningOfWordGivenCursor:MIN(_selectionStart, _selectionEnd)]; [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordRightAndModifySelection:(id)sender { _selectionEnd = [TEXT ab_endOfWordGivenCursor:_selectionEnd]; [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveWordLeftAndModifySelection:(id)sender { _selectionEnd = [TEXT ab_beginningOfWordGivenCursor:_selectionEnd]; [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfLineAndModifySelection:(id)sender { _selectionEnd = 0; // fixme for multiline [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToEndOfLineAndModifySelection:(id)sender { _selectionEnd = [TEXT length]; // fixme for multiline [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfLine:(id)sender { _selectionStart = _selectionEnd = 0; [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToEndOfLine:(id)sender { _selectionStart = _selectionEnd = [TEXT length]; [self.view setNeedsDisplay]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfParagraphAndModifySelection:(id)sender @@ -278,13 +278,13 @@ - (void)moveToEndOfDocumentAndModifySelection:(id)sender - (void)insertNewline:(id)sender { [[self _textEditor] insertText:@"\n"]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)insertNewlineIgnoringFieldEditor:(id)sender { - [[self _textEditor] insertText:@"\n"]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [[self _textEditor] insertText:@"\n"]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)deleteBackward:(id)sender @@ -301,7 +301,7 @@ - (void)deleteBackward:(id)sender } [[self _textEditor] deleteCharactersInRange:deleteRange]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)deleteForward:(id)sender @@ -317,7 +317,7 @@ - (void)deleteForward:(id)sender } [[self _textEditor] deleteCharactersInRange:deleteRange]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } @@ -329,7 +329,7 @@ - (void)deleteToBeginningOfLine:(id)sender } else { [self deleteBackward:nil]; } - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)deleteWordBackward:(id)sender @@ -341,7 +341,7 @@ - (void)deleteWordBackward:(id)sender } else { [self deleteBackward:nil]; } - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; } - (void)moveToBeginningOfParagraph:(id)sender @@ -401,31 +401,31 @@ - (void)moveToEndOfDocument:(id)sender } - (void)deleteToBeginningOfParagraph:(id)sender { - [self deleteToBeginningOfLine:sender]; + [self deleteToBeginningOfLine:sender]; } - (void)deleteToEndOfLine:(id)sender { - NSRange deleteRange = [self selectedRange]; - if(deleteRange.length == 0) - deleteRange.length = [TEXT length] - deleteRange.location; - killBuffer = [[self _textEditor].backingStore attributedSubstringFromRange:deleteRange]; - [[self _textEditor] deleteCharactersInRange:deleteRange]; - [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; + NSRange deleteRange = [self selectedRange]; + if(deleteRange.length == 0) + deleteRange.length = [TEXT length] - deleteRange.location; + killBuffer = [[self _textEditor].backingStore attributedSubstringFromRange:deleteRange]; + [[self _textEditor] deleteCharactersInRange:deleteRange]; + [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } - (void)deleteToEndOfParagraph:(id)sender { - [self deleteToEndOfLine:sender]; + [self deleteToEndOfLine:sender]; } - (void)yank:(id)sender { - if(killBuffer) - { - [[self _textEditor] insertText:killBuffer]; - [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; - } + if(killBuffer) + { + [[self _textEditor] insertText:killBuffer]; + [self _scrollToIndex:MIN(_selectionStart, _selectionEnd)]; + } } @end From d2f3ffa833cd9568e72e8033956450b13c573449 Mon Sep 17 00:00:00 2001 From: Bryan Hansen Date: Tue, 2 Oct 2012 01:15:03 -0700 Subject: [PATCH 04/18] Correcting sizing issue when drawing button's with text edge insets. Defaulting button title rendering to be vertically aligned. --- lib/UIKit/TUIButton.m | 1 + lib/UIKit/TUILabel.m | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/UIKit/TUIButton.m b/lib/UIKit/TUIButton.m index 88bd54c7..7b37c2b2 100644 --- a/lib/UIKit/TUIButton.m +++ b/lib/UIKit/TUIButton.m @@ -236,6 +236,7 @@ - (void)drawRect:(CGRect)r CGContextSetAlpha(ctx, 0.5); CGRect titleFrame = self.bounds; titleFrame.size.width -= (_titleEdgeInsets.left + _titleEdgeInsets.right); + titleFrame.size.height -= (_titleEdgeInsets.top + _titleEdgeInsets.bottom); self.titleLabel.frame = titleFrame; [self.titleLabel drawRect:self.titleLabel.bounds]; CGContextRestoreGState(ctx); diff --git a/lib/UIKit/TUILabel.m b/lib/UIKit/TUILabel.m index b17b83fd..e7c3fd2a 100644 --- a/lib/UIKit/TUILabel.m +++ b/lib/UIKit/TUILabel.m @@ -40,6 +40,7 @@ - (id)initWithFrame:(CGRect)frame { if((self = [super initWithFrame:frame])) { renderer = [[TUITextRenderer alloc] init]; + renderer.verticalAlignment = TUITextVerticalAlignmentMiddle; [self setTextRenderers:[NSArray arrayWithObjects:renderer, nil]]; _lineBreakMode = TUILineBreakModeClip; From 715d967ff80d388a66a1fe01258a90e0f6f61414 Mon Sep 17 00:00:00 2001 From: Bryan Hansen Date: Tue, 2 Oct 2012 10:48:55 -0700 Subject: [PATCH 05/18] Changing spaces to tabs :) --- lib/UIKit/TUIButton.m | 2 +- lib/UIKit/TUILabel.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/UIKit/TUIButton.m b/lib/UIKit/TUIButton.m index 7b37c2b2..ba18fb63 100644 --- a/lib/UIKit/TUIButton.m +++ b/lib/UIKit/TUIButton.m @@ -236,7 +236,7 @@ - (void)drawRect:(CGRect)r CGContextSetAlpha(ctx, 0.5); CGRect titleFrame = self.bounds; titleFrame.size.width -= (_titleEdgeInsets.left + _titleEdgeInsets.right); - titleFrame.size.height -= (_titleEdgeInsets.top + _titleEdgeInsets.bottom); + titleFrame.size.height -= (_titleEdgeInsets.top + _titleEdgeInsets.bottom); self.titleLabel.frame = titleFrame; [self.titleLabel drawRect:self.titleLabel.bounds]; CGContextRestoreGState(ctx); diff --git a/lib/UIKit/TUILabel.m b/lib/UIKit/TUILabel.m index e7c3fd2a..19812019 100644 --- a/lib/UIKit/TUILabel.m +++ b/lib/UIKit/TUILabel.m @@ -40,7 +40,7 @@ - (id)initWithFrame:(CGRect)frame { if((self = [super initWithFrame:frame])) { renderer = [[TUITextRenderer alloc] init]; - renderer.verticalAlignment = TUITextVerticalAlignmentMiddle; + renderer.verticalAlignment = TUITextVerticalAlignmentMiddle; [self setTextRenderers:[NSArray arrayWithObjects:renderer, nil]]; _lineBreakMode = TUILineBreakModeClip; From aef468263333d0577a91f3bd56fc5ebfc14567f6 Mon Sep 17 00:00:00 2001 From: galaxas0 Date: Tue, 2 Oct 2012 13:21:58 -0700 Subject: [PATCH 06/18] Fixed getter syntax. --- lib/UIKit/TUIScrollKnob.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/UIKit/TUIScrollKnob.m b/lib/UIKit/TUIScrollKnob.m index 3c1b2ad0..a91fe8fa 100644 --- a/lib/UIKit/TUIScrollKnob.m +++ b/lib/UIKit/TUIScrollKnob.m @@ -72,7 +72,7 @@ - (void)dealloc { - (void)refreshKnobTimer { if([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay) { TUIScrollViewIndicatorVisibility visibility; - if(self.isVertical) + if(self.vertical) visibility = scrollView.verticalScrollIndicatorVisibility; else visibility = scrollView.horizontalScrollIndicatorVisibility; From cf1120ab68dfcc35cfc63effbd1c610f04111c43 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Tue, 2 Oct 2012 13:43:25 -0700 Subject: [PATCH 07/18] Revert "Take acceptsFirstResponder into account." This reverts commit c636424772341201126bc8bea6f70f4f67b36962. Conflicts: lib/UIKit/TUINSWindow.m --- lib/UIKit/TUINSWindow.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/UIKit/TUINSWindow.m b/lib/UIKit/TUINSWindow.m index 2b0b4ebc..b047caf2 100644 --- a/lib/UIKit/TUINSWindow.m +++ b/lib/UIKit/TUINSWindow.m @@ -67,8 +67,6 @@ - (NSInteger)futureMakeFirstResponderRequestToken - (BOOL)tui_makeFirstResponder:(NSResponder *)aResponder { - if(![aResponder acceptsFirstResponder]) - return NO; ++makeFirstResponderCount; // cool if it overflows if([aResponder respondsToSelector:@selector(initialFirstResponder)]) aResponder = ((TUIResponder *)aResponder).initialFirstResponder; From d1c4c35626219b63019940b1f59de6d15df404b0 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Tue, 2 Oct 2012 13:59:05 -0700 Subject: [PATCH 08/18] .vertical isn't actually a property CC @galaxas0 --- lib/UIKit/TUIScrollKnob.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/UIKit/TUIScrollKnob.m b/lib/UIKit/TUIScrollKnob.m index a91fe8fa..86b08f97 100644 --- a/lib/UIKit/TUIScrollKnob.m +++ b/lib/UIKit/TUIScrollKnob.m @@ -72,7 +72,7 @@ - (void)dealloc { - (void)refreshKnobTimer { if([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay) { TUIScrollViewIndicatorVisibility visibility; - if(self.vertical) + if([self isVertical]) visibility = scrollView.verticalScrollIndicatorVisibility; else visibility = scrollView.horizontalScrollIndicatorVisibility; From a3499195e9b8848108932a145ed2538336437757 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Sat, 6 Oct 2012 18:54:26 -0700 Subject: [PATCH 09/18] Style changes and -enclosingScrollView --- lib/UIKit/TUITextEditor.m | 5 ---- lib/UIKit/TUITextRenderer+KeyBindings.m | 38 +++++++++++++++++-------- lib/UIKit/TUITextRenderer+Private.h | 6 ++++ lib/UIKit/TUIView.h | 6 ++++ lib/UIKit/TUIView.m | 9 +++++- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/lib/UIKit/TUITextEditor.m b/lib/UIKit/TUITextEditor.m index ceb918ad..e1c569d8 100644 --- a/lib/UIKit/TUITextEditor.m +++ b/lib/UIKit/TUITextEditor.m @@ -19,10 +19,6 @@ #import "TUINSWindow.h" #import "TUITextRenderer+Private.h" -@interface TUITextRenderer () -- (void)_scrollToIndex:(long)index; -@end - @implementation TUITextEditor @synthesize defaultAttributes; @@ -150,7 +146,6 @@ - (void)paste:(id)sender if (self.editable) { [self insertText:[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]]; } - [self insertText:[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]]; [self _scrollToIndex:MAX(_selectionStart, _selectionEnd)]; } diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index 963a8be0..c27ce9b1 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -77,18 +77,24 @@ - (TUITextEditor *)_textEditor return nil; } -- (void)_scrollToIndex:(long)index { - if(self.view && [self.view.superview isKindOfClass:[TUIScrollView class]]) { - TUIScrollView *scrollView = (TUIScrollView*)self.view.superview; - CFRange r = { index, 0 }; - CFIndex nRects = 1; - CGRect rects[nRects]; - AB_CTFrameGetRectsForRange([self ctFrame], r, rects, &nRects); - if(nRects == 1) - [scrollView scrollRectToVisible:rects[0] animated:YES]; - else if(nRects == 0) - [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) - animated:YES]; +- (void)_scrollToIndex:(CFIndex)index { + TUIScrollView *scrollView = self.view.enclosingScrollView; + if(scrollView) { + + // Get the rect for the index passed within the text. + CFRange r = CFRangeMake(index, 0); + CFIndex nRects = 1; + CGRect rects[nRects]; + AB_CTFrameGetRectsForRange([self ctFrame], r, rects, &nRects); + + // If it exists, then scroll the the beginning of the rects. + if(nRects == 1) + [scrollView scrollRectToVisible:rects[0] animated:YES]; + + // Otherwise, scroll to the middle of the text rects. + else if(nRects == 0) + [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) + animated:YES]; } } @@ -401,6 +407,10 @@ - (void)moveToEndOfDocument:(id)sender } - (void)deleteToBeginningOfParagraph:(id)sender { + NSRange deleteRange = [self selectedRange]; + if(deleteRange.length == 0) + deleteRange.length = [TEXT length] - deleteRange.location; + killBuffer = [[self _textEditor].backingStore attributedSubstringFromRange:deleteRange]; [self deleteToBeginningOfLine:sender]; } @@ -416,6 +426,10 @@ - (void)deleteToEndOfLine:(id)sender - (void)deleteToEndOfParagraph:(id)sender { + NSRange deleteRange = [self selectedRange]; + if(deleteRange.length == 0) + deleteRange.length = [TEXT length] - deleteRange.location; + killBuffer = [[self _textEditor].backingStore attributedSubstringFromRange:deleteRange]; [self deleteToEndOfLine:sender]; } diff --git a/lib/UIKit/TUITextRenderer+Private.h b/lib/UIKit/TUITextRenderer+Private.h index 1526793e..50d6553b 100644 --- a/lib/UIKit/TUITextRenderer+Private.h +++ b/lib/UIKit/TUITextRenderer+Private.h @@ -9,3 +9,9 @@ - (void)_resetFramesetter; @end + +@interface TUITextRenderer (KeyBindings) + +- (void)_scrollToIndex:(long)index; + +@end diff --git a/lib/UIKit/TUIView.h b/lib/UIKit/TUIView.h index 8a3251dd..eb79700b 100644 --- a/lib/UIKit/TUIView.h +++ b/lib/UIKit/TUIView.h @@ -276,6 +276,8 @@ extern CGRect(^TUIViewCenteredLayout)(TUIView*); @end +@class TUIScrollView; + @interface TUIView (TUIViewHierarchy) @property (nonatomic, readonly) TUIView *superview; @@ -325,6 +327,10 @@ extern CGRect(^TUIViewCenteredLayout)(TUIView*); */ - (TUIView *)firstSuperviewOfClass:(Class)c; +// Return the scroll view responder this view is enclosed in. +// This is not neccessarily the superview, and is not the reciever. +- (TUIScrollView *)enclosingScrollView; + - (void)setNeedsLayout; - (void)layoutIfNeeded; diff --git a/lib/UIKit/TUIView.m b/lib/UIKit/TUIView.m index 7941edd6..d59b61c9 100644 --- a/lib/UIKit/TUIView.m +++ b/lib/UIKit/TUIView.m @@ -14,15 +14,16 @@ limitations under the License. */ -#import "TUIView.h" #import #import "NSColor+TUIExtensions.h" #import "TUICGAdditions.h" +#import "TUIView.h" #import "TUILayoutManager.h" #import "TUINSView.h" #import "TUINSWindow.h" #import "TUITextRenderer.h" #import "TUIViewController.h" +#import "TUIScrollView.h" /* * Enable this to debug blending. @@ -975,6 +976,12 @@ - (TUIView *)firstSuperviewOfClass:(Class)c return [self.superview firstSuperviewOfClass:c]; } +- (TUIScrollView *)enclosingScrollView { + if([self.superview isKindOfClass:TUIScrollView.class]) + return (TUIScrollView *)self.superview; + else return nil; +} + - (void)setNeedsLayout { [self.layer setNeedsLayout]; From ed02a8e208198088362e561853ef74da08cbd87d Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Sun, 7 Oct 2012 20:56:35 -0700 Subject: [PATCH 10/18] Fixed enclosingScrollView. --- lib/UIKit/TUITextRenderer+KeyBindings.m | 2 +- lib/UIKit/TUIView.m | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index c27ce9b1..b6ccc875 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -95,7 +95,7 @@ - (void)_scrollToIndex:(CFIndex)index { else if(nRects == 0) [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) animated:YES]; - } + } } - (CFIndex)_indexByMovingIndex:(CFIndex)index diff --git a/lib/UIKit/TUIView.m b/lib/UIKit/TUIView.m index d59b61c9..3c91ffdc 100644 --- a/lib/UIKit/TUIView.m +++ b/lib/UIKit/TUIView.m @@ -977,9 +977,7 @@ - (TUIView *)firstSuperviewOfClass:(Class)c } - (TUIScrollView *)enclosingScrollView { - if([self.superview isKindOfClass:TUIScrollView.class]) - return (TUIScrollView *)self.superview; - else return nil; + return (TUIScrollView *)[self.superview firstSuperviewOfClass:TUIScrollView.class]; } - (void)setNeedsLayout From e7a3d71b5fe20ac6dc0adbd356958f308b36eddf Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Mon, 8 Oct 2012 17:18:19 -0700 Subject: [PATCH 11/18] Use screen scale for TUIGraphicsDrawAsImage() --- lib/UIKit/TUICGAdditions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/UIKit/TUICGAdditions.m b/lib/UIKit/TUICGAdditions.m index a91963c4..14d0e129 100644 --- a/lib/UIKit/TUICGAdditions.m +++ b/lib/UIKit/TUICGAdditions.m @@ -246,7 +246,7 @@ void TUIGraphicsEndImageContext(void) NSImage *TUIGraphicsDrawAsImage(CGSize size, void(^draw)(void)) { - TUIGraphicsBeginImageContext(size); + TUIGraphicsBeginImageContextWithOptions(size, NO, 0); draw(); NSImage *image = TUIGraphicsGetImageFromCurrentImageContext(); TUIGraphicsEndImageContext(); From 76016a8620221fc8d264d40ee5960f6d435f3be9 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Mon, 8 Oct 2012 17:20:24 -0700 Subject: [PATCH 12/18] Update the returned image's size --- lib/UIKit/TUICGAdditions.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/UIKit/TUICGAdditions.m b/lib/UIKit/TUICGAdditions.m index 14d0e129..3fabe9f5 100644 --- a/lib/UIKit/TUICGAdditions.m +++ b/lib/UIKit/TUICGAdditions.m @@ -250,7 +250,8 @@ void TUIGraphicsEndImageContext(void) draw(); NSImage *image = TUIGraphicsGetImageFromCurrentImageContext(); TUIGraphicsEndImageContext(); - + + image.size = size; return image; } From e95fe456994edc60df425a7b74514bc8a02f1560 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Mon, 8 Oct 2012 20:28:10 -0700 Subject: [PATCH 13/18] Used ancestorScrollView instead. --- lib/UIKit/TUITextRenderer+KeyBindings.m | 4 +++- lib/UIKit/TUIView.h | 4 ---- lib/UIKit/TUIView.m | 4 ---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index b6ccc875..9dd79151 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -20,6 +20,8 @@ #import "CoreText+Additions.h" #import "TUITextRenderer+Private.h" #import "TUIScrollView.h" +#import "TUIView+TUIBridgedView.h" +#import "TUIScrollView+TUIBridgedScrollView.h" static NSAttributedString *killBuffer = nil; @@ -78,7 +80,7 @@ - (TUITextEditor *)_textEditor } - (void)_scrollToIndex:(CFIndex)index { - TUIScrollView *scrollView = self.view.enclosingScrollView; + TUIScrollView *scrollView = (TUIScrollView *)self.view.ancestorScrollView; if(scrollView) { // Get the rect for the index passed within the text. diff --git a/lib/UIKit/TUIView.h b/lib/UIKit/TUIView.h index eb79700b..2500d073 100644 --- a/lib/UIKit/TUIView.h +++ b/lib/UIKit/TUIView.h @@ -327,10 +327,6 @@ extern CGRect(^TUIViewCenteredLayout)(TUIView*); */ - (TUIView *)firstSuperviewOfClass:(Class)c; -// Return the scroll view responder this view is enclosed in. -// This is not neccessarily the superview, and is not the reciever. -- (TUIScrollView *)enclosingScrollView; - - (void)setNeedsLayout; - (void)layoutIfNeeded; diff --git a/lib/UIKit/TUIView.m b/lib/UIKit/TUIView.m index 3c91ffdc..69904395 100644 --- a/lib/UIKit/TUIView.m +++ b/lib/UIKit/TUIView.m @@ -976,10 +976,6 @@ - (TUIView *)firstSuperviewOfClass:(Class)c return [self.superview firstSuperviewOfClass:c]; } -- (TUIScrollView *)enclosingScrollView { - return (TUIScrollView *)[self.superview firstSuperviewOfClass:TUIScrollView.class]; -} - - (void)setNeedsLayout { [self.layer setNeedsLayout]; From 19ae40bb524d45bece745d6f2a6d3a1c1048a444 Mon Sep 17 00:00:00 2001 From: Sheng Luo Date: Fri, 12 Oct 2012 13:24:57 +0800 Subject: [PATCH 14/18] Prefetch scroll view's pulling state. --- lib/UIKit/TUIScrollView.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/UIKit/TUIScrollView.m b/lib/UIKit/TUIScrollView.m index 8e8739a5..a52901b2 100644 --- a/lib/UIKit/TUIScrollView.m +++ b/lib/UIKit/TUIScrollView.m @@ -979,6 +979,8 @@ - (void)_startThrow _throw.t = t; [self _startTimer:AnimationModeThrow]; + + BOOL pulling = self._pulling; if(_pull.xPulling) { _pull.xPulling = NO; @@ -994,7 +996,7 @@ - (void)_startThrow _bounce.y = _pull.y; } - if(self._pulling && _scrollViewFlags.didChangeContentInset){ + if(pulling && _scrollViewFlags.didChangeContentInset){ _scrollViewFlags.didChangeContentInset = 0; _bounce.x += _contentInset.left; _bounce.y += _contentInset.top; From b6f04cc0e28c8f4e5dcaae5ff9927cffe44a3961 Mon Sep 17 00:00:00 2001 From: Sheng Luo Date: Sat, 13 Oct 2012 09:34:40 +0800 Subject: [PATCH 15/18] Add an explanation. --- lib/UIKit/TUIScrollView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/UIKit/TUIScrollView.m b/lib/UIKit/TUIScrollView.m index a52901b2..d7c5665f 100644 --- a/lib/UIKit/TUIScrollView.m +++ b/lib/UIKit/TUIScrollView.m @@ -980,7 +980,7 @@ - (void)_startThrow [self _startTimer:AnimationModeThrow]; - BOOL pulling = self._pulling; + BOOL pulling = self._pulling; // prefetch the pulling state before resetting it if(_pull.xPulling) { _pull.xPulling = NO; From 49415e0f6dfae40f3284254d43d5d49a938ff7a8 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Sat, 13 Oct 2012 19:20:23 -0700 Subject: [PATCH 16/18] Added protocol cast to TUIBridgedScrollView. --- lib/UIKit/TUITextRenderer+KeyBindings.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index 9dd79151..041b8be0 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -80,7 +80,7 @@ - (TUITextEditor *)_textEditor } - (void)_scrollToIndex:(CFIndex)index { - TUIScrollView *scrollView = (TUIScrollView *)self.view.ancestorScrollView; + TUIScrollView *scrollView = (TUIScrollView *)self.view.ancestorScrollView; if(scrollView) { // Get the rect for the index passed within the text. From 719927dd89e07f8ceaab975a600335dc76700425 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Sat, 13 Oct 2012 19:31:40 -0700 Subject: [PATCH 17/18] Stick to TUIBridgedScrollView methods only. --- lib/UIKit/TUITextRenderer+KeyBindings.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index 041b8be0..796e2d6e 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -80,7 +80,7 @@ - (TUITextEditor *)_textEditor } - (void)_scrollToIndex:(CFIndex)index { - TUIScrollView *scrollView = (TUIScrollView *)self.view.ancestorScrollView; + id scrollView = (id )self.view.ancestorScrollView; if(scrollView) { // Get the rect for the index passed within the text. @@ -91,12 +91,11 @@ - (void)_scrollToIndex:(CFIndex)index { // If it exists, then scroll the the beginning of the rects. if(nRects == 1) - [scrollView scrollRectToVisible:rects[0] animated:YES]; + [scrollView scrollToIncludeRect:rects[0]]; // Otherwise, scroll to the middle of the text rects. else if(nRects == 0) - [scrollView scrollRectToVisible:CGRectMake(0, self.view.frame.size.height / 2, 0, 1) - animated:YES]; + [scrollView scrollToIncludeRect:CGRectMake(0, self.view.frame.size.height / 2, 0, 1)]; } } From 19fc9e0d0290727da9c6fefd8aa3043dd65bdb65 Mon Sep 17 00:00:00 2001 From: Aditya Nrusimha Date: Mon, 15 Oct 2012 11:23:20 -0700 Subject: [PATCH 18/18] Fixed imports and casting. --- lib/UIKit/TUITextRenderer+KeyBindings.m | 2 +- lib/UIKit/TUIView.h | 2 -- lib/UIKit/TUIView.m | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/UIKit/TUITextRenderer+KeyBindings.m b/lib/UIKit/TUITextRenderer+KeyBindings.m index 796e2d6e..d6da42e1 100644 --- a/lib/UIKit/TUITextRenderer+KeyBindings.m +++ b/lib/UIKit/TUITextRenderer+KeyBindings.m @@ -80,7 +80,7 @@ - (TUITextEditor *)_textEditor } - (void)_scrollToIndex:(CFIndex)index { - id scrollView = (id )self.view.ancestorScrollView; + id scrollView = self.view.ancestorScrollView; if(scrollView) { // Get the rect for the index passed within the text. diff --git a/lib/UIKit/TUIView.h b/lib/UIKit/TUIView.h index 2500d073..8a3251dd 100644 --- a/lib/UIKit/TUIView.h +++ b/lib/UIKit/TUIView.h @@ -276,8 +276,6 @@ extern CGRect(^TUIViewCenteredLayout)(TUIView*); @end -@class TUIScrollView; - @interface TUIView (TUIViewHierarchy) @property (nonatomic, readonly) TUIView *superview; diff --git a/lib/UIKit/TUIView.m b/lib/UIKit/TUIView.m index 69904395..4ee9225d 100644 --- a/lib/UIKit/TUIView.m +++ b/lib/UIKit/TUIView.m @@ -23,7 +23,6 @@ #import "TUINSWindow.h" #import "TUITextRenderer.h" #import "TUIViewController.h" -#import "TUIScrollView.h" /* * Enable this to debug blending.