github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwedit/cursor.go (about) 1 package rwedit 2 3 type Cursor interface { 4 Set(c SimpleCursor) 5 Get() SimpleCursor 6 7 Index() int 8 SetIndex(int) 9 SelectionIndex() int 10 SetSelection(si, ci int) 11 SetSelectionOff() 12 SetIndexSelectionOff(i int) 13 HaveSelection() bool 14 UpdateSelection(on bool, ci int) 15 SelectionIndexes() (int, int, bool) 16 SelectionIndexesUnsorted() (int, int, bool) 17 } 18 19 //---------- 20 21 type SimpleCursor struct { 22 index int 23 sel struct { // selection 24 on bool 25 index int 26 } 27 } 28 29 func (c *SimpleCursor) Set(c2 SimpleCursor) { 30 *c = c2 31 } 32 func (c *SimpleCursor) Get() SimpleCursor { 33 return *c 34 } 35 36 //---------- 37 38 func (c *SimpleCursor) Index() int { 39 return c.index 40 } 41 func (c *SimpleCursor) SetIndex(i int) { 42 c.index = i 43 } 44 func (c *SimpleCursor) SelectionIndex() int { 45 return c.sel.index 46 } 47 func (c *SimpleCursor) SetSelection(si, ci int) { // start/finish 48 c.sel.on = true 49 c.sel.index = si 50 c.index = ci 51 } 52 func (c *SimpleCursor) SetSelectionOff() { 53 c.sel.on = false 54 c.sel.index = 0 55 } 56 func (c *SimpleCursor) SetIndexSelectionOff(i int) { 57 c.index = i 58 c.sel.on = false 59 c.sel.index = 0 60 } 61 62 //---------- 63 64 func (c *SimpleCursor) HaveSelection() bool { 65 return c.sel.on && c.sel.index != c.index 66 } 67 68 //---------- 69 70 func (c *SimpleCursor) UpdateSelection(on bool, ci int) { 71 if on { 72 si := c.sel.index 73 if !c.sel.on { 74 si = c.index 75 } 76 if si == ci { 77 c.SetIndexSelectionOff(ci) 78 } else { 79 c.SetSelection(si, ci) 80 } 81 } else { 82 c.SetIndexSelectionOff(ci) 83 } 84 } 85 86 //---------- 87 88 // Values returned are sorted 89 func (c *SimpleCursor) SelectionIndexes() (int, int, bool) { 90 if !c.HaveSelection() { 91 return 0, 0, false 92 } 93 a, b := c.index, c.sel.index 94 if a > b { 95 a, b = b, a 96 } 97 return a, b, true 98 } 99 100 func (c *SimpleCursor) SelectionIndexesUnsorted() (int, int, bool) { 101 if !c.HaveSelection() { 102 return 0, 0, false 103 } 104 return c.sel.index, c.index, true // start/finish (can be finish<start) 105 } 106 107 //---------- 108 109 type TriggerCursor struct { 110 *SimpleCursor 111 c *SimpleCursor 112 onChange func() 113 } 114 115 func NewTriggerCursor(onChange func()) *TriggerCursor { 116 tc := &TriggerCursor{onChange: onChange} 117 c := &SimpleCursor{} 118 tc.SimpleCursor = c 119 tc.c = c 120 return tc 121 } 122 123 //---------- 124 125 func (tc *TriggerCursor) Set(c SimpleCursor) { 126 tmp := tc.copy() 127 *tc.SimpleCursor = c 128 tc.changed(tmp) 129 } 130 func (tc *TriggerCursor) SetIndex(i int) { 131 tmp := tc.copy() 132 tc.c.SetIndex(i) 133 tc.changed(tmp) 134 } 135 func (tc *TriggerCursor) SetSelection(si, ci int) { // start/finish 136 tmp := tc.copy() 137 tc.c.SetSelection(si, ci) 138 tc.changed(tmp) 139 } 140 func (tc *TriggerCursor) SetSelectionOff() { 141 tmp := tc.copy() 142 tc.c.SetSelectionOff() 143 tc.changed(tmp) 144 } 145 func (tc *TriggerCursor) SetIndexSelectionOff(i int) { 146 tmp := tc.copy() 147 tc.c.SetIndexSelectionOff(i) 148 tc.changed(tmp) 149 } 150 func (tc *TriggerCursor) UpdateSelection(on bool, ci int) { 151 tmp := tc.copy() 152 tc.c.UpdateSelection(on, ci) 153 tc.changed(tmp) 154 } 155 156 //---------- 157 158 func (tc *TriggerCursor) copy() SimpleCursor { 159 return *tc.SimpleCursor 160 } 161 func (tc *TriggerCursor) changed(c SimpleCursor) { 162 if tc.onChange == nil { 163 return 164 } 165 if c != *tc.c { 166 tc.onChange() 167 } 168 }