Add menu bar and center playback controls

UI improvements:
- Add menu bar at top with File, View, and Tools menus
- Move File operations (Open, Add Folder, Clear) to File menu
- Add Frame-Accurate Mode toggle in Tools menu
- Center playback controls (Prev, Play, Next) at bottom
- Move volume controls to left, playlist toggle to right
- Remove redundant top control bar for cleaner interface
- Add keyframingMode state to appState for feature toggle

Layout changes:
- Menu bar provides access to advanced features
- Main player area takes full space below menu
- Controls centered bottom like modern video players (Haruna/VLC)
- Cleaner interface suitable for basic playback or advanced editing

Prepares for:
- Frame-accurate navigation features (when keyframing enabled)
- Timeline with keyframe markers
- In/out point cutting tools
- Integration with VideoTools chapter support

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Stu Leak 2025-12-05 10:03:31 -05:00 committed by Stu
parent 5e2171a95e
commit c7d821e03a

71
main.go
View File

@ -197,6 +197,7 @@ type appState struct {
queueOffset fyne.Position
compareFile1 *videoSource
compareFile2 *videoSource
keyframingMode bool // Toggle for frame-accurate editing features
}
func (s *appState) stopPreview() {
@ -558,14 +559,14 @@ func (s *appState) showPlayerView() {
s.stopCompareSessions()
s.active = "player"
header := widget.NewLabelWithStyle("VT Player", fyne.TextAlignLeading, fyne.TextStyle{Bold: true})
// Helper to refresh the view after selection/loads.
refresh := func() {
s.showPlayerView()
}
openFile := widget.NewButton("Open File…", func() {
// Create menu bar
fileMenu := fyne.NewMenu("File",
fyne.NewMenuItem("Open File…", func() {
dlg := dialog.NewFileOpen(func(r fyne.URIReadCloser, err error) {
if err != nil || r == nil {
return
@ -576,9 +577,8 @@ func (s *appState) showPlayerView() {
}, s.window)
dlg.Resize(fyne.NewSize(700, 480))
dlg.Show()
})
addFolder := widget.NewButton("Add Folder…", func() {
}),
fyne.NewMenuItem("Open Folder…", func() {
dlg := dialog.NewFolderOpen(func(l fyne.ListableURI, err error) {
if err != nil || l == nil {
return
@ -591,27 +591,38 @@ func (s *appState) showPlayerView() {
}, s.window)
dlg.Resize(fyne.NewSize(700, 480))
dlg.Show()
})
clearList := widget.NewButton("Clear Playlist", func() {
}),
fyne.NewMenuItemSeparator(),
fyne.NewMenuItem("Clear Playlist", func() {
s.clearVideo()
refresh()
})
clearList.Importance = widget.LowImportance
}),
)
viewMenu := fyne.NewMenu("View",
fyne.NewMenuItem("Playlist", func() {
// Will be implemented with playlist toggle
}),
)
var compareBtn *widget.Button
if len(s.loadedVideos) >= 2 {
compareBtn = widget.NewButton("Compare View", func() {
viewMenu.Items = append(viewMenu.Items, fyne.NewMenuItem("Compare Videos", func() {
s.showCompareView()
})
}))
}
barItems := []fyne.CanvasObject{openFile, addFolder, clearList}
if compareBtn != nil {
barItems = append(barItems, compareBtn)
}
barItems = append(barItems, layout.NewSpacer())
controlsBar := container.NewHBox(barItems...)
toolsMenu := fyne.NewMenu("Tools")
// Keyframing mode toggle
keyframeModeItem := fyne.NewMenuItem("Frame-Accurate Mode", func() {
s.keyframingMode = !s.keyframingMode
refresh()
})
keyframeModeItem.Checked = s.keyframingMode
toolsMenu.Items = append(toolsMenu.Items, keyframeModeItem)
mainMenu := fyne.NewMainMenu(fileMenu, viewMenu, toolsMenu)
s.window.SetMainMenu(mainMenu)
// Player area
var playerArea fyne.CanvasObject
@ -836,7 +847,17 @@ func (s *appState) showPlayerView() {
progressBar := container.NewBorder(nil, nil, currentTime, totalTime, container.NewMax(slider))
volContainer := container.NewHBox(volIcon, container.NewMax(volSlider))
volContainer.Resize(fyne.NewSize(150, 32))
controlRow := container.NewHBox(prevBtn, playBtn, nextBtn, layout.NewSpacer(), playlistToggleBtn, volContainer)
// Center the playback controls
playbackControls := container.NewHBox(prevBtn, playBtn, nextBtn)
// Create control row with centered playback controls
controlRow := container.NewBorder(
nil, nil,
volContainer, // Volume on left
container.NewHBox(playlistToggleBtn), // Playlist toggle on right
container.NewCenter(playbackControls), // Playback controls centered
)
playerArea = container.NewBorder(
nil,
@ -847,13 +868,7 @@ func (s *appState) showPlayerView() {
)
}
mainPanel := container.NewBorder(
container.NewVBox(header, controlsBar, widget.NewSeparator()),
nil,
nil,
nil,
playerArea,
)
mainPanel := playerArea
s.setContent(mainPanel)
}