giowrap/cmd/scroll/main.go
Greg 70e5529a9b Add List widget combinator. Add HScroll and VScroll functions. Add
scroll demo to see a 2-way scrolling field of selectable labels.
2019-08-23 10:46:59 -04:00

153 lines
3.1 KiB
Go

package main
import (
"image/color"
"fmt"
"log"
gio "git.wow.st/gmp/giowrap"
"gioui.org/ui"
"gioui.org/ui/app"
"gioui.org/ui/layout"
"gioui.org/ui/text"
"golang.org/x/image/font/sfnt"
"golang.org/x/image/font/gofont/goregular"
)
var (
face text.Face
black color.RGBA = color.RGBA{ A: 0xff, R: 0x00, G: 0x00, B: 0x00 }
gray2 color.RGBA = color.RGBA{ A: 0xff, R: 0x70, G: 0x70, B: 0x70 }
gray1 color.RGBA = color.RGBA{ A: 0xff, R: 0x50, G: 0x50, B: 0x50 }
)
type SLabel struct {
w gio.Clickable
bg *gio.Background
active *bool
}
func NewSLabel(t string, active *bool, lops ...gio.LabelOption) *SLabel {
ret := &SLabel{}
lops = append([]gio.LabelOption{gio.Face(face)},lops...)
lbl := gio.NewLabel(t, lops...)
bg := &gio.Background{
Color: gray2,
Radius: ui.Dp(4),
Inset: layout.UniformInset(ui.Dp(4)),
}
if *active {
bg.Color = gray1
}
l := gio.AsClickable(gio.Enclose(bg,lbl))
ret.w = l
ret.bg = bg
ret.active = active
return ret
}
func (w *SLabel) Layout(ctx *gio.Context) {
if *w.active {
w.bg.Color = gray1
} else {
w.bg.Color = gray2
}
w.w.Layout(ctx)
if w.w.Clicked(ctx) {
if *w.active {
*w.active = false
} else {
*w.active = true
}
}
}
func main() {
log.Print("Staring event loop")
go eventloop()
app.Main()
log.Print("App closed")
}
func diffInsets(x, y app.Insets) bool {
return x.Top != y.Top ||
x.Bottom != y.Bottom ||
x.Left != y.Left ||
x.Right != y.Right
}
func eventloop() {
w := app.NewWindow(
app.WithWidth(ui.Dp(200)),
app.WithHeight(ui.Dp(400)),
app.WithTitle("Tickets"))
ctx := gio.NewContext(w)
regular, err := sfnt.Parse(goregular.TTF)
face = ctx.Faces.For(regular, ui.Sp(16))
if err != nil { log.Fatal("Cannot parse font.") }
sysbg := gio.NewBackground(gio.Color(black))
bg := gio.NewBackground(gio.Color(gray2))
margin := gio.NewInset(gio.Size(ui.Dp(10)))
sh := gio.HScroll(gio.NewFlex(gio.Axis(layout.Horizontal)))
sv := gio.VScroll(gio.NewFlex(gio.Axis(layout.Vertical)))
numlabs := 50
labs := make([][]gio.Widget, numlabs)
sels := make([][]bool, numlabs)
for i := 0; i < 16; i++ {
labs[i] = make([]gio.Widget, numlabs)
sels[i] = make([]bool, numlabs)
for j := 0; j < numlabs; j++ {
labs[i][j] = NewSLabel(fmt.Sprintf("%03d",i * j), &sels[i][j])
}
}
sysinset := gio.NewInset(gio.Size(ui.Dp(0)))
resetSysinset := func(x app.Insets) {
sysinset = gio.NewInset(gio.Top(x.Top), gio.Bottom(x.Bottom),
gio.Left(x.Left), gio.Right(x.Right))
}
var oldInsets app.Insets
for { select {
case e:= <-w.Events():
switch e := e.(type) {
case app.DestroyEvent:
return
case app.UpdateEvent:
ctx.Reset(e)
if diffInsets(e.Insets, oldInsets) {
oldInsets = e.Insets
resetSysinset(e.Insets)
}
sysbg(sysinset(bg(margin(
sh(
sv(labs[0]...),
sv(labs[1]...),
sv(labs[2]...),
sv(labs[3]...),
sv(labs[4]...),
sv(labs[5]...),
sv(labs[6]...),
sv(labs[7]...),
sv(labs[8]...),
sv(labs[9]...),
sv(labs[10]...),
sv(labs[11]...),
sv(labs[12]...),
sv(labs[13]...),
sv(labs[14]...),
sv(labs[15]...),
))))).Layout(ctx)
ctx.Update()
}
}}
}