Give video pane dedicated transport bar
This commit is contained in:
parent
2c75a2fd75
commit
30eeaef753
89
main.go
89
main.go
|
|
@ -7305,10 +7305,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make panel sizes responsive with modest minimums to avoid forcing the window beyond the screen
|
// Make panel sizes responsive with modest minimums to avoid forcing the window beyond the screen.
|
||||||
// Use a smaller minimum size to allow window to be more flexible
|
// The video pane should be the primary region; keep a stronger minimum.
|
||||||
// The video pane will scale to fit available space
|
videoPanel := buildVideoPane(state, fyne.NewSize(640, 360), src, updateCover)
|
||||||
videoPanel := buildVideoPane(state, fyne.NewSize(320, 180), src, updateCover)
|
|
||||||
metaPanel, metaCoverUpdate := buildMetadataPanel(state, src, fyne.NewSize(0, 200))
|
metaPanel, metaCoverUpdate := buildMetadataPanel(state, src, fyne.NewSize(0, 200))
|
||||||
updateMetaCover = metaCoverUpdate
|
updateMetaCover = metaCoverUpdate
|
||||||
|
|
||||||
|
|
@ -9872,24 +9871,24 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
snippetRow = container.NewHBox(snippetBtn, snippetOptionsBtn, layout.NewSpacer(), snippetHint)
|
snippetRow = container.NewHBox(snippetBtn, snippetOptionsBtn, layout.NewSpacer(), snippetHint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack video and metadata with 10px spacing between them
|
// Stack options and metadata with a small gap on the right.
|
||||||
// Create a 10px spacer using a container with fixed size
|
|
||||||
spacerRect := canvas.NewRectangle(color.Transparent)
|
spacerRect := canvas.NewRectangle(color.Transparent)
|
||||||
spacerRect.SetMinSize(fyne.NewSize(1, 10))
|
spacerRect.SetMinSize(fyne.NewSize(1, 10))
|
||||||
spacer := container.NewMax(spacerRect)
|
spacer := container.NewMax(spacerRect)
|
||||||
spacer.Resize(fyne.NewSize(1, 10))
|
spacer.Resize(fyne.NewSize(1, 10))
|
||||||
|
|
||||||
leftColumn := container.NewVBox(videoPanel, spacer, metaPanel)
|
leftColumn := container.NewVBox(videoPanel)
|
||||||
|
rightColumn := container.NewVBox(optionsPanel, spacer, metaPanel)
|
||||||
|
|
||||||
// Add minimal spacing (10px) between left and right panels
|
// Add minimal spacing (10px) between left and right panels
|
||||||
horizontalSpacer := canvas.NewRectangle(color.Transparent)
|
horizontalSpacer := canvas.NewRectangle(color.Transparent)
|
||||||
horizontalSpacer.SetMinSize(fyne.NewSize(10, 1))
|
horizontalSpacer.SetMinSize(fyne.NewSize(10, 1))
|
||||||
|
|
||||||
// Split: left side (video + metadata) takes 50% | right side (options) takes 50%
|
// Split: left side (player) takes priority | right side (controls + metadata).
|
||||||
mainSplit := container.NewHSplit(
|
mainSplit := container.NewHSplit(
|
||||||
leftColumn,
|
leftColumn,
|
||||||
optionsPanel)
|
rightColumn)
|
||||||
mainSplit.SetOffset(0.5) // 50/50 split
|
mainSplit.SetOffset(0.65) // 65/35 split
|
||||||
|
|
||||||
// Add horizontal padding around the split (10px on each side)
|
// Add horizontal padding around the split (10px on each side)
|
||||||
mainContent := container.NewPadded(mainSplit)
|
mainContent := container.NewPadded(mainSplit)
|
||||||
|
|
@ -10642,34 +10641,24 @@ func buildVideoPane(state *appState, min fyne.Size, src *videoSource, onCover fu
|
||||||
outer.CornerRadius = 8
|
outer.CornerRadius = 8
|
||||||
outer.StrokeColor = gridColor
|
outer.StrokeColor = gridColor
|
||||||
outer.StrokeWidth = 1
|
outer.StrokeWidth = 1
|
||||||
defaultAspect := 9.0 / 16.0
|
defaultAspect := 16.0 / 9.0
|
||||||
if src != nil && src.Width > 0 && src.Height > 0 {
|
if src != nil && src.Width > 0 && src.Height > 0 {
|
||||||
defaultAspect = float64(src.Height) / float64(src.Width)
|
defaultAspect = float64(src.Width) / float64(src.Height)
|
||||||
}
|
}
|
||||||
baseWidth := float64(min.Width)
|
targetWidth := float32(min.Width)
|
||||||
targetWidth := float32(baseWidth)
|
|
||||||
_ = defaultAspect
|
|
||||||
targetHeight := float32(min.Height)
|
targetHeight := float32(min.Height)
|
||||||
if state != nil && state.window != nil {
|
if targetWidth <= 0 {
|
||||||
winSize := state.window.Canvas().Size()
|
targetWidth = 320
|
||||||
if winSize.Height >= 900 {
|
}
|
||||||
desiredHeight := float32(360)
|
if targetHeight <= 0 {
|
||||||
desiredWidth := desiredHeight / float32(defaultAspect)
|
targetHeight = 180
|
||||||
maxWidth := winSize.Width - 48
|
}
|
||||||
maxHeight := winSize.Height - 200
|
aspect := float32(defaultAspect)
|
||||||
if maxWidth > 0 && desiredWidth > maxWidth {
|
stageWidth := targetWidth
|
||||||
desiredWidth = maxWidth
|
stageHeight := stageWidth / aspect
|
||||||
desiredHeight = desiredWidth * float32(defaultAspect)
|
if stageHeight < targetHeight {
|
||||||
}
|
stageHeight = targetHeight
|
||||||
if maxHeight > 0 && desiredHeight > maxHeight {
|
stageWidth = stageHeight * aspect
|
||||||
desiredHeight = maxHeight
|
|
||||||
desiredWidth = desiredHeight / float32(defaultAspect)
|
|
||||||
}
|
|
||||||
if desiredWidth > 0 && desiredHeight > 0 {
|
|
||||||
targetWidth = desiredWidth
|
|
||||||
targetHeight = desiredHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Don't set rigid MinSize - let the outer container be flexible
|
// Don't set rigid MinSize - let the outer container be flexible
|
||||||
// outer.SetMinSize(fyne.NewSize(targetWidth, targetHeight))
|
// outer.SetMinSize(fyne.NewSize(targetWidth, targetHeight))
|
||||||
|
|
@ -10756,13 +10745,7 @@ func buildVideoPane(state *appState, min fyne.Size, src *videoSource, onCover fu
|
||||||
stage := canvas.NewRectangle(utils.MustHex("#0F1529"))
|
stage := canvas.NewRectangle(utils.MustHex("#0F1529"))
|
||||||
stage.CornerRadius = 6
|
stage.CornerRadius = 6
|
||||||
// Set minimum size based on source aspect ratio
|
// Set minimum size based on source aspect ratio
|
||||||
stageWidth := float32(200)
|
// Set minimum size based on source aspect ratio.
|
||||||
stageHeight := float32(113) // Default 16:9
|
|
||||||
if src != nil && src.Width > 0 && src.Height > 0 {
|
|
||||||
// Calculate height based on actual aspect ratio
|
|
||||||
aspectRatio := float32(src.Width) / float32(src.Height)
|
|
||||||
stageHeight = stageWidth / aspectRatio
|
|
||||||
}
|
|
||||||
stage.SetMinSize(fyne.NewSize(stageWidth, stageHeight))
|
stage.SetMinSize(fyne.NewSize(stageWidth, stageHeight))
|
||||||
// Overlay the image directly so it fills the stage while preserving aspect.
|
// Overlay the image directly so it fills the stage while preserving aspect.
|
||||||
videoStage := container.NewMax(stage, img)
|
videoStage := container.NewMax(stage, img)
|
||||||
|
|
@ -10965,12 +10948,12 @@ func buildVideoPane(state *appState, min fyne.Size, src *videoSource, onCover fu
|
||||||
fullBtn := utils.MakeIconButton("⛶", "Toggle fullscreen", func() {
|
fullBtn := utils.MakeIconButton("⛶", "Toggle fullscreen", func() {
|
||||||
// Placeholder: embed fullscreen toggle into playback surface later.
|
// Placeholder: embed fullscreen toggle into playback surface later.
|
||||||
})
|
})
|
||||||
volBox := container.NewHBox(volIcon, container.NewMax(volSlider))
|
volBox := container.NewHBox(volIcon, container.NewMax(volSlider))
|
||||||
progress := container.NewBorder(nil, nil, currentTime, totalTime, container.NewMax(slider))
|
progress := container.NewBorder(nil, nil, currentTime, totalTime, container.NewMax(slider))
|
||||||
controls = container.NewVBox(
|
controls = container.NewVBox(
|
||||||
container.NewHBox(prevFrameBtn, playBtn, nextFrameBtn, fullBtn, coverBtn, saveFrameBtn, importBtn, layout.NewSpacer(), frameLabel, volBox),
|
container.NewHBox(prevFrameBtn, playBtn, nextFrameBtn, fullBtn, coverBtn, saveFrameBtn, importBtn, layout.NewSpacer(), frameLabel, volBox),
|
||||||
progress,
|
progress,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
slider := widget.NewSlider(0, math.Max(1, float64(len(src.PreviewFrames)-1)))
|
slider := widget.NewSlider(0, math.Max(1, float64(len(src.PreviewFrames)-1)))
|
||||||
slider.Step = 1
|
slider.Step = 1
|
||||||
|
|
@ -11016,17 +10999,17 @@ func buildVideoPane(state *appState, min fyne.Size, src *videoSource, onCover fu
|
||||||
}
|
}
|
||||||
|
|
||||||
barBg := canvas.NewRectangle(color.NRGBA{R: 12, G: 17, B: 31, A: 180})
|
barBg := canvas.NewRectangle(color.NRGBA{R: 12, G: 17, B: 31, A: 180})
|
||||||
barBg.SetMinSize(fyne.NewSize(targetWidth-32, 72))
|
barBg.SetMinSize(fyne.NewSize(0, 72))
|
||||||
overlayBar := container.NewMax(barBg, container.NewPadded(controls))
|
transportBar := container.NewMax(barBg, container.NewPadded(controls))
|
||||||
|
|
||||||
overlay := container.NewVBox(layout.NewSpacer(), overlayBar)
|
videoWithOverlay := videoStage
|
||||||
videoWithOverlay := container.NewMax(videoStage, overlay)
|
|
||||||
if usePlayer {
|
if usePlayer {
|
||||||
state.setPlayerSurface(videoStage, int(targetWidth-12), int(targetHeight-12))
|
state.setPlayerSurface(videoStage, int(stageWidth), int(stageHeight))
|
||||||
}
|
}
|
||||||
|
|
||||||
stack := container.NewVBox(
|
stack := container.NewVBox(
|
||||||
container.NewPadded(videoWithOverlay),
|
container.NewPadded(videoWithOverlay),
|
||||||
|
container.NewPadded(transportBar),
|
||||||
)
|
)
|
||||||
return container.NewMax(outer, container.NewPadded(stack))
|
return container.NewMax(outer, container.NewPadded(stack))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user