diff --git a/dialog/color_channel.go b/dialog/color_channel.go index 313698c964..6ab7d311ae 100644 --- a/dialog/color_channel.go +++ b/dialog/color_channel.go @@ -2,6 +2,7 @@ package dialog import ( "strconv" + "sync" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" @@ -124,25 +125,21 @@ func (r *colorChannelRenderer) updateObjects() { } type colorChannelEntry struct { - widget.Entry + userChangeEntry } func newColorChannelEntry(c *colorChannel) *colorChannelEntry { - e := &colorChannelEntry{ - Entry: widget.Entry{ - Text: "0", - OnChanged: func(text string) { - value, err := strconv.Atoi(text) - if err != nil { - fyne.LogError("Couldn't parse: "+text, err) - } else { - c.SetValue(value) - } - }, - // TODO add number min/max validator - }, - } + e := &colorChannelEntry{} + e.Text = "0" e.ExtendBaseWidget(e) + e.setOnChanged(func(text string) { + value, err := strconv.Atoi(text) + if err != nil { + fyne.LogError("Couldn't parse: "+text, err) + return + } + c.SetValue(value) + }) return e } @@ -152,3 +149,49 @@ func (e *colorChannelEntry) MinSize() fyne.Size { min = min.Add(fyne.NewSize(theme.Padding()*6, theme.Padding()*4)) return min.Max(e.Entry.MinSize()) } + +type userChangeEntry struct { + widget.Entry + + lock sync.RWMutex + userTyped bool +} + +func newUserChangeEntry(text string) *userChangeEntry { + e := &userChangeEntry{} + e.Entry.Text = text + e.ExtendBaseWidget(e) + return e +} + +func (e *userChangeEntry) setOnChanged(onChanged func(s string)) { + e.Entry.OnChanged = func(text string) { + e.lock.Lock() + userTyped := e.userTyped + if userTyped { + e.userTyped = false + } + e.lock.Unlock() + if !userTyped { + return + } + if onChanged != nil { + onChanged(text) + } + } + e.ExtendBaseWidget(e) +} + +func (e *userChangeEntry) TypedRune(r rune) { + e.lock.Lock() + e.userTyped = true + e.lock.Unlock() + e.Entry.TypedRune(r) +} + +func (e *userChangeEntry) TypedKey(ev *fyne.KeyEvent) { + e.lock.Lock() + e.userTyped = true + e.lock.Unlock() + e.Entry.TypedKey(ev) +} diff --git a/dialog/color_picker.go b/dialog/color_picker.go index 835c9fadde..6c0a784078 100644 --- a/dialog/color_picker.go +++ b/dialog/color_picker.go @@ -162,17 +162,16 @@ func (p *colorAdvancedPicker) CreateRenderer() fyne.WidgetRenderer { }) // Hex - hex := &widget.Entry{ - OnChanged: func(text string) { - c, err := stringToColor(text) - if err != nil { - fyne.LogError("Error parsing color: "+text, err) - // TODO trigger entry invalid state - } else { - p.SetColor(c) - } - }, - } + hex := newUserChangeEntry("") + hex.setOnChanged(func(text string) { + c, err := stringToColor(text) + if err != nil { + fyne.LogError("Error parsing color: "+text, err) + // TODO trigger entry invalid state + } else { + p.SetColor(c) + } + }) contents := fyne.NewContainerWithLayout(layout.NewPaddedLayout(), container.NewVBox( container.NewGridWithColumns(3, @@ -264,7 +263,7 @@ type colorPickerRenderer struct { wheel *colorWheel preview *canvas.Rectangle alphaChannel *colorChannel - hex *widget.Entry + hex *userChangeEntry contents fyne.CanvasObject }