~pierrec/giox

29b417532cfdcbf5b437116dd69cca7fe47a01d9 — pierre 9 months ago 38151c3
colorx: removed Fill

Signed-off-by: pierre <pierre.curto@gmail.com>
3 files changed, 162 insertions(+), 132 deletions(-)

M colorx/colorx.go
M widgetx/file.go
M widgetx/materialx/input.go
M colorx/colorx.go => colorx/colorx.go +0 -19
@@ 1,28 1,9 @@
package colorx

import (
	"image"
	"image/color"

	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/op/clip"
	"gioui.org/op/paint"
)

// Fill sets a widget's background.
func Fill(gtx layout.Context, col color.NRGBA, w layout.Widget) layout.Dimensions {
	m := op.Record(gtx.Ops)
	dims := w(gtx)
	c := m.Stop()
	s := op.Save(gtx.Ops)
	clip.Rect(image.Rectangle{Max: dims.Size}).Add(gtx.Ops)
	paint.Fill(gtx.Ops, col)
	s.Load()
	c.Add(gtx.Ops)
	return dims
}

// Hover returns a color representing the hover state for a clickable area.
func Hover(c color.NRGBA) color.NRGBA {
	return MulAlpha(c, 64)

M widgetx/file.go => widgetx/file.go +144 -106
@@ 12,6 12,7 @@ import (
	"strings"
	"time"

	"gioui.org/f32"
	"gioui.org/io/key"
	"gioui.org/layout"
	"gioui.org/op"


@@ 271,28 272,46 @@ func (a fileArea) Layout(gtx layout.Context, w, status layout.Widget) layout.Dim
			CornerRadius: inset.Top,
			Width:        inset.Top,
		}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
			return colorx.Fill(gtx, a.Palette.Bg, func(gtx layout.Context) layout.Dimensions {
				if status == nil {
					return stack(gtx)
				}
				return layout.Flex{
					Axis:    layout.Vertical,
					Spacing: layout.SpaceBetween,
				}.Layout(gtx,
					layout.Flexed(1, stack),
					layout.Rigid(func(gtx layout.Context) layout.Dimensions {
						return colorx.Fill(gtx, a.Palette.ContrastBg, func(gtx layout.Context) layout.Dimensions {
							return layout.Inset{
								Left:  unit.Dp(4),
								Right: unit.Dp(4),
							}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
								paint.ColorOp{Color: a.Palette.ContrastFg}.Add(gtx.Ops)
								return status(gtx)
							})
						})
					}),
				)
			})
			return layout.Stack{}.Layout(gtx,
				layout.Expanded(func(gtx layout.Context) layout.Dimensions {
					paint.FillShape(gtx.Ops, a.Palette.Bg, clip.Rect{Max: gtx.Constraints.Min}.Op())
					return layout.Dimensions{Size: gtx.Constraints.Min}
				}),
				layout.Stacked(func(gtx layout.Context) layout.Dimensions {
					if status == nil {
						return stack(gtx)
					}
					return layout.Flex{
						Axis:    layout.Vertical,
						Spacing: layout.SpaceBetween,
					}.Layout(gtx,
						layout.Flexed(1, stack),
						layout.Rigid(func(gtx layout.Context) layout.Dimensions {
							return layout.Stack{}.Layout(gtx,
								layout.Expanded(func(gtx layout.Context) layout.Dimensions {
									radius := gtx.Metric.Px(inset.Top)
									r := clip.RRect{
										Rect: f32.Rectangle{Max: layout.FPt(gtx.Constraints.Min)},
										SE:   float32(radius), SW: float32(radius),
									}
									paint.FillShape(gtx.Ops, a.Palette.ContrastBg, r.Op(gtx.Ops))
									return layout.Dimensions{Size: gtx.Constraints.Min}
								}),
								layout.Stacked(func(gtx layout.Context) layout.Dimensions {
									return layout.Inset{
										Left:  unit.Dp(4),
										Right: unit.Dp(4),
									}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
										gtx.Constraints.Min.X = gtx.Constraints.Max.X
										paint.ColorOp{Color: a.Palette.ContrastFg}.Add(gtx.Ops)
										return status(gtx)
									})
								}),
							)
						}),
					)
				}),
			)
		})
	})
}


