refactor to add ViewManager and View structs

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2019-06-26 17:40:31 -04:00 committed by Jakub
parent fbb29afb49
commit ae37f8b1e8
3 changed files with 115 additions and 45 deletions

16
keys.go
View File

@ -12,22 +12,6 @@ type Binding struct {
Handler func(g *gocui.Gui, v *gocui.View) error
}
var bindings = [...]Binding{
Binding{gocui.KeyCtrlC, gocui.ModNone, quit},
Binding{gocui.KeyArrowUp, gocui.ModNone, HandlerCursorDispenser(-1)},
Binding{gocui.KeyArrowDown, gocui.ModNone, HandlerCursorDispenser(1)},
}
func keybindings(g *gocui.Gui) error {
for _, b := range bindings {
// IDEA: I can pass a method instead of a function here
if err := g.SetKeybinding("", b.Key, b.Mod, b.Handler); err != nil {
return err
}
}
return nil
}
func HandlerCursorDispenser(mod int) func(g *gocui.Gui, v *gocui.View) error {
return func(g *gocui.Gui, v *gocui.View) error {
if v == nil {

67
main.go
View File

@ -28,15 +28,48 @@ func main() {
}
defer g.Close()
views := []*View{
&View{
Name: "main",
Title: "Peers",
Placeholder: "Loading peers...",
Cursor: true,
Highlight: true,
Current: true,
SelFgColor: gocui.ColorBlack,
SelBgColor: gocui.ColorGreen,
Keybindings: []Binding{
Binding{gocui.KeyCtrlC, gocui.ModNone, quit},
Binding{gocui.KeyArrowUp, gocui.ModNone, HandlerCursorDispenser(-1)},
Binding{gocui.KeyArrowDown, gocui.ModNone, HandlerCursorDispenser(1)},
},
TopLeft: func(mx, my int) (int, int) {
return 0, 0
},
BotRight: func(mx, my int) (int, int) {
return mx - 1, my / 2
},
},
&View{
Name: "info",
Title: "Details",
Placeholder: "Loading details...",
TopLeft: func(mx, my int) (int, int) {
return 0, my/2 + 1
},
BotRight: func(mx, my int) (int, int) {
return mx - 1, my - 1
},
},
}
vm := NewViewManager(g, views)
g.SelFgColor = gocui.ColorGreen
g.Highlight = true
g.Cursor = true
g.SetManagerFunc(layout)
if err := keybindings(g); err != nil {
log.Panicln(err)
}
g.SetManagerFunc(vm.Layout)
url := fmt.Sprintf("http://%s:%d", host, port)
c, err := newClient(url)
@ -52,30 +85,6 @@ func main() {
}
}
func layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
if v, err := g.SetView("main", 0, 0, maxX-1, maxY/2); err != nil {
if err != gocui.ErrUnknownView {
return err
}
v.SelFgColor = gocui.ColorBlack
v.SelBgColor = gocui.ColorGreen
v.Title = "Peers"
v.Highlight = true
v.SetCursor(0, 0)
g.SetCurrentView("main")
fmt.Fprintln(v, "Loading peers...")
}
if v, err := g.SetView("info", 0, maxY/2+1, maxX-1, maxY-1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
v.Title = "Details"
fmt.Fprintln(v, "Loading details...")
}
return nil
}
func quit(g *gocui.Gui, v *gocui.View) error {
close(threadDone)
return gocui.ErrQuit

77
view.go Normal file
View File

@ -0,0 +1,77 @@
package main
import (
"fmt"
"github.com/jroimartin/gocui"
)
type View struct {
Name string
Title string
Placeholder string
Cursor bool
Current bool
Highlight bool
TopLeft func(int, int) (int, int)
BotRight func(int, int) (int, int)
SelBgColor gocui.Attribute
SelFgColor gocui.Attribute
Keybindings []Binding
Manager ViewManager
}
type ViewManager struct {
g *gocui.Gui
views []*View
}
func NewViewManager(g *gocui.Gui, views []*View) *ViewManager {
vm := ViewManager{
g: g,
views: views,
}
// Attach a ViewManager instance to Views
for _, v := range vm.views {
v.Manager = vm
}
return &vm
}
func (m *ViewManager) Layout(g *gocui.Gui) error {
mx, my := g.Size()
for _, cfg := range m.views {
x0, y0 := cfg.TopLeft(mx, my)
x1, y1 := cfg.BotRight(mx, my)
v, err := g.SetView(cfg.Name, x0, y0, x1, y1)
if err == nil && err != gocui.ErrUnknownView {
return err
}
v.SelFgColor = cfg.SelFgColor
v.SelBgColor = cfg.SelBgColor
v.Title = cfg.Title
v.Highlight = cfg.Highlight
if cfg.Cursor {
v.SetCursor(0, 0)
}
if cfg.Current {
g.SetCurrentView("main")
}
fmt.Fprintln(v, cfg.Placeholder)
cfg.SetKeybindings(g)
}
return nil
}
func (v *View) SetKeybindings(g *gocui.Gui) error {
for _, b := range v.Keybindings {
// IDEA: I can pass a method instead of a function here
if err := g.SetKeybinding("", b.Key, b.Mod, b.Handler); err != nil {
return err
}
}
return nil
}