giowrap/cmd/cal/main.go

176 lines
3.9 KiB
Go

// +build darwin linux
package main
import (
"fmt"
"log"
"image/color"
"time"
gio "git.wow.st/gmp/giowrap"
"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"
"golang.org/x/image/font/gofont/goregular"
)
var (
sel int32
face text.Face
)
func main() {
log.Print("Staring event loop")
go eventloop()
app.Main()
log.Print("App closed")
}
func NewButton(t string, lops ...gio.LabelOption) gio.Clickable {
lops = append([]gio.LabelOption{gio.Face(face), gio.Align(text.Center)}, lops...)
lbl := gio.NewLabel(t, lops...)
bg := gio.NewBackground(
gio.Color(color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xe0}),
gio.Radius(ui.Dp(4)))
return gio.AsClickable(bg(lbl))
}
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: color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xe0},
Radius: ui.Dp(4),
Inset: layout.UniformInset(ui.Dp(4)),
}
if *active {
bg.Color = color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xe0}
}
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 = color.RGBA{A: 0xff, R: 0xe0, G: 0xe0, B: 0xe0}
} else {
w.bg.Color = color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xe0}
}
w.w.Layout(ctx)
if w.w.Clicked(ctx) {
if *w.active {
*w.active = false
} else {
*w.active = true
}
}
}
func NewCal(sm *SelectableMonth) gio.Widget {
pad := gio.NewLabel("", gio.Face(face), gio.Align(text.End))
ds := make([]gio.Widget,42)
for i := 0; i < len(ds); i++ {
if i < sm.Pad || i >= sm.DaysIn + sm.Pad {
ds[i] = pad
} else {
ds[i] = NewSLabel(fmt.Sprintf("%d",i+1-sm.Pad), &sm.S[i+1-sm.Pad], gio.Align(text.End))
}
}
return gio.NewGrid(7)(ds...)
}
func eventloop() {
w := app.NewWindow(&app.WindowOptions{
Width: ui.Dp(600), Height: ui.Dp(600), Title: "Tickets"})
ctx := gio.NewContext(w)
sm := NewMonth(time.Now())
regular, err := sfnt.Parse(goregular.TTF)
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}))
var cal gio.Widget
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))
tue := NewSLabel("Tue",&sm.Ws[time.Tuesday], gio.Align(text.End))
wed := NewSLabel("Wed",&sm.Ws[time.Wednesday], gio.Align(text.End))
thu := NewSLabel("Thu",&sm.Ws[time.Thursday], gio.Align(text.End))
fri := NewSLabel("Fri",&sm.Ws[time.Friday], gio.Align(text.End))
sat := NewSLabel("Sat",&sm.Ws[time.Saturday], gio.Align(text.End))
resetCal := func() {
cal = NewCal(sm)
w.Invalidate()
}
resetCal()
for { select {
case e:= <-w.Events():
switch e := e.(type) {
case app.DestroyEvent:
return
case app.DrawEvent:
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,
))).Layout(ctx)
ctx.Draw()
for i := time.Sunday; i < 7; i++ {
switch {
case sm.Ws[i] && !ows[i]:
sm.SelectWeekday(i)
resetCal()
case !sm.Ws[i] && ows[i]:
sm.DeselectWeekday(i)
resetCal()
}
}
if lbtn.Clicked(ctx) {
sm.Previous()
resetCal()
}
if rbtn.Clicked(ctx) {
sm.Next()
resetCal()
}
sm.CheckSel()
}
}}
}