Implements intuitive video player interactions for enhanced user experience. Video Interaction Features: - Double-click video area to toggle fullscreen - Right-click video area to play/pause - Single-click does nothing (reserved for future use) - Transparent tappable overlay on video canvas Implementation: - Created TappableOverlay widget in internal/ui/tappable.go - Invisible widget captures tap, double-tap, and secondary-tap events - Extends widget.BaseWidget for Fyne compatibility - Added overlay to stage container after video image User Experience: - Double-click anywhere on video → instant fullscreen - Right-click anywhere on video → quick play/pause - Works alongside existing keyboard shortcuts (F11, Space, ESC) - Play button icon updates when using right-click Technical Details: - TappableOverlay has no visual representation - Implements Tapped(), DoubleTapped(), TappedSecondary() - Callbacks are configurable per instance - Positioned as top layer in container.NewMax() stack Usage: 1. Load a video 2. Double-click video to enter fullscreen 3. Right-click to pause/play 4. ESC or F11 to exit fullscreen Next Steps: - Consider adding single-click functionality - Add visual feedback for interactions - Implement mouse cursor auto-hide in fullscreen 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
package ui
|
|
|
|
import (
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
// TappableOverlay is an invisible widget that captures tap and double-tap events
|
|
type TappableOverlay struct {
|
|
widget.BaseWidget
|
|
OnTapped func()
|
|
OnDoubleTapped func()
|
|
OnSecondaryTapped func()
|
|
}
|
|
|
|
// NewTappableOverlay creates a new tappable overlay
|
|
func NewTappableOverlay(onTapped, onDoubleTapped, onSecondaryTapped func()) *TappableOverlay {
|
|
t := &TappableOverlay{
|
|
OnTapped: onTapped,
|
|
OnDoubleTapped: onDoubleTapped,
|
|
OnSecondaryTapped: onSecondaryTapped,
|
|
}
|
|
t.ExtendBaseWidget(t)
|
|
return t
|
|
}
|
|
|
|
// Tapped handles single tap events
|
|
func (t *TappableOverlay) Tapped(*fyne.PointEvent) {
|
|
if t.OnTapped != nil {
|
|
t.OnTapped()
|
|
}
|
|
}
|
|
|
|
// TappedSecondary handles right-click events
|
|
func (t *TappableOverlay) TappedSecondary(*fyne.PointEvent) {
|
|
if t.OnSecondaryTapped != nil {
|
|
t.OnSecondaryTapped()
|
|
}
|
|
}
|
|
|
|
// DoubleTapped handles double-tap events
|
|
func (t *TappableOverlay) DoubleTapped(*fyne.PointEvent) {
|
|
if t.OnDoubleTapped != nil {
|
|
t.OnDoubleTapped()
|
|
}
|
|
}
|
|
|
|
// CreateRenderer implements fyne.Widget
|
|
func (t *TappableOverlay) CreateRenderer() fyne.WidgetRenderer {
|
|
return &tappableRenderer{}
|
|
}
|
|
|
|
// MinSize returns minimum size (should fill parent)
|
|
func (t *TappableOverlay) MinSize() fyne.Size {
|
|
return fyne.NewSize(1, 1)
|
|
}
|
|
|
|
type tappableRenderer struct{}
|
|
|
|
func (r *tappableRenderer) Layout(size fyne.Size) {}
|
|
func (r *tappableRenderer) MinSize() fyne.Size { return fyne.NewSize(1, 1) }
|
|
func (r *tappableRenderer) Refresh() {}
|
|
func (r *tappableRenderer) Objects() []fyne.CanvasObject { return nil }
|
|
func (r *tappableRenderer) Destroy() {}
|