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
117 lines
3.1 KiB
Go
117 lines
3.1 KiB
Go
package container
|
|
|
|
import (
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/internal/cache"
|
|
intTheme "fyne.io/fyne/v2/internal/theme"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
// ThemeOverride is a container where the child widgets are themed by the specified theme.
|
|
// Containers will be traversed and all child widgets will reflect the theme in this container.
|
|
// This should be used sparingly to avoid a jarring user experience.
|
|
//
|
|
// Since: 2.5
|
|
type ThemeOverride struct {
|
|
widget.BaseWidget
|
|
|
|
Content fyne.CanvasObject
|
|
Theme fyne.Theme
|
|
|
|
holder *fyne.Container
|
|
|
|
mobile bool
|
|
}
|
|
|
|
// NewThemeOverride provides a container where the child widgets are themed by the specified theme.
|
|
// Containers will be traversed and all child widgets will reflect the theme in this container.
|
|
// This should be used sparingly to avoid a jarring user experience.
|
|
//
|
|
// If the content `obj` of this theme override is a container and items are later added to the container or any
|
|
// sub-containers ensure that you call `Refresh()` on this `ThemeOverride` to ensure the new items match the theme.
|
|
//
|
|
// Since: 2.5
|
|
func NewThemeOverride(obj fyne.CanvasObject, th fyne.Theme) *ThemeOverride {
|
|
t := &ThemeOverride{Content: obj, Theme: th, holder: NewStack(obj)}
|
|
t.ExtendBaseWidget(t)
|
|
|
|
cache.OverrideTheme(obj, addFeatures(th, t))
|
|
obj.Refresh() // required as the widgets passed in could have been initially rendered with default theme
|
|
return t
|
|
}
|
|
|
|
func (t *ThemeOverride) CreateRenderer() fyne.WidgetRenderer {
|
|
cache.OverrideTheme(t.Content, addFeatures(t.Theme, t))
|
|
|
|
return &overrideRenderer{parent: t, objs: []fyne.CanvasObject{t.holder}}
|
|
}
|
|
|
|
func (t *ThemeOverride) Refresh() {
|
|
if t.holder.Objects[0] != t.Content {
|
|
t.holder.Objects[0] = t.Content
|
|
t.holder.Refresh()
|
|
}
|
|
|
|
cache.OverrideTheme(t.Content, addFeatures(t.Theme, t))
|
|
t.Content.Refresh()
|
|
t.BaseWidget.Refresh()
|
|
}
|
|
|
|
// SetDeviceIsMobile allows a ThemeOverride container to shape the contained widgets as a mobile device.
|
|
// This will impact containers such as AppTabs and DocTabs, and more in the future, to display a layout
|
|
// that would automatically be used for a mobile device runtime.
|
|
//
|
|
// Since: 2.6
|
|
func (t *ThemeOverride) SetDeviceIsMobile(on bool) {
|
|
t.mobile = on
|
|
t.BaseWidget.Refresh()
|
|
}
|
|
|
|
type featureTheme struct {
|
|
fyne.Theme
|
|
|
|
over *ThemeOverride
|
|
}
|
|
|
|
func addFeatures(th fyne.Theme, o *ThemeOverride) fyne.Theme {
|
|
return &featureTheme{Theme: th, over: o}
|
|
}
|
|
|
|
func (f *featureTheme) Feature(n intTheme.FeatureName) any {
|
|
if n == intTheme.FeatureNameDeviceIsMobile {
|
|
return f.over.mobile
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type overrideRenderer struct {
|
|
parent *ThemeOverride
|
|
|
|
objs []fyne.CanvasObject
|
|
}
|
|
|
|
func (r *overrideRenderer) Destroy() {
|
|
}
|
|
|
|
func (r *overrideRenderer) Layout(s fyne.Size) {
|
|
intTheme.PushRenderingTheme(r.parent.Theme)
|
|
defer intTheme.PopRenderingTheme()
|
|
|
|
r.parent.holder.Resize(s)
|
|
}
|
|
|
|
func (r *overrideRenderer) MinSize() fyne.Size {
|
|
intTheme.PushRenderingTheme(r.parent.Theme)
|
|
defer intTheme.PopRenderingTheme()
|
|
|
|
return r.parent.Content.MinSize()
|
|
}
|
|
|
|
func (r *overrideRenderer) Objects() []fyne.CanvasObject {
|
|
return r.objs
|
|
}
|
|
|
|
func (r *overrideRenderer) Refresh() {
|
|
}
|