@@ 693,6 712,12 @@ func (cc *clickColumn) Layout(cols *clickColumns, gtx layout.Context, label func
	}
	cc.update(cols)
	return layout.Stack{}.Layout(gtx,
		layout.Expanded(func(gtx layout.Context) layout.Dimensions {
			if cc.click.Hovered() {
				paint.FillShape(gtx.Ops, cols.Hover.Color, clip.Rect{Max: gtx.Constraints.Min}.Op())
			}
			return layout.Dimensions{Size: gtx.Constraints.Min}
		}),
		layout.Stacked(func(gtx layout.Context) layout.Dimensions {
			return layout.Flex{
				Axis:      layout.Horizontal,


@@ 730,12 755,7 @@ func (cc *clickColumn) Layout(cols *clickColumns, gtx layout.Context, label func
				}),
			)
		}),
		layout.Expanded(func(gtx layout.Context) layout.Dimensions {
			if !cc.click.Hovered() {
				return cc.click.Layout(gtx)
			}
			return colorx.Fill(gtx, cols.Hover.Color, cc.click.Layout)
		}),
		layout.Expanded(cc.click.Layout),
	)
}



@@ 1324,13 1344,19 @@ func (f *File) layoutPaths(gtx layout.Context) layout.Dimensions {
					m, s := f.splitPath()
					return f.pList.Layout(gtx, len(s), func(gtx layout.Context, idx int, _ *widget.Clickable) layout.Dimensions {
						if idx == 0 {
							return colorx.Fill(gtx, f.Palettes.Area.ContrastBg, func(gtx layout.Context) layout.Dimensions {
								inset.Right = unit.Dp(4)
								return inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
									paint.ColorOp{Color: f.Palettes.Area.ContrastFg}.Add(gtx.Ops)
									return f.body1(gtx, m)
								})
							})
							return layout.Stack{}.Layout(gtx,
								layout.Expanded(func(gtx layout.Context) layout.Dimensions {
									paint.FillShape(gtx.Ops, f.Palettes.Area.ContrastBg, clip.Rect{Max: gtx.Constraints.Min}.Op())
									return layout.Dimensions{Size: gtx.Constraints.Min}
								}),
								layout.Stacked(func(gtx layout.Context) layout.Dimensions {
									inset.Right = unit.Dp(4)
									return inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
										paint.ColorOp{Color: f.Palettes.Area.ContrastFg}.Add(gtx.Ops)
										return f.body1(gtx, m)
									})
								}),
							)
						}
						return inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
							return f.body1(gtx, s[idx])


@@ 1453,14 1479,20 @@ func (f *File) layoutSelected(gtx layout.Context) layout.Dimensions {
		return f.selected.Area.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
			gtx.Constraints.Min = gtx.Constraints.Max
			return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
				bg := colorx.MulAlpha(f.Palettes.Area.Bg, 32)
				return colorx.Fill(gtx, bg, func(gtx layout.Context) layout.Dimensions {
					inset := layout.UniformInset(unit.Dp(4))
					gtx.Constraints.Min.X = gtx.Constraints.Max.X / 2
					return inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
						return f.Text.Editor(gtx, &f.sInput)
					})
				})
				return layout.Stack{}.Layout(gtx,
					layout.Expanded(func(gtx layout.Context) layout.Dimensions {
						col := colorx.MulAlpha(f.Palettes.Area.Bg, 32)
						paint.FillShape(gtx.Ops, col, clip.Rect{Max: gtx.Constraints.Min}.Op())
						return layout.Dimensions{Size: gtx.Constraints.Min}
					}),
					layout.Stacked(func(gtx layout.Context) layout.Dimensions {
						inset := layout.UniformInset(unit.Dp(4))
						gtx.Constraints.Min.X = gtx.Constraints.Max.X / 2
						return inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
							return f.Text.Editor(gtx, &f.sInput)
						})
					}),
				)
			})
		}, nil)
	case SelectFiles:


