diff --git a/widget/button.go b/widget/button.go index 40d5dad6b1..7d79fa8fac 100644 --- a/widget/button.go +++ b/widget/button.go @@ -358,7 +358,7 @@ func (r *buttonRenderer) applyTheme() { r.button.applyButtonTheme() r.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameForeground switch { - case r.button.disabled: + case r.button.Disabled(): r.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameDisabled case r.button.Importance == HighImportance || r.button.Importance == DangerImportance || r.button.Importance == WarningImportance || r.button.Importance == SuccessImportance: if r.button.focused { diff --git a/widget/check.go b/widget/check.go index 19d7dbced4..f22124ea43 100644 --- a/widget/check.go +++ b/widget/check.go @@ -55,7 +55,7 @@ func (c *checkRenderer) Layout(size fyne.Size) { func (c *checkRenderer) applyTheme() { c.label.Color = theme.ForegroundColor() c.label.TextSize = theme.TextSize() - if c.check.disabled { + if c.check.Disabled() { c.label.Color = theme.DisabledColor() } } @@ -86,7 +86,7 @@ func (c *checkRenderer) updateResource() { res.ColorName = theme.ColorNamePrimary bgRes.ColorName = theme.ColorNameBackground } - if c.check.disabled { + if c.check.Disabled() { if c.check.Checked { res = theme.NewThemedResource(theme.CheckButtonCheckedIcon()) } @@ -98,7 +98,7 @@ func (c *checkRenderer) updateResource() { } func (c *checkRenderer) updateFocusIndicator() { - if c.check.disabled { + if c.check.Disabled() { c.focusIndicator.FillColor = color.Transparent } else if c.check.focused { c.focusIndicator.FillColor = theme.FocusColor() diff --git a/widget/check_group.go b/widget/check_group.go index 7fc6430030..2b559a3694 100644 --- a/widget/check_group.go +++ b/widget/check_group.go @@ -168,7 +168,7 @@ func (r *CheckGroup) update() { item.Text = r.Options[i] item.Checked = contains - item.DisableableWidget.disabled = r.disabled + item.DisableableWidget.disabled.Store(r.Disabled()) item.Refresh() } } @@ -261,7 +261,7 @@ func (r *checkGroupRenderer) updateItems() { } item.Text = r.checks.Options[i] item.Checked = contains - item.disabled = r.checks.disabled + item.disabled.Store(r.checks.Disabled()) item.Refresh() } } diff --git a/widget/check_internal_test.go b/widget/check_internal_test.go index 6047db9ac1..2ec4a5a8d9 100644 --- a/widget/check_internal_test.go +++ b/widget/check_internal_test.go @@ -147,7 +147,7 @@ func TestCheck_Focused(t *testing.T) { } check.Disable() - assert.True(t, check.disabled) + assert.True(t, check.Disabled()) assert.Equal(t, color.Transparent, render.focusIndicator.FillColor) check.Enable() @@ -185,7 +185,7 @@ func TestCheck_Hovered(t *testing.T) { } check.Disable() - assert.True(t, check.disabled) + assert.True(t, check.Disabled()) assert.True(t, check.hovered) assert.Equal(t, color.Transparent, render.focusIndicator.FillColor) diff --git a/widget/entry.go b/widget/entry.go index ceda8beb1f..d7b7987b37 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -226,7 +226,7 @@ func (e *Entry) Disable() { // // Implements: fyne.Disableable func (e *Entry) Disabled() bool { - return e.DisableableWidget.disabled + return e.DisableableWidget.Disabled() } // DoubleTapped is called when this entry has been double tapped so we should select text below the pointer @@ -1305,7 +1305,8 @@ func (e *Entry) textPosFromRowCol(row, col int) int { func (e *Entry) syncSegments() { colName := theme.ColorNameForeground wrap := e.textWrap() - if e.disabled { + disabled := e.Disabled() + if disabled { colName = theme.ColorNameDisabled } e.textProvider().Wrapping = wrap @@ -1324,7 +1325,7 @@ func (e *Entry) syncSegments() { Text: e.Text, }} colName = theme.ColorNamePlaceHolder - if e.disabled { + if disabled { colName = theme.ColorNameDisabled } e.placeholderProvider().Wrapping = wrap @@ -1666,7 +1667,7 @@ func (r *entryRenderer) Objects() []fyne.CanvasObject { func (r *entryRenderer) Refresh() { r.entry.propertyLock.RLock() content := r.entry.content - focusedAppearance := r.entry.focused && !r.entry.disabled + focusedAppearance := r.entry.focused && !r.entry.Disabled() scroll := r.entry.Scroll wrapping := r.entry.Wrapping r.entry.propertyLock.RUnlock() @@ -1841,7 +1842,7 @@ func (r *entryContentRenderer) Refresh() { r.content.entry.propertyLock.RLock() provider := r.content.entry.textProvider() placeholder := r.content.entry.placeholderProvider() - focusedAppearance := r.content.entry.focused && !r.content.entry.disabled + focusedAppearance := r.content.entry.focused && !r.content.entry.Disabled() selections := r.selection r.updateScrollDirections() r.content.entry.propertyLock.RUnlock() diff --git a/widget/entry_password.go b/widget/entry_password.go index 501925667c..5e9bae09ba 100644 --- a/widget/entry_password.go +++ b/widget/entry_password.go @@ -76,7 +76,7 @@ func (r *passwordRevealerRenderer) Refresh() { r.icon.Resource = theme.VisibilityOffIcon() } - if r.entry.disabled { + if r.entry.Disabled() { r.icon.Resource = theme.NewDisabledResource(r.icon.Resource) } canvas.Refresh(r.icon) diff --git a/widget/entry_validation.go b/widget/entry_validation.go index caec2f8a33..8aa14e76c6 100644 --- a/widget/entry_validation.go +++ b/widget/entry_validation.go @@ -93,7 +93,7 @@ func (r *validationStatusRenderer) MinSize() fyne.Size { func (r *validationStatusRenderer) Refresh() { r.entry.propertyLock.RLock() defer r.entry.propertyLock.RUnlock() - if r.entry.disabled { + if r.entry.Disabled() { r.icon.Hide() return } diff --git a/widget/radio_group.go b/widget/radio_group.go index d28572b311..8b3a31e43a 100644 --- a/widget/radio_group.go +++ b/widget/radio_group.go @@ -124,7 +124,7 @@ func (r *RadioGroup) update() { for i, item := range r.items { item.Label = r.Options[i] item.Selected = item.Label == r.Selected - item.DisableableWidget.disabled = r.disabled + item.DisableableWidget.disabled.Store(r.Disabled()) item.Refresh() } } @@ -207,7 +207,7 @@ func (r *radioGroupRenderer) updateItems() { for i, item := range r.items { item.Label = r.radio.Options[i] item.Selected = item.Label == r.radio.Selected - item.disabled = r.radio.disabled + item.disabled.Store(r.radio.Disabled()) item.Refresh() } } diff --git a/widget/select.go b/widget/select.go index c56ddff570..19a68091fd 100644 --- a/widget/select.go +++ b/widget/select.go @@ -66,7 +66,7 @@ func (s *Select) CreateRenderer() fyne.WidgetRenderer { txtProv.inset = fyne.NewSize(theme.Padding(), theme.Padding()) txtProv.ExtendBaseWidget(txtProv) txtProv.Truncation = fyne.TextTruncateEllipsis - if s.disabled { + if s.Disabled() { txtProv.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameDisabled } @@ -342,7 +342,7 @@ func (s *selectRenderer) Refresh() { } func (s *selectRenderer) bgColor() color.Color { - if s.combo.disabled { + if s.combo.Disabled() { return theme.DisabledButtonColor() } if s.combo.focused { @@ -355,7 +355,7 @@ func (s *selectRenderer) bgColor() color.Color { } func (s *selectRenderer) updateIcon() { - if s.combo.disabled { + if s.combo.Disabled() { s.icon.Resource = theme.NewDisabledResource(theme.MenuDropDownIcon()) } else { s.icon.Resource = theme.MenuDropDownIcon() @@ -369,7 +369,7 @@ func (s *selectRenderer) updateLabel() { } s.label.Segments[0].(*TextSegment).Style.Alignment = s.combo.Alignment - if s.combo.disabled { + if s.combo.Disabled() { s.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameDisabled } else { s.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameForeground diff --git a/widget/widget.go b/widget/widget.go index 0fed691f21..adf0d07927 100644 --- a/widget/widget.go +++ b/widget/widget.go @@ -155,7 +155,7 @@ func (w *BaseWidget) super() fyne.Widget { type DisableableWidget struct { BaseWidget - disabled bool + disabled atomic.Bool } // Enable this widget, updating any style or features appropriately. @@ -164,9 +164,13 @@ func (w *DisableableWidget) Enable() { return } - w.setFieldsAndRefresh(func() { - w.disabled = false - }) + w.disabled.Store(false) + + impl := w.super() + if impl == nil { + return + } + impl.Refresh() } // Disable this widget so that it cannot be interacted with, updating any style appropriately. @@ -175,17 +179,18 @@ func (w *DisableableWidget) Disable() { return } - w.setFieldsAndRefresh(func() { - w.disabled = true - }) + w.disabled.Store(true) + + impl := w.super() + if impl == nil { + return + } + impl.Refresh() } // Disabled returns true if this widget is currently disabled or false if it can currently be interacted with. func (w *DisableableWidget) Disabled() bool { - w.propertyLock.RLock() - defer w.propertyLock.RUnlock() - - return w.disabled + return w.disabled.Load() } // NewSimpleRenderer creates a new SimpleRenderer to render a widget using a