mirror of
				https://github.com/taigrr/wtf
				synced 2025-01-18 04:03:14 -08:00 
			
		
		
		
	
		
			
				
	
	
		
			218 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package todo
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 
 | |
| 	"github.com/gdamore/tcell"
 | |
| 	"github.com/rivo/tview"
 | |
| 	"github.com/wtfutil/wtf/cfg"
 | |
| 	"github.com/wtfutil/wtf/checklist"
 | |
| 	"github.com/wtfutil/wtf/utils"
 | |
| 	"github.com/wtfutil/wtf/view"
 | |
| 	"github.com/wtfutil/wtf/wtf"
 | |
| 	"gopkg.in/yaml.v2"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	offscreen   = -1000
 | |
| 	modalWidth  = 80
 | |
| 	modalHeight = 7
 | |
| )
 | |
| 
 | |
| // A Widget represents a Todo widget
 | |
| type Widget struct {
 | |
| 	view.KeyboardWidget
 | |
| 	view.TextWidget
 | |
| 
 | |
| 	app      *tview.Application
 | |
| 	settings *Settings
 | |
| 	filePath string
 | |
| 	list     checklist.Checklist
 | |
| 	pages    *tview.Pages
 | |
| }
 | |
| 
 | |
| // NewWidget creates a new instance of a widget
 | |
| func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
 | |
| 	widget := Widget{
 | |
| 		KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
 | |
| 		TextWidget:     view.NewTextWidget(app, settings.common, true),
 | |
| 
 | |
| 		app:      app,
 | |
| 		settings: settings,
 | |
| 		filePath: settings.filePath,
 | |
| 		list:     checklist.NewChecklist(settings.common.Sigils.Checkbox.Checked, settings.common.Sigils.Checkbox.Unchecked),
 | |
| 		pages:    pages,
 | |
| 	}
 | |
| 
 | |
| 	widget.init()
 | |
| 
 | |
| 	widget.initializeKeyboardControls()
 | |
| 	widget.View.SetInputCapture(widget.InputCapture)
 | |
| 
 | |
| 	widget.View.SetRegions(true)
 | |
| 	widget.View.SetScrollable(true)
 | |
| 
 | |
| 	widget.KeyboardWidget.SetView(widget.View)
 | |
| 
 | |
| 	return &widget
 | |
| }
 | |
| 
 | |
| /* -------------------- Exported Functions -------------------- */
 | |
| 
 | |
| func (widget *Widget) Refresh() {
 | |
| 	widget.load()
 | |
| 	widget.display()
 | |
| }
 | |
| 
 | |
| func (widget *Widget) SetList(list checklist.Checklist) {
 | |
| 	widget.list = list
 | |
| }
 | |
| 
 | |
| func (widget *Widget) HelpText() string {
 | |
| 	return widget.KeyboardWidget.HelpText()
 | |
| }
 | |
| 
 | |
| /* -------------------- Unexported Functions -------------------- */
 | |
| 
 | |
| // edit opens a modal dialog that permits editing the text of the currently-selected item
 | |
| func (widget *Widget) editSelected() {
 | |
| 	if widget.list.SelectedItem() == nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	form := widget.modalForm("Edit:", widget.list.SelectedItem().Text)
 | |
| 
 | |
| 	saveFctn := func() {
 | |
| 		text := form.GetFormItem(0).(*tview.InputField).GetText()
 | |
| 
 | |
| 		widget.list.Update(text)
 | |
| 		widget.persist()
 | |
| 		widget.pages.RemovePage("modal")
 | |
| 		widget.app.SetFocus(widget.View)
 | |
| 		widget.display()
 | |
| 	}
 | |
| 
 | |
| 	widget.addButtons(form, saveFctn)
 | |
| 	widget.modalFocus(form)
 | |
| }
 | |
| 
 | |
| func (widget *Widget) init() {
 | |
| 	_, err := cfg.CreateFile(widget.filePath)
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Loads the todo list from Yaml file
 | |
| func (widget *Widget) load() {
 | |
| 	confDir, _ := cfg.WtfConfigDir()
 | |
| 	filePath := fmt.Sprintf("%s/%s", confDir, widget.filePath)
 | |
| 
 | |
| 	fileData, _ := utils.ReadFileBytes(filePath)
 | |
| 
 | |
| 	yaml.Unmarshal(fileData, &widget.list)
 | |
| 
 | |
| 	widget.setItemChecks()
 | |
| }
 | |
| 
 | |
| func (widget *Widget) newItem() {
 | |
| 	form := widget.modalForm("New Todo:", "")
 | |
| 
 | |
| 	saveFctn := func() {
 | |
| 		text := form.GetFormItem(0).(*tview.InputField).GetText()
 | |
| 
 | |
| 		widget.list.Add(false, text)
 | |
| 		widget.persist()
 | |
| 		widget.pages.RemovePage("modal")
 | |
| 		widget.app.SetFocus(widget.View)
 | |
| 		widget.display()
 | |
| 	}
 | |
| 
 | |
| 	widget.addButtons(form, saveFctn)
 | |
| 	widget.modalFocus(form)
 | |
| 
 | |
| 	widget.app.QueueUpdate(func() {
 | |
| 		widget.app.Draw()
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // persist writes the todo list to Yaml file
 | |
| func (widget *Widget) persist() {
 | |
| 	confDir, _ := cfg.WtfConfigDir()
 | |
| 	filePath := fmt.Sprintf("%s/%s", confDir, widget.filePath)
 | |
| 
 | |
| 	fileData, _ := yaml.Marshal(&widget.list)
 | |
| 
 | |
| 	err := ioutil.WriteFile(filePath, fileData, 0644)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // setItemChecks rolls through the checklist and ensures that all checklist
 | |
| // items have the correct checked/unchecked icon per the user's preferences
 | |
| func (widget *Widget) setItemChecks() {
 | |
| 	for _, item := range widget.list.Items {
 | |
| 		item.CheckedIcon = widget.settings.common.Checkbox.Checked
 | |
| 		item.UncheckedIcon = widget.settings.common.Checkbox.Unchecked
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /* -------------------- Modal Form -------------------- */
 | |
| 
 | |
| func (widget *Widget) addButtons(form *tview.Form, saveFctn func()) {
 | |
| 	widget.addSaveButton(form, saveFctn)
 | |
| 	widget.addCancelButton(form)
 | |
| }
 | |
| 
 | |
| func (widget *Widget) addCancelButton(form *tview.Form) {
 | |
| 	cancelFn := func() {
 | |
| 		widget.pages.RemovePage("modal")
 | |
| 		widget.app.SetFocus(widget.View)
 | |
| 		widget.display()
 | |
| 	}
 | |
| 
 | |
| 	form.AddButton("Cancel", cancelFn)
 | |
| 	form.SetCancelFunc(cancelFn)
 | |
| }
 | |
| 
 | |
| func (widget *Widget) addSaveButton(form *tview.Form, fctn func()) {
 | |
| 	form.AddButton("Save", fctn)
 | |
| }
 | |
| 
 | |
| func (widget *Widget) modalFocus(form *tview.Form) {
 | |
| 	widget.app.QueueUpdateDraw(func() {
 | |
| 		frame := widget.modalFrame(form)
 | |
| 		widget.pages.AddPage("modal", frame, false, true)
 | |
| 		widget.app.SetFocus(frame)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func (widget *Widget) modalForm(lbl, text string) *tview.Form {
 | |
| 	form := tview.NewForm().SetFieldBackgroundColor(wtf.ColorFor(widget.settings.common.Colors.Background))
 | |
| 	form.SetButtonsAlign(tview.AlignCenter).SetButtonTextColor(wtf.ColorFor(widget.settings.common.Colors.Text))
 | |
| 
 | |
| 	form.AddInputField(lbl, text, 60, nil, nil)
 | |
| 
 | |
| 	return form
 | |
| }
 | |
| 
 | |
| func (widget *Widget) modalFrame(form *tview.Form) *tview.Frame {
 | |
| 	frame := tview.NewFrame(form).SetBorders(0, 0, 0, 0, 0, 0)
 | |
| 	frame.SetRect(offscreen, offscreen, modalWidth, modalHeight)
 | |
| 	frame.SetBorder(true)
 | |
| 	frame.SetBorders(1, 1, 0, 0, 1, 1)
 | |
| 
 | |
| 	drawFunc := func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) {
 | |
| 		w, h := screen.Size()
 | |
| 		frame.SetRect((w/2)-(width/2), (h/2)-(height/2), width, height)
 | |
| 		return x, y, width, height
 | |
| 	}
 | |
| 
 | |
| 	frame.SetDrawFunc(drawFunc)
 | |
| 
 | |
| 	return frame
 | |
| }
 |