diff --git a/cmd/fyne_demo/tutorials/widget.go b/cmd/fyne_demo/tutorials/widget.go index 3d58bbc9c7..d40738ece0 100644 --- a/cmd/fyne_demo/tutorials/widget.go +++ b/cmd/fyne_demo/tutorials/widget.go @@ -351,6 +351,8 @@ func makeInputTab(_ fyne.Window) fyne.CanvasObject { disabledRadio := widget.NewRadioGroup([]string{"Disabled radio"}, func(string) {}) disabledRadio.Disable() + disabledSlider := widget.NewSlider(0, 1000) + disabledSlider.Disable() return container.NewVBox( widget.NewSelect([]string{"Option 1", "Option 2", "Option 3"}, func(s string) { fmt.Println("selected", s) }), selectEntry, @@ -359,7 +361,8 @@ func makeInputTab(_ fyne.Window) fyne.CanvasObject { checkGroup, radio, disabledRadio, - widget.NewSlider(0, 1000), + container.NewBorder(nil, nil, widget.NewLabel("Slider"), nil, widget.NewSlider(0, 1000)), + container.NewBorder(nil, nil, widget.NewLabel("Disabled slider"), nil, disabledSlider), ) } diff --git a/widget/slider.go b/widget/slider.go index d799c253a9..0918be700d 100644 --- a/widget/slider.go +++ b/widget/slider.go @@ -26,6 +26,7 @@ var _ fyne.Draggable = (*Slider)(nil) var _ fyne.Focusable = (*Slider)(nil) var _ desktop.Hoverable = (*Slider)(nil) var _ fyne.Tappable = (*Slider)(nil) +var _ fyne.Disableable = (*Slider)(nil) // Slider is a widget that can slide between two fixed values. type Slider struct { @@ -45,6 +46,7 @@ type Slider struct { binder basicBinder hovered bool focused bool + disabled bool // don't use DisableableWidget so we can put Since comments on funcs pendingChange bool // true if value changed since last OnChangeEnded } @@ -87,11 +89,16 @@ func (s *Slider) Bind(data binding.Float) { // DragEnd is called when the drag ends. func (s *Slider) DragEnd() { - s.fireChangeEnded() + if !s.disabled { + s.fireChangeEnded() + } } // DragEnd is called when a drag event occurs. func (s *Slider) Dragged(e *fyne.DragEvent) { + if s.disabled { + return + } ratio := s.getRatio(&e.PointEvent) lastValue := s.Value @@ -147,6 +154,9 @@ func (s *Slider) fireChangeEnded() { // // Since: 2.4 func (s *Slider) FocusGained() { + if s.disabled { + return + } s.focused = true s.Refresh() } @@ -155,6 +165,9 @@ func (s *Slider) FocusGained() { // // Since: 2.4 func (s *Slider) FocusLost() { + if s.disabled { + return + } s.focused = false s.Refresh() } @@ -163,6 +176,9 @@ func (s *Slider) FocusLost() { // // Since: 2.4 func (s *Slider) MouseIn(_ *desktop.MouseEvent) { + if s.disabled { + return + } s.hovered = true s.Refresh() } @@ -177,6 +193,9 @@ func (s *Slider) MouseMoved(_ *desktop.MouseEvent) { // // Since: 2.4 func (s *Slider) MouseOut() { + if s.disabled { + return + } s.hovered = false s.Refresh() } @@ -185,6 +204,9 @@ func (s *Slider) MouseOut() { // // Since: 2.4 func (s *Slider) TypedKey(key *fyne.KeyEvent) { + if s.disabled { + return + } if s.Orientation == Vertical { switch key.Name { case fyne.KeyUp: @@ -293,6 +315,33 @@ func (s *Slider) MinSize() fyne.Size { return s.BaseWidget.MinSize() } +// Disable disables the slider +// +// Since: 2.5 +func (s *Slider) Disable() { + if !s.disabled { + defer s.Refresh() + } + s.disabled = true +} + +// Enable enables the slider +// +// Since: 2.5 +func (s *Slider) Enable() { + if s.disabled { + defer s.Refresh() + } + s.disabled = false +} + +// Disabled returns true if the slider is currently disabled +// +// Since: 2.5 +func (s *Slider) Disabled() bool { + return s.disabled +} + // CreateRenderer links this widget to its renderer. func (s *Slider) CreateRenderer() fyne.WidgetRenderer { s.ExtendBaseWidget(s) @@ -373,12 +422,17 @@ type sliderRenderer struct { // Refresh updates the widget state for drawing. func (s *sliderRenderer) Refresh() { s.track.FillColor = theme.InputBackgroundColor() - s.thumb.FillColor = theme.ForegroundColor() - s.active.FillColor = theme.ForegroundColor() + if s.slider.disabled { + s.thumb.FillColor = theme.DisabledColor() + s.active.FillColor = theme.DisabledColor() + } else { + s.thumb.FillColor = theme.ForegroundColor() + s.active.FillColor = theme.ForegroundColor() + } - if s.slider.focused { + if s.slider.focused && !s.slider.disabled { s.focusIndicator.FillColor = theme.FocusColor() - } else if s.slider.hovered { + } else if s.slider.hovered && !s.slider.disabled { s.focusIndicator.FillColor = theme.HoverColor() } else { s.focusIndicator.FillColor = color.Transparent diff --git a/widget/slider_test.go b/widget/slider_test.go index faf24a1b48..6a4bc26b29 100644 --- a/widget/slider_test.go +++ b/widget/slider_test.go @@ -310,3 +310,26 @@ func TestSlider_Focus(t *testing.T) { slider.TypedKey(down) assert.Equal(t, slider.Min, slider.Value) } + +func TestSlider_Disabled(t *testing.T) { + slider := NewSlider(0, 5) + slider.Disable() + + changes := 0 + slider.OnChanged = func(_ float64) { + changes++ + } + + drag := &fyne.DragEvent{} + drag.PointEvent.Position = fyne.NewPos(25, 2) + slider.Dragged(drag) + assert.Equal(t, 0, changes) + + slider.TypedKey(&fyne.KeyEvent{Name: fyne.KeyRight}) + assert.Equal(t, 0, changes) + + slider.Enable() + + slider.Dragged(drag) + assert.Equal(t, 1, changes) +}