~eliasnaur/gio-example

092707750d41257206c2cf473e7549505dad2215 — Chris Waldon 2 months ago be4210b
gio-extras/scroll: add scrollbar example

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

A gio-extras/scroll/main.go
M go.mod
M go.sum
A gio-extras/scroll/main.go => gio-extras/scroll/main.go +116 -0
@@ 0,0 1,116 @@
// 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"
	"git.sr.ht/~whereswaldon/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 {
					// Track how many items we are laying out
					var visibleCount int
					dims := list.Layout(gtx, length, func(gtx C, index int) D {
						visibleCount++
						return layout.Center.Layout(gtx, material.H3(th, "List item #"+strconv.Itoa(index)).Layout)
					})
					// Compute (using the heuristic that each item is the same vertical height)
					// the fraction of all items that are currently visible
					visibleFraction := float32(visibleCount) / float32(length)
					// Compute how far through the list items we have scrolled
					scrollDepth := float32(list.Position.First) / float32(length)

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

M go.mod => go.mod +1 -0
@@ 8,6 8,7 @@ require (
	git.sr.ht/~whereswaldon/haptic v0.0.0-20201207220958-78675dee81dd
	git.sr.ht/~whereswaldon/niotify v0.0.3
	git.sr.ht/~whereswaldon/outlay v0.0.0-20201207220906-cbe824700857
	git.sr.ht/~whereswaldon/scroll v0.0.0-20201208022259-cc815a044b0b
	github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7
	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4
	github.com/google/go-github/v24 v24.0.1

M go.sum => go.sum +2 -0
@@ 12,6 12,8 @@ git.sr.ht/~whereswaldon/niotify v0.0.3 h1:EWRqPOzqTLU92A9h207LkS/U/nQxuawJ0PF7UE
git.sr.ht/~whereswaldon/niotify v0.0.3/go.mod h1:itJ9vAQqq8+liURizx7mAdIY4o8gRDF6SAVfswYVg1U=
git.sr.ht/~whereswaldon/outlay v0.0.0-20201207220906-cbe824700857 h1:Sc+1cZRrwGyiBYgqIto5OlK+RTea1T7FYmZj+JC6RZI=
git.sr.ht/~whereswaldon/outlay v0.0.0-20201207220906-cbe824700857/go.mod h1:basiujMeRXbgNAivgbiWlxy+gsS0oO70suSRSZ96Nw4=
git.sr.ht/~whereswaldon/scroll v0.0.0-20201208022259-cc815a044b0b h1:KzG0qB0Vxr6X3kgvYV2HTSjZFbcIx6YiZvbxD+hZIAU=
git.sr.ht/~whereswaldon/scroll v0.0.0-20201208022259-cc815a044b0b/go.mod h1:/AM8KrZLPyehiTttCs4hYx+9NtV2EaQe4rBGyblqHGo=
git.wow.st/gmp/jni v0.0.0-20200619201040-d0d3f316ae09/go.mod h1:lfKZKu2afBKJODTFgDNIaBfhq6qmQS0xsS/phLO5Urk=
git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0 h1:Ynp3h+TC8k1clvf45D28VFQlmy0bPx8M/MG5bB24Vj8=
git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo=