gtk_entry_target.go RawHistoryFolder
1package textinput
2
3import (
4 "context"
5
6 "github.com/bnema/dumber/internal/application/port"
7 "github.com/bnema/dumber/internal/logging"
8 "github.com/bnema/puregotk/v4/gtk"
9)
10
11// GTKEntryTarget implements TextInputTarget for GTK SearchEntry widgets.
12// It uses the Editable interface methods to insert and delete text.
13type GTKEntryTarget struct {
14 entry *gtk.SearchEntry
15}
16
17// Compile-time interface checks.
18var _ port.TextInputTarget = (*GTKEntryTarget)(nil)
19var _ port.EntryInputTarget = (*GTKEntryTarget)(nil)
20
21// IsGTKEntryTarget implements port.EntryInputTarget.
22func (*GTKEntryTarget) IsGTKEntryTarget() bool { return true }
23
24// NewGTKEntryTarget creates a new GTK entry target for a SearchEntry.
25func NewGTKEntryTarget(entry *gtk.SearchEntry) *GTKEntryTarget {
26 return >KEntryTarget{entry: entry}
27}
28
29// InsertText inserts text at the current cursor position.
30func (t *GTKEntryTarget) InsertText(ctx context.Context, text string) error {
31 log := logging.FromContext(ctx)
32
33 if t.entry == nil {
34 log.Warn().Msg("GTKEntryTarget: entry is nil")
35 return nil
36 }
37
38 // Get current text and cursor position
39 currentText := t.entry.GetText()
40 pos := t.entry.GetPosition()
41
42 // Convert to runes for proper Unicode handling
43 runes := []rune(currentText)
44 textRunes := []rune(text)
45
46 // Clamp position to valid range
47 if pos < 0 {
48 pos = 0
49 }
50 if pos > len(runes) {
51 pos = len(runes)
52 }
53
54 // Build new text with insertion
55 newRunes := make([]rune, 0, len(runes)+len(textRunes))
56 newRunes = append(newRunes, runes[:pos]...)
57 newRunes = append(newRunes, textRunes...)
58 newRunes = append(newRunes, runes[pos:]...)
59
60 // Set new text and cursor position
61 t.entry.SetText(string(newRunes))
62 newPos := pos + len(textRunes)
63 t.entry.SetPosition(newPos)
64
65 log.Debug().
66 Str("text", text).
67 Int("pos", pos).
68 Msg("inserted text into GTK entry")
69
70 return nil
71}
72
73// DeleteBeforeCursor deletes n characters before the cursor position.
74func (t *GTKEntryTarget) DeleteBeforeCursor(ctx context.Context, n int) error {
75 log := logging.FromContext(ctx)
76
77 if t.entry == nil {
78 log.Warn().Msg("GTKEntryTarget: entry is nil")
79 return nil
80 }
81
82 pos := t.entry.GetPosition()
83 if pos < n {
84 n = pos // Don't delete more than available
85 }
86
87 if n <= 0 {
88 return nil
89 }
90
91 // DeleteText takes start and end positions
92 t.entry.DeleteText(pos-n, pos)
93
94 log.Debug().
95 Int("n", n).
96 Int("pos", pos).
97 Msg("deleted text before cursor in GTK entry")
98
99 return nil
100}