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
357 lines
9.2 KiB
Go
357 lines
9.2 KiB
Go
// Package theme defines how a Fyne app should look when rendered.
|
|
package theme // import "fyne.io/fyne/v2/theme"
|
|
|
|
import (
|
|
"image/color"
|
|
"os"
|
|
"strings"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/internal/cache"
|
|
internaltheme "fyne.io/fyne/v2/internal/theme"
|
|
)
|
|
|
|
// Keep in mind to add new constants to the tests at test/theme.go.
|
|
const (
|
|
// VariantDark is the version of a theme that satisfies a user preference for a dark look.
|
|
//
|
|
// Since: 2.0
|
|
VariantDark = internaltheme.VariantDark
|
|
|
|
// VariantLight is the version of a theme that satisfies a user preference for a light look.
|
|
//
|
|
// Since: 2.0
|
|
VariantLight = internaltheme.VariantLight
|
|
)
|
|
|
|
var defaultTheme, systemTheme fyne.Theme
|
|
|
|
// DarkTheme defines the built-in dark theme colors and sizes.
|
|
//
|
|
// Deprecated: This method ignores user preference and should not be used, it will be removed in v3.0.
|
|
// If developers want to ignore user preference for theme variant they can set a custom theme.
|
|
func DarkTheme() fyne.Theme {
|
|
theme := &builtinTheme{variant: VariantDark}
|
|
|
|
theme.initFonts()
|
|
return theme
|
|
}
|
|
|
|
// DefaultTheme returns a built-in theme that can adapt to the user preference of light or dark colors.
|
|
//
|
|
// Since: 2.0
|
|
func DefaultTheme() fyne.Theme {
|
|
if defaultTheme == nil {
|
|
defaultTheme = setupDefaultTheme()
|
|
}
|
|
|
|
// check system too
|
|
if systemTheme != nil {
|
|
return systemTheme
|
|
}
|
|
|
|
return defaultTheme
|
|
}
|
|
|
|
// LightTheme defines the built-in light theme colors and sizes.
|
|
//
|
|
// Deprecated: This method ignores user preference and should not be used, it will be removed in v3.0.
|
|
// If developers want to ignore user preference for theme variant they can set a custom theme.
|
|
func LightTheme() fyne.Theme {
|
|
theme := &builtinTheme{variant: VariantLight}
|
|
|
|
theme.initFonts()
|
|
return theme
|
|
}
|
|
|
|
type builtinTheme struct {
|
|
variant fyne.ThemeVariant
|
|
|
|
regular, bold, italic, boldItalic, monospace, symbol fyne.Resource
|
|
}
|
|
|
|
func (t *builtinTheme) initFonts() {
|
|
t.regular = regular
|
|
t.bold = bold
|
|
t.italic = italic
|
|
t.boldItalic = bolditalic
|
|
t.monospace = monospace
|
|
t.symbol = symbol
|
|
|
|
font := os.Getenv("FYNE_FONT")
|
|
if font != "" {
|
|
t.regular = loadCustomFont(font, "Regular", regular)
|
|
if t.regular == regular { // failed to load
|
|
t.bold = loadCustomFont(font, "Bold", bold)
|
|
t.italic = loadCustomFont(font, "Italic", italic)
|
|
t.boldItalic = loadCustomFont(font, "BoldItalic", bolditalic)
|
|
} else { // first custom font loaded, fall back to that
|
|
t.bold = loadCustomFont(font, "Bold", t.regular)
|
|
t.italic = loadCustomFont(font, "Italic", t.regular)
|
|
t.boldItalic = loadCustomFont(font, "BoldItalic", t.regular)
|
|
}
|
|
}
|
|
font = os.Getenv("FYNE_FONT_MONOSPACE")
|
|
if font != "" {
|
|
t.monospace = loadCustomFont(font, "Regular", monospace)
|
|
}
|
|
font = os.Getenv("FYNE_FONT_SYMBOL")
|
|
if font != "" {
|
|
t.symbol = loadCustomFont(font, "Regular", symbol)
|
|
}
|
|
}
|
|
|
|
func (t *builtinTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
|
|
if t.variant != internaltheme.VariantNameUserPreference {
|
|
v = t.variant
|
|
}
|
|
|
|
primary := fyne.CurrentApp().Settings().PrimaryColor()
|
|
if n == ColorNamePrimary || n == ColorNameHyperlink {
|
|
return internaltheme.PrimaryColorNamed(primary)
|
|
} else if n == ColorNameForegroundOnPrimary {
|
|
return internaltheme.ForegroundOnPrimaryColorNamed(primary)
|
|
} else if n == ColorNameFocus {
|
|
return focusColorNamed(primary)
|
|
} else if n == ColorNameSelection {
|
|
return selectionColorNamed(primary)
|
|
}
|
|
|
|
if v == VariantLight {
|
|
return lightPaletteColorNamed(n)
|
|
}
|
|
|
|
return darkPaletteColorNamed(n)
|
|
}
|
|
|
|
func (t *builtinTheme) Font(style fyne.TextStyle) fyne.Resource {
|
|
if style.Monospace {
|
|
return t.monospace
|
|
}
|
|
if style.Bold {
|
|
if style.Italic {
|
|
return t.boldItalic
|
|
}
|
|
return t.bold
|
|
}
|
|
if style.Italic {
|
|
return t.italic
|
|
}
|
|
if style.Symbol {
|
|
return t.symbol
|
|
}
|
|
return t.regular
|
|
}
|
|
|
|
// Current returns the theme that is currently used for the running application.
|
|
// It looks up based on user preferences and application configuration.
|
|
//
|
|
// Since: 2.5
|
|
func Current() fyne.Theme {
|
|
app := fyne.CurrentApp()
|
|
if app == nil {
|
|
return DarkTheme()
|
|
}
|
|
currentTheme := app.Settings().Theme()
|
|
if currentTheme == nil {
|
|
return DarkTheme()
|
|
}
|
|
|
|
return internaltheme.CurrentlyRenderingWithFallback(currentTheme)
|
|
}
|
|
|
|
// CurrentForWidget returns the theme that is currently used for the specified widget.
|
|
// It looks for widget overrides and falls back to the application's current theme.
|
|
//
|
|
// Since: 2.5
|
|
func CurrentForWidget(w fyne.CanvasObject) fyne.Theme {
|
|
if custom := cache.WidgetTheme(w); custom != nil {
|
|
return custom
|
|
}
|
|
|
|
return Current()
|
|
}
|
|
|
|
func currentVariant() fyne.ThemeVariant {
|
|
if std, ok := Current().(*builtinTheme); ok {
|
|
if std.variant != internaltheme.VariantNameUserPreference {
|
|
return std.variant // override if using the old LightTheme() or DarkTheme() constructor
|
|
}
|
|
}
|
|
|
|
return fyne.CurrentApp().Settings().ThemeVariant()
|
|
}
|
|
|
|
func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color {
|
|
switch name {
|
|
case ColorNameBackground:
|
|
return colorDarkBackground
|
|
case ColorNameButton:
|
|
return colorDarkButton
|
|
case ColorNameDisabled:
|
|
return colorDarkDisabled
|
|
case ColorNameDisabledButton:
|
|
return colorDarkDisabledButton
|
|
case ColorNameError:
|
|
return colorDarkError
|
|
case ColorNameForeground:
|
|
return colorDarkForeground
|
|
case ColorNameForegroundOnError:
|
|
return colorDarkForegroundOnError
|
|
case ColorNameForegroundOnSuccess:
|
|
return colorDarkForegroundOnSuccess
|
|
case ColorNameForegroundOnWarning:
|
|
return colorDarkForegroundOnWarning
|
|
case ColorNameHover:
|
|
return colorDarkHover
|
|
case ColorNameHeaderBackground:
|
|
return colorDarkHeaderBackground
|
|
case ColorNameInputBackground:
|
|
return colorDarkInputBackground
|
|
case ColorNameInputBorder:
|
|
return colorDarkInputBorder
|
|
case ColorNameMenuBackground:
|
|
return colorDarkMenuBackground
|
|
case ColorNameOverlayBackground:
|
|
return colorDarkOverlayBackground
|
|
case ColorNamePlaceHolder:
|
|
return colorDarkPlaceholder
|
|
case ColorNamePressed:
|
|
return colorDarkPressed
|
|
case ColorNameScrollBar:
|
|
return colorDarkScrollBar
|
|
case ColorNameScrollBarBackground:
|
|
return colorDarkScrollBarBackground
|
|
case ColorNameSeparator:
|
|
return colorDarkSeparator
|
|
case ColorNameShadow:
|
|
return colorDarkShadow
|
|
case ColorNameSuccess:
|
|
return colorDarkSuccess
|
|
case ColorNameWarning:
|
|
return colorDarkWarning
|
|
}
|
|
|
|
return color.Transparent
|
|
}
|
|
|
|
func focusColorNamed(name string) color.NRGBA {
|
|
switch name {
|
|
case ColorRed:
|
|
return colorLightFocusRed
|
|
case ColorOrange:
|
|
return colorLightFocusOrange
|
|
case ColorYellow:
|
|
return colorLightFocusYellow
|
|
case ColorGreen:
|
|
return colorLightFocusGreen
|
|
case ColorPurple:
|
|
return colorLightFocusPurple
|
|
case ColorBrown:
|
|
return colorLightFocusBrown
|
|
case ColorGray:
|
|
return colorLightFocusGray
|
|
}
|
|
|
|
// We return the value for ColorBlue for every other value.
|
|
// There is no need to have it in the switch above.
|
|
return colorLightFocusBlue
|
|
}
|
|
|
|
func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color {
|
|
switch name {
|
|
case ColorNameBackground:
|
|
return colorLightBackground
|
|
case ColorNameButton:
|
|
return colorLightButton
|
|
case ColorNameDisabled:
|
|
return colorLightDisabled
|
|
case ColorNameDisabledButton:
|
|
return colorLightDisabledButton
|
|
case ColorNameError:
|
|
return colorLightError
|
|
case ColorNameForeground:
|
|
return colorLightForeground
|
|
case ColorNameForegroundOnError:
|
|
return colorLightForegroundOnError
|
|
case ColorNameForegroundOnSuccess:
|
|
return colorLightForegroundOnSuccess
|
|
case ColorNameForegroundOnWarning:
|
|
return colorLightForegroundOnWarning
|
|
case ColorNameHover:
|
|
return colorLightHover
|
|
case ColorNameHeaderBackground:
|
|
return colorLightHeaderBackground
|
|
case ColorNameInputBackground:
|
|
return colorLightInputBackground
|
|
case ColorNameInputBorder:
|
|
return colorLightInputBorder
|
|
case ColorNameMenuBackground:
|
|
return colorLightMenuBackground
|
|
case ColorNameOverlayBackground:
|
|
return colorLightOverlayBackground
|
|
case ColorNamePlaceHolder:
|
|
return colorLightPlaceholder
|
|
case ColorNamePressed:
|
|
return colorLightPressed
|
|
case ColorNameScrollBar:
|
|
return colorLightScrollBar
|
|
case ColorNameScrollBarBackground:
|
|
return colorLightScrollBarBackground
|
|
case ColorNameSeparator:
|
|
return colorLightSeparator
|
|
case ColorNameShadow:
|
|
return colorLightShadow
|
|
case ColorNameSuccess:
|
|
return colorLightSuccess
|
|
case ColorNameWarning:
|
|
return colorLightWarning
|
|
}
|
|
|
|
return color.Transparent
|
|
}
|
|
|
|
func loadCustomFont(env, variant string, fallback fyne.Resource) fyne.Resource {
|
|
variantPath := strings.ReplaceAll(env, "Regular", variant)
|
|
|
|
res, err := fyne.LoadResourceFromPath(variantPath)
|
|
if err != nil {
|
|
fyne.LogError("Error loading specified font", err)
|
|
return fallback
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func selectionColorNamed(name string) color.NRGBA {
|
|
switch name {
|
|
case ColorRed:
|
|
return colorLightSelectionRed
|
|
case ColorOrange:
|
|
return colorLightSelectionOrange
|
|
case ColorYellow:
|
|
return colorLightSelectionYellow
|
|
case ColorGreen:
|
|
return colorLightSelectionGreen
|
|
case ColorPurple:
|
|
return colorLightSelectionPurple
|
|
case ColorBrown:
|
|
return colorLightSelectionBrown
|
|
case ColorGray:
|
|
return colorLightSelectionGray
|
|
}
|
|
|
|
// We return the value for ColorBlue for every other value.
|
|
// There is no need to have it in the switch above.
|
|
return colorLightSelectionBlue
|
|
}
|
|
|
|
func setupDefaultTheme() fyne.Theme {
|
|
theme := &builtinTheme{variant: internaltheme.VariantNameUserPreference}
|
|
theme.initFonts()
|
|
|
|
systemTheme = setupSystemTheme(theme)
|
|
|
|
return theme
|
|
}
|