YYTextInput.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //
  2. // YYTextInput.m
  3. // YYKit <https://github.com/ibireme/YYKit>
  4. //
  5. // Created by ibireme on 15/4/17.
  6. // Copyright (c) 2015 ibireme.
  7. //
  8. // This source code is licensed under the MIT-style license found in the
  9. // LICENSE file in the root directory of this source tree.
  10. //
  11. #import "YYTextInput.h"
  12. #import "YYKitMacro.h"
  13. @implementation YYTextPosition
  14. + (instancetype)positionWithOffset:(NSInteger)offset {
  15. return [self positionWithOffset:offset affinity:YYTextAffinityForward];
  16. }
  17. + (instancetype)positionWithOffset:(NSInteger)offset affinity:(YYTextAffinity)affinity {
  18. YYTextPosition *p = [self new];
  19. p->_offset = offset;
  20. p->_affinity = affinity;
  21. return p;
  22. }
  23. - (instancetype)copyWithZone:(NSZone *)zone {
  24. return [self.class positionWithOffset:_offset affinity:_affinity];
  25. }
  26. - (NSString *)description {
  27. return [[NSString alloc] initWithFormat:@"<%@: %p> (%@%@)", self.class, self, @(_offset), _affinity == YYTextAffinityForward ? @"F":@"B"];
  28. }
  29. - (NSUInteger)hash {
  30. return _offset * 2 + (_affinity == YYTextAffinityForward ? 1 : 0);
  31. }
  32. - (BOOL)isEqual:(YYTextPosition *)object {
  33. if (!object) return NO;
  34. return _offset == object.offset && _affinity == object.affinity;
  35. }
  36. - (NSComparisonResult)compare:(YYTextPosition *)otherPosition {
  37. if (!otherPosition) return NSOrderedAscending;
  38. if (_offset < otherPosition.offset) return NSOrderedAscending;
  39. if (_offset > otherPosition.offset) return NSOrderedDescending;
  40. if (_affinity == YYTextAffinityBackward && otherPosition.affinity == YYTextAffinityForward) return NSOrderedAscending;
  41. if (_affinity == YYTextAffinityForward && otherPosition.affinity == YYTextAffinityBackward) return NSOrderedDescending;
  42. return NSOrderedSame;
  43. }
  44. @end
  45. @implementation YYTextRange {
  46. YYTextPosition *_start;
  47. YYTextPosition *_end;
  48. }
  49. - (instancetype)init {
  50. self = [super init];
  51. if (!self) return nil;
  52. _start = [YYTextPosition positionWithOffset:0];
  53. _end = [YYTextPosition positionWithOffset:0];
  54. return self;
  55. }
  56. - (YYTextPosition *)start {
  57. return _start;
  58. }
  59. - (YYTextPosition *)end {
  60. return _end;
  61. }
  62. - (BOOL)isEmpty {
  63. return _start.offset == _end.offset;
  64. }
  65. - (NSRange)asRange {
  66. return NSMakeRange(_start.offset, _end.offset - _start.offset);
  67. }
  68. + (instancetype)rangeWithRange:(NSRange)range {
  69. return [self rangeWithRange:range affinity:YYTextAffinityForward];
  70. }
  71. + (instancetype)rangeWithRange:(NSRange)range affinity:(YYTextAffinity)affinity {
  72. YYTextPosition *start = [YYTextPosition positionWithOffset:range.location affinity:affinity];
  73. YYTextPosition *end = [YYTextPosition positionWithOffset:range.location + range.length affinity:affinity];
  74. return [self rangeWithStart:start end:end];
  75. }
  76. + (instancetype)rangeWithStart:(YYTextPosition *)start end:(YYTextPosition *)end {
  77. if (!start || !end) return nil;
  78. if ([start compare:end] == NSOrderedDescending) {
  79. YY_SWAP(start, end);
  80. }
  81. YYTextRange *range = [YYTextRange new];
  82. range->_start = start;
  83. range->_end = end;
  84. return range;
  85. }
  86. + (instancetype)defaultRange {
  87. return [self new];
  88. }
  89. - (instancetype)copyWithZone:(NSZone *)zone {
  90. return [self.class rangeWithStart:_start end:_end];
  91. }
  92. - (NSString *)description {
  93. return [[NSString alloc] initWithFormat:@"<%@: %p> (%@, %@)%@", self.class, self, @(_start.offset), @(_end.offset - _start.offset), _end.affinity == YYTextAffinityForward ? @"F":@"B"];
  94. }
  95. - (NSUInteger)hash {
  96. return (sizeof(NSUInteger) == 8 ? OSSwapInt64(_start.hash) : OSSwapInt32(_start.hash)) + _end.hash;
  97. }
  98. - (BOOL)isEqual:(YYTextRange *)object {
  99. if (!object) return NO;
  100. return [_start isEqual:object.start] && [_end isEqual:object.end];
  101. }
  102. @end
  103. @implementation YYTextSelectionRect
  104. @synthesize rect = _rect;
  105. @synthesize writingDirection = _writingDirection;
  106. @synthesize containsStart = _containsStart;
  107. @synthesize containsEnd = _containsEnd;
  108. @synthesize isVertical = _isVertical;
  109. - (id)copyWithZone:(NSZone *)zone {
  110. YYTextSelectionRect *one = [self.class new];
  111. one.rect = _rect;
  112. one.writingDirection = _writingDirection;
  113. one.containsStart = _containsStart;
  114. one.containsEnd = _containsEnd;
  115. one.isVertical = _isVertical;
  116. return one;
  117. }
  118. @end