VideoTools/vendor/fyne.io/fyne/v2/widget/label.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

247 lines
5.5 KiB
Go

package widget
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/data/binding"
"fyne.io/fyne/v2/theme"
)
var _ fyne.Widget = (*Label)(nil)
// Label widget is a label component with appropriate padding and layout.
type Label struct {
BaseWidget
Text string
Alignment fyne.TextAlign // The alignment of the text
Wrapping fyne.TextWrap // The wrapping of the text
TextStyle fyne.TextStyle // The style of the label text
// The truncation mode of the text
//
// Since: 2.4
Truncation fyne.TextTruncation
// Importance informs how the label should be styled, i.e. warning or disabled
//
// Since: 2.4
Importance Importance
// The theme size name for the text size of the label
//
// Since: 2.6
SizeName fyne.ThemeSizeName
// If set to true, Selectable indicates that this label should support select interaction
// to allow the text to be copied.
//
//Since: 2.6
Selectable bool
provider *RichText
binder basicBinder
selection *focusSelectable
}
// NewLabel creates a new label widget with the set text content
func NewLabel(text string) *Label {
return NewLabelWithStyle(text, fyne.TextAlignLeading, fyne.TextStyle{})
}
// NewLabelWithData returns a Label widget connected to the specified data source.
//
// Since: 2.0
func NewLabelWithData(data binding.String) *Label {
label := NewLabel("")
label.Bind(data)
return label
}
// NewLabelWithStyle creates a new label widget with the set text content
func NewLabelWithStyle(text string, alignment fyne.TextAlign, style fyne.TextStyle) *Label {
l := &Label{
Text: text,
Alignment: alignment,
TextStyle: style,
}
l.ExtendBaseWidget(l)
return l
}
// Bind connects the specified data source to this Label.
// The current value will be displayed and any changes in the data will cause the widget to update.
//
// Since: 2.0
func (l *Label) Bind(data binding.String) {
l.binder.SetCallback(l.updateFromData) // This could only be done once, maybe in ExtendBaseWidget?
l.binder.Bind(data)
}
// CreateRenderer is a private method to Fyne which links this widget to its renderer
func (l *Label) CreateRenderer() fyne.WidgetRenderer {
l.provider = NewRichTextWithText(l.Text)
l.ExtendBaseWidget(l)
l.syncSegments()
l.selection = &focusSelectable{}
l.selection.ExtendBaseWidget(l.selection)
l.selection.focus = l.selection
l.selection.style = l.TextStyle
l.selection.theme = l.Theme()
l.selection.provider = l.provider
return &labelRenderer{l}
}
// MinSize returns the size that this label should not shrink below.
func (l *Label) MinSize() fyne.Size {
l.ExtendBaseWidget(l)
return l.BaseWidget.MinSize()
}
// Refresh triggers a redraw of the label.
func (l *Label) Refresh() {
if l.provider == nil { // not created until visible
return
}
l.syncSegments()
l.provider.Refresh()
l.BaseWidget.Refresh()
}
// SelectedText returns the text currently selected in this Label.
// If the label is not Selectable it will return an empty string.
// If there is no selection it will return the empty string.
//
// Since: 2.6
func (l *Label) SelectedText() string {
if !l.Selectable || l.selection == nil {
return ""
}
return l.selection.SelectedText()
}
// SetText sets the text of the label
func (l *Label) SetText(text string) {
l.Text = text
l.Refresh()
}
// Unbind disconnects any configured data source from this Label.
// The current value will remain at the last value of the data source.
//
// Since: 2.0
func (l *Label) Unbind() {
l.binder.Unbind()
}
func (l *Label) syncSegments() {
var color fyne.ThemeColorName
switch l.Importance {
case LowImportance:
color = theme.ColorNameDisabled
case MediumImportance:
color = theme.ColorNameForeground
case HighImportance:
color = theme.ColorNamePrimary
case DangerImportance:
color = theme.ColorNameError
case WarningImportance:
color = theme.ColorNameWarning
case SuccessImportance:
color = theme.ColorNameSuccess
default:
color = theme.ColorNameForeground
}
sizeName := l.SizeName
if sizeName == "" {
sizeName = theme.SizeNameText
}
l.provider.Wrapping = l.Wrapping
l.provider.Truncation = l.Truncation
l.provider.Segments[0].(*TextSegment).Style = RichTextStyle{
Alignment: l.Alignment,
ColorName: color,
Inline: true,
TextStyle: l.TextStyle,
SizeName: sizeName,
}
l.provider.Segments[0].(*TextSegment).Text = l.Text
}
func (l *Label) updateFromData(data binding.DataItem) {
if data == nil {
return
}
textSource, ok := data.(binding.String)
if !ok {
return
}
val, err := textSource.Get()
if err != nil {
fyne.LogError("Error getting current data value", err)
return
}
l.SetText(val)
}
type labelRenderer struct {
l *Label
}
func (r *labelRenderer) Destroy() {
}
func (r *labelRenderer) Layout(s fyne.Size) {
r.l.selection.Resize(s)
r.l.provider.Resize(s)
}
func (r *labelRenderer) MinSize() fyne.Size {
return r.l.provider.MinSize()
}
func (r *labelRenderer) Objects() []fyne.CanvasObject {
if !r.l.Selectable {
return []fyne.CanvasObject{r.l.provider}
}
return []fyne.CanvasObject{r.l.selection, r.l.provider}
}
func (r *labelRenderer) Refresh() {
r.l.provider.Refresh()
sel := r.l.selection
if !r.l.Selectable || sel == nil {
return
}
sel.sizeName = r.l.SizeName
sel.style = r.l.TextStyle
sel.theme = r.l.Theme()
sel.Refresh()
}
type focusSelectable struct {
selectable
}
func (f *focusSelectable) FocusGained() {
f.focussed = true
f.Refresh()
}
func (f *focusSelectable) FocusLost() {
f.focussed = false
f.Refresh()
}
func (f *focusSelectable) TypedKey(*fyne.KeyEvent) {
}
func (f *focusSelectable) TypedRune(rune) {
}