mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Basic selectable todo functionality working
Can: - move between todo items - toggle checked/unchecked state Cannot: - persiste changes to file - add items - delete items
This commit is contained in:
31
todo/display.go
Normal file
31
todo/display.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package todo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (widget *Widget) display() {
|
||||
widget.View.Clear()
|
||||
|
||||
title := fmt.Sprintf(" 📝 %s ", widget.FilePath)
|
||||
widget.View.SetTitle(title)
|
||||
|
||||
str := ""
|
||||
for idx, item := range widget.list.Items {
|
||||
foreColor, backColor := "white", "black"
|
||||
|
||||
if widget.View.HasFocus() && idx == widget.list.selected {
|
||||
foreColor, backColor = "black", "olive"
|
||||
}
|
||||
|
||||
str = str + fmt.Sprintf(
|
||||
"[%s:%s]|%s| %s[white]\n",
|
||||
foreColor,
|
||||
backColor,
|
||||
item.CheckMark(),
|
||||
item.Text,
|
||||
)
|
||||
}
|
||||
|
||||
fmt.Fprintf(widget.View, "%s", str)
|
||||
}
|
||||
29
todo/item.go
Normal file
29
todo/item.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package todo
|
||||
|
||||
import(
|
||||
"time"
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
Checked bool
|
||||
Index int
|
||||
Text string
|
||||
|
||||
createdAt time.Time
|
||||
updatedAt time.Time
|
||||
}
|
||||
|
||||
func (item *Item) CheckMark() string {
|
||||
if item.Checked {
|
||||
return "x"
|
||||
} else {
|
||||
return " "
|
||||
}
|
||||
}
|
||||
|
||||
func (item *Item) Toggle() {
|
||||
item.Checked = !item.Checked
|
||||
item.updatedAt = time.Now()
|
||||
}
|
||||
|
||||
|
||||
44
todo/list.go
Normal file
44
todo/list.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package todo
|
||||
|
||||
import ()
|
||||
|
||||
type List struct {
|
||||
Items []*Item
|
||||
|
||||
selected int
|
||||
}
|
||||
|
||||
func (list *List) Len() int {
|
||||
return len(list.Items)
|
||||
}
|
||||
|
||||
func (list *List) Less(i, j int) bool {
|
||||
return list.Items[i].Index < list.Items[j].Index
|
||||
}
|
||||
|
||||
func (list *List) Swap(i, j int) {
|
||||
list.Items[i], list.Items[j] = list.Items[j], list.Items[i]
|
||||
}
|
||||
|
||||
func (list *List) Next() {
|
||||
list.selected = list.selected + 1
|
||||
if list.selected >= len(list.Items) {
|
||||
list.selected = 0
|
||||
}
|
||||
}
|
||||
|
||||
func (list *List) Prev() {
|
||||
list.selected = list.selected - 1
|
||||
if list.selected < 0 {
|
||||
list.selected = len(list.Items) - 1
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle switches the checked state of the selected item
|
||||
func (list *List) Toggle() {
|
||||
list.Items[list.selected].Toggle()
|
||||
}
|
||||
|
||||
func (list *List) Unselect() {
|
||||
list.selected = -1
|
||||
}
|
||||
101
todo/widget.go
Normal file
101
todo/widget.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package todo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/olebedev/config"
|
||||
"github.com/senorprogrammer/wtf/wtf"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Config is a pointer to the global config object
|
||||
var Config *config.Config
|
||||
|
||||
type Widget struct {
|
||||
wtf.TextWidget
|
||||
|
||||
FilePath string
|
||||
list *List
|
||||
}
|
||||
|
||||
func NewWidget() *Widget {
|
||||
widget := Widget{
|
||||
TextWidget: wtf.NewTextWidget(" 📝 Todo ", "todo"),
|
||||
FilePath: Config.UString("wtf.mods.todo.filename"),
|
||||
|
||||
list: &List{selected: -1},
|
||||
}
|
||||
|
||||
widget.init()
|
||||
widget.View.SetInputCapture(widget.keyboardIntercept)
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) Refresh() {
|
||||
if widget.Disabled() {
|
||||
return
|
||||
}
|
||||
|
||||
confDir, _ := wtf.ConfigDir()
|
||||
|
||||
fileData, _ := wtf.ReadYamlFile(fmt.Sprintf("%s/%s", confDir, widget.FilePath))
|
||||
yaml.Unmarshal(fileData, &widget.list)
|
||||
|
||||
widget.display()
|
||||
widget.RefreshedAt = time.Now()
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) init() {
|
||||
_, err := wtf.CreateFile(widget.FilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey {
|
||||
switch string(event.Rune()) {
|
||||
case " ":
|
||||
// Check/uncheck selected item
|
||||
widget.list.Toggle()
|
||||
widget.display()
|
||||
return nil
|
||||
case "e":
|
||||
// Edit selected item
|
||||
return nil
|
||||
case "n":
|
||||
// Add a new item
|
||||
return nil
|
||||
}
|
||||
|
||||
switch event.Key() {
|
||||
case tcell.KeyCtrlD:
|
||||
// Delete selected item
|
||||
return nil
|
||||
case tcell.KeyDown:
|
||||
widget.list.Next()
|
||||
widget.display()
|
||||
return nil
|
||||
//case tcell.KeySpac:
|
||||
//// Check/uncheck an item
|
||||
//return nil
|
||||
case tcell.KeyEsc:
|
||||
// Unselect the current row and pass the key on through to unselect the widget
|
||||
widget.list.Unselect()
|
||||
widget.display()
|
||||
return event
|
||||
case tcell.KeyUp:
|
||||
// Select next item up
|
||||
widget.list.Prev()
|
||||
widget.display()
|
||||
return nil
|
||||
default:
|
||||
return event
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user