batman
This commit is contained in:
commit
185c84742a
7 changed files with 254 additions and 0 deletions
7
constants.go
Normal file
7
constants.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "image/color"
|
||||
|
||||
var (
|
||||
ColorRed = color.NRGBA{R: 0xff, G: 0x0, B: 0x0, A: 255}
|
||||
)
|
18
go.mod
Normal file
18
go.mod
Normal file
|
@ -0,0 +1,18 @@
|
|||
module git.mstar.dev/mstar/timer
|
||||
|
||||
go 1.23.5
|
||||
|
||||
require (
|
||||
gioui.org v0.8.0 // indirect
|
||||
gioui.org/shader v1.0.8 // indirect
|
||||
git.mstar.dev/mstar/goutils v1.6.1 // indirect
|
||||
github.com/go-text/typesetting v0.2.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/rs/zerolog v1.33.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect
|
||||
golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37 // indirect
|
||||
golang.org/x/image v0.18.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
)
|
33
go.sum
Normal file
33
go.sum
Normal file
|
@ -0,0 +1,33 @@
|
|||
gioui.org v0.8.0 h1:QV5p5JvsmSmGiIXVYOKn6d9YDliTfjtLlVf5J+BZ9Pg=
|
||||
gioui.org v0.8.0/go.mod h1:vEMmpxMOd/iwJhXvGVIzWEbxMWhnMQ9aByOGQdlQ8rc=
|
||||
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
||||
gioui.org/shader v1.0.8 h1:6ks0o/A+b0ne7RzEqRZK5f4Gboz2CfG+mVliciy6+qA=
|
||||
gioui.org/shader v1.0.8/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM=
|
||||
git.mstar.dev/mstar/goutils v1.6.1 h1:2yr9GYN8CJByZsJRu1pZ6WBp51Nn+3zJq49ky54xYDk=
|
||||
git.mstar.dev/mstar/goutils v1.6.1/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8=
|
||||
github.com/go-text/typesetting v0.2.1/go.mod h1:mTOxEwasOFpAMBjEQDhdWRckoLLeI/+qrQeBCTGEt6M=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w=
|
||||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37 h1:SOSg7+sueresE4IbmmGM60GmlIys+zNX63d6/J4CMtU=
|
||||
golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37/go.mod h1:3F+MieQB7dRYLTmnncoFbb1crS5lfQoTfDgQy6K4N0o=
|
||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
33
main.go
Normal file
33
main.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"gioui.org/app"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var t time.Time
|
||||
|
||||
func main() {
|
||||
window := new(app.Window)
|
||||
var err error
|
||||
t, err = time.Parse(time.RFC3339, "2025-01-31T22:50:00Z")
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Send()
|
||||
}
|
||||
go func() {
|
||||
// window.Option(func(m unit.Metric, c *app.Config) {
|
||||
// c.Size = image.Pt(500, 150)
|
||||
// c.MaxSize = image.Pt(500, 150)
|
||||
// c.MinSize = image.Pt(500, 150)
|
||||
// })
|
||||
err := run(window, &StateEnterTime{})
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to run main window")
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
app.Main()
|
||||
}
|
62
window.go
Normal file
62
window.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"gioui.org/app"
|
||||
"gioui.org/widget/material"
|
||||
)
|
||||
|
||||
type GlobalState struct {
|
||||
Window *app.Window
|
||||
Theme *material.Theme
|
||||
state WindowState
|
||||
}
|
||||
|
||||
func ticker(window *app.Window) {
|
||||
t := time.NewTicker(time.Second)
|
||||
for range t.C {
|
||||
window.Invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
func run(window *app.Window, initialState WindowState) error {
|
||||
state := GlobalState{}
|
||||
theme := material.NewTheme()
|
||||
theme.Bg = color.NRGBA{A: 0xff}
|
||||
state.Theme = theme
|
||||
state.Window = window
|
||||
state.state = initialState
|
||||
for {
|
||||
e := window.Event()
|
||||
newState := state.state.Run(&state, e)
|
||||
if newState.NextState != nil {
|
||||
state.state = newState.NextState
|
||||
}
|
||||
if newState.ExitCode != nil {
|
||||
os.Exit(*newState.ExitCode)
|
||||
}
|
||||
// log.Debug().Any("size", e.Size).Msg("Redrawing")
|
||||
// // This graphics context is used for managing the rendering state.
|
||||
// gtx := app.NewContext(&ops, e)
|
||||
// paint.FillShape(gtx.Ops, theme.Bg, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op())
|
||||
// //
|
||||
// // // Define an large label with an appropriate text:
|
||||
// log.Debug().Dur("d", t.Sub(e.Now)).Time("t", t).Send()
|
||||
// title := material.H1(theme, e.Now.Sub(t).Round(time.Second).String())
|
||||
// //
|
||||
// // // Change the color of the label.
|
||||
// maroon := color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 255}
|
||||
// title.Color = maroon
|
||||
// //
|
||||
// // // 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.
|
||||
// e.Frame(&ops)
|
||||
}
|
||||
}
|
81
windowEnterTime.go
Normal file
81
windowEnterTime.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"gioui.org/app"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"git.mstar.dev/mstar/goutils/other"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type StateEnterTime struct {
|
||||
initialSetupDone bool
|
||||
editor *widget.Editor
|
||||
inputField *material.EditorStyle
|
||||
ops op.Ops
|
||||
}
|
||||
|
||||
func (s *StateEnterTime) initialSetup(globalState *GlobalState) {
|
||||
s.editor = &widget.Editor{
|
||||
SingleLine: true,
|
||||
Submit: true,
|
||||
Filter: "01234567890TZ+-:",
|
||||
}
|
||||
field := material.Editor(globalState.Theme, s.editor, "timestamp")
|
||||
s.inputField = &field
|
||||
s.initialSetupDone = true
|
||||
}
|
||||
|
||||
func (s *StateEnterTime) Run(globalState *GlobalState, event event.Event) 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 EmptyEvent()
|
||||
default:
|
||||
log.Debug().Any("event", event).Type("type", event).Msg("Unknown event")
|
||||
return NewState{}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateEnterTime) handleFrameEvent(
|
||||
globalState *GlobalState,
|
||||
frameEvent *app.FrameEvent,
|
||||
) NewState {
|
||||
gtx := app.NewContext(&s.ops, *frameEvent)
|
||||
for ev, ok := s.editor.Update(gtx); ok; ev, ok = s.editor.Update(gtx) {
|
||||
log.Debug().Any("Editor event", ev).Send()
|
||||
}
|
||||
label := material.H3(globalState.Theme, "Enter timestamp")
|
||||
hint := material.Subtitle1(
|
||||
globalState.Theme,
|
||||
"Format: <YYYY>-<MM>-<DD>T<hh>:<mm>:<ss>(Z|+<TZ>)",
|
||||
)
|
||||
list := layout.List{Axis: layout.Vertical}
|
||||
list.Layout(gtx, 3, func(gtx layout.Context, index int) layout.Dimensions {
|
||||
switch index {
|
||||
case 0:
|
||||
return label.Layout(gtx)
|
||||
case 1:
|
||||
return hint.Layout(gtx)
|
||||
case 2:
|
||||
return s.inputField.Layout(gtx)
|
||||
default:
|
||||
return hint.Layout(gtx)
|
||||
}
|
||||
})
|
||||
frameEvent.Frame(&s.ops)
|
||||
return NewState{}
|
||||
}
|
||||
|
||||
func (s *StateEnterTime) handleQuitEvent() NewState {
|
||||
return NewState{ExitCode: other.IntoPointer(0)}
|
||||
}
|
20
windowState.go
Normal file
20
windowState.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"gioui.org/io/event"
|
||||
)
|
||||
|
||||
type WindowState interface {
|
||||
Run(globalState *GlobalState, event event.Event) NewState
|
||||
}
|
||||
|
||||
type NewState struct {
|
||||
// If null, keep current state
|
||||
NextState WindowState
|
||||
Error error
|
||||
ExitCode *int
|
||||
}
|
||||
|
||||
func EmptyEvent() NewState {
|
||||
return NewState{}
|
||||
}
|
Loading…
Reference in a new issue