adding the options form for the stream view

This commit is contained in:
2026-06-18 17:05:27 +01:00
parent 74d57a6ece
commit 3e92467beb
6 changed files with 100 additions and 40 deletions
+3
View File
@@ -24,6 +24,9 @@ func ListFormButtonLabels(form *tview.Form) []string {
}
func SetFormButtonCallback(form *tview.Form, btnLabel string, fn func()) error {
// NOTE: is there a better way to do this ???
// Find out
btnIndex := form.GetButtonIndex(btnLabel)
if btnIndex == -1 {
availableButtons := ListFormButtonLabels(form)
+4 -3
View File
@@ -2,9 +2,10 @@
package controllers
import (
"fmt"
serv "esdi/tui/internal/services"
"esdi/tui/internal/views"
"fmt"
"github.com/gdamore/tcell/v2"
)
@@ -76,12 +77,12 @@ func (mc *DeviceController) AddDeviceAPIListItems() {
AddItem("stream", "stream data to the display", func() {
views.AddAndShowPage(mc.DeviceAPIView.DevAPIToolView.Pages,
"streaming-tool",
mc.StreamCtrl.StreamView.TextView,
mc.StreamCtrl.StreamView.Flex,
)
mc.StreamCtrl.SetInternalState()
mc.App.SetFocus(mc.StreamCtrl.StreamView.TextView)
mc.App.SetFocus(mc.StreamCtrl.StreamView.Options.Form)
})
}
+24 -6
View File
@@ -1,11 +1,12 @@
package controllers
import (
"fmt"
"sync/atomic"
"esdi/telemetry"
"esdi/tui/internal/services"
"esdi/tui/internal/views"
"fmt"
"sync/atomic"
"github.com/gdamore/tcell/v2"
)
@@ -13,7 +14,7 @@ import (
type StreamingCtrl struct {
*Controller
Service *services.CDashService
StreamView *views.StreamView
StreamView *views.StreamToolView
Messages chan string
Internal chan string
Run bool
@@ -34,7 +35,7 @@ func NewStreamingCtrl(
Messages: make(chan string, 10),
Internal: make(chan string, 10),
Run: false,
StreamView: views.NewStreamView(),
StreamView: views.NewStreamToolView(),
isRunning: false,
}
@@ -44,7 +45,7 @@ func NewStreamingCtrl(
}
func (sc *StreamingCtrl) registerHooks() {
sc.StreamView.TextView.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
sc.StreamView.Options.Form.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
switch ev.Key() {
case tcell.KeyEsc:
sc.OnExit()
@@ -57,10 +58,22 @@ func (sc *StreamingCtrl) registerHooks() {
case 'p':
// Pause
// sc.Stop()
case 'u':
// Update
// NOTE: run the same routine for the form Update button here
}
return ev
})
// Set the options form callbacks
err := SetFormButtonCallback(sc.StreamView.Options.Form, "Update", func() {
sc.updateStream()
})
if err != nil {
// NOTE: what do we do here?
panic("Failed to set callback for streaming controller form update button")
}
}
func (sc *StreamingCtrl) Start() {
@@ -77,13 +90,18 @@ func (sc *StreamingCtrl) Start() {
isDrawing.Store(true)
sc.App.QueueUpdateDraw(func() {
sc.StreamView.Update(&msg)
sc.StreamView.Visualizer.Update(&msg)
isDrawing.Store(false)
})
}
}()
}
// updateStream will get the new options from the form and update the state accordingly
func (sc *StreamingCtrl) updateStream() {
sc.Messages <- "Request to update stream received - parsing form"
}
// SetInternalState is used to update the stuff in here, for example, the user
// goes into the layout tool, sets up the data to transmit to his devices and
// then comes here to stream that data. We call this to set the fields the user
+1
View File
@@ -87,6 +87,7 @@ func NewCreateWindowFormView() *CreateWindowFormView {
Form: NewCDashDisplayWindowFormView(),
}
// NOTE: is this variable actually used anywhere
view.CreateBtn = tview.NewButton("Create")
// Need to inject the button functionality later
-25
View File
@@ -51,9 +51,6 @@ type DeviceAPIListView struct {
func NewDeviceAPIListView() *DeviceAPIListView {
deviceAPIList := tview.NewList()
// AddItem("layout", "build a layout for CDashDisplay", 0, func() {
// layoutToolUIOnSelect(bus, doc)
// })
deviceAPIList.SetBorder(true).SetTitle("list")
return &DeviceAPIListView{
@@ -75,40 +72,18 @@ func (dl *DeviceAPIListView) AddItem(name, description string, onSelect func())
}
func NewDeviceAPIView() (*DeviceAPIView, error) {
// To build the main view we must set the DOM root
mainFlex := tview.NewFlex().SetDirection(tview.FlexColumn)
// mainFlexUINode, err := doc.NewUINode(MainFlexID, nil, mainFlex)
// if err != nil {
// return nil, err
// }
//
// doc.SetRoot(mainFlexUINode)
deviceAPIList := NewDeviceAPIListView()
// apiListWindowUINode, err := doc.NewUINode(DeviceAPIListID, doc.GetRootElem(),
// deviceAPIList.List)
// if err != nil {
// return nil, err
// }
apiToolPages := NewDeviceAPIToolView()
// apiToolPagesNode, err := doc.NewUINode(APIToolPagesID, doc.GetElemByID(RightFlexID),
// apiToolPages.Pages)
// if err != nil {
// return nil, err
// }
mainFlex.
AddItem(deviceAPIList.List, 0, 1, false).
AddItem(apiToolPages.Pages, 0, 4, false)
// Output window
outputWin := NewOutputWinView()
// _, err = doc.NewUINode("output-window", nil, outputWin.TextArea)
// if err != nil {
// return nil, err
// }
// Flex with debug window
// --------------------------------------------------------------------------
+68 -6
View File
@@ -1,11 +1,13 @@
package views
import (
telem "esdi/telemetry"
"fmt"
"strings"
"time"
"esdi/providers"
telem "esdi/telemetry"
"github.com/rivo/tview"
)
@@ -17,20 +19,51 @@ const (
BrakeBiasLen = 6
)
type StreamView struct {
// Form to select the game and whatnot ↓↓↓↓
// StreamOptionsView will be our view element to show the stream data
type StreamOptionsView struct {
Form *tview.Form
SimDropdown *tview.DropDown
UpdateBtn *tview.Button
}
func NewStreamOptionsView() *StreamOptionsView {
sov := &StreamOptionsView{}
sov.Form = tview.NewForm()
sov.Form.SetTitle("Stream Options").SetBorder(true)
sov.SimDropdown = tview.NewDropDown().SetLabel("SIM").SetCurrentOption(0)
for _, prov := range providers.Providers {
sov.SimDropdown.AddOption(prov.Name, func() {})
}
sov.Form.AddFormItem(sov.SimDropdown)
// Inject callback on the controller
sov.Form.AddButton("Update", func() {})
return sov
}
// Form to select the game and whatnot ↑↑↑↑
// Area to visualize what data is being passed to the game and whatnot ↓↓↓↓
type StreamVisualizerView struct {
TextView *tview.TextView
}
func NewStreamView() *StreamView {
func NewStreamVisualizerView() *StreamVisualizerView {
tv := tview.NewTextView()
tv.SetTitle("Streaming Tool").SetBorder(true)
tv.SetTitle("Streaming Visualizer").SetBorder(true)
return &StreamView{
return &StreamVisualizerView{
TextView: tv,
}
}
func (sv *StreamView) Update(data *telem.TelemetryData) {
func (sv *StreamVisualizerView) Update(data *telem.TelemetryData) {
sv.TextView.SetText(stringify(data))
}
@@ -49,3 +82,32 @@ func stringify(data *telem.TelemetryData) string {
return buffer.String()
}
// Area to visualize what data is being passed to the game and whatnot ↑↑↑↑
// Stream Tool ↓↓↓↓
type StreamToolView struct {
Flex *tview.Flex
Options *StreamOptionsView
Visualizer *StreamVisualizerView
}
func NewStreamToolView() *StreamToolView {
optionsView := NewStreamOptionsView()
visualizerView := NewStreamVisualizerView()
flex := tview.NewFlex().SetDirection(tview.FlexColumn)
flex.SetTitle("Streaming Tool")
flex.
AddItem(optionsView.Form, 0, 2, true).
AddItem(visualizerView.TextView, 0, 5, true)
return &StreamToolView{
Flex: flex,
Options: optionsView,
Visualizer: visualizerView,
}
}
// Stream Tool ↑↑↑↑