From ee25f80a9c1ca781164dad1cb040eb3c6718ba93 Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Thu, 2 Jan 2020 14:00:55 +0000 Subject: [PATCH] integrate widget order, toggling into global config and compact grid --- config/file.go | 15 +++++ config/main.go | 15 +++-- config/param.go | 10 ++- config/switch.go | 17 +++++- config/widget.go | 122 +++++++++++++++++++++++++++++++++++++ cwidgets/compact/gauge.go | 1 + cwidgets/compact/grid.go | 14 +++-- cwidgets/compact/header.go | 4 ++ cwidgets/compact/status.go | 1 + cwidgets/compact/text.go | 1 + 10 files changed, 186 insertions(+), 14 deletions(-) create mode 100644 config/widget.go diff --git a/config/file.go b/config/file.go index 92bec57..4019807 100644 --- a/config/file.go +++ b/config/file.go @@ -16,22 +16,33 @@ var ( type File struct { Options map[string]string `toml:"options"` Toggles map[string]bool `toml:"toggles"` + Widgets []Widget `toml:"widget"` } func exportConfig() File { + lock.RLock() + defer lock.RUnlock() + c := File{ Options: make(map[string]string), Toggles: make(map[string]bool), + Widgets: make([]Widget, len(GlobalWidgets)), } + for _, p := range GlobalParams { c.Options[p.Key] = p.Val } for _, sw := range GlobalSwitches { c.Toggles[sw.Key] = sw.Val } + for n, w := range GlobalWidgets { + c.Widgets[n] = *w + } + return c } +// func Read() error { var config File @@ -50,6 +61,10 @@ func Read() error { for k, v := range config.Toggles { UpdateSwitch(k, v) } + for _, w := range config.Widgets { + UpdateWidget(strings.ToLower(w.Name), w.Enabled) + } + return nil } diff --git a/config/main.go b/config/main.go index 2b4b997..cb873cc 100644 --- a/config/main.go +++ b/config/main.go @@ -3,6 +3,7 @@ package config import ( "fmt" "os" + "sync" "github.com/bcicen/ctop/logging" ) @@ -10,17 +11,23 @@ import ( var ( GlobalParams []*Param GlobalSwitches []*Switch + GlobalWidgets []*Widget + lock sync.RWMutex log = logging.Init() ) func Init() { - for _, p := range params { + for _, p := range defaultParams { GlobalParams = append(GlobalParams, p) - log.Infof("loaded config param: %s: %s", quote(p.Key), quote(p.Val)) + log.Infof("loaded default config param: %s: %s", quote(p.Key), quote(p.Val)) } - for _, s := range switches { + for _, s := range defaultSwitches { GlobalSwitches = append(GlobalSwitches, s) - log.Infof("loaded config switch: %s: %t", quote(s.Key), s.Val) + log.Infof("loaded default config switch: %s: %t", quote(s.Key), s.Val) + } + for _, w := range defaultWidgets { + GlobalWidgets = append(GlobalWidgets, w) + log.Infof("loaded default widget: %s: %t", quote(w.Name), w.Enabled) } } diff --git a/config/param.go b/config/param.go index 86f5828..6233d5d 100644 --- a/config/param.go +++ b/config/param.go @@ -1,7 +1,7 @@ package config // defaults -var params = []*Param{ +var defaultParams = []*Param{ &Param{ Key: "filterStr", Val: "", @@ -27,6 +27,9 @@ type Param struct { // Get Param by key func Get(k string) *Param { + lock.RLock() + defer lock.RUnlock() + for _, p := range GlobalParams { if p.Key == k { return p @@ -43,7 +46,10 @@ func GetVal(k string) string { // Set param value func Update(k, v string) { p := Get(k) - log.Noticef("config change: %s: %s -> %s", k, quote(p.Val), quote(v)) + log.Noticef("config change [%s]: %s -> %s", k, quote(p.Val), quote(v)) + + lock.Lock() + defer lock.Unlock() p.Val = v // log.Errorf("ignoring update for non-existant parameter: %s", k) } diff --git a/config/switch.go b/config/switch.go index ab3d7e0..b5c3673 100644 --- a/config/switch.go +++ b/config/switch.go @@ -1,7 +1,7 @@ package config // defaults -var switches = []*Switch{ +var defaultSwitches = []*Switch{ &Switch{ Key: "sortReversed", Val: false, @@ -37,6 +37,9 @@ type Switch struct { // GetSwitch returns Switch by key func GetSwitch(k string) *Switch { + lock.RLock() + defer lock.RUnlock() + for _, sw := range GlobalSwitches { if sw.Key == k { return sw @@ -52,8 +55,12 @@ func GetSwitchVal(k string) bool { func UpdateSwitch(k string, val bool) { sw := GetSwitch(k) + + lock.Lock() + defer lock.Unlock() + if sw.Val != val { - log.Noticef("config change: %s: %t -> %t", k, sw.Val, val) + log.Noticef("config change [%s]: %t -> %t", k, sw.Val, val) sw.Val = val } } @@ -61,8 +68,12 @@ func UpdateSwitch(k string, val bool) { // Toggle a boolean switch func Toggle(k string) { sw := GetSwitch(k) + + lock.Lock() + defer lock.Unlock() + newVal := !sw.Val - log.Noticef("config change: %s: %t -> %t", k, sw.Val, newVal) + log.Noticef("config change [%s]: %t -> %t", k, sw.Val, newVal) sw.Val = newVal //log.Errorf("ignoring toggle for non-existant switch: %s", k) } diff --git a/config/widget.go b/config/widget.go new file mode 100644 index 0000000..3783950 --- /dev/null +++ b/config/widget.go @@ -0,0 +1,122 @@ +package config + +import ( + "strings" +) + +// defaults +var defaultWidgets = []*Widget{ + &Widget{ + Name: "status", + Enabled: true, + }, + &Widget{ + Name: "name", + Enabled: true, + }, + &Widget{ + Name: "id", + Enabled: true, + }, + &Widget{ + Name: "cpu", + Enabled: true, + }, + &Widget{ + Name: "mem", + Enabled: true, + }, + &Widget{ + Name: "net", + Enabled: true, + }, + &Widget{ + Name: "io", + Enabled: true, + }, + &Widget{ + Name: "pids", + Enabled: true, + }, +} + +type Widget struct { + Name string + Enabled bool +} + +// GetWidget returns a Widget by name +func GetWidget(name string) *Widget { + lock.RLock() + defer lock.RUnlock() + + for _, w := range GlobalWidgets { + if w.Name == name { + return w + } + } + log.Errorf("widget name not found: %s", name) + return &Widget{} // default +} + +// Widgets returns a copy of all configurable Widgets, in order +func Widgets() []Widget { + a := make([]Widget, len(GlobalWidgets)) + + lock.RLock() + defer lock.RUnlock() + + for n, w := range GlobalWidgets { + a[n] = *w + } + return a +} + +// EnabledWidgets returns an ordered array of enabled widget names +func EnabledWidgets() (a []string) { + for _, w := range Widgets() { + if w.Enabled { + a = append(a, w.Name) + } + } + return a +} + +func UpdateWidget(name string, enabled bool) { + w := GetWidget(name) + oldVal := w.Enabled + log.Noticef("config change [%s-enabled]: %t -> %t", name, oldVal, enabled) + + lock.Lock() + defer lock.Unlock() + w.Enabled = enabled +} + +func ToggleWidgetEnabled(name string) { + w := GetWidget(name) + newVal := !w.Enabled + log.Noticef("config change [%s-enabled]: %t -> %t", name, w.Enabled, newVal) + + lock.Lock() + defer lock.Unlock() + w.Enabled = newVal +} + +// UpdateWidgets replaces existing ordered widgets with those provided +func UpdateWidgets(newWidgets []Widget) { + oldOrder := widgetNames() + lock.Lock() + for n, w := range newWidgets { + GlobalWidgets[n] = &w + } + lock.Unlock() + log.Noticef("config change [widget-order]: %s -> %s", oldOrder, widgetNames()) +} + +func widgetNames() string { + a := make([]string, len(GlobalWidgets)) + for n, w := range Widgets() { + a[n] = w.Name + } + return strings.Join(a, ", ") +} diff --git a/cwidgets/compact/gauge.go b/cwidgets/compact/gauge.go index fdf3a03..0862569 100644 --- a/cwidgets/compact/gauge.go +++ b/cwidgets/compact/gauge.go @@ -5,6 +5,7 @@ import ( "github.com/bcicen/ctop/cwidgets" "github.com/bcicen/ctop/models" + ui "github.com/gizak/termui" ) diff --git a/cwidgets/compact/grid.go b/cwidgets/compact/grid.go index 710d7f2..3e95ec7 100644 --- a/cwidgets/compact/grid.go +++ b/cwidgets/compact/grid.go @@ -17,11 +17,7 @@ type CompactGrid struct { func NewCompactGrid() *CompactGrid { cg := &CompactGrid{header: NewCompactHeader()} - for _, wFn := range allCols { - w := wFn() - cg.cols = append(cg.cols, w) - cg.header.addFieldPar(w.Header()) - } + cg.RebuildHeader() return cg } @@ -41,6 +37,14 @@ func (cg *CompactGrid) Align() { } } +func (cg *CompactGrid) RebuildHeader() { + cg.cols = newRowWidgets() + cg.header.clearFieldPars() + for _, col := range cg.cols { + cg.header.addFieldPar(col.Header()) + } +} + func (cg *CompactGrid) Clear() { cg.Rows = []RowBufferer{} } func (cg *CompactGrid) GetHeight() int { return len(cg.Rows) + cg.header.Height } func (cg *CompactGrid) SetX(x int) { cg.X = x } diff --git a/cwidgets/compact/header.go b/cwidgets/compact/header.go index 2d5ecc9..bec7533 100644 --- a/cwidgets/compact/header.go +++ b/cwidgets/compact/header.go @@ -51,6 +51,10 @@ func (row *CompactHeader) Buffer() ui.Buffer { return buf } +func (row *CompactHeader) clearFieldPars() { + row.pars = []*ui.Par{} +} + func (row *CompactHeader) addFieldPar(s string) { p := ui.NewPar(s) p.Height = row.Height diff --git a/cwidgets/compact/status.go b/cwidgets/compact/status.go index fae7bdc..b5bb261 100644 --- a/cwidgets/compact/status.go +++ b/cwidgets/compact/status.go @@ -2,6 +2,7 @@ package compact import ( "github.com/bcicen/ctop/models" + ui "github.com/gizak/termui" ) diff --git a/cwidgets/compact/text.go b/cwidgets/compact/text.go index 3ff9440..dfc9f53 100644 --- a/cwidgets/compact/text.go +++ b/cwidgets/compact/text.go @@ -5,6 +5,7 @@ import ( "github.com/bcicen/ctop/cwidgets" "github.com/bcicen/ctop/models" + ui "github.com/gizak/termui" )