VideoTools/vendor/fyne.io/fyne/v2/test/driver.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

154 lines
3.6 KiB
Go

package test
import (
"image"
"sync"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/internal/async"
intdriver "fyne.io/fyne/v2/internal/driver"
"fyne.io/fyne/v2/internal/painter"
"fyne.io/fyne/v2/internal/painter/software"
intRepo "fyne.io/fyne/v2/internal/repository"
"fyne.io/fyne/v2/storage/repository"
)
// SoftwarePainter describes a simple type that can render canvases
type SoftwarePainter interface {
Paint(fyne.Canvas) image.Image
}
type driver struct {
device device
painter SoftwarePainter
windows []fyne.Window
windowsMutex sync.RWMutex
}
// Declare conformity with Driver
var _ fyne.Driver = (*driver)(nil)
// NewDriver sets up and registers a new dummy driver for test purpose
func NewDriver() fyne.Driver {
drv := &driver{windowsMutex: sync.RWMutex{}}
repository.Register("file", intRepo.NewFileRepository())
httpHandler := intRepo.NewHTTPRepository()
repository.Register("http", httpHandler)
repository.Register("https", httpHandler)
// make a single dummy window for rendering tests
drv.CreateWindow("")
return drv
}
// NewDriverWithPainter creates a new dummy driver that will pass the given
// painter to all canvases created
func NewDriverWithPainter(painter SoftwarePainter) fyne.Driver {
return &driver{painter: painter}
}
// DoFromGoroutine on a test driver ignores the wait flag as our threading is simple
func (d *driver) DoFromGoroutine(f func(), _ bool) {
// Tests all run on a single (but potentially different per-test) thread
async.EnsureNotMain(f)
}
func (d *driver) AbsolutePositionForObject(co fyne.CanvasObject) fyne.Position {
c := d.CanvasForObject(co)
if c == nil {
return fyne.NewPos(0, 0)
}
tc := c.(*canvas)
pos := intdriver.AbsolutePositionForObject(co, tc.objectTrees())
inset, _ := c.InteractiveArea()
return pos.Subtract(inset)
}
func (d *driver) AllWindows() []fyne.Window {
d.windowsMutex.RLock()
defer d.windowsMutex.RUnlock()
return d.windows
}
func (d *driver) CanvasForObject(fyne.CanvasObject) fyne.Canvas {
d.windowsMutex.RLock()
defer d.windowsMutex.RUnlock()
// cheating: probably the last created window is meant
return d.windows[len(d.windows)-1].Canvas()
}
func (d *driver) CreateWindow(title string) fyne.Window {
c := NewCanvas().(*canvas)
if d.painter != nil {
c.painter = d.painter
} else {
c.painter = software.NewPainter()
}
w := &window{canvas: c, driver: d, title: title}
d.windowsMutex.Lock()
d.windows = append(d.windows, w)
d.windowsMutex.Unlock()
return w
}
func (d *driver) Device() fyne.Device {
return &d.device
}
// RenderedTextSize looks up how bit a string would be if drawn on screen
func (d *driver) RenderedTextSize(text string, size float32, style fyne.TextStyle, source fyne.Resource) (fyne.Size, float32) {
return painter.RenderedTextSize(text, size, style, source)
}
func (d *driver) Run() {
// no-op
}
func (d *driver) StartAnimation(a *fyne.Animation) {
// currently no animations in test app, we just initialise it and leave
a.Tick(1.0)
}
func (d *driver) StopAnimation(a *fyne.Animation) {
// currently no animations in test app, do nothing
}
func (d *driver) Quit() {
// no-op
}
func (d *driver) Clipboard() fyne.Clipboard {
return nil
}
func (d *driver) removeWindow(w *window) {
d.windowsMutex.Lock()
i := 0
for _, win := range d.windows {
if win == w {
break
}
i++
}
copy(d.windows[i:], d.windows[i+1:])
d.windows[len(d.windows)-1] = nil // Allow the garbage collector to reclaim the memory.
d.windows = d.windows[:len(d.windows)-1]
d.windowsMutex.Unlock()
}
func (d *driver) DoubleTapDelay() time.Duration {
return 300 * time.Millisecond
}
func (d *driver) SetDisableScreenBlanking(_ bool) {
// no-op for test
}