1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
wtf/checklist/checklist.go
2019-04-18 19:02:08 -07:00

198 lines
4.1 KiB
Go

package checklist
// Checklist is a module for creating generic checklist implementations
// See 'Todo' for an implementation example
type Checklist struct {
Items []*ChecklistItem
checkedIcon string
selected int
uncheckedIcon string
}
func NewChecklist(checkedIcon, uncheckedIcon string) Checklist {
list := Checklist{
checkedIcon: checkedIcon,
selected: -1,
uncheckedIcon: uncheckedIcon,
}
return list
}
/* -------------------- Exported Functions -------------------- */
// Add creates a new item in the checklist
func (list *Checklist) Add(checked bool, text string) {
item := NewChecklistItem(
checked,
text,
list.checkedIcon,
list.uncheckedIcon,
)
list.Items = append([]*ChecklistItem{item}, list.Items...)
}
// CheckedItems returns a slice of all the checked items
func (list *Checklist) CheckedItems() []*ChecklistItem {
items := []*ChecklistItem{}
for _, item := range list.Items {
if item.Checked {
items = append(items, item)
}
}
return items
}
// Delete removes the selected item from the checklist
func (list *Checklist) Delete() {
list.Items = append(list.Items[:list.selected], list.Items[list.selected+1:]...)
list.Prev()
}
// Demote moves the selected item down in the checklist
func (list *Checklist) Demote() {
if list.IsUnselectable() {
return
}
j := list.selected + 1
if j >= len(list.Items) {
j = 0
}
list.Swap(list.selected, j)
list.selected = j
}
// IsSelectable returns true if the checklist has selectable items, false if it does not
func (list *Checklist) IsSelectable() bool {
return list.selected >= 0 && list.selected < len(list.Items)
}
// IsUnselectable returns true if the checklist has no selectable items, false if it does
func (list *Checklist) IsUnselectable() bool {
return !list.IsSelectable()
}
// Next selects the next item in the checklist
func (list *Checklist) Next() {
list.selected = list.selected + 1
if list.selected >= len(list.Items) {
list.selected = 0
}
}
// LongestLine returns the length of the longest checklist item's text
func (list *Checklist) LongestLine() int {
maxLen := 0
for _, item := range list.Items {
if len(item.Text) > maxLen {
maxLen = len(item.Text)
}
}
return maxLen
}
// Prev selects the previous item in the checklist
func (list *Checklist) Prev() {
list.selected = list.selected - 1
if list.selected < 0 {
list.selected = len(list.Items) - 1
}
}
// Promote moves the selected item up in the checklist
func (list *Checklist) Promote() {
if list.IsUnselectable() {
return
}
j := list.selected - 1
if j < 0 {
j = len(list.Items) - 1
}
list.Swap(list.selected, j)
list.selected = j
}
func (list *Checklist) Selected() int {
return list.selected
}
// SelectedItem returns the currently-selected checklist item or nil if no item is selected
func (list *Checklist) SelectedItem() *ChecklistItem {
if list.IsUnselectable() {
return nil
}
return list.Items[list.selected]
}
func (list *Checklist) SetSelectedByItem(selectableItem *ChecklistItem) {
for idx, item := range list.Items {
if item == selectableItem {
list.selected = idx
break
}
}
}
// Toggle switches the checked state of the currently-selected item
func (list *Checklist) Toggle() {
if list.IsUnselectable() {
return
}
list.SelectedItem().Toggle()
}
// UncheckedItems returns a slice of all the unchecked items
func (list *Checklist) UncheckedItems() []*ChecklistItem {
items := []*ChecklistItem{}
for _, item := range list.Items {
if !item.Checked {
items = append(items, item)
}
}
return items
}
// Unselect removes the current select such that no item is selected
func (list *Checklist) Unselect() {
list.selected = -1
}
// Update sets the text of the currently-selected item to the provided text
func (list *Checklist) Update(text string) {
item := list.SelectedItem()
if item == nil {
return
}
item.Text = text
}
/* -------------------- Sort Interface -------------------- */
func (list *Checklist) Len() int {
return len(list.Items)
}
func (list *Checklist) Less(i, j int) bool {
return list.Items[i].Text < list.Items[j].Text
}
func (list *Checklist) Swap(i, j int) {
list.Items[i], list.Items[j] = list.Items[j], list.Items[i]
}