~eliasnaur/gio-example

14281bf0d29425e0c695ed4508d41abe56747494 — Chris Waldon 3 months ago e267006
x/scroll: remove scroll example

The scrollbar is now part of core, and thus used throughout
the other examples. It no longer needs a dedicated one.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
1 files changed, 0 insertions(+), 124 deletions(-)

D x/scroll/main.go
D x/scroll/main.go => x/scroll/main.go +0 -124
@@ 1,124 0,0 @@
// SPDX-License-Identifier: Unlicense OR MIT
package main

// A simple Gio program. See https://gioui.org for more information.

import (
	"log"
	"os"
	"strconv"

	"gioui.org/app"
	"gioui.org/io/system"
	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/unit"
	"gioui.org/widget"
	"gioui.org/widget/material"
	"gioui.org/x/scroll"

	"gioui.org/font/gofont"
)

func main() {
	go func() {
		w := app.NewWindow()
		if err := loop(w); err != nil {
			log.Fatal(err)
		}
		os.Exit(0)
	}()
	app.Main()
}

var (
	increaseBtn, decreaseBtn widget.Clickable
	length                   int
	list                     layout.List

	indicator scroll.Scrollable
)

type (
	C = layout.Context
	D = layout.Dimensions
)

func loop(w *app.Window) error {
	th := material.NewTheme(gofont.Collection())
	var ops op.Ops
	length = 32
	list.Axis = layout.Vertical
	list.Alignment = layout.Middle
	inset := layout.UniformInset(unit.Dp(4))
	for {
		e := <-w.Events()
		switch e := e.(type) {
		case system.DestroyEvent:
			return e.Err
		case system.FrameEvent:
			gtx := layout.NewContext(&ops, e)
			if increaseBtn.Clicked() {
				length *= 2
			}
			if decreaseBtn.Clicked() {
				length /= 2
				if length < 1 {
					length = 1
				}
			}
			/*
				Here we check whether the scrollbar experienced user-initiated scrolling
				during the past frame and update the state of the List accordingly
			*/
			if scrolled, progress := indicator.Scrolled(); scrolled {
				list.Position.First = int(float32(length) * progress)
			}
			const third float32 = 1.0 / 3.0
			layout.Flex{Axis: layout.Vertical}.Layout(gtx,
				layout.Rigid(func(gtx C) D {
					return layout.Flex{Alignment: layout.Baseline}.Layout(gtx,
						layout.Flexed(third, func(gtx C) D {
							return inset.Layout(gtx, material.Button(th, &increaseBtn, "Double list length").Layout)
						}),
						layout.Flexed(third, func(gtx C) D {
							return layout.Center.Layout(gtx, func(gtx C) D {
								return material.Body1(th, "Current List Length: "+strconv.Itoa(length)).Layout(gtx)
							})
						}),
						layout.Flexed(third, func(gtx C) D {
							return inset.Layout(gtx, material.Button(th, &decreaseBtn, "Halve list length").Layout)
						}),
					)
				}),
				layout.Flexed(1, func(gtx C) D {
					longAxisSum := 0
					longAxisElements := 0
					// Track how many items we are laying out
					dims := list.Layout(gtx, length, func(gtx C, index int) D {
						d := layout.Center.Layout(gtx, material.H3(th, "List item #"+strconv.Itoa(index)).Layout)
						longAxisSum += d.Size.Y
						longAxisElements++
						return d
					})
					meanElementHeight := float32(longAxisSum) / float32(longAxisElements)
					visibleCount := list.Position.Count
					pixelLength := meanElementHeight * float32(length)
					// Compute (using the heuristic that each item is the same vertical height)
					// the fraction of all items that are currently visible
					visiblePixels := float32(visibleCount)*meanElementHeight - float32(list.Position.Offset) + float32(list.Position.OffsetLast)
					visibleFraction := visiblePixels / pixelLength
					// Compute how far through the list items we have scrolled
					offset := (float32(list.Position.First) * meanElementHeight) + float32(list.Position.Offset)
					scrollDepth := offset / (float32(length) * meanElementHeight)

					// Lay out the scroll bar
					bar := scroll.DefaultBar(&indicator, scrollDepth, visibleFraction)
					bar.Layout(gtx)
					return dims
				}),
			)
			e.Frame(gtx.Ops)
		}
	}
}