random-apps/timer/windowCountdown.go

89 lines
2.1 KiB
Go
Raw Normal View History

2025-02-03 15:41:15 +00:00
package timer
import (
"image"
"sync"
"time"
"gioui.org/app"
"gioui.org/io/event"
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/text"
"gioui.org/widget/material"
"git.mstar.dev/mstar/timer/shared"
"github.com/rs/zerolog/log"
)
type StateCountdown struct {
initialSetupDone bool
TargetTime time.Time
ops op.Ops
}
func (s *StateCountdown) Run(globalState *shared.GlobalState, event event.Event) shared.NewState {
if !s.initialSetupDone {
s.initialSetup(globalState)
}
switch event := event.(type) {
case app.FrameEvent:
return s.handleFrameEvent(globalState, &event)
case app.DestroyEvent:
return s.handleQuitEvent()
case app.WaylandViewEvent, app.X11ViewEvent:
return shared.EmptyEvent()
default:
log.Debug().Any("event", event).Type("type", event).Msg("Unknown event")
return shared.NewState{}
}
}
func (s *StateCountdown) Exit(globalState *shared.GlobalState, wg *sync.WaitGroup) {
wg.Done()
}
func (s *StateCountdown) initialSetup(globalState *shared.GlobalState) {
s.initialSetupDone = true
go func(window *app.Window) {
t := time.NewTicker(time.Second)
for range t.C {
window.Invalidate()
}
}(globalState.Window)
}
func (s *StateCountdown) handleQuitEvent() shared.NewState {
return shared.NewState{ExitCode: shared.ErrExitOk}
}
func (s *StateCountdown) handleFrameEvent(
globalState *shared.GlobalState,
frameEvent *app.FrameEvent,
) shared.NewState {
gtx := app.NewContext(&s.ops, *frameEvent)
paint.FillShape(
gtx.Ops,
globalState.Theme.Bg,
clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op(),
)
diff := frameEvent.Now.Sub(s.TargetTime)
diff *= -1
title := material.H1(
globalState.Theme,
diff.Round(time.Second).String(),
)
// //
// // // Change the color of the label.
title.Color = shared.TextColor
// //
// // // Change the position of the label.
title.Alignment = text.Middle
//
// // Draw the label to the graphics context.
title.Layout(gtx)
// // Pass the drawing operations to the GPU.
frameEvent.Frame(&s.ops)
return shared.NewState{}
}