1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 1996-2010, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 */ 9 package com.ibm.icu.dev.demo.impl; 10 import java.text.BreakIterator; 11 12 public final class Selection { 13 14 public int anchor; 15 public int caret; 16 public boolean clickAfter; 17 getStart()18 public int getStart() { 19 return anchor < caret ? anchor : caret; 20 } 21 getEnd()22 public int getEnd() { 23 return anchor > caret ? anchor : caret; 24 } 25 isCaret()26 public boolean isCaret() { 27 return anchor == caret; 28 } 29 set(Selection other)30 public Selection set(Selection other) { 31 anchor = other.anchor; 32 caret = other.caret; 33 clickAfter = other.clickAfter; 34 return this; 35 } 36 set(int anchor, int caret, boolean clickAfter)37 public Selection set(int anchor, int caret, boolean clickAfter) { 38 this.anchor = anchor; 39 this.caret = caret; 40 this.clickAfter = clickAfter; 41 return this; 42 } 43 equals(Object other)44 public boolean equals(Object other) { 45 Selection other2 = (Selection)other; 46 return anchor == other2.anchor 47 && caret == other2.caret 48 && clickAfter == other2.clickAfter; 49 } 50 isLessThan(Selection other)51 public boolean isLessThan(Selection other) { 52 return getStart() < other.getEnd(); 53 } 54 pin(String text)55 public Selection pin(String text) { 56 if (anchor > text.length()) { 57 anchor = text.length(); 58 } else if (anchor < 0) { 59 anchor = 0; 60 } 61 if (caret > text.length()) { 62 caret = text.length(); 63 clickAfter = true; 64 } else if (caret < 0) { 65 caret = 0; 66 clickAfter = false; 67 } 68 return this; 69 } 70 swap(Selection after)71 public Selection swap(Selection after) { 72 int temp = anchor; 73 anchor = after.anchor; 74 after.anchor = temp; 75 temp = caret; 76 caret = after.caret; 77 after.caret = temp; 78 boolean b = clickAfter; 79 clickAfter = after.clickAfter; 80 after.clickAfter = b; 81 return this; 82 } 83 fixAfterReplace(int start, int end, int len)84 public Selection fixAfterReplace(int start, int end, int len) { 85 if (anchor >= start) { 86 if (anchor < end) anchor = end; 87 anchor = start + len + anchor - end; 88 } 89 if (caret >= start) { 90 if (caret < end) caret = end; 91 caret = start + len + caret - end; 92 } 93 return this; 94 } 95 96 // Mac & Windows considerably different 97 // Mac: end++. If start!=end, start=end 98 // SHIFT: move end right 99 // CTL: no different 100 // Windows: 101 // UNSHIFTED: if start!=end, start = end, else start=end=end+1; 102 // anchor = tip = start 103 // SHIFT: tip++ 104 // CTL: if start!=end, start = end = nextbound(end-1), 105 // else start=end=nextbound(end) 106 // anchor = tip = start 107 // CTL/SHIFT: tip = nextbound(tip) 108 nextBound(BreakIterator breaker, int direction, boolean extend)109 public Selection nextBound(BreakIterator breaker, 110 int direction, boolean extend) { 111 if (!extend && anchor != caret) caret -= direction; 112 caret = next(caret, breaker, direction, true); 113 if (!extend) anchor = caret; 114 clickAfter = false; 115 return this; 116 } 117 118 // expand start and end to word breaks--if they are not already on one expand(BreakIterator breaker)119 public void expand(BreakIterator breaker) { 120 if (anchor <= caret) { 121 anchor = next(anchor,breaker,-1,false); 122 caret = next(caret,breaker,1,false); 123 /* 124 try { 125 breaker.following(anchor); 126 anchor = breaker.previous(); 127 } catch (Exception e) {} 128 try { 129 caret = breaker.following(caret-1); 130 } catch (Exception e) {} 131 */ 132 } else { 133 anchor = next(anchor,breaker,1,false); 134 caret = next(caret,breaker,-1,false); 135 /* 136 try { 137 breaker.following(caret); 138 caret = breaker.previous(); 139 } catch (Exception e) {} 140 try { 141 anchor = breaker.following(anchor-1); 142 } catch (Exception e) {} 143 */ 144 } 145 } 146 147 // different = false - move to next boundary, unless on one 148 // true - move to next boundary, even if on one next(int position, BreakIterator breaker, int direction, boolean different)149 public static int next(int position, BreakIterator breaker, 150 int direction, boolean different) { 151 if (!different) position -= direction; 152 try { 153 if (direction > 0) { 154 position = breaker.following(position); 155 } else { 156 breaker.following(position-1); 157 position = breaker.previous(); 158 } 159 } catch (Exception e) {} 160 return position; 161 } 162 } 163 164