Skip to content

Commit

Permalink
Full pane toggling support (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacez320 authored Feb 25, 2024
1 parent b605412 commit f67f549
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 69 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,6 @@ There doesn't seem to be much out there easily visible that matches the same set
but there are a few projects I've found that do some things similarly.
- [DataDash](https://github.com/keithknott26/datadash), a data visualization tool for the terminal.
- [Grafterm](https://github.com/slok/grafterm), visualize metrics dashboards on the terminal.
- [Euoporie](https://github.com/joouha/euporie), a terminal interactive computing environment for
Jupyter.
65 changes: 43 additions & 22 deletions internal/lib/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/mum4k/termdash/cell"
"github.com/mum4k/termdash/widgets/sparkline"
"github.com/mum4k/termdash/widgets/text"
"golang.org/x/exp/slog"
)

// Display driver constants. Each display mode uses a specific display driver.
Expand Down Expand Up @@ -110,7 +109,7 @@ func RawDisplay(query string) {
}

// Update the results pane with new results as they are generated.
func StreamDisplay(query string) {
func StreamDisplay(query string, showHelp, showLogs bool) {
var (
reader = readerIndexes[query] // Reader index for the query.
)
Expand All @@ -120,7 +119,15 @@ func StreamDisplay(query string) {
reader.Dec()

// Initialize the display.
resultsView, _, _ := initDisplayTviewText(helpText())
resultsView, helpView, logsView, flexBox := initDisplayTviewText(helpText())

// Hide displays we don't want to show.
if !showHelp {
flexBox.RemoveItem(helpView)
}
if !showLogs {
flexBox.RemoveItem(logsView)
}

// Start the display.
display(
Expand Down Expand Up @@ -156,7 +163,7 @@ func StreamDisplay(query string) {
}

// Creates a table of results for the results pane.
func TableDisplay(query string, filters []string) {
func TableDisplay(query string, filters []string, showHelp, showLogs bool) {
var (
reader = readerIndexes[query] // Reader index for the query.
tableCellPadding = strings.Repeat(" ", TABLE_PADDING) // Padding to add to table cell content.
Expand All @@ -168,7 +175,15 @@ func TableDisplay(query string, filters []string) {
reader.Dec()

// Initialize the display.
resultsView, _, _ := initDisplayTviewTable(helpText())
resultsView, helpView, logsView, flexBox := initDisplayTviewTable(helpText())

// Hide displays we don't want to show.
if !showHelp {
flexBox.RemoveItem(helpView)
}
if !showLogs {
flexBox.RemoveItem(logsView)
}

// Start the display.
display(
Expand Down Expand Up @@ -258,8 +273,11 @@ func TableDisplay(query string, filters []string) {
}

// Creates a graph of results for the results pane.
func GraphDisplay(query string, filters []string) {
func GraphDisplay(query string, filters []string, showHelp, showLogs bool) {
var (
helpWidget, logsWidget *text.Text // Accessory widgets to display.
resultsWidget *sparkline.SparkLine // Results widget.

reader = readerIndexes[query] // Reader index for the query.
valueIndex = 0 // Index of the result value to graph.
)
Expand All @@ -274,25 +292,24 @@ func GraphDisplay(query string, filters []string) {
}

// Initialize the results view.
resultWidget, err := sparkline.New(
resultsWidget, err := sparkline.New(
sparkline.Label(store.GetLabels(query)[valueIndex]),
sparkline.Color(cell.ColorGreen),
)
e(err)

// Initialize the help view.
helpWidget, err := text.New()
e(err)
helpWidget.Write(helpText())
if showHelp {
helpWidget, err = text.New()
e(err)
helpWidget.Write(helpText())
}

// Initialize the logs view.
logsWidget, err := text.New()
e(err)
logsWidgetWriter := termdashTextWriter{text: *logsWidget}
slog.SetDefault(slog.New(slog.NewTextHandler(
&logsWidgetWriter,
&slog.HandlerOptions{Level: config.SlogLogLevel()},
)))
if showLogs {
logsWidget, err = text.New()
e(err)
}

// Start the display.
display(
Expand All @@ -305,9 +322,9 @@ func GraphDisplay(query string, filters []string) {

switch value.(type) {
case int64:
resultWidget.Add([]int{int(value.(int64))})
resultsWidget.Add([]int{int(value.(int64))})
case float64:
resultWidget.Add([]int{int(value.(float64))})
resultsWidget.Add([]int{int(value.(float64))})
}
}

Expand All @@ -326,9 +343,9 @@ func GraphDisplay(query string, filters []string) {

switch value.(type) {
case int64:
resultWidget.Add([]int{int(value.(int64))})
resultsWidget.Add([]int{int(value.(int64))})
case float64:
resultWidget.Add([]int{int(value.(float64))})
resultsWidget.Add([]int{int(value.(float64))})
}
}
}
Expand All @@ -337,5 +354,9 @@ func GraphDisplay(query string, filters []string) {

// Initialize the display. This must happen after the display function is invoked, otherwise data
// will never appear.
initDisplayTermdash(resultWidget, helpWidget, &logsWidgetWriter.text)
initDisplayTermdash(termDashWidgets{
resultsWidget: resultsWidget,
helpWidget: helpWidget,
logsWidget: logsWidget,
})
}
149 changes: 114 additions & 35 deletions internal/lib/display_termdash.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ func (t *termdashTextWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}

// Used to supply optional widgets to Termdash initialization.
type termDashWidgets struct {
helpWidget, logsWidget *text.Text // Accessory widgets which are always text.
resultsWidget widgetapi.Widget // Results widget, which varies by display type.
}

var (
appTermdash *tcell.Terminal // Termdash display.
cancel context.CancelFunc // Cancel function for the termdash display.
Expand Down Expand Up @@ -78,10 +84,13 @@ func errorTermdashHandler(e error) {
}

// Sets-up the termdash container, which defines the overall layout, and begins running the display.
func initDisplayTermdash(resultsWidget, helpWidget, logsWidget widgetapi.Widget) {
// func initDisplayTermdash(resultsWidget, helpWidget, logsWidget widgetapi.Widget) {
func initDisplayTermdash(widgets termDashWidgets) {
var (
ctx context.Context // Termdash specific context.
err error // General error holder.
ctx context.Context // Termdash specific context.
err error // General error holder.
logsWidgetWriter termdashTextWriter // Writer implementation for logs.
widgetContainer *container.Container // Wrapper for widgets.
)

// Set-up the context and enable it to close on key-press.
Expand All @@ -91,47 +100,117 @@ func initDisplayTermdash(resultsWidget, helpWidget, logsWidget widgetapi.Widget)
appTermdash, err = tcell.New()
e(err)

// Render the widget.
c, err := container.New(
appTermdash,
container.PaddingBottom(OUTER_PADDING_BOTTOM),
container.PaddingLeft(OUTER_PADDING_LEFT),
container.PaddingTop(OUTER_PADDING_TOP),
container.PaddingRight(OUTER_PADDING_RIGHT),
container.SplitHorizontal(
container.Top(
container.Border(linestyle.Light),
container.BorderTitle("Results"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(resultsWidget),
),
container.Bottom(
container.SplitHorizontal(
container.Top(
container.Border(linestyle.Light),
container.BorderTitle("Help"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(helpWidget),
),
container.Bottom(
container.Border(linestyle.Light),
container.BorderTitle("Logs"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(logsWidget),
if widgets.helpWidget != nil && widgets.logsWidget != nil {
// All widgets enabled.
widgetContainer, err = container.New(
appTermdash,
container.PaddingBottom(OUTER_PADDING_BOTTOM),
container.PaddingLeft(OUTER_PADDING_LEFT),
container.PaddingTop(OUTER_PADDING_TOP),
container.PaddingRight(OUTER_PADDING_RIGHT),
container.SplitHorizontal(
container.Top(
container.Border(linestyle.Light),
container.BorderTitle("Results"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.resultsWidget),
),
container.Bottom(
container.SplitHorizontal(
container.Top(
container.Border(linestyle.Light),
container.BorderTitle("Help"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.helpWidget),
),
container.Bottom(
container.Border(linestyle.Light),
container.BorderTitle("Logs"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.logsWidget),
),
container.SplitOption(container.SplitPercent(RelativePerc(RESULTS_SIZE, HELP_SIZE))),
),
container.SplitOption(container.SplitPercent(RelativePerc(RESULTS_SIZE, HELP_SIZE))),
),
container.SplitOption(container.SplitPercent(RESULTS_SIZE)),
),
container.SplitOption(container.SplitPercent(RESULTS_SIZE)),
),
)
)
} else if widgets.helpWidget != nil {
// We have just the help widget enabled.
widgetContainer, err = container.New(
appTermdash,
container.PaddingBottom(OUTER_PADDING_BOTTOM),
container.PaddingLeft(OUTER_PADDING_LEFT),
container.PaddingTop(OUTER_PADDING_TOP),
container.PaddingRight(OUTER_PADDING_RIGHT),
container.SplitHorizontal(
container.Top(
container.Border(linestyle.Light),
container.BorderTitle("Results"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.resultsWidget),
),
container.Bottom(
container.Border(linestyle.Light),
container.BorderTitle("Help"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.helpWidget),
),
container.SplitOption(container.SplitPercent(RESULTS_SIZE+LOGS_SIZE)),
),
)
} else if widgets.logsWidget != nil {
// We have just the logs widget enabled. We also need to point logs to it.
logsWidgetWriter = termdashTextWriter{text: *widgets.logsWidget}
slog.SetDefault(slog.New(slog.NewTextHandler(
&logsWidgetWriter,
&slog.HandlerOptions{Level: config.SlogLogLevel()},
)))

widgetContainer, err = container.New(
appTermdash,
container.PaddingBottom(OUTER_PADDING_BOTTOM),
container.PaddingLeft(OUTER_PADDING_LEFT),
container.PaddingTop(OUTER_PADDING_TOP),
container.PaddingRight(OUTER_PADDING_RIGHT),
container.SplitHorizontal(
container.Top(
container.Border(linestyle.Light),
container.BorderTitle("Results"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.resultsWidget),
),
container.Bottom(
container.Border(linestyle.Light),
container.BorderTitle("Logs"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(&logsWidgetWriter.text),
),
container.SplitOption(container.SplitPercent(RESULTS_SIZE+HELP_SIZE)),
),
)
} else {
// Just the results pane.
widgetContainer, err = container.New(
appTermdash,
container.PaddingBottom(OUTER_PADDING_BOTTOM),
container.PaddingLeft(OUTER_PADDING_LEFT),
container.PaddingTop(OUTER_PADDING_TOP),
container.PaddingRight(OUTER_PADDING_RIGHT),
container.Border(linestyle.Light),
container.BorderTitle("Results"),
container.BorderTitleAlignCenter(),
container.PlaceWidget(widgets.resultsWidget),
)
}

e(err)

// Run the display.
termdash.Run(
ctx,
appTermdash,
c,
widgetContainer,
termdash.ErrorHandler(errorTermdashHandler),
termdash.KeyboardSubscriber(keyboardTermdashHandler),
)
Expand Down
18 changes: 11 additions & 7 deletions internal/lib/display_tview.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func keyboardTviewHandler(event *tcell.EventKey) *tcell.EventKey {
func initDisplayTviewTable(helpText string) (
resultsView *tview.Table,
helpView, logsView *tview.TextView,
flexBox *tview.Flex,
) {
resultsView = tview.NewTable()
helpView = tview.NewTextView()
Expand All @@ -76,13 +77,16 @@ func initDisplayTviewTable(helpText string) (
resultsView.SetBorders(true)
resultsView.SetBorder(true).SetTitle("Results")

initDisplayTview(resultsView, helpView, logsView, helpText)
flexBox = initDisplayTview(resultsView, helpView, logsView, helpText)

return
}

// Display init function specific to text results.
func initDisplayTviewText(helpText string) (resultsView, helpView, logsView *tview.TextView) {
func initDisplayTviewText(helpText string) (
resultsView, helpView, logsView *tview.TextView,
flexBox *tview.Flex,
) {
resultsView = tview.NewTextView()
helpView = tview.NewTextView()
logsView = tview.NewTextView()
Expand All @@ -91,7 +95,7 @@ func initDisplayTviewText(helpText string) (resultsView, helpView, logsView *tvi
resultsView.SetChangedFunc(func() { appTview.Draw() })
resultsView.SetBorder(true).SetTitle("Results")

initDisplayTview(resultsView, helpView, logsView, helpText)
flexBox = initDisplayTview(resultsView, helpView, logsView, helpText)

return
}
Expand All @@ -106,10 +110,8 @@ func initDisplayTview(
resultsView tview.Primitive,
helpView, logsView *tview.TextView,
helpText string,
) {
var (
flexBox = tview.NewFlex() // Tview flexbox.
)
) (flexBox *tview.Flex) {
flexBox = tview.NewFlex() // Tview flexbox.

// Set-up the layout and apply views.
flexBox = flexBox.SetDirection(tview.FlexRow).
Expand All @@ -136,4 +138,6 @@ func initDisplayTview(
logsView,
&slog.HandlerOptions{Level: config.SlogLogLevel()},
)))

return
}
Loading

0 comments on commit f67f549

Please sign in to comment.