Update gio version. Add side grid for year selection to cmd/cal.

This commit is contained in:
Greg 2019-08-22 14:40:30 -04:00
parent 25847d5921
commit 014ace99a6
5 changed files with 112 additions and 63 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
cmd/hello/hello
cmd/cal/cal
*.apk

View File

@ -31,6 +31,10 @@ func _newMonth(y int, m time.Month) SelectableMonth {
return *NewMonth(time.Date(y,m,1,0,0,0,0,time.Local))
}
func (sm *SelectableMonth) Refresh() {
*sm = _newMonth(sm.Year, sm.Month)
}
func (sm *SelectableMonth) Previous() {
m, y := sm.Month - 1, sm.Year
if m > 11 {

View File

@ -13,7 +13,6 @@ import (
"gioui.org/ui"
"gioui.org/ui/app"
"gioui.org/ui/layout"
//"gioui.org/ui/measure"
"gioui.org/ui/text"
"golang.org/x/image/font/sfnt"
@ -33,7 +32,7 @@ func main() {
}
func NewButton(t string, lops ...gio.LabelOption) gio.Clickable {
lops = append([]gio.LabelOption{gio.Face(face), gio.Align(text.Center)}, lops...)
lops = append([]gio.LabelOption{gio.Face(face), gio.Align(text.Middle)}, lops...)
lbl := gio.NewLabel(t, lops...)
bg := gio.NewBackground(
gio.Color(color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xe0}),
@ -96,8 +95,10 @@ func NewCal(sm *SelectableMonth) gio.Widget {
}
func eventloop() {
w := app.NewWindow(&app.WindowOptions{
Width: ui.Dp(600), Height: ui.Dp(600), Title: "Tickets"})
w := app.NewWindow(
app.WithWidth(ui.Dp(600)),
app.WithHeight(ui.Dp(600)),
app.WithTitle("Calendar"))
ctx := gio.NewContext(w)
sm := NewMonth(time.Now())
@ -105,18 +106,24 @@ func eventloop() {
face = ctx.Faces.For(regular, ui.Sp(20))
if err != nil { log.Fatal("Cannot parse font.") }
margin := gio.NewInset(gio.Size(ui.Dp(10)))
topgrid := gio.NewGrid(3)
lbtn := NewButton(" < ")
mth := gio.NewLabel("", gio.Face(face), gio.Align(text.Center))
rbtn := NewButton(" > ")
f1 := gio.NewFlex(gio.Axis(layout.Vertical))
bg := gio.NewBackground(
gio.Color(color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xe0}))
margin := gio.NewInset(gio.Size(ui.Dp(10)))
f1 := gio.NewFlex(gio.Axis(layout.Vertical))
f2 := gio.NewFlex(gio.Axis(layout.Horizontal))
sidegrid := gio.NewGrid(1)
yrs := make([]gio.Widget,6)
curyr := sm.Year
topgrid := gio.NewGrid(3)
lbtn := NewButton(" < ")
mth := gio.NewLabel("", gio.Face(face), gio.Align(text.Middle))
rbtn := NewButton(" > ")
var cal gio.Widget
f3 := gio.NewFlex(gio.Axis(layout.Vertical))
daygrid := gio.NewGrid(7)
sun := NewSLabel("Sun",&sm.Ws[time.Sunday], gio.Align(text.End))
mon := NewSLabel("Mon",&sm.Ws[time.Monday], gio.Align(text.End))
@ -128,6 +135,10 @@ func eventloop() {
resetCal := func() {
cal = NewCal(sm)
for i,_ := range yrs {
yrs[i] = NewButton(fmt.Sprintf("%d",curyr - i),
gio.Align(text.Start))
}
w.Invalidate()
}
resetCal()
@ -137,18 +148,23 @@ func eventloop() {
switch e := e.(type) {
case app.DestroyEvent:
return
case app.DrawEvent:
case app.UpdateEvent:
ctx.Reset(e)
mth.SetText(fmt.Sprintf("%s %d",sm.Month.String(),sm.Year))
ows := sm.Ws
bg(margin(f1(
topgrid(lbtn,mth,rbtn),
daygrid(sun,mon,tue,wed,thu,fri,sat),
cal,
topgrid(lbtn,mth,rbtn),
f2(
sidegrid(yrs...),
f3(
daygrid(sun,mon,tue,wed,thu,fri,sat),
cal,
),
),
))).Layout(ctx)
ctx.Draw()
ctx.Update()
for i := time.Sunday; i < 7; i++ {
switch {
@ -168,6 +184,13 @@ func eventloop() {
sm.Next()
resetCal()
}
for i,y := range yrs {
if y.(gio.Clickable).Clicked(ctx) {
sm.Year = curyr - i
sm.Refresh()
resetCal()
}
}
sm.CheckSel()
}
}}

View File

@ -3,6 +3,7 @@ package main
import (
"git.wow.st/gmp/giowrap"
"image"
"image/color"
"log"
"os"
@ -13,7 +14,7 @@ import (
"gioui.org/ui"
"gioui.org/ui/app"
gdraw "gioui.org/ui/draw"
"gioui.org/ui/paint"
"gioui.org/ui/f32"
"gioui.org/ui/gesture"
"gioui.org/ui/layout"
@ -35,7 +36,7 @@ var (
)
func NewButton(face text.Face, t string, c color.RGBA) giowrap.Clickable {
lbl := giowrap.NewLabel(t, giowrap.Face(face), giowrap.Align(text.Center))
lbl := giowrap.NewLabel(t, giowrap.Face(face), giowrap.Align(text.Middle))
bg := giowrap.NewBackground(giowrap.Color(c), giowrap.Radius(ui.Dp(4)))
return giowrap.AsClickable(bg(lbl))
}
@ -79,7 +80,7 @@ hello [main1|main2]
}
func main1() {
w := app.NewWindow(nil)
w := app.NewWindow()
regular, err := sfnt.Parse(goregular.TTF)
if err != nil {
log.Fatal("Cannot parse font.")
@ -114,7 +115,7 @@ func main1() {
switch e := e.(type) {
case app.DestroyEvent:
return
case app.DrawEvent:
case app.UpdateEvent:
ctx.Reset(e)
OuterInset(
f1(
@ -128,7 +129,7 @@ func main1() {
InnerInset(btn2),
),
)).Layout(ctx)
ctx.Draw()
ctx.Update()
if btn1.Clicked(ctx) {
log.Print("Clicked: " + e1.Text() )
}
@ -161,7 +162,7 @@ func main1() {
}
func main2() {
w := app.NewWindow(nil)
w := app.NewWindow()
q := w.Queue()
ops := new(ui.Ops)
var faces measure.Faces
@ -216,7 +217,7 @@ func main2() {
switch e := e.(type) {
case app.DestroyEvent:
return
case app.DrawEvent:
case app.UpdateEvent:
c := &e.Config
ops.Reset()
faces.Reset(c)
@ -239,14 +240,14 @@ func main2() {
cs = b1ins.Begin(c, ops, cs)
dims = btn1.Layout(ops, cs)
dims = b1ins.End(dims)
pointer.RectAreaOp{Size: dims.Size}.Add(ops)
pointer.RectAreaOp{image.Rect(0,0,dims.Size.X,dims.Size.Y)}.Add(ops)
click1.Add(ops)
bg1.Stop()
wi, h := float32(dims.Size.X), float32(dims.Size.Y)
r := float32(c.Px(ui.Dp(4)))
giowrap.Rrect(ops, wi, h, r, r, r, r)
gdraw.ColorOp{Color: color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}}.Add(ops)
gdraw.DrawOp{Rect: f32.Rectangle{Max: f32.Point{X: wi, Y: h}}}.Add(ops)
paint.ColorOp{Color: color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}}.Add(ops)
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: wi, Y: h}}}.Add(ops)
bg1.Add(ops)
dims = InnerInset.End(dims)
f2c1 := f2.End(dims)
@ -256,13 +257,13 @@ func main2() {
cs = b2ins.Begin(c, ops, cs)
dims = btn2.Layout(ops, cs)
dims = b2ins.End(dims)
pointer.RectAreaOp{Size: dims.Size}.Add(ops)
pointer.RectAreaOp{image.Rect(0,0,dims.Size.X,dims.Size.Y)}.Add(ops)
click2.Add(ops)
bg2.Stop()
wi, h = float32(dims.Size.X), float32(dims.Size.Y)
giowrap.Rrect(ops, wi, h, r, r, r, r)
gdraw.ColorOp{Color: color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}}.Add(ops)
gdraw.DrawOp{Rect: f32.Rectangle{Max: f32.Point{X: wi, Y: h}}}.Add(ops)
paint.ColorOp{Color: color.RGBA{A: 0xff, R: 0x3c, G: 0x98, B: 0xc6}}.Add(ops)
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: wi, Y: h}}}.Add(ops)
bg2.Add(ops)
dims = InnerInset.End(dims)
f2c2 := f2.End(dims)
@ -270,13 +271,13 @@ func main2() {
f1c3 := f1.End(dims)
dims = f1.Layout(f1c1, f1c2, f1c3)
dims = OuterInset.End(dims)
w.Draw(ops)
for _,ev := range click1.Events(q) {
w.Update(ops)
for ev, ok := click1.Next(q); ok; ev, ok = click1.Next(q) {
if ev.Type == gesture.TypeClick {
log.Print("Clicked: " + e1.Text() )
}
}
for _, ev := range click2.Events(q) {
for ev, ok := click2.Next(q); ok; ev, ok = click2.Next(q) {
if ev.Type == gesture.TypeClick {
log.Print("Clicked: " + e2.Text() )
}

82
main.go
View File

@ -14,7 +14,7 @@ import (
"gioui.org/ui/text"
"gioui.org/ui/f32"
gdraw "gioui.org/ui/draw"
"gioui.org/ui/paint"
"gioui.org/ui/gesture"
"gioui.org/ui/pointer"
)
@ -56,15 +56,15 @@ func NewContext(w *app.Window) *Context {
}
}
func (ctx *Context) Reset(e app.DrawEvent) {
func (ctx *Context) Reset(e app.UpdateEvent) {
ctx.c = &e.Config
ctx.ops.Reset()
ctx.cs = layout.RigidConstraints(e.Size)
ctx.Faces.Reset(ctx.c)
}
func (ctx *Context) Draw() {
ctx.w.Draw(ctx.ops)
func (ctx *Context) Update() {
ctx.w.Update(ctx.ops)
}
type Layout func(*Context)
@ -193,22 +193,18 @@ func Rigid() Widget {
type AxisOpt struct { axis layout.Axis }
func Axis(x layout.Axis) AxisOpt { return AxisOpt{ x } }
type MainAxisAlignmentOpt struct { mainAxisAlignment layout.MainAxisAlignment }
func MainAxisAlignment(x layout.MainAxisAlignment) MainAxisAlignmentOpt { return MainAxisAlignmentOpt{ x } }
type CrossAxisAlignmentOpt struct { crossAxisAlignment layout.CrossAxisAlignment }
func CrossAxisAlignment(x layout.CrossAxisAlignment) CrossAxisAlignmentOpt { return CrossAxisAlignmentOpt{ x } }
type AlignmentOpt struct { alignment layout.Alignment }
func Alignment(x layout.Alignment) AlignmentOpt { return AlignmentOpt{ x } }
type FlexOpts struct {
AxisOpt
MainAxisAlignmentOpt
CrossAxisAlignmentOpt
AlignmentOpt
flexible float32
}
type FlexOption interface { DoFlexOption(*FlexOpts) }
func (x AxisOpt) DoFlexOption(o *FlexOpts) { o.axis = x.axis }
func (x MainAxisAlignmentOpt) DoFlexOption(o *FlexOpts) { o.mainAxisAlignment = x.mainAxisAlignment }
func (x CrossAxisAlignmentOpt) DoFlexOption(o *FlexOpts) { o.crossAxisAlignment = x.crossAxisAlignment }
func (x AlignmentOpt) DoFlexOption(o *FlexOpts) { o.alignment = x.alignment }
// NewFlex returns a WidgetCombinator that wraps the layout.Flex element.
func NewFlex(fos ...FlexOption) Flex {
@ -216,8 +212,7 @@ func NewFlex(fos ...FlexOption) Flex {
for _,o := range fos { o.DoFlexOption(opts) }
f := layout.Flex{
Axis: opts.axis,
MainAxisAlignment: opts.mainAxisAlignment,
CrossAxisAlignment: opts.crossAxisAlignment,
Alignment: opts.alignment,
}
index := extra.New()
extra.data[index] = opts
@ -361,8 +356,8 @@ func (bg *Background) End(ctx *Context) {
}
Rrect(ctx.ops, w, h, r, r, r, r)
}
gdraw.ColorOp{Color: bg.Color}.Add(ctx.ops)
gdraw.DrawOp{Rect: f32.Rectangle{Max: f32.Point{X: w, Y: h}}}.Add(ctx.ops)
paint.ColorOp{Color: bg.Color}.Add(ctx.ops)
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: w, Y: h}}}.Add(ctx.ops)
bg.macro.Add(ctx.ops)
stack.Pop()
}
@ -371,7 +366,7 @@ func (bg *Background) End(ctx *Context) {
func Rrect(ops *ui.Ops, width, height, se, sw, nw, ne float32) {
w, h := float32(width), float32(height)
const c = 0.55228475 // 4*(sqrt(2)-1)/3
var b gdraw.PathBuilder
var b paint.PathBuilder
b.Init(ops)
b.Move(f32.Point{X: w, Y: h - se})
b.Cube(f32.Point{X: 0, Y: se * c}, f32.Point{X: -se + se*c, Y: se}, f32.Point{X: -se, Y: se}) // SE
@ -397,12 +392,12 @@ type cWidget struct {
func (w cWidget) Layout(ctx *Context) {
w.w.Layout(ctx)
pointer.RectAreaOp{Size: ctx.dims.Size}.Add(ctx.ops)
pointer.RectAreaOp{image.Rect(0,0,ctx.dims.Size.X,ctx.dims.Size.Y)}.Add(ctx.ops)
w.click.Add(ctx.ops)
}
func (w cWidget) Clicked(ctx *Context) bool {
for _,e := range w.click.Events(ctx.q) {
for e, ok := w.click.Next(ctx.q); ok; e, ok = w.click.Next(ctx.q) {
if e.Type == gesture.TypeClick {
ctx.w.Invalidate()
return true
@ -417,9 +412,8 @@ func AsClickable(w Widget) cWidget {
}
type Grid struct {
Axis layout.Axis
Cols int
Height int
Height, Width int
macro ui.MacroOp
ops *ui.Ops
@ -446,11 +440,14 @@ func (g *Grid) Init(ops *ui.Ops, cs layout.Constraints) layout.Constraints {
g.row, g.col = 0, 0
cs.Height.Min = 0
if g.Height != 0 {
cs.Height.Max = g.Height
}
if g.Height != 0 { g.cs.Height.Max = g.Height }
if g.Width != 0 { g.cs.Width.Max = g.Width }
cs.Width.Max = g.cs.Width.Max / g.Cols
cs.Width.Min = cs.Width.Max
if g.Cols > 1 {
cs.Width.Min = cs.Width.Max
}
return cs
}
@ -470,6 +467,7 @@ func (g *Grid) Layout(cs ...GridChild) layout.Dimens {
rowheight := 0
height := 0
var width float32
var maxwidth float32
for _,c := range cs {
var stack ui.StackOp
stack.Push(g.ops)
@ -479,10 +477,17 @@ func (g *Grid) Layout(cs ...GridChild) layout.Dimens {
rowheight = c.dims.Size.Y
}
g.col = g.col+1
x := float32(g.cs.Width.Max / g.Cols)
ui.TransformOp{}.Offset(f32.Point{X: x}).Add(g.ops)
width = width + x
if g.col >= g.Cols {
var x float32
if g.Cols == 1 {
x = float32(c.dims.Size.X)
if x > maxwidth { maxwidth = x }
} else {
x = float32(g.cs.Width.Max / g.Cols)
}
if g.col < g.Cols {
ui.TransformOp{}.Offset(f32.Point{X: x}).Add(g.ops)
width = width + x
} else {
g.col = 0
ui.TransformOp{}.Offset(f32.Point{ X: -width, Y: float32(rowheight) }).Add(g.ops)
g.row = g.row + 1
@ -493,15 +498,30 @@ func (g *Grid) Layout(cs ...GridChild) layout.Dimens {
}
if height == 0 { height = rowheight }
g.mode = modeNone
return layout.Dimens{ Size: image.Point{ g.cs.Width.Max, height } }
var dwidth int
if g.Cols == 1 {
dwidth = int(maxwidth)
} else {
dwidth = g.cs.Width.Max
}
return layout.Dimens{ Size: image.Point{ dwidth, height } }
}
func toPointF(p image.Point) f32.Point {
return f32.Point{X: float32(p.X), Y: float32(p.Y)}
}
func NewGrid(cols int) WidgetCombinator {
type GridOption interface { DoGridOption(*Grid) }
type HeightOpt struct { height int }
func Height(x int) HeightOpt { return HeightOpt{ x } }
func (x HeightOpt) DoGridOption(g *Grid) { g.Height = x.height }
func NewGrid(cols int, gops ...GridOption) WidgetCombinator {
g := &Grid{ Cols: cols }
for _, gop := range gops {
gop.DoGridOption(g)
}
gcs := make([]GridChild,0)
return func(ws ...Widget) Widget {
return NewfWidget(func(ctx *Context) {