widget/material: remove padding from Slider

Remove padding from the sides of the Slider to align them with
other components.

However, since sliders still need to be used with fingers try to
enforce a minimum finger height, if there is sufficient room.
The sides don't need similar treatment since after grabbing it's
possible to move the finger beyond the touch area, without losing
interaction.

To not enforce finger size, the theme can be adjusted:

    theme.FingerSize = unit.Px(0)

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
This commit is contained in:
Egon Elbre
2020-12-12 13:21:06 +02:00
committed by Elias Naur
parent 8e7066ecd7
commit 296303210f
2 changed files with 36 additions and 18 deletions
+30 -18
View File
@@ -19,10 +19,11 @@ import (
// Slider is for selecting a value in a range.
func Slider(th *Theme, float *widget.Float, min, max float32) SliderStyle {
return SliderStyle{
Min: min,
Max: max,
Color: th.Palette.ContrastBg,
Float: float,
Min: min,
Max: max,
Color: th.Palette.ContrastBg,
Float: float,
FingerSize: th.FingerSize,
}
}
@@ -30,28 +31,39 @@ type SliderStyle struct {
Min, Max float32
Color color.NRGBA
Float *widget.Float
FingerSize unit.Value
}
func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
thumbRadiusInt := gtx.Px(unit.Dp(6))
trackWidth := float32(gtx.Px(unit.Dp(2)))
thumbRadius := float32(thumbRadiusInt)
halfWidthInt := 2 * thumbRadiusInt
halfWidth := float32(halfWidthInt)
size := gtx.Constraints.Min
// Keep a minimum length so that the track is always visible.
minLength := halfWidthInt + 3*thumbRadiusInt + halfWidthInt
minLength := thumbRadiusInt + 3*thumbRadiusInt + thumbRadiusInt
if size.X < minLength {
size.X = minLength
}
size.Y = 2 * halfWidthInt
size.Y = 2 * thumbRadiusInt
// Try to expand to finger size, but only if the constraints
// allow for it.
touchSizePx := gtx.Px(s.FingerSize)
if touchSizePx > gtx.Constraints.Max.Y {
touchSizePx = gtx.Constraints.Max.Y
}
if size.Y < touchSizePx {
size.Y = 2 * (touchSizePx / 2)
}
st := op.Push(gtx.Ops)
op.Offset(f32.Pt(halfWidth, 0)).Add(gtx.Ops)
gtx.Constraints.Min = image.Pt(size.X-2*halfWidthInt, size.Y)
s.Float.Layout(gtx, halfWidthInt, s.Min, s.Max)
thumbPos := halfWidth + s.Float.Pos()
op.Offset(f32.Pt(thumbRadius, 0)).Add(gtx.Ops)
gtx.Constraints.Min = image.Pt(size.X-2*thumbRadiusInt, size.Y)
s.Float.Layout(gtx, thumbRadiusInt, s.Min, s.Max)
gtx.Constraints.Min.Y = size.Y
thumbPos := thumbRadius + s.Float.Pos()
st.Pop()
color := s.Color
@@ -63,12 +75,12 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
st = op.Push(gtx.Ops)
track := f32.Rectangle{
Min: f32.Point{
X: halfWidth,
Y: halfWidth - trackWidth/2,
X: thumbRadius,
Y: float32(size.Y/2) - trackWidth/2,
},
Max: f32.Point{
X: thumbPos,
Y: halfWidth + trackWidth/2,
Y: float32(size.Y/2) + trackWidth/2,
},
}
clip.RRect{Rect: track}.Add(gtx.Ops)
@@ -79,7 +91,7 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
// Draw track after thumb.
st = op.Push(gtx.Ops)
track.Min.X = thumbPos
track.Max.X = float32(size.X) - halfWidth
track.Max.X = float32(size.X) - thumbRadius
clip.RRect{Rect: track}.Add(gtx.Ops)
paint.ColorOp{Color: f32color.MulAlpha(color, 96)}.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops)
@@ -90,11 +102,11 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
thumb := f32.Rectangle{
Min: f32.Point{
X: thumbPos - thumbRadius,
Y: halfWidth - thumbRadius,
Y: float32(size.Y/2) - thumbRadius,
},
Max: f32.Point{
X: thumbPos + thumbRadius,
Y: halfWidth + thumbRadius,
Y: float32(size.Y/2) + thumbRadius,
},
}
rr := thumbRadius
+6
View File
@@ -40,6 +40,9 @@ type Theme struct {
RadioChecked *widget.Icon
RadioUnchecked *widget.Icon
}
// FingerSize is the minimum touch target size.
FingerSize unit.Value
}
func NewTheme(fontCollection []text.FontFace) *Theme {
@@ -59,6 +62,9 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
t.Icon.RadioChecked = mustIcon(widget.NewIcon(icons.ToggleRadioButtonChecked))
t.Icon.RadioUnchecked = mustIcon(widget.NewIcon(icons.ToggleRadioButtonUnchecked))
// 38dp is on the lower end of possible finger size.
t.FingerSize = unit.Dp(38)
return t
}