~eliasnaur/gio-patches

gio: widget,widget/material: add Axis to the Float widget v1 PROPOSED

~pierrec
~pierrec: 1
 widget,widget/material: add Axis to the Float widget

 2 files changed, 78 insertions(+), 58 deletions(-)
#394919 apple.yml success
#394920 freebsd.yml success
#394921 linux.yml success
#394922 openbsd.yml success
OK. What about its f32.Point equivalent? FConvert?



          
          
          
        
      

      
      
      
      

      

      
      
      
      

      
      
        
          







Hmm probably not enough. Let's leave it out for now. Sending a patch for this.

Le mer. 13 janv. 2021 à 19:52, Elias Naur <mail@eliasnaur.com> a écrit :
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/19523/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH gio] widget,widget/material: add Axis to the Float widget Export this patch

~pierrec
From: pierre <pierre.curto@gmail.com>

Adding an axis to the Float widget, allows positioning the Slider one not only horizontally but also vertically.
Also update the fill ops while there.

Signed-off-by: pierre <pierre.curto@gmail.com>
---
 widget/float.go           |  27 +++++++---
 widget/material/slider.go | 109 ++++++++++++++++++++------------------
 2 files changed, 78 insertions(+), 58 deletions(-)

diff --git a/widget/float.go b/widget/float.go
index 3c59a26..a467646 100644
--- a/widget/float.go
+++ b/widget/float.go
@@ -14,6 +14,7 @@ import (
// Float is for selecting a value in a range.
type Float struct {
	Value float32
	Axis  layout.Axis

	drag    gesture.Drag
	pos     float32 // position normalized to [0, 1]
@@ -24,13 +25,15 @@ type Float struct {
// Dragging returns whether the value is being interacted with.
func (f *Float) Dragging() bool { return f.drag.Dragging() }

// Layout processes events.
// Layout updates the value according to drag events along the f's main axis.
//
// The range of f is set by the minimum constraints main axis value.
func (f *Float) Layout(gtx layout.Context, pointerMargin int, min, max float32) layout.Dimensions {
	size := gtx.Constraints.Min
	f.length = float32(size.X)
	f.length = float32(f.Axis.Main(size))

	var de *pointer.Event
	for _, e := range f.drag.Events(gtx.Metric, gtx, gesture.Horizontal) {
	for _, e := range f.drag.Events(gtx.Metric, gtx, gesture.Axis(f.Axis)) {
		if e.Type == pointer.Press || e.Type == pointer.Drag {
			de = &e
		}
@@ -38,7 +41,11 @@ func (f *Float) Layout(gtx layout.Context, pointerMargin int, min, max float32)

	value := f.Value
	if de != nil {
		f.pos = de.Position.X / f.length
		xy := de.Position.X
		if f.Axis == layout.Vertical {
			xy = de.Position.Y
		}
		f.pos = xy / f.length
		value = min + (max-min)*f.pos
	} else if min != max {
		f.pos = value/(max-min) - min
@@ -54,8 +61,9 @@ func (f *Float) Layout(gtx layout.Context, pointerMargin int, min, max float32)

	defer op.Save(gtx.Ops).Load()
	rect := image.Rectangle{Max: size}
	rect.Min.X -= pointerMargin
	rect.Max.X += pointerMargin
	margin := axisPoint(f.Axis, pointerMargin, 0)
	rect.Min = rect.Min.Sub(margin)
	rect.Max = rect.Max.Add(margin)
	pointer.Rect(rect).Add(gtx.Ops)
	f.drag.Add(gtx.Ops)

@@ -89,3 +97,10 @@ func (f *Float) Changed() bool {
	f.changed = false
	return changed
}

func axisPoint(a layout.Axis, x, y int) image.Point {
	if a == layout.Horizontal {
		return image.Pt(x, y)
	}
	return image.Pt(y, x)
}
diff --git a/widget/material/slider.go b/widget/material/slider.go
index 1ce95ff..f03075d 100644
--- a/widget/material/slider.go
+++ b/widget/material/slider.go
@@ -36,34 +36,26 @@ type SliderStyle struct {
}

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)
	thumbRadius := gtx.Px(unit.Dp(6))
	trackWidth := gtx.Px(unit.Dp(2))

	size := gtx.Constraints.Min
	axis := s.Float.Axis
	// Keep a minimum length so that the track is always visible.
	minLength := thumbRadiusInt + 3*thumbRadiusInt + thumbRadiusInt
	if size.X < minLength {
		size.X = minLength
	}
	size.Y = 2 * thumbRadiusInt

	minLength := thumbRadius + 3*thumbRadius + thumbRadius
	// 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)
	}
	touchSizePx := min(gtx.Px(s.FingerSize), axis.Cross(gtx.Constraints.Max))
	sizeMain := max(axis.Main(gtx.Constraints.Min), minLength)
	sizeCross := max(2*thumbRadius, touchSizePx)
	size := axisPoint(axis, sizeMain, sizeCross)

	st := op.Save(gtx.Ops)
	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()
	o := axisPoint(axis, thumbRadius, 0)
	op.Offset(layout.FPt(o)).Add(gtx.Ops)
	gtx.Constraints.Min = axisPoint(axis, sizeMain-2*thumbRadius, sizeCross)
	s.Float.Layout(gtx, thumbRadius, s.Min, s.Max)
	gtx.Constraints.Min = gtx.Constraints.Min.Add(axisPoint(axis, 0, sizeCross))
	thumbPos := thumbRadius + int(s.Float.Pos())
	st.Load()

	color := s.Color
@@ -73,50 +65,63 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {

	// Draw track before thumb.
	st = op.Save(gtx.Ops)
	track := f32.Rectangle{
		Min: f32.Point{
			X: thumbRadius,
			Y: float32(size.Y/2) - trackWidth/2,
		},
		Max: f32.Point{
			X: thumbPos,
			Y: float32(size.Y/2) + trackWidth/2,
		},
	track := image.Rectangle{
		Min: axisPoint(axis, thumbRadius, sizeCross/2-trackWidth/2),
		Max: axisPoint(axis, thumbPos, sizeCross/2+trackWidth/2),
	}
	clip.RRect{Rect: track}.Add(gtx.Ops)
	paint.ColorOp{Color: color}.Add(gtx.Ops)
	paint.PaintOp{}.Add(gtx.Ops)
	clip.Rect(track).Add(gtx.Ops)
	paint.Fill(gtx.Ops, color)
	st.Load()

	// Draw track after thumb.
	st = op.Save(gtx.Ops)
	track.Min.X = thumbPos
	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)
	track.Min = axisPoint(axis, thumbPos, axis.Cross(track.Min))
	track.Max = axisPoint(axis, sizeMain-thumbRadius, axis.Cross(track.Max))
	clip.Rect(track).Add(gtx.Ops)
	paint.Fill(gtx.Ops, f32color.MulAlpha(color, 96))
	st.Load()

	// Draw thumb.
	st = op.Save(gtx.Ops)
	thumb := f32.Rectangle{
		Min: f32.Point{
			X: thumbPos - thumbRadius,
			Y: float32(size.Y/2) - thumbRadius,
		},
		Max: f32.Point{
			X: thumbPos + thumbRadius,
			Y: float32(size.Y/2) + thumbRadius,
		},
	thumb := image.Rectangle{
		Min: axisPoint(axis, thumbPos-thumbRadius, sizeCross/2-thumbRadius),
		Max: axisPoint(axis, thumbPos+thumbRadius, sizeCross/2+thumbRadius),
	}
	rr := thumbRadius
	rr := float32(thumbRadius)
	clip.RRect{
		Rect: thumb,
		Rect: layout.FRect(thumb),
		NE:   rr, NW: rr, SE: rr, SW: rr,
	}.Add(gtx.Ops)
	paint.ColorOp{Color: color}.Add(gtx.Ops)
	paint.PaintOp{}.Add(gtx.Ops)
	paint.Fill(gtx.Ops, color)
	st.Load()

	return layout.Dimensions{Size: size}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func axisPoint(a layout.Axis, x, y int) image.Point {
	if a == layout.Horizontal {
		return image.Pt(x, y)
	}
	return image.Pt(y, x)
}

func axisFPoint(a layout.Axis, x, y float32) f32.Point {
	if a == layout.Horizontal {
		return f32.Pt(x, y)
	}
	return f32.Pt(y, x)
}
-- 
2.26.2