~eliasnaur/gio

22aa00f4767a62091329bbce1e67410136a0c19b — Gordon Klaus 4 months ago ac2c284
widget/material: add Float.Invert

Setting Float.Invert=true not only inverts the order of values (which was already easily done by swapping min and max), it also draws the widget inverted so that the track is darkened on the opposite side from usual.

This patch also fixes a bug wherein a vertical slider was drawn inverted by default.

Signed-off-by: Gordon Klaus <gordon.klaus@gmail.com>
2 files changed, 30 insertions(+), 16 deletions(-)

M widget/float.go
M widget/material/slider.go
M widget/float.go => widget/float.go +7 -3
@@ 13,8 13,9 @@ import (

// Float is for selecting a value in a range.
type Float struct {
	Value float32
	Axis  layout.Axis
	Value  float32
	Axis   layout.Axis
	Invert bool

	drag    gesture.Drag
	pos     float32 // position normalized to [0, 1]


@@ 43,7 44,10 @@ func (f *Float) Layout(gtx layout.Context, pointerMargin int, min, max float32) 
	if de != nil {
		xy := de.Position.X
		if f.Axis == layout.Vertical {
			xy = de.Position.Y
			xy = f.length - de.Position.Y
		}
		if f.Invert {
			xy = f.length - xy
		}
		f.pos = xy / f.length
		value = min + (max-min)*f.pos

M widget/material/slider.go => widget/material/slider.go +23 -13
@@ 61,26 61,36 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
		color = f32color.Disabled(color)
	}

	// Draw track before thumb.
	track := image.Rectangle{
		Min: axis.Convert(image.Pt(thumbRadius, sizeCross/2-trackWidth/2)),
		Max: axis.Convert(image.Pt(thumbPos, sizeCross/2+trackWidth/2)),
	rect := func(minx, miny, maxx, maxy int) image.Rectangle {
		r := image.Rect(minx, miny, maxx, maxy)
		if s.Float.Invert != (axis == layout.Vertical) {
			r.Max.X, r.Min.X = sizeMain-r.Min.X, sizeMain-r.Max.X
		}
		r.Min = axis.Convert(r.Min)
		r.Max = axis.Convert(r.Max)
		return r
	}

	// Draw track before thumb.
	track := rect(
		thumbRadius, sizeCross/2-trackWidth/2,
		thumbPos, sizeCross/2+trackWidth/2,
	)
	paint.FillShape(gtx.Ops, color, clip.Rect(track).Op())

	// Draw track after thumb.
	track = image.Rectangle{
		Min: axis.Convert(image.Pt(thumbPos, axis.Convert(track.Min).Y)),
		Max: axis.Convert(image.Pt(sizeMain-thumbRadius, axis.Convert(track.Max).Y)),
	}
	track = rect(
		thumbPos, axis.Convert(track.Min).Y,
		sizeMain-thumbRadius, axis.Convert(track.Max).Y,
	)
	paint.FillShape(gtx.Ops, f32color.MulAlpha(color, 96), clip.Rect(track).Op())

	// Draw thumb.
	pt := axis.Convert(image.Pt(thumbPos, sizeCross/2))
	thumb := image.Rectangle{
		Min: image.Pt(pt.X-thumbRadius, pt.Y-thumbRadius),
		Max: image.Pt(pt.X+thumbRadius, pt.Y+thumbRadius),
	}
	pt := image.Pt(thumbPos, sizeCross/2)
	thumb := rect(
		pt.X-thumbRadius, pt.Y-thumbRadius,
		pt.X+thumbRadius, pt.Y+thumbRadius,
	)
	paint.FillShape(gtx.Ops, color, clip.Ellipse(thumb).Op(gtx.Ops))

	return layout.Dimensions{Size: size}