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  }