mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
☢️ WTF-1031 Support multiple simultaneous configurations (#1032)
* WTF-1031 Rename WtfApp.app to WtfApp.tviewApp Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-1031 Add scaffolding for main to support multiple WtfApp instances Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-1031 WIP Signed-off-by: Chris Cummer <chriscummer@me.com> * Remove common functionality from KeyboardWidget and into Base Signed-off-by: Chris Cummer <chriscummer@me.com> * Augment with some descriptive comments Signed-off-by: Chris Cummer <chriscummer@me.com> * Add full support for multiple app instances via the AppManager. Still to do: * Config support for multiple apps/multiple config files * The ability to switch between apps Signed-off-by: Chris Cummer <chriscummer@me.com> * Move SetTerminal out of main and into its own file Signed-off-by: Chris Cummer <chriscummer@me.com>
This commit is contained in:
@@ -30,10 +30,10 @@ type Bar struct {
|
||||
}
|
||||
|
||||
// NewBarGraph creates and returns an instance of BarGraph
|
||||
func NewBarGraph(app *tview.Application, name string, commonSettings *cfg.Common) BarGraph {
|
||||
func NewBarGraph(tviewApp *tview.Application, name string, commonSettings *cfg.Common) BarGraph {
|
||||
widget := BarGraph{
|
||||
Base: NewBase(app, commonSettings),
|
||||
KeyboardWidget: NewKeyboardWidget(app, nil, commonSettings),
|
||||
Base: NewBase(tviewApp, nil, commonSettings),
|
||||
KeyboardWidget: NewKeyboardWidget(commonSettings),
|
||||
|
||||
maxStars: commonSettings.Config.UInt("graphStars", 20),
|
||||
starChar: commonSettings.Config.UString("graphIcon", "|"),
|
||||
|
||||
40
view/base.go
40
view/base.go
@@ -10,35 +10,39 @@ import (
|
||||
)
|
||||
|
||||
type Base struct {
|
||||
app *tview.Application
|
||||
bordered bool
|
||||
commonSettings *cfg.Common
|
||||
enabled bool
|
||||
enabledMutex *sync.Mutex
|
||||
focusChar string
|
||||
focusable bool
|
||||
helpTextFunc func() string
|
||||
name string
|
||||
pages *tview.Pages
|
||||
quitChan chan bool
|
||||
refreshing bool
|
||||
refreshInterval int
|
||||
enabledMutex *sync.Mutex
|
||||
refreshing bool
|
||||
tviewApp *tview.Application
|
||||
view *tview.TextView
|
||||
}
|
||||
|
||||
// NewBase creates and returns an instance of the Base module, the lowest-level
|
||||
// primitive module from which all others are derived
|
||||
func NewBase(app *tview.Application, commonSettings *cfg.Common) *Base {
|
||||
func NewBase(tviewApp *tview.Application, pages *tview.Pages, commonSettings *cfg.Common) *Base {
|
||||
base := &Base{
|
||||
commonSettings: commonSettings,
|
||||
|
||||
app: app,
|
||||
bordered: commonSettings.Bordered,
|
||||
enabled: commonSettings.Enabled,
|
||||
enabledMutex: &sync.Mutex{},
|
||||
focusChar: commonSettings.FocusChar(),
|
||||
focusable: commonSettings.Focusable,
|
||||
name: commonSettings.Name,
|
||||
pages: pages,
|
||||
quitChan: make(chan bool),
|
||||
refreshInterval: commonSettings.RefreshInterval,
|
||||
refreshing: false,
|
||||
tviewApp: tviewApp,
|
||||
}
|
||||
|
||||
return base
|
||||
@@ -134,6 +138,32 @@ func (base *Base) SetFocusChar(char string) {
|
||||
base.focusChar = char
|
||||
}
|
||||
|
||||
// SetView assigns the passed-in tview.TextView view to this widget
|
||||
func (base *Base) SetView(view *tview.TextView) {
|
||||
base.view = view
|
||||
}
|
||||
|
||||
// ShowHelp displays the modal help dialog for a module
|
||||
func (base *Base) ShowHelp() {
|
||||
if base.pages == nil {
|
||||
return
|
||||
}
|
||||
|
||||
closeFunc := func() {
|
||||
base.pages.RemovePage("help")
|
||||
base.tviewApp.SetFocus(base.view)
|
||||
}
|
||||
|
||||
modal := NewBillboardModal(base.helpTextFunc(), closeFunc)
|
||||
|
||||
base.pages.AddPage("help", modal, false, true)
|
||||
base.tviewApp.SetFocus(modal)
|
||||
|
||||
base.tviewApp.QueueUpdate(func() {
|
||||
base.tviewApp.Draw()
|
||||
})
|
||||
}
|
||||
|
||||
func (base *Base) Stop() {
|
||||
base.enabledMutex.Lock()
|
||||
base.enabled = false
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
)
|
||||
|
||||
const helpKeyChar = "/"
|
||||
const refreshKeyChar = "r"
|
||||
|
||||
type helpItem struct {
|
||||
@@ -19,9 +19,6 @@ type helpItem struct {
|
||||
|
||||
// KeyboardWidget manages keyboard control for a widget
|
||||
type KeyboardWidget struct {
|
||||
app *tview.Application
|
||||
pages *tview.Pages
|
||||
view *tview.TextView
|
||||
settings *cfg.Common
|
||||
|
||||
charMap map[string]func()
|
||||
@@ -32,10 +29,9 @@ type KeyboardWidget struct {
|
||||
}
|
||||
|
||||
// NewKeyboardWidget creates and returns a new instance of KeyboardWidget
|
||||
func NewKeyboardWidget(app *tview.Application, pages *tview.Pages, settings *cfg.Common) *KeyboardWidget {
|
||||
// func NewKeyboardWidget(tviewApp *tview.Application, pages *tview.Pages, settings *cfg.Common) *KeyboardWidget {
|
||||
func NewKeyboardWidget(settings *cfg.Common) *KeyboardWidget {
|
||||
keyWidget := &KeyboardWidget{
|
||||
app: app,
|
||||
pages: pages,
|
||||
settings: settings,
|
||||
charMap: make(map[string]func()),
|
||||
keyMap: make(map[tcell.Key]func()),
|
||||
@@ -78,6 +74,14 @@ func (widget *KeyboardWidget) HelpText() string {
|
||||
return str
|
||||
}
|
||||
|
||||
// InitializeHelpTextKeyboardControl assigns the function that displays help text to the
|
||||
// common help text key value
|
||||
func (widget *KeyboardWidget) InitializeHelpTextKeyboardControl(helpFunc func()) {
|
||||
if helpFunc != nil {
|
||||
widget.SetKeyboardChar(helpKeyChar, helpFunc, "Show/hide this help prompt")
|
||||
}
|
||||
}
|
||||
|
||||
// InitializeRefreshKeyboardControl assigns the module's explicit refresh function to
|
||||
// the commom refresh key value
|
||||
func (widget *KeyboardWidget) InitializeRefreshKeyboardControl(refreshFunc func()) {
|
||||
@@ -155,37 +159,10 @@ func (widget *KeyboardWidget) SetKeyboardKey(key tcell.Key, fn func(), helpText
|
||||
}
|
||||
}
|
||||
|
||||
// SetView assigns the passed-in tview.TextView view to this widget
|
||||
func (widget *KeyboardWidget) SetView(view *tview.TextView) {
|
||||
widget.view = view
|
||||
}
|
||||
|
||||
// ShowHelp displays the modal help dialog for a module
|
||||
func (widget *KeyboardWidget) ShowHelp() {
|
||||
if widget.pages == nil {
|
||||
return
|
||||
}
|
||||
|
||||
closeFunc := func() {
|
||||
widget.pages.RemovePage("help")
|
||||
widget.app.SetFocus(widget.view)
|
||||
}
|
||||
|
||||
modal := NewBillboardModal(widget.HelpText(), closeFunc)
|
||||
|
||||
widget.pages.AddPage("help", modal, false, true)
|
||||
widget.app.SetFocus(modal)
|
||||
|
||||
widget.app.QueueUpdate(func() {
|
||||
widget.app.Draw()
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
// initializeCommonKeyboardControls sets up the keyboard controls that are common to
|
||||
// all widgets that accept keyboard input
|
||||
func (widget *KeyboardWidget) initializeCommonKeyboardControls() {
|
||||
widget.SetKeyboardChar("/", widget.ShowHelp, "Show/hide this help prompt")
|
||||
widget.SetKeyboardChar("\\", widget.LaunchDocumentation, "Open the documentation for this module in a browser")
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
)
|
||||
@@ -13,8 +12,6 @@ func test() {}
|
||||
|
||||
func testKeyboardWidget() *KeyboardWidget {
|
||||
keyWid := NewKeyboardWidget(
|
||||
tview.NewApplication(),
|
||||
tview.NewPages(),
|
||||
&cfg.Common{
|
||||
Module: cfg.Module{
|
||||
Name: "testWidget",
|
||||
@@ -178,7 +175,6 @@ func Test_initializeCommonKeyboardControls(t *testing.T) {
|
||||
t.Run("nil refreshFunc", func(t *testing.T) {
|
||||
keyWid := testKeyboardWidget()
|
||||
|
||||
assert.NotNil(t, keyWid.charMap["/"])
|
||||
assert.NotNil(t, keyWid.charMap["\\"])
|
||||
})
|
||||
}
|
||||
@@ -206,18 +202,3 @@ func Test_HelpText(t *testing.T) {
|
||||
|
||||
assert.NotNil(t, keyWid.HelpText())
|
||||
}
|
||||
|
||||
func Test_SetView(t *testing.T) {
|
||||
keyWid := testKeyboardWidget()
|
||||
assert.Nil(t, keyWid.view)
|
||||
|
||||
view := &tview.TextView{}
|
||||
keyWid.SetView(view)
|
||||
assert.Equal(t, view, keyWid.view)
|
||||
}
|
||||
|
||||
func Test_ShowHelp(t *testing.T) {
|
||||
keyWid := testKeyboardWidget()
|
||||
|
||||
assert.NotPanics(t, func() { keyWid.ShowHelp() })
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ type ScrollableWidget struct {
|
||||
RenderFunction func()
|
||||
}
|
||||
|
||||
func NewScrollableWidget(app *tview.Application, pages *tview.Pages, commonSettings *cfg.Common) ScrollableWidget {
|
||||
func NewScrollableWidget(tviewApp *tview.Application, pages *tview.Pages, commonSettings *cfg.Common) ScrollableWidget {
|
||||
widget := ScrollableWidget{
|
||||
TextWidget: NewTextWidget(app, pages, commonSettings),
|
||||
TextWidget: NewTextWidget(tviewApp, pages, commonSettings),
|
||||
}
|
||||
|
||||
widget.Unselect()
|
||||
@@ -84,7 +84,7 @@ func (widget *ScrollableWidget) Unselect() {
|
||||
func (widget *ScrollableWidget) Redraw(data func() (string, string, bool)) {
|
||||
widget.TextWidget.Redraw(data)
|
||||
|
||||
widget.Base.app.QueueUpdateDraw(func() {
|
||||
widget.tviewApp.QueueUpdateDraw(func() {
|
||||
widget.View.Highlight(strconv.Itoa(widget.Selected)).ScrollToHighlight()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,19 +14,24 @@ type TextWidget struct {
|
||||
*KeyboardWidget
|
||||
|
||||
View *tview.TextView
|
||||
|
||||
tviewApp *tview.Application
|
||||
}
|
||||
|
||||
// NewTextWidget creates and returns an instance of TextWidget
|
||||
func NewTextWidget(app *tview.Application, pages *tview.Pages, commonSettings *cfg.Common) TextWidget {
|
||||
func NewTextWidget(tviewApp *tview.Application, pages *tview.Pages, commonSettings *cfg.Common) TextWidget {
|
||||
widget := TextWidget{
|
||||
Base: NewBase(app, commonSettings),
|
||||
KeyboardWidget: NewKeyboardWidget(app, pages, commonSettings),
|
||||
Base: NewBase(tviewApp, pages, commonSettings),
|
||||
KeyboardWidget: NewKeyboardWidget(commonSettings),
|
||||
|
||||
tviewApp: tviewApp,
|
||||
}
|
||||
|
||||
widget.View = widget.createView(widget.bordered)
|
||||
widget.View.SetInputCapture(widget.KeyboardWidget.InputCapture)
|
||||
|
||||
widget.KeyboardWidget.SetView(widget.View)
|
||||
widget.Base.SetView(widget.View)
|
||||
widget.Base.helpTextFunc = widget.KeyboardWidget.HelpText
|
||||
|
||||
return widget
|
||||
}
|
||||
@@ -38,8 +43,9 @@ func (widget *TextWidget) TextView() *tview.TextView {
|
||||
return widget.View
|
||||
}
|
||||
|
||||
// Redraw forces a refresh of the onscreen text content of this widget
|
||||
func (widget *TextWidget) Redraw(data func() (string, string, bool)) {
|
||||
widget.Base.app.QueueUpdateDraw(func() {
|
||||
widget.tviewApp.QueueUpdateDraw(func() {
|
||||
title, content, wrap := data()
|
||||
|
||||
widget.View.Clear()
|
||||
|
||||
Reference in New Issue
Block a user