@@ 1508,70 1540,76 @@ func (f *File) Layout(gtx layout.Context) layout.Dimensions {
		gtx.Constraints.Min = gtx.Constraints.Max
		f.shadow.Layout(gtx)
	}
	return colorx.Fill(gtx, f.Palettes.Area.Bg, func(gtx layout.Context) layout.Dimensions {
		return layout.Flex{
			Axis: layout.Vertical,
		}.Layout(gtx,
			// Transient error message.
			layout.Rigid(func(gtx layout.Context) layout.Dimensions {
				if f.err == nil {
	return layout.Stack{}.Layout(gtx,
		layout.Expanded(func(gtx layout.Context) layout.Dimensions {
			paint.FillShape(gtx.Ops, f.Palettes.Area.Bg, clip.Rect{Max: gtx.Constraints.Min}.Op())
			return layout.Dimensions{Size: gtx.Constraints.Min}
		}),
		layout.Stacked(func(gtx layout.Context) layout.Dimensions {
			return layout.Flex{
				Axis: layout.Vertical,
			}.Layout(gtx,
				// Transient error message.
				layout.Rigid(func(gtx layout.Context) layout.Dimensions {
					if f.err == nil {
						return layout.Dimensions{Size: gtx.Constraints.Min}
					}
					switch {
					case f.errAt.IsZero():
						f.errAt = gtx.Now.Add(errTimeout)
						fallthrough
					case f.errAt.After(gtx.Now):
						return f.layoutError(gtx)
					}
					f.err = nil
					f.errAt = time.Time{}
					op.InvalidateOp{}.Add(gtx.Ops)
					return layout.Dimensions{Size: gtx.Constraints.Min}
				}
				switch {
				case f.errAt.IsZero():
					f.errAt = gtx.Now.Add(errTimeout)
					fallthrough
				case f.errAt.After(gtx.Now):
					return f.layoutError(gtx)
				}
				f.err = nil
				f.errAt = time.Time{}
				op.InvalidateOp{}.Add(gtx.Ops)
				return layout.Dimensions{Size: gtx.Constraints.Min}
			}),
			layout.Rigid(f.layoutPaths),
			layout.Flexed(f.sSep.Ratio, func(gtx layout.Context) layout.Dimensions {
				var dirFlex, fileFlex layout.FlexChild
				switch dirs, files := f.dirs.Collapsed(), f.files.Collapsed(); {
				case dirs && files:
					dirFlex = layout.Rigid(f.layoutDirs)
					fileFlex = layout.Rigid(f.layoutFiles)
				case dirs && !files:
					dirFlex = layout.Rigid(f.layoutDirs)
					fileFlex = layout.Flexed(1, f.layoutFiles)
				case !dirs && files:
					dirFlex = layout.Flexed(1, f.layoutDirs)
					fileFlex = layout.Rigid(f.layoutFiles)
				default:
					dirFlex = layout.Flexed(f.dSep.Ratio, f.layoutDirs)
					fileFlex = layout.Flexed(1-f.dSep.Ratio, f.layoutFiles)
				}
				return layout.Flex{
					Axis: layout.Horizontal,
				}.Layout(gtx,
					layout.Flexed(f.favrecSep.Ratio, f.layoutFavRec),
					layout.Rigid(func(gtx layout.Context) layout.Dimensions {
						if !f.pBar.Status(barFavRec) {
							return layout.Dimensions{Size: gtx.Constraints.Min}
						}
						return f.favrecSep.Layout(gtx, f.layoutVerticalHandle)
					}),
					dirFlex,
					layout.Rigid(func(gtx layout.Context) layout.Dimensions {
						if f.dirs.Collapsed() || f.files.Collapsed() {
							return layout.Dimensions{Size: gtx.Constraints.Min}
						}
						return f.dSep.Layout(gtx, f.layoutVerticalHandle)
					}),
					fileFlex,
				)
			}),
			layout.Rigid(func(gtx layout.Context) layout.Dimensions {
				return f.sSep.Layout(gtx, f.layoutHorizontalHandle)
			}),
			layout.Flexed(1-f.sSep.Ratio, f.layoutSelected),
		)
	})
				}),
				layout.Rigid(f.layoutPaths),
				layout.Flexed(f.sSep.Ratio, func(gtx layout.Context) layout.Dimensions {
					var dirFlex, fileFlex layout.FlexChild
					switch dirs, files := f.dirs.Collapsed(), f.files.Collapsed(); {
					case dirs && files:
						dirFlex = layout.Rigid(f.layoutDirs)
						fileFlex = layout.Rigid(f.layoutFiles)
					case dirs && !files:
						dirFlex = layout.Rigid(f.layoutDirs)
						fileFlex = layout.Flexed(1, f.layoutFiles)
					case !dirs && files:
						dirFlex = layout.Flexed(1, f.layoutDirs)
						fileFlex = layout.Rigid(f.layoutFiles)
					default:
						dirFlex = layout.Flexed(f.dSep.Ratio, f.layoutDirs)
						fileFlex = layout.Flexed(1-f.dSep.Ratio, f.layoutFiles)
					}
					return layout.Flex{
						Axis: layout.Horizontal,
					}.Layout(gtx,
						layout.Flexed(f.favrecSep.Ratio, f.layoutFavRec),
						layout.Rigid(func(gtx layout.Context) layout.Dimensions {
							if !f.pBar.Status(barFavRec) {
								return layout.Dimensions{Size: gtx.Constraints.Min}
							}
							return f.favrecSep.Layout(gtx, f.layoutVerticalHandle)
						}),
						dirFlex,
						layout.Rigid(func(gtx layout.Context) layout.Dimensions {
							if f.dirs.Collapsed() || f.files.Collapsed() {
								return layout.Dimensions{Size: gtx.Constraints.Min}
							}
							return f.dSep.Layout(gtx, f.layoutVerticalHandle)
						}),
						fileFlex,
					)
				}),
				layout.Rigid(func(gtx layout.Context) layout.Dimensions {
					return f.sSep.Layout(gtx, f.layoutHorizontalHandle)
				}),
				layout.Flexed(1-f.sSep.Ratio, f.layoutSelected),
			)
		}),
	)
}

