feat(ui): add accent picker support to find bar
- commit
- 37b085fb77e31b4e6bc0f424fa2826e4e627c24c
- author
- brice · · 2025-12-29 22:59 UTC
- committer
- brice · · 2025-12-30 13:48 UTC
- parent
- b3920c5
- signature
- unsigned
1 file · +43 -4
M internal/ui/component/find_bar.go +43 -4
| @@ -39,16 +39,19 @@ type FindBar struct { | |||
| 39 | 39 | ||
| 40 | 40 | uc *usecase.FindInPageUseCase | |
| 41 | 41 | ||
| 42 | - | visible bool | |
| 43 | - | mu sync.RWMutex | |
| 44 | - | ctx context.Context | |
| 45 | - | onClose func() | |
| 42 | + | visible bool | |
| 43 | + | mu sync.RWMutex | |
| 44 | + | ctx context.Context | |
| 45 | + | onClose func() | |
| 46 | + | retainedCallbacks []interface{} // Keep callbacks alive for GC | |
| 46 | 47 | } | |
| 47 | 48 | ||
| 48 | 49 | // FindBarConfig holds configuration for creating a FindBar. | |
| 49 | 50 | type FindBarConfig struct { | |
| 50 | 51 | OnClose func() | |
| 51 | 52 | GetFindController func(paneID entity.PaneID) port.FindController | |
| 53 | + | OnFocusIn func(entry *gtk.SearchEntry) // Callback when entry gains focus (for accent picker) | |
| 54 | + | OnFocusOut func() // Callback when entry loses focus | |
| 52 | 55 | } | |
| 53 | 56 | ||
| 54 | 57 | // NewFindBar creates a new FindBar component. | |
| @@ -68,6 +71,7 @@ func NewFindBar(ctx context.Context, cfg FindBarConfig) *FindBar { | |||
| 68 | 71 | ||
| 69 | 72 | fb.setupHandlers() | |
| 70 | 73 | fb.bindUseCase() | |
| 74 | + | fb.setupFocusCallbacks(cfg.OnFocusIn, cfg.OnFocusOut) | |
| 71 | 75 | ||
| 72 | 76 | log.Debug().Msg("find bar created") | |
| 73 | 77 | return fb | |
| @@ -405,3 +409,38 @@ func (fb *FindBar) bindUseCase() { | |||
| 405 | 409 | glib.IdleAdd(&cb, 0) | |
| 406 | 410 | }) | |
| 407 | 411 | } | |
| 412 | + | ||
| 413 | + | // setupFocusCallbacks wires focus in/out callbacks for accent picker integration. | |
| 414 | + | func (fb *FindBar) setupFocusCallbacks(onFocusIn func(*gtk.SearchEntry), onFocusOut func()) { | |
| 415 | + | if onFocusIn == nil && onFocusOut == nil { | |
| 416 | + | return | |
| 417 | + | } | |
| 418 | + | ||
| 419 | + | if fb.entry == nil { | |
| 420 | + | return | |
| 421 | + | } | |
| 422 | + | ||
| 423 | + | focusController := gtk.NewEventControllerFocus() | |
| 424 | + | if focusController == nil { | |
| 425 | + | return | |
| 426 | + | } | |
| 427 | + | ||
| 428 | + | if onFocusIn != nil { | |
| 429 | + | entry := fb.entry // Capture for closure | |
| 430 | + | focusInCb := func(_ gtk.EventControllerFocus) { | |
| 431 | + | onFocusIn(entry) | |
| 432 | + | } | |
| 433 | + | fb.retainedCallbacks = append(fb.retainedCallbacks, focusInCb) | |
| 434 | + | focusController.ConnectEnter(&focusInCb) | |
| 435 | + | } | |
| 436 | + | ||
| 437 | + | if onFocusOut != nil { | |
| 438 | + | focusOutCb := func(_ gtk.EventControllerFocus) { | |
| 439 | + | onFocusOut() | |
| 440 | + | } | |
| 441 | + | fb.retainedCallbacks = append(fb.retainedCallbacks, focusOutCb) | |
| 442 | + | focusController.ConnectLeave(&focusOutCb) | |
| 443 | + | } | |
| 444 | + | ||
| 445 | + | fb.entry.AddController(&focusController.EventController) | |
| 446 | + | } | |
| @@ -39,16 +39,19 @@ type FindBar struct { | |||||
| 39 | 39 | ||||
| 40 | uc *usecase.FindInPageUseCase | 40 | uc *usecase.FindInPageUseCase | ||
| 41 | 41 | ||||
| 42 | - | visible bool | 42 | + | visible bool |
| 43 | - | mu sync.RWMutex | 43 | + | mu sync.RWMutex |
| 44 | - | ctx context.Context | 44 | + | ctx context.Context |
| 45 | - | onClose func() | 45 | + | onClose func() |
| 46 | + | retainedCallbacks []interface{} // Keep callbacks alive for GC | |||
| 46 | } | 47 | } | ||
| 47 | 48 | ||||
| 48 | // FindBarConfig holds configuration for creating a FindBar. | 49 | // FindBarConfig holds configuration for creating a FindBar. | ||
| 49 | type FindBarConfig struct { | 50 | type FindBarConfig struct { | ||
| 50 | OnClose func() | 51 | OnClose func() | ||
| 51 | GetFindController func(paneID entity.PaneID) port.FindController | 52 | GetFindController func(paneID entity.PaneID) port.FindController | ||
| 53 | + | OnFocusIn func(entry *gtk.SearchEntry) // Callback when entry gains focus (for accent picker) | |||
| 54 | + | OnFocusOut func() // Callback when entry loses focus | |||
| 52 | } | 55 | } | ||
| 53 | 56 | ||||
| 54 | // NewFindBar creates a new FindBar component. | 57 | // NewFindBar creates a new FindBar component. | ||
| @@ -68,6 +71,7 @@ func NewFindBar(ctx context.Context, cfg FindBarConfig) *FindBar { | |||||
| 68 | 71 | ||||
| 69 | fb.setupHandlers() | 72 | fb.setupHandlers() | ||
| 70 | fb.bindUseCase() | 73 | fb.bindUseCase() | ||
| 74 | + | fb.setupFocusCallbacks(cfg.OnFocusIn, cfg.OnFocusOut) | |||
| 71 | 75 | ||||
| 72 | log.Debug().Msg("find bar created") | 76 | log.Debug().Msg("find bar created") | ||
| 73 | return fb | 77 | return fb | ||
| @@ -405,3 +409,38 @@ func (fb *FindBar) bindUseCase() { | |||||
| 405 | glib.IdleAdd(&cb, 0) | 409 | glib.IdleAdd(&cb, 0) | ||
| 406 | }) | 410 | }) | ||
| 407 | } | 411 | } | ||
| 412 | + | ||||
| 413 | + | // setupFocusCallbacks wires focus in/out callbacks for accent picker integration. | |||
| 414 | + | func (fb *FindBar) setupFocusCallbacks(onFocusIn func(*gtk.SearchEntry), onFocusOut func()) { | |||
| 415 | + | if onFocusIn == nil && onFocusOut == nil { | |||
| 416 | + | return | |||
| 417 | + | } | |||
| 418 | + | ||||
| 419 | + | if fb.entry == nil { | |||
| 420 | + | return | |||
| 421 | + | } | |||
| 422 | + | ||||
| 423 | + | focusController := gtk.NewEventControllerFocus() | |||
| 424 | + | if focusController == nil { | |||
| 425 | + | return | |||
| 426 | + | } | |||
| 427 | + | ||||
| 428 | + | if onFocusIn != nil { | |||
| 429 | + | entry := fb.entry // Capture for closure | |||
| 430 | + | focusInCb := func(_ gtk.EventControllerFocus) { | |||
| 431 | + | onFocusIn(entry) | |||
| 432 | + | } | |||
| 433 | + | fb.retainedCallbacks = append(fb.retainedCallbacks, focusInCb) | |||
| 434 | + | focusController.ConnectEnter(&focusInCb) | |||
| 435 | + | } | |||
| 436 | + | ||||
| 437 | + | if onFocusOut != nil { | |||
| 438 | + | focusOutCb := func(_ gtk.EventControllerFocus) { | |||
| 439 | + | onFocusOut() | |||
| 440 | + | } | |||
| 441 | + | fb.retainedCallbacks = append(fb.retainedCallbacks, focusOutCb) | |||
| 442 | + | focusController.ConnectLeave(&focusOutCb) | |||
| 443 | + | } | |||
| 444 | + | ||||
| 445 | + | fb.entry.AddController(&focusController.EventController) | |||
| 446 | + | } | |||