New file |
| | |
| | | // |
| | | // YYTextInput.m |
| | | // YYText <https://github.com/ibireme/YYText> |
| | | // |
| | | // Created by ibireme on 15/4/17. |
| | | // Copyright (c) 2015 ibireme. |
| | | // |
| | | // This source code is licensed under the MIT-style license found in the |
| | | // LICENSE file in the root directory of this source tree. |
| | | // |
| | | |
| | | #import "YYTextInput.h" |
| | | #import "YYTextUtilities.h" |
| | | |
| | | |
| | | @implementation YYTextPosition |
| | | |
| | | + (instancetype)positionWithOffset:(NSInteger)offset { |
| | | return [self positionWithOffset:offset affinity:YYTextAffinityForward]; |
| | | } |
| | | |
| | | + (instancetype)positionWithOffset:(NSInteger)offset affinity:(YYTextAffinity)affinity { |
| | | YYTextPosition *p = [self new]; |
| | | p->_offset = offset; |
| | | p->_affinity = affinity; |
| | | return p; |
| | | } |
| | | |
| | | - (instancetype)copyWithZone:(NSZone *)zone { |
| | | return [self.class positionWithOffset:_offset affinity:_affinity]; |
| | | } |
| | | |
| | | - (NSString *)description { |
| | | return [NSString stringWithFormat:@"<%@: %p> (%@%@)", self.class, self, @(_offset), _affinity == YYTextAffinityForward ? @"F":@"B"]; |
| | | } |
| | | |
| | | - (NSUInteger)hash { |
| | | return _offset * 2 + (_affinity == YYTextAffinityForward ? 1 : 0); |
| | | } |
| | | |
| | | - (BOOL)isEqual:(YYTextPosition *)object { |
| | | if (!object) return NO; |
| | | return _offset == object.offset && _affinity == object.affinity; |
| | | } |
| | | |
| | | - (NSComparisonResult)compare:(YYTextPosition *)otherPosition { |
| | | if (!otherPosition) return NSOrderedAscending; |
| | | if (_offset < otherPosition.offset) return NSOrderedAscending; |
| | | if (_offset > otherPosition.offset) return NSOrderedDescending; |
| | | if (_affinity == YYTextAffinityBackward && otherPosition.affinity == YYTextAffinityForward) return NSOrderedAscending; |
| | | if (_affinity == YYTextAffinityForward && otherPosition.affinity == YYTextAffinityBackward) return NSOrderedDescending; |
| | | return NSOrderedSame; |
| | | } |
| | | |
| | | @end |
| | | |
| | | |
| | | |
| | | @implementation YYTextRange { |
| | | YYTextPosition *_start; |
| | | YYTextPosition *_end; |
| | | } |
| | | |
| | | - (instancetype)init { |
| | | self = [super init]; |
| | | if (!self) return nil; |
| | | _start = [YYTextPosition positionWithOffset:0]; |
| | | _end = [YYTextPosition positionWithOffset:0]; |
| | | return self; |
| | | } |
| | | |
| | | - (YYTextPosition *)start { |
| | | return _start; |
| | | } |
| | | |
| | | - (YYTextPosition *)end { |
| | | return _end; |
| | | } |
| | | |
| | | - (BOOL)isEmpty { |
| | | return _start.offset == _end.offset; |
| | | } |
| | | |
| | | - (NSRange)asRange { |
| | | return NSMakeRange(_start.offset, _end.offset - _start.offset); |
| | | } |
| | | |
| | | + (instancetype)rangeWithRange:(NSRange)range { |
| | | return [self rangeWithRange:range affinity:YYTextAffinityForward]; |
| | | } |
| | | |
| | | + (instancetype)rangeWithRange:(NSRange)range affinity:(YYTextAffinity)affinity { |
| | | YYTextPosition *start = [YYTextPosition positionWithOffset:range.location affinity:affinity]; |
| | | YYTextPosition *end = [YYTextPosition positionWithOffset:range.location + range.length affinity:affinity]; |
| | | return [self rangeWithStart:start end:end]; |
| | | } |
| | | |
| | | + (instancetype)rangeWithStart:(YYTextPosition *)start end:(YYTextPosition *)end { |
| | | if (!start || !end) return nil; |
| | | if ([start compare:end] == NSOrderedDescending) { |
| | | YYTEXT_SWAP(start, end); |
| | | } |
| | | YYTextRange *range = [YYTextRange new]; |
| | | range->_start = start; |
| | | range->_end = end; |
| | | return range; |
| | | } |
| | | |
| | | + (instancetype)defaultRange { |
| | | return [self new]; |
| | | } |
| | | |
| | | - (instancetype)copyWithZone:(NSZone *)zone { |
| | | return [self.class rangeWithStart:_start end:_end]; |
| | | } |
| | | |
| | | - (NSString *)description { |
| | | return [NSString stringWithFormat:@"<%@: %p> (%@, %@)%@", self.class, self, @(_start.offset), @(_end.offset - _start.offset), _end.affinity == YYTextAffinityForward ? @"F":@"B"]; |
| | | } |
| | | |
| | | - (NSUInteger)hash { |
| | | return (sizeof(NSUInteger) == 8 ? OSSwapInt64(_start.hash) : OSSwapInt32(_start.hash)) + _end.hash; |
| | | } |
| | | |
| | | - (BOOL)isEqual:(YYTextRange *)object { |
| | | if (!object) return NO; |
| | | return [_start isEqual:object.start] && [_end isEqual:object.end]; |
| | | } |
| | | |
| | | @end |
| | | |
| | | |
| | | |
| | | @implementation YYTextSelectionRect |
| | | |
| | | @synthesize rect = _rect; |
| | | @synthesize writingDirection = _writingDirection; |
| | | @synthesize containsStart = _containsStart; |
| | | @synthesize containsEnd = _containsEnd; |
| | | @synthesize isVertical = _isVertical; |
| | | |
| | | - (id)copyWithZone:(NSZone *)zone { |
| | | YYTextSelectionRect *one = [self.class new]; |
| | | one.rect = _rect; |
| | | one.writingDirection = _writingDirection; |
| | | one.containsStart = _containsStart; |
| | | one.containsEnd = _containsEnd; |
| | | one.isVertical = _isVertical; |
| | | return one; |
| | | } |
| | | |
| | | @end |