// Selected returns the slice of selected files or directories.

M widgetx/materialx/input.go => widgetx/materialx/input.go +18 -7
@@ 4,6 4,8 @@ import (
	"image"

	"gioui.org/layout"
	"gioui.org/op/clip"
	"gioui.org/op/paint"
	"gioui.org/widget"
	"gioui.org/widget/material"



@@ 34,7 36,8 @@ func InputLayout(th *material.Theme, input *widgetx.Input, hint string) InputLay
}

func (in InputLayoutStyle) Layout(gtx layout.Context) layout.Dimensions {
	gtx.Constraints.Max.X = gtx.Constraints.Min.X
	minX := gtx.Constraints.Min.X
	gtx.Constraints.Max.X = minX
	return layout.Flex{
		Axis: layout.Vertical,
	}.Layout(gtx,


@@ 43,18 46,26 @@ func (in InputLayoutStyle) Layout(gtx layout.Context) layout.Dimensions {
			if in.Input.Focused() {
				alpha = 64
			}
			return colorx.Fill(gtx, colorx.MulAlpha(in.Palette.Bg, alpha), func(gtx layout.Context) layout.Dimensions {
				return in.Input.Layout(gtx, in.input.Layout)
			})
			return layout.Stack{}.Layout(gtx,
				layout.Expanded(func(gtx layout.Context) layout.Dimensions {
					col := colorx.MulAlpha(in.Palette.Bg, alpha)
					paint.FillShape(gtx.Ops, col, clip.Rect{Max: gtx.Constraints.Min}.Op())
					return layout.Dimensions{Size: gtx.Constraints.Min}
				}),
				layout.Stacked(func(gtx layout.Context) layout.Dimensions {
					gtx.Constraints.Min.X = minX
					return in.Input.Layout(gtx, in.input.Layout)
				}),
			)
		}),
		layout.Rigid(func(gtx layout.Context) layout.Dimensions {
			col := in.Palette.ContrastBg
			if !in.Input.Focused() {
				col = colorx.MulAlpha(col, 64)
			}
			return colorx.Fill(gtx, col, func(gtx layout.Context) layout.Dimensions {
				return layout.Dimensions{Size: image.Pt(gtx.Constraints.Min.X, 4)}
			})
			size := image.Pt(gtx.Constraints.Min.X, 4)
			paint.FillShape(gtx.Ops, col, clip.Rect{Max: size}.Op())
			return layout.Dimensions{Size: size}
		}),
	)
}