redesign settings

This commit is contained in:
Dmitry Sergeev
2026-09-01 17:56:13 +03:00
parent a4626fbb19
commit 7a19fe0dad
4 changed files with 223 additions and 144 deletions
+130 -84
View File
@@ -99,6 +99,8 @@ func main() {
// timelapse audio: 5fbec3b1-1b0f-417d-9059-8b94a47197ec // timelapse audio: 5fbec3b1-1b0f-417d-9059-8b94a47197ec
// f1 video: 5fbec3b1-1b0f-417d-9059-8b94a47197ef // f1 video: 5fbec3b1-1b0f-417d-9059-8b94a47197ef
// f1 audio: 5fbec3b1-1b0f-417d-9059-8b94a47197eb // f1 audio: 5fbec3b1-1b0f-417d-9059-8b94a47197eb
// sync video: 2618979d-76a5-45e0-83cb-0f192978d1cd
// sync audio: 9d2a041b-01cf-4ee4-bffa-188fe093c99b
var args appArgs var args appArgs
flagSet := pflag.NewFlagSet(APP_NAME, pflag.ContinueOnError) flagSet := pflag.NewFlagSet(APP_NAME, pflag.ContinueOnError)
flagSet.SortFlags = false flagSet.SortFlags = false
@@ -200,6 +202,19 @@ func main() {
// ImGui init // ImGui init
gui := imgui.New() gui := imgui.New()
defer gui.Destroy() defer gui.Destroy()
fontConfig := cimgui.NewFontConfig()
font := gui.IO().Fonts().AddFontFromFileTTFV(
"/home/itten/Downloads/JetBrainsMono/JetBrainsMonoNLNerdFontMono-Regular.ttf",
18,
fontConfig,
nil,
)
fontConfig.Destroy()
if font == nil || font.CData == nil {
log.Fatal("failed to load ImGui font")
}
gui.IO().SetFontDefault(font)
// sdl keys handler
sdl.StartTextInput(windowHandler) sdl.StartTextInput(windowHandler)
defer sdl.StopTextInput(windowHandler) defer sdl.StopTextInput(windowHandler)
// fin on ImGui init // fin on ImGui init
@@ -421,6 +436,12 @@ func main() {
) )
lastFrame = time.Now() lastFrame = time.Now()
// ImGui
var (
settingWindowWidth float32 = 700
settingsWindowState bool = true
)
for running { for running {
frameStart := time.Now() frameStart := time.Now()
var event [128]byte var event [128]byte
@@ -447,6 +468,8 @@ func main() {
resized = true resized = true
case sdl.KeyF1: case sdl.KeyF1:
showStats = !showStats showStats = !showStats
case sdl.KeyF2:
settingsWindowState = !settingsWindowState
} }
} }
gui.ProcessEvent(&event) gui.ProcessEvent(&event)
@@ -523,8 +546,6 @@ func main() {
// end of stats // end of stats
if r != nil { if r != nil {
gui.BeginFrame(time.Since(lastFrame), int32(r.Extent().Width), int32(r.Extent().Height)) gui.BeginFrame(time.Since(lastFrame), int32(r.Extent().Width), int32(r.Extent().Height))
// test widget
// cimgui.Begin("Test")
if showStats { if showStats {
cimgui.SetNextWindowPos(cimgui.Vec2{X: 10, Y: 10}) cimgui.SetNextWindowPos(cimgui.Vec2{X: 10, Y: 10})
cimgui.SetNextWindowSize(cimgui.Vec2{X: 200, Y: 200}) cimgui.SetNextWindowSize(cimgui.Vec2{X: 200, Y: 200})
@@ -540,13 +561,9 @@ func main() {
displayedVideoHeight, displayedVideoHeight,
)) ))
} }
cimgui.Text("\nPress F1 to hide stats")
cimgui.Text("Q or Esc to quit")
cimgui.Text("F for fullscreen")
cimgui.End() cimgui.End()
} }
cimgui.Begin("Connection") // settings & info window
snapshot, hasSnapshot := player.Controller.Snapshot() snapshot, hasSnapshot := player.Controller.Snapshot()
videoConfigured := videoStr != "" videoConfigured := videoStr != ""
audioConfigured := audioStr != "" audioConfigured := audioStr != ""
@@ -556,20 +573,63 @@ func main() {
videoConfigured = snapshot.Desired.Video.IsConfigured() videoConfigured = snapshot.Desired.Video.IsConfigured()
audioConfigured = snapshot.Desired.Audio.IsConfigured() audioConfigured = snapshot.Desired.Audio.IsConfigured()
syncRequested = snapshot.Desired.SyncRequested syncRequested = snapshot.Desired.SyncRequested
cimgui.Text(fmt.Sprintf(
"Topology: %s (generation %d)",
snapshot.Plan.Topology,
snapshot.Generation,
))
} else {
cimgui.Text("Topology: starting")
} }
cimgui.Separator() drawSettingsContents := func() {
var collapsingHeaderFlags cimgui.TreeNodeFlags = cimgui.TreeNodeFlagsDefaultOpen
drawFeedsSections := func() {
cimgui.SeparatorText("Video")
cimgui.InputTextWithHint("Video domain", "/dev/shm/mxl", &videoDomainStr, 0, nil) cimgui.InputTextWithHint("Video domain", "/dev/shm/mxl", &videoDomainStr, 0, nil)
cimgui.InputTextWithHint("Video UUID", "", &videoStr, 0, nil) cimgui.InputTextWithHint("Video UUID", "", &videoStr, 0, nil)
if videoActive {
cimgui.SameLine()
if cimgui.Button("Stop##video") {
videoActive = false
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopVideo})
}
}
if !videoActive && videoConfigured {
cimgui.SameLine()
if cimgui.Button("Resume##video") {
videoActive = true
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeVideo})
}
}
if videoConfigured {
cimgui.SameLine()
if cimgui.Button("Remove##video") {
videoActive = false
videoStr = ""
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveVideo})
}
}
cimgui.SeparatorText("Audio")
cimgui.InputTextWithHint("Audio domain", "/dev/shm/mxl", &audioDomainStr, 0, nil) cimgui.InputTextWithHint("Audio domain", "/dev/shm/mxl", &audioDomainStr, 0, nil)
cimgui.InputTextWithHint("Audio UUID", "", &audioStr, 0, nil) cimgui.InputTextWithHint("Audio UUID", "", &audioStr, 0, nil)
if audioActive {
cimgui.SameLine()
if cimgui.Button("Stop##audio") {
audioActive = false
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopAudio})
}
}
if !audioActive && audioConfigured {
cimgui.SameLine()
if cimgui.Button("Resume##audio") {
audioActive = true
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAudio})
}
}
if audioConfigured {
cimgui.SameLine()
if cimgui.Button("Remove##audio") {
audioActive = false
audioStr = ""
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveAudio})
}
}
cimgui.SeparatorText("Controls")
if cimgui.Button("Apply feeds") { if cimgui.Button("Apply feeds") {
doReconnect() doReconnect()
} }
@@ -587,7 +647,7 @@ func main() {
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAll}) enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAll})
} }
} }
cimgui.SameLine()
if cimgui.Checkbox("Synchronize", &syncRequested) { if cimgui.Checkbox("Synchronize", &syncRequested) {
kind := playback.CommandDisableSync kind := playback.CommandDisableSync
if syncRequested { if syncRequested {
@@ -595,6 +655,33 @@ func main() {
} }
enqueueCommand(playback.SessionCommand{Kind: kind}) enqueueCommand(playback.SessionCommand{Kind: kind})
} }
cimgui.SeparatorText("Feeds stats")
cimgui.Checkbox("Show stats", &showStats)
}
if cimgui.CollapsingHeaderTreeNodeFlagsV("Feeds", collapsingHeaderFlags) {
drawFeedsSections()
}
drawHotkeysSection := func() {
cimgui.Text("F1 - show/hide stats")
cimgui.Text("F2 - show/hide settings")
cimgui.Text("F - toggle fullscreen")
cimgui.Text("Q or Esc - quit")
}
if cimgui.CollapsingHeaderTreeNodeFlagsV("Hotkeys", collapsingHeaderFlags) {
drawHotkeysSection()
}
drawDebugSection := func() {
if hasSnapshot {
cimgui.Text(fmt.Sprintf(
"Topology: %s (generation %d)",
snapshot.Plan.Topology,
snapshot.Generation,
))
} else {
cimgui.Text("Topology: starting")
}
if hasSnapshot && syncRequested && snapshot.Plan.Topology != playback.TopologySynchronized { if hasSnapshot && syncRequested && snapshot.Plan.Topology != playback.TopologySynchronized {
switch { switch {
case !videoConfigured || !audioConfigured: case !videoConfigured || !audioConfigured:
@@ -607,72 +694,6 @@ func main() {
cimgui.TextWrapped("Sync requested but currently unavailable. Playing independently.") cimgui.TextWrapped("Sync requested but currently unavailable. Playing independently.")
} }
} }
cimgui.Separator()
cimgui.Text("Video")
if videoActive {
if cimgui.Button("Stop video") {
videoActive = false
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopVideo})
}
}
if !videoActive && videoConfigured {
cimgui.SameLine()
if cimgui.Button("Resume video") {
videoActive = true
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeVideo})
}
}
if videoConfigured {
cimgui.SameLine()
if cimgui.Button("Remove video") {
videoActive = false
videoStr = ""
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveVideo})
}
}
if videoActive {
cimgui.Text("Video desired: active")
} else if videoConfigured {
cimgui.Text("Video desired: stopped")
} else {
cimgui.Text("Video desired: not configured")
}
cimgui.Separator()
cimgui.Text("Audio")
if audioActive {
if cimgui.Button("Stop audio") {
audioActive = false
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopAudio})
}
}
if !audioActive && audioConfigured {
cimgui.SameLine()
if cimgui.Button("Resume audio") {
audioActive = true
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAudio})
}
}
if audioConfigured {
cimgui.SameLine()
if cimgui.Button("Remove audio") {
audioActive = false
audioStr = ""
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveAudio})
}
}
if audioActive {
cimgui.Text("Audio desired: active")
} else if audioConfigured {
cimgui.Text("Audio desired: stopped")
} else {
cimgui.Text("Audio desired: not configured")
}
cimgui.Separator() cimgui.Separator()
cimgui.Text("Current playback") cimgui.Text("Current playback")
if hasSnapshot { if hasSnapshot {
@@ -692,11 +713,36 @@ func main() {
} else { } else {
cimgui.Text("Playback controller is starting") cimgui.Text("Playback controller is starting")
} }
cimgui.Separator() cimgui.Separator()
cimgui.Checkbox("Show stats", &showStats) if videoActive {
cimgui.Text("Video desired: active")
} else if videoConfigured {
cimgui.Text("Video desired: stopped")
} else {
cimgui.Text("Video desired: not configured")
}
if audioActive {
cimgui.Text("Audio desired: active")
} else if audioConfigured {
cimgui.Text("Audio desired: stopped")
} else {
cimgui.Text("Audio desired: not configured")
}
}
if cimgui.CollapsingHeaderTreeNodeFlagsV("Debug Info", collapsingHeaderFlags) {
drawDebugSection()
}
}
if settingsWindowState {
cimgui.SetNextWindowPos(cimgui.Vec2{X: float32(r.Extent().Width) - settingWindowWidth, Y: 0})
cimgui.SetNextWindowSize(cimgui.Vec2{X: settingWindowWidth, Y: float32(r.Extent().Height)})
if cimgui.BeginV("Settings & Info", &settingsWindowState, cimgui.WindowFlagsNone) {
drawSettingsContents()
}
cimgui.End() cimgui.End()
}
gui.EndFrame() gui.EndFrame()
lastFrame = time.Now() lastFrame = time.Now()
// end of test widget // end of test widget
+24 -4
View File
@@ -1,6 +1,6 @@
[Window][Debug##Default] [Window][Debug##Default]
Pos=60,60 Pos=519,181
Size=400,400 Size=400,398
Collapsed=0 Collapsed=0
[Window][Test] [Window][Test]
@@ -14,7 +14,27 @@ Size=200,200
Collapsed=0 Collapsed=0
[Window][Connection] [Window][Connection]
Pos=322,130 Pos=42,264
Size=661,444 Size=605,416
Collapsed=0
[Window][Test slider]
Pos=1370,0
Size=550,1080
Collapsed=0
[Window][Settings]
Pos=730,0
Size=550,720
Collapsed=0
[Window][Settings & Info]
Pos=1220,0
Size=700,1080
Collapsed=0
[Window][Seetings & Info]
Pos=1220,0
Size=700,1080
Collapsed=0 Collapsed=0
+1
View File
@@ -32,6 +32,7 @@ const (
KeyF uint32 = 0x66 KeyF uint32 = 0x66
KeyQ uint32 = 0x71 KeyQ uint32 = 0x71
KeyF1 uint32 = 0x4000003A KeyF1 uint32 = 0x4000003A
KeyF2 uint32 = 0x4000003B
InitAudio uint32 = 0x00000010 InitAudio uint32 = 0x00000010
AudioDeviceDefaultPlayback uint32 = 0xFFFFFFFF AudioDeviceDefaultPlayback uint32 = 0xFFFFFFFF
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
VIDEO_ID="2618979d-76a5-45e0-83cb-0f192978d1cd"
AUDIO_ID="9d2a041b-01cf-4ee4-bffa-188fe093c99b"
VIDEO_URI=$1
if [[ -z "${VIDEO_URI}" ]] then
VIDEO_URI="${HOME}/Videos/test-vid/motogp.ts"
fi
export GST_PLUGIN_PATH="${HOME}/.gst-plugin:${GST_PLUGIN_PATH}"
mxl-gst-looping-filesrc -d /dev/shm/mxl -i "${VIDEO_URI}" --video-id "${VIDEO_ID}" --audio-id "${AUDIO_ID}" 2>/dev/null
# sleep 5
# kill -9 $(pidof "mxl-gst-looping-filesrc")
# echo -e "\ngst-looping-filesrc killed"