| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package widget
- import (
- "image/color"
- "sync"
- "time"
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- col "fyne.io/fyne/v2/internal/color"
- "fyne.io/fyne/v2/theme"
- )
- const cursorInterruptTime = 300 * time.Millisecond
- type entryCursorAnimation struct {
- mu *sync.RWMutex
- cursor *canvas.Rectangle
- anim *fyne.Animation
- lastInterruptTime time.Time
- timeNow func() time.Time // useful for testing
- }
- func newEntryCursorAnimation(cursor *canvas.Rectangle) *entryCursorAnimation {
- a := &entryCursorAnimation{mu: &sync.RWMutex{}, cursor: cursor, timeNow: time.Now}
- return a
- }
- // creates fyne animation
- func (a *entryCursorAnimation) createAnim(inverted bool) *fyne.Animation {
- cursorOpaque := theme.PrimaryColor()
- r, g, b, _ := col.ToNRGBA(theme.PrimaryColor())
- cursorDim := color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: 0x16}
- start, end := color.Color(cursorDim), cursorOpaque
- if inverted {
- start, end = cursorOpaque, color.Color(cursorDim)
- }
- interrupted := false
- anim := canvas.NewColorRGBAAnimation(start, end, time.Second/2, func(c color.Color) {
- a.mu.RLock()
- shouldInterrupt := a.timeNow().Sub(a.lastInterruptTime) <= cursorInterruptTime
- a.mu.RUnlock()
- if shouldInterrupt {
- if !interrupted {
- a.cursor.FillColor = cursorOpaque
- a.cursor.Refresh()
- interrupted = true
- }
- return
- }
- if interrupted {
- a.mu.Lock()
- a.anim.Stop()
- if !inverted {
- a.anim = a.createAnim(true)
- }
- interrupted = false
- a.mu.Unlock()
- go func() {
- a.mu.RLock()
- canStart := a.anim != nil
- a.mu.RUnlock()
- if canStart {
- a.anim.Start()
- }
- }()
- return
- }
- a.cursor.FillColor = c
- a.cursor.Refresh()
- })
- anim.RepeatCount = fyne.AnimationRepeatForever
- anim.AutoReverse = true
- return anim
- }
- // starts cursor animation.
- func (a *entryCursorAnimation) start() {
- a.mu.Lock()
- isStopped := a.anim == nil
- if isStopped {
- a.anim = a.createAnim(false)
- }
- a.mu.Unlock()
- if isStopped {
- a.anim.Start()
- }
- }
- // temporarily stops the animation by "cursorInterruptTime".
- func (a *entryCursorAnimation) interrupt() {
- a.mu.Lock()
- a.lastInterruptTime = a.timeNow()
- a.mu.Unlock()
- }
- // stops cursor animation.
- func (a *entryCursorAnimation) stop() {
- a.mu.Lock()
- if a.anim != nil {
- a.anim.Stop()
- a.anim = nil
- }
- a.mu.Unlock()
- }
|