From 2fb1a06ca0384cd7eda73f17ea870dcf6a7fd0a9 Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Wed, 15 May 2019 20:03:58 -0400 Subject: [PATCH] Add Scrollable to todoist widget This is now a multi-source scrollable widget, trying to leverage as much of existing functionality as possible for consistency --- modules/todoist/display.go | 18 +++------ modules/todoist/keyboard.go | 14 ++++--- modules/todoist/project.go | 24 ------------ modules/todoist/widget.go | 73 ++++++++++++++++++++----------------- wtf/scrollable.go | 22 +++++------ 5 files changed, 65 insertions(+), 86 deletions(-) diff --git a/modules/todoist/display.go b/modules/todoist/display.go index fa839f71..f07758b3 100644 --- a/modules/todoist/display.go +++ b/modules/todoist/display.go @@ -24,18 +24,12 @@ func (widget *Widget) display() { maxLen := proj.LongestLine() for index, item := range proj.tasks { - foreColor, backColor := widget.settings.common.Colors.Text, widget.settings.common.Colors.Background - - if index == proj.index { - foreColor = widget.settings.common.Colors.HighlightFore - backColor = widget.settings.common.Colors.HighlightBack - } - row := fmt.Sprintf( - "[%s:%s]| | %s[white]", - foreColor, - backColor, + `["%d"][""][%s]| | %s[%s]`, + index, + widget.RowColor(index), tview.Escape(item.Content), + widget.RowColor(index), ) _, _, w, _ := widget.View.GetInnerRect() @@ -43,8 +37,8 @@ func (widget *Widget) display() { maxLen = w } - str = str + row + wtf.PadRow((checkWidth+len(item.Content)), (checkWidth+maxLen+1)) + "\n" + str = str + row + wtf.PadRow((checkWidth+len(item.Content)), (checkWidth+maxLen+1)) + `[""]` + "\n" } - widget.TextWidget.Redraw(title, str, false) + widget.ScrollableWidget.Redraw(title, str, false) } diff --git a/modules/todoist/keyboard.go b/modules/todoist/keyboard.go index fbd585f2..43381f11 100644 --- a/modules/todoist/keyboard.go +++ b/modules/todoist/keyboard.go @@ -5,15 +5,17 @@ import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp, "Show/hide this help prompt") widget.SetKeyboardChar("r", widget.Refresh, "Refresh widget") - widget.SetKeyboardChar("j", widget.Down, "Select next item") - widget.SetKeyboardChar("k", widget.Up, "Select previous item") - widget.SetKeyboardChar("c", widget.Close, "Close item") widget.SetKeyboardChar("d", widget.Delete, "Delete item") + widget.SetKeyboardChar("j", widget.Prev, "Select previous item") + widget.SetKeyboardChar("k", widget.Next, "Select next item") widget.SetKeyboardChar("h", widget.PrevSource, "Select previous project") + widget.SetKeyboardChar("c", widget.Close, "Close item") widget.SetKeyboardChar("l", widget.NextSource, "Select next project") + widget.SetKeyboardChar("u", widget.Unselect, "Clear selection") - widget.SetKeyboardKey(tcell.KeyRight, widget.NextSource, "Select next project") + widget.SetKeyboardKey(tcell.KeyDown, widget.Next, "Select next item") + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev, "Select previous item") + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect, "Clear selection") widget.SetKeyboardKey(tcell.KeyLeft, widget.PrevSource, "Select previous project") - widget.SetKeyboardKey(tcell.KeyDown, widget.Down, "Select next item") - widget.SetKeyboardKey(tcell.KeyUp, widget.Up, "Select previous item") + widget.SetKeyboardKey(tcell.KeyRight, widget.NextSource, "Select next project") } diff --git a/modules/todoist/project.go b/modules/todoist/project.go index 1f1f6863..b3e39808 100644 --- a/modules/todoist/project.go +++ b/modules/todoist/project.go @@ -32,34 +32,10 @@ func NewProject(id int) *Project { return proj } -func (proj *Project) isFirst() bool { - return proj.index == 0 -} - func (proj *Project) isLast() bool { return proj.index >= len(proj.tasks)-1 } -func (proj *Project) up() { - proj.index-- - - if proj.index < 0 { - proj.index = len(proj.tasks) - 1 - } -} - -func (proj *Project) down() { - if proj.index == -1 { - proj.index = 0 - return - } - - proj.index++ - if proj.index >= len(proj.tasks) { - proj.index = 0 - } -} - func (proj *Project) loadTasks() { tasks, err := todoist.ListTask(todoist.QueryParam{"project_id": fmt.Sprintf("%d", proj.ID)}) if err == nil { diff --git a/modules/todoist/widget.go b/modules/todoist/widget.go index 9600e627..362a82b5 100644 --- a/modules/todoist/widget.go +++ b/modules/todoist/widget.go @@ -1,8 +1,8 @@ package todoist import ( + "fmt" "github.com/darkSasori/todoist" - "github.com/gdamore/tcell" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" ) @@ -10,8 +10,8 @@ import ( // A Widget represents a Todoist widget type Widget struct { wtf.KeyboardWidget - wtf.TextWidget wtf.MultiSourceWidget + wtf.ScrollableWidget projects []*Project settings *Settings @@ -21,8 +21,8 @@ type Widget struct { func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ KeyboardWidget: wtf.NewKeyboardWidget(app, pages, settings.common), - TextWidget: wtf.NewTextWidget(app, settings.common, true), MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common, "project", "projects"), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), settings: settings, } @@ -30,6 +30,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * widget.loadAPICredentials() widget.loadProjects() + widget.SetRenderFunction(widget.display) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) widget.SetDisplayFunction(widget.display) @@ -55,9 +56,11 @@ func (widget *Widget) ProjectAt(idx int) *Project { func (w *Widget) Refresh() { if w.Disabled() || w.CurrentProject() == nil { + w.SetItemCount(0) return } + w.SetItemCount(len(w.CurrentProject().tasks)) w.display() } @@ -65,30 +68,48 @@ func (widget *Widget) HelpText() string { return widget.KeyboardWidget.HelpText() } +func (widget *Widget) NextSource() { + widget.MultiSourceWidget.NextSource() + widget.Selected = widget.CurrentProject().index + widget.SetItemCount(len(widget.CurrentProject().tasks)) + widget.RenderFunction() +} + +func (widget *Widget) PrevSource() { + widget.MultiSourceWidget.PrevSource() + widget.Selected = widget.CurrentProject().index + widget.SetItemCount(len(widget.CurrentProject().tasks)) + widget.RenderFunction() +} + +func (widget *Widget) Prev() { + widget.ScrollableWidget.Prev() + widget.CurrentProject().index = widget.Selected +} + +func (widget *Widget) Next() { + widget.ScrollableWidget.Next() + widget.CurrentProject().index = widget.Selected +} + +func (widget *Widget) Unselect() { + widget.ScrollableWidget.Unselect() + widget.CurrentProject().index = -1 + widget.RenderFunction() +} + /* -------------------- Keyboard Movement -------------------- */ -// Down selects the next item in the list -func (w *Widget) Down() { - w.CurrentProject().down() - w.display() -} - -// Up selects the previous item in the list -func (w *Widget) Up() { - w.CurrentProject().up() - w.display() -} - // Close closes the currently-selected task in the currently-selected project func (w *Widget) Close() { w.CurrentProject().closeSelectedTask() if w.CurrentProject().isLast() { - w.Up() + w.Prev() return } - w.Down() + w.Next() } // Delete deletes the currently-selected task in the currently-selected project @@ -96,11 +117,11 @@ func (w *Widget) Delete() { w.CurrentProject().deleteSelectedTask() if w.CurrentProject().isLast() { - w.Up() + w.Prev() return } - w.Down() + w.Next() } /* -------------------- Unexported Functions -------------------- */ @@ -119,17 +140,3 @@ func (widget *Widget) loadProjects() { widget.projects = projects } - -func (w *Widget) vimBindings(event *tcell.EventKey) tcell.Key { - switch string(event.Rune()) { - case "h": - return tcell.KeyLeft - case "l": - return tcell.KeyRight - case "k": - return tcell.KeyUp - case "j": - return tcell.KeyDown - } - return event.Key() -} diff --git a/wtf/scrollable.go b/wtf/scrollable.go index fe716a32..496151ed 100644 --- a/wtf/scrollable.go +++ b/wtf/scrollable.go @@ -10,7 +10,7 @@ import ( type ScrollableWidget struct { TextWidget - selected int + Selected int maxItems int RenderFunction func() } @@ -36,11 +36,11 @@ func (widget *ScrollableWidget) SetItemCount(items int) { } func (widget *ScrollableWidget) GetSelected() int { - return widget.selected + return widget.Selected } func (widget *ScrollableWidget) RowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { + if widget.View.HasFocus() && (idx == widget.Selected) { return widget.CommonSettings.DefaultFocussedRowColor() } @@ -48,23 +48,23 @@ func (widget *ScrollableWidget) RowColor(idx int) string { } func (widget *ScrollableWidget) Next() { - widget.selected++ - if widget.selected >= widget.maxItems { - widget.selected = 0 + widget.Selected++ + if widget.Selected >= widget.maxItems { + widget.Selected = 0 } widget.RenderFunction() } func (widget *ScrollableWidget) Prev() { - widget.selected-- - if widget.selected < 0 { - widget.selected = widget.maxItems - 1 + widget.Selected-- + if widget.Selected < 0 { + widget.Selected = widget.maxItems - 1 } widget.RenderFunction() } func (widget *ScrollableWidget) Unselect() { - widget.selected = -1 + widget.Selected = -1 if widget.RenderFunction != nil { widget.RenderFunction() } @@ -74,6 +74,6 @@ func (widget *ScrollableWidget) Redraw(title, content string, wrap bool) { widget.TextWidget.Redraw(title, content, wrap) widget.app.QueueUpdateDraw(func() { - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + widget.View.Highlight(strconv.Itoa(widget.Selected)).ScrollToHighlight() }) }