diff --git a/weather/widget.go b/weather/widget.go index 24572f18..60300de0 100644 --- a/weather/widget.go +++ b/weather/widget.go @@ -36,6 +36,7 @@ func (widget *Widget) Refresh() { data := Fetch(wtf.ToInts(Config.UList("wtf.mods.weather.cityids", widget.defaultCityCodes()))) + //widget.SetBorder() widget.View.Clear() widget.contentFor(data) widget.RefreshedAt = time.Now() diff --git a/wtf.go b/wtf.go index 73174eab..5af139ab 100644 --- a/wtf.go +++ b/wtf.go @@ -4,6 +4,7 @@ import ( "flag" "os" "time" + //"math/rand" "github.com/gdamore/tcell" "github.com/olebedev/config" @@ -35,7 +36,7 @@ func addToGrid(grid *tview.Grid, widget wtf.TextViewer) { widget.Width(), 0, 0, - false, // has focus + false, ) } @@ -54,22 +55,29 @@ func buildGrid(modules []wtf.TextViewer) *tview.Grid { return grid } -// FIXME: Not a fan of how this function has to reach outside itself, grab -// Modules, and then operate on them. Should be able to pass that in instead func keyboardIntercept(event *tcell.EventKey) *tcell.EventKey { - // Ctrl-R: force-refreshes every widget - if event.Key() == tcell.KeyCtrlR { - for _, module := range Widgets { - go module.Refresh() - } - } else if event.Key() == tcell.KeyTab { + switch event.Key() { + case tcell.KeyCtrlR: + refreshAllModules() + case tcell.KeyTab: + FocusTracker.Next() + case tcell.KeyBacktab: + FocusTracker.Prev() + case tcell.KeyEsc: + FocusTracker.None() + default: + return event } return event } -func refresher(app *tview.Application) { - tick := time.NewTicker(time.Duration(Config.UInt("wtf.refreshInterval", 1)) * time.Second) +// redrawApp redraws the rendered views to screen on a defined interval (set in config.yml) +// Use this because each textView widget can have it's own update interval, and I don't want to +// manage drawing co-ordination amongst them all. If you need to have a +// widget redraw on it's own schedule, use the view's SetChangedFunc() and pass it `app`. +func redrawApp(app *tview.Application) { + tick := time.NewTicker(time.Duration(Config.UInt("wtf.refreshInterval", 2)) * time.Second) quit := make(chan struct{}) for { @@ -83,9 +91,16 @@ func refresher(app *tview.Application) { } } +func refreshAllModules() { + for _, module := range Widgets { + go module.Refresh() + } +} + var result = wtf.CreateConfigDir() var Config *config.Config +var FocusTracker wtf.FocusTracker var Widgets []wtf.TextViewer /* -------------------- Main -------------------- */ @@ -128,8 +143,14 @@ func main() { app := tview.NewApplication() app.SetInputCapture(keyboardIntercept) + FocusTracker = wtf.FocusTracker{ + App: app, + Idx: 0, + Widgets: Widgets, + } + // Loop in a routine to redraw the screen - go refresher(app) + go redrawApp(app) grid := buildGrid(Widgets) if err := app.SetRoot(grid, true).Run(); err != nil { diff --git a/wtf/config_files.go b/wtf/config_files.go index eeb28c5d..8e9b8c82 100644 --- a/wtf/config_files.go +++ b/wtf/config_files.go @@ -18,6 +18,7 @@ func CreateConfigDir() bool { panic(err) } } + return true } diff --git a/wtf/focus_tracker.go b/wtf/focus_tracker.go new file mode 100644 index 00000000..bb008d33 --- /dev/null +++ b/wtf/focus_tracker.go @@ -0,0 +1,60 @@ +package wtf + +import ( + "github.com/rivo/tview" + "github.com/senorprogrammer/wtf/color" +) + +type FocusTracker struct { + App *tview.Application + Idx int + Widgets []TextViewer +} + +/* -------------------- Exported Functions -------------------- */ + +func (tracker *FocusTracker) Next() { + tracker.blur(tracker.Idx) + tracker.increment() + tracker.focus(tracker.Idx) +} + +func (tracker *FocusTracker) None() { + tracker.blur(tracker.Idx) +} + +func (tracker *FocusTracker) Prev() { + tracker.blur(tracker.Idx) + tracker.decrement() + tracker.focus(tracker.Idx) +} + +/* -------------------- Exported Functions -------------------- */ + +func (tracker *FocusTracker) blur(idx int) { + view := tracker.Widgets[idx].TextView() + view.Blur() + view.SetBorderColor(color.ColorFor(Config.UString("wtf.border.normal"))) +} + +func (tracker *FocusTracker) decrement() { + tracker.Idx = tracker.Idx - 1 + + if tracker.Idx < 0 { + tracker.Idx = len(tracker.Widgets) - 1 + } +} + +func (tracker *FocusTracker) focus(idx int) { + view := tracker.Widgets[idx].TextView() + tracker.App.SetFocus(view) + view.SetBorderColor(color.ColorFor(Config.UString("wtf.border.focus"))) +} + +func (tracker *FocusTracker) increment() { + tracker.Idx = tracker.Idx + 1 + + if tracker.Idx == len(tracker.Widgets) { + tracker.Idx = 0 + } +} diff --git a/wtf/text_widget.go b/wtf/text_widget.go index 606c04e8..3b85601f 100644 --- a/wtf/text_widget.go +++ b/wtf/text_widget.go @@ -40,20 +40,20 @@ func NewTextWidget(name string, configKey string) TextWidget { return widget } -func (widget *TextWidget) addView() { - view := tview.NewTextView() - - view.SetBorder(true) - view.SetBorderColor(color.ColorFor(Config.UString("wtf.border.normal"))) - view.SetDynamicColors(true) - view.SetTitle(widget.Name) - view.SetWrap(false) - - widget.View = view -} - /* -------------------- Exported Functions -------------------- */ +//func (widget *TextWidget) SetBorder() { + //var colorName string + + //if widget.View.HasFocus() { + //colorName = Config.UString("wtf.border.normal") + //} else { + //colorName = Config.UString("wtf.border.focus") + //} + + //widget.View.SetBorderColor(color.ColorFor(colorName)) +//} + func (widget *TextWidget) Disabled() bool { return !widget.Enabled() } @@ -69,3 +69,18 @@ func (widget *TextWidget) RefreshInterval() int { func (widget *TextWidget) TextView() *tview.TextView { return widget.View } + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *TextWidget) addView() { + view := tview.NewTextView() + + view.SetBorder(true) + view.SetBorderColor(color.ColorFor(Config.UString("wtf.border.normal"))) + view.SetDynamicColors(true) + view.SetTitle(widget.Name) + view.SetWrap(false) + + widget.View = view +} +