1package checklist 2 3// Checklist is a module for creating generic checklist implementations 4// See 'Todo' for an implementation example 5type Checklist struct { 6 Items []*ChecklistItem 7 8 checkedIcon string 9 selected int 10 uncheckedIcon string 11} 12 13func NewChecklist(checkedIcon, uncheckedIcon string) Checklist { 14 list := Checklist{ 15 checkedIcon: checkedIcon, 16 selected: -1, 17 uncheckedIcon: uncheckedIcon, 18 } 19 20 return list 21} 22 23/* -------------------- Exported Functions -------------------- */ 24 25// Add creates a new item in the checklist 26func (list *Checklist) Add(checked bool, text string) { 27 item := NewChecklistItem( 28 checked, 29 text, 30 list.checkedIcon, 31 list.uncheckedIcon, 32 ) 33 34 list.Items = append([]*ChecklistItem{item}, list.Items...) 35} 36 37// CheckedItems returns a slice of all the checked items 38func (list *Checklist) CheckedItems() []*ChecklistItem { 39 items := []*ChecklistItem{} 40 41 for _, item := range list.Items { 42 if item.Checked { 43 items = append(items, item) 44 } 45 } 46 47 return items 48} 49 50// Delete removes the selected item from the checklist 51func (list *Checklist) Delete() { 52 list.Items = append(list.Items[:list.selected], list.Items[list.selected+1:]...) 53 list.Prev() 54} 55 56// IsSelectable returns true if the checklist has selectable items, false if it does not 57func (list *Checklist) IsSelectable() bool { 58 return list.selected >= 0 && list.selected < len(list.Items) 59} 60 61// IsUnselectable returns true if the checklist has no selectable items, false if it does 62func (list *Checklist) IsUnselectable() bool { 63 return !list.IsSelectable() 64} 65 66// LongestLine returns the length of the longest checklist item's text 67func (list *Checklist) LongestLine() int { 68 maxLen := 0 69 70 for _, item := range list.Items { 71 if len(item.Text) > maxLen { 72 maxLen = len(item.Text) 73 } 74 } 75 76 return maxLen 77} 78 79func (list *Checklist) Selected() int { 80 return list.selected 81} 82 83// SelectedItem returns the currently-selected checklist item or nil if no item is selected 84func (list *Checklist) SelectedItem() *ChecklistItem { 85 if list.IsUnselectable() { 86 return nil 87 } 88 89 return list.Items[list.selected] 90} 91 92func (list *Checklist) SetSelectedByItem(selectableItem *ChecklistItem) { 93 for idx, item := range list.Items { 94 if item == selectableItem { 95 list.selected = idx 96 break 97 } 98 } 99} 100 101// Toggle switches the checked state of the currently-selected item 102func (list *Checklist) Toggle() { 103 if list.IsUnselectable() { 104 return 105 } 106 107 list.SelectedItem().Toggle() 108} 109 110// UncheckedItems returns a slice of all the unchecked items 111func (list *Checklist) UncheckedItems() []*ChecklistItem { 112 items := []*ChecklistItem{} 113 114 for _, item := range list.Items { 115 if !item.Checked { 116 items = append(items, item) 117 } 118 } 119 120 return items 121} 122 123// Unselect removes the current select such that no item is selected 124func (list *Checklist) Unselect() { 125 list.selected = -1 126} 127 128// Update sets the text of the currently-selected item to the provided text 129func (list *Checklist) Update(text string) { 130 item := list.SelectedItem() 131 132 if item == nil { 133 return 134 } 135 136 item.Text = text 137} 138 139/* -------------------- Item Movement -------------------- */ 140 141// Prev selects the previous item UP in the checklist 142func (list *Checklist) Prev() { 143 list.selected-- 144 if list.selected < 0 { 145 list.selected = len(list.Items) - 1 146 } 147} 148 149// Next selects the next item DOWN in the checklist 150func (list *Checklist) Next() { 151 list.selected++ 152 if list.selected >= len(list.Items) { 153 list.selected = 0 154 } 155} 156 157// Promote moves the selected item UP in the checklist 158func (list *Checklist) Promote() { 159 if list.IsUnselectable() { 160 return 161 } 162 163 k := list.selected - 1 164 if k < 0 { 165 k = len(list.Items) - 1 166 } 167 168 list.Swap(list.selected, k) 169 list.selected = k 170} 171 172// Demote moves the selected item DOWN in the checklist 173func (list *Checklist) Demote() { 174 if list.IsUnselectable() { 175 return 176 } 177 178 j := list.selected + 1 179 if j >= len(list.Items) { 180 j = 0 181 } 182 183 list.Swap(list.selected, j) 184 list.selected = j 185} 186 187/* -------------------- Sort Interface -------------------- */ 188 189func (list *Checklist) Len() int { 190 return len(list.Items) 191} 192 193func (list *Checklist) Less(i, j int) bool { 194 return list.Items[i].Text < list.Items[j].Text 195} 196 197func (list *Checklist) Swap(i, j int) { 198 list.Items[i], list.Items[j] = list.Items[j], list.Items[i] 199} 200