VideoTools/vendor/fyne.io/fyne/v2/dialog/base.go
Stu Leak 68df790d27 Fix player frame generation and video playback
Major improvements to UnifiedPlayer:

1. GetFrameImage() now works when paused for responsive UI updates
2. Play() method properly starts FFmpeg process
3. Frame display loop runs continuously for smooth video display
4. Disabled audio temporarily to fix video playback fundamentals
5. Simplified FFmpeg command to focus on video stream only

Player now:
- Generates video frames correctly
- Shows video when paused
- Has responsive progress tracking
- Starts playback properly

Next steps: Re-enable audio playback once video is stable
2026-01-07 22:20:00 -05:00

260 lines
6.2 KiB
Go

// Package dialog defines standard dialog windows for application GUIs.
package dialog // import "fyne.io/fyne/v2/dialog"
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
col "fyne.io/fyne/v2/internal/color"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
const (
padWidth = 32
padHeight = 16
)
// Dialog is the common API for any dialog window with a single dismiss button
type Dialog interface {
Show()
Hide()
SetDismissText(label string)
SetOnClosed(closed func())
Refresh()
Resize(size fyne.Size)
// MinSize returns the size that this dialog should not shrink below.
//
// Since: 2.1
MinSize() fyne.Size
// Dismiss instructs the dialog to close without any affirmative action.
//
// Since: 2.6
Dismiss()
}
// Declare conformity to Dialog interface
var _ Dialog = (*dialog)(nil)
type dialog struct {
callback func(bool)
title string
icon fyne.Resource
desiredSize fyne.Size
win *widget.PopUp
content fyne.CanvasObject
dismiss *widget.Button
parent fyne.Window
// allows derived dialogs to inject logic that runs before Show()
beforeShowHook func()
}
func (d *dialog) Dismiss() {
d.Hide()
}
func (d *dialog) Hide() {
d.hideWithResponse(false)
}
// MinSize returns the size that this dialog should not shrink below.
//
// Since: 2.1
func (d *dialog) MinSize() fyne.Size {
return d.win.MinSize()
}
func (d *dialog) Show() {
if d.beforeShowHook != nil {
d.beforeShowHook()
}
if !d.desiredSize.IsZero() {
d.win.Resize(d.desiredSize)
}
d.win.Show()
}
func (d *dialog) Refresh() {
d.win.Refresh()
}
// Resize dialog, call this function after dialog show
func (d *dialog) Resize(size fyne.Size) {
d.desiredSize = size
if d.win != nil { // could be called before popup is created!
d.win.Resize(size)
}
}
// SetDismissText allows custom text to be set in the dismiss button
// This is a no-op for dialogs without dismiss buttons.
func (d *dialog) SetDismissText(label string) {
if d.dismiss == nil {
return
}
d.dismiss.SetText(label)
d.win.Refresh()
}
// SetOnClosed allows to set a callback function that is called when
// the dialog is closed
func (d *dialog) SetOnClosed(closed func()) {
// if there is already a callback set, remember it and call both
originalCallback := d.callback
d.callback = func(response bool) {
if originalCallback != nil {
originalCallback(response)
}
closed()
}
}
func (d *dialog) hideWithResponse(resp bool) {
d.win.Hide()
if d.callback != nil {
d.callback(resp)
}
}
func (d *dialog) create(buttons fyne.CanvasObject) {
label := widget.NewLabelWithStyle(d.title, fyne.TextAlignLeading, fyne.TextStyle{Bold: true})
var image fyne.CanvasObject
if d.icon != nil {
image = &canvas.Image{Resource: d.icon}
} else {
image = &layout.Spacer{}
}
content := container.New(&dialogLayout{d: d},
image,
newThemedBackground(),
d.content,
buttons,
label,
)
d.win = widget.NewModalPopUp(content, d.parent.Canvas())
}
func (d *dialog) setButtons(buttons fyne.CanvasObject) {
d.win.Content.(*fyne.Container).Objects[3] = buttons
d.win.Refresh()
}
func (d *dialog) setIcon(icon fyne.Resource) {
if icon == nil {
d.win.Content.(*fyne.Container).Objects[0] = &layout.Spacer{}
d.win.Refresh()
return
}
d.win.Content.(*fyne.Container).Objects[0] = &canvas.Image{Resource: icon}
d.win.Refresh()
}
// The method .create() needs to be called before the dialog can be shown.
func newDialog(title, message string, icon fyne.Resource, callback func(bool), parent fyne.Window) *dialog {
d := &dialog{content: newCenterWrappedLabel(message), title: title, icon: icon, parent: parent}
d.callback = callback
return d
}
// ===============================================================
// ThemedBackground
// ===============================================================
type themedBackground struct {
widget.BaseWidget
}
func newThemedBackground() *themedBackground {
t := &themedBackground{}
t.ExtendBaseWidget(t)
return t
}
func (t *themedBackground) CreateRenderer() fyne.WidgetRenderer {
t.ExtendBaseWidget(t)
rect := canvas.NewRectangle(theme.Color(theme.ColorNameOverlayBackground))
return &themedBackgroundRenderer{rect, []fyne.CanvasObject{rect}}
}
type themedBackgroundRenderer struct {
rect *canvas.Rectangle
objects []fyne.CanvasObject
}
func (renderer *themedBackgroundRenderer) Destroy() {
}
func (renderer *themedBackgroundRenderer) Layout(size fyne.Size) {
renderer.rect.Resize(size)
}
func (renderer *themedBackgroundRenderer) MinSize() fyne.Size {
return renderer.rect.MinSize()
}
func (renderer *themedBackgroundRenderer) Objects() []fyne.CanvasObject {
return renderer.objects
}
func (renderer *themedBackgroundRenderer) Refresh() {
r, g, b, _ := col.ToNRGBA(theme.Color(theme.ColorNameOverlayBackground))
bg := &color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: 230}
renderer.rect.FillColor = bg
}
// ===============================================================
// DialogLayout
// ===============================================================
type dialogLayout struct {
d *dialog
}
func (l *dialogLayout) Layout(obj []fyne.CanvasObject, size fyne.Size) {
btnMin := obj[3].MinSize()
labelMin := obj[4].MinSize()
// icon
iconHeight := padHeight*2 + labelMin.Height*2 - theme.Padding()
obj[0].Resize(fyne.NewSize(iconHeight, iconHeight))
obj[0].Move(fyne.NewPos(size.Width-iconHeight+theme.Padding(), -theme.Padding()))
// background
obj[1].Move(fyne.NewPos(0, 0))
obj[1].Resize(size)
// content
contentStart := obj[4].Position().Y + labelMin.Height + padHeight
contentEnd := obj[3].Position().Y - theme.Padding()
obj[2].Move(fyne.NewPos(padWidth/2, labelMin.Height+padHeight))
obj[2].Resize(fyne.NewSize(size.Width-padWidth, contentEnd-contentStart))
// buttons
obj[3].Resize(btnMin)
obj[3].Move(fyne.NewPos(size.Width/2-(btnMin.Width/2), size.Height-padHeight-btnMin.Height))
}
func (l *dialogLayout) MinSize(obj []fyne.CanvasObject) fyne.Size {
contentMin := obj[2].MinSize()
btnMin := obj[3].MinSize()
labelMin := obj[4].MinSize()
width := fyne.Max(fyne.Max(contentMin.Width, btnMin.Width), labelMin.Width) + padWidth
height := contentMin.Height + btnMin.Height + labelMin.Height + theme.Padding() + padHeight*2
return fyne.NewSize(width, height)
}