178 lines
3.9 KiB
Go
178 lines
3.9 KiB
Go
//go:build gui
|
|
|
|
package ui
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"image/color"
|
|
"io"
|
|
|
|
"gioui.org/app"
|
|
"gioui.org/font/gofont"
|
|
"gioui.org/io/system"
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/widget/material"
|
|
"gioui.org/x/pref/theme"
|
|
"github.com/bedrock-tool/bedrocktool/ui/gui/pages"
|
|
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/packs"
|
|
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/settings"
|
|
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/skins"
|
|
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/update"
|
|
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/worlds"
|
|
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
|
"github.com/bedrock-tool/bedrocktool/utils"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type GUI struct {
|
|
utils.BaseUI
|
|
|
|
router pages.Router
|
|
cancel context.CancelFunc
|
|
authPopup bool
|
|
authPopupText string
|
|
}
|
|
|
|
func (g *GUI) Init() bool {
|
|
utils.Auth.LoginWithMicrosoftCallback = g.LoginWithMicrosoftCallback
|
|
return true
|
|
}
|
|
|
|
var paletteLight = material.Palette{
|
|
Bg: color.NRGBA{0xff, 0xff, 0xff, 0xff},
|
|
Fg: color.NRGBA{0x12, 0x12, 0x12, 0xff},
|
|
ContrastBg: color.NRGBA{0x7c, 0x00, 0xf8, 0xff},
|
|
ContrastFg: color.NRGBA{0x00, 0x00, 0x00, 0xff},
|
|
}
|
|
|
|
var paletteDark = material.Palette{
|
|
Bg: color.NRGBA{0x12, 0x12, 0x12, 0xff},
|
|
Fg: color.NRGBA{0xff, 0xff, 0xff, 0xff},
|
|
ContrastBg: color.NRGBA{0x7c, 0x00, 0xf8, 0xff},
|
|
ContrastFg: color.NRGBA{0xff, 0xff, 0xff, 0xff},
|
|
}
|
|
|
|
func (g *GUI) Start(ctx context.Context, cancel context.CancelFunc) (err error) {
|
|
g.cancel = cancel
|
|
|
|
w := app.NewWindow(
|
|
app.Title("Bedrocktool " + utils.Version),
|
|
)
|
|
|
|
th := material.NewTheme(gofont.Collection())
|
|
dark, err := theme.IsDarkMode()
|
|
if err != nil {
|
|
logrus.Warn(err)
|
|
}
|
|
if dark {
|
|
_th := th.WithPalette(paletteDark)
|
|
th = &_th
|
|
} else {
|
|
_th := th.WithPalette(paletteLight)
|
|
th = &_th
|
|
}
|
|
|
|
g.router = pages.NewRouter(ctx, w.Invalidate, th)
|
|
g.router.Register("Settings", settings.New(&g.router))
|
|
g.router.Register("worlds", worlds.New(&g.router))
|
|
g.router.Register("skins", skins.New(&g.router))
|
|
g.router.Register("packs", packs.New(&g.router))
|
|
g.router.Register("update", update.New(&g.router))
|
|
|
|
g.router.SwitchTo("Settings")
|
|
|
|
go func() {
|
|
app.Main()
|
|
}()
|
|
|
|
return g.run(w)
|
|
}
|
|
|
|
func (g *GUI) run(w *app.Window) error {
|
|
var ops op.Ops
|
|
for {
|
|
select {
|
|
case e := <-w.Events():
|
|
switch e := e.(type) {
|
|
case system.DestroyEvent:
|
|
logrus.Info("Closing")
|
|
g.cancel()
|
|
g.router.Wg.Wait()
|
|
return e.Err
|
|
case system.FrameEvent:
|
|
gtx := layout.NewContext(&ops, e)
|
|
layout.Stack{
|
|
Alignment: layout.Center,
|
|
}.Layout(gtx,
|
|
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
|
|
return g.router.Layout(gtx, g.router.Theme)
|
|
}),
|
|
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
|
|
if g.authPopup {
|
|
return g.AuthPopup(gtx)
|
|
}
|
|
return layout.Dimensions{}
|
|
}),
|
|
)
|
|
|
|
e.Frame(gtx.Ops)
|
|
}
|
|
case <-g.router.Ctx.Done():
|
|
logrus.Info("Closing")
|
|
g.cancel()
|
|
g.router.Wg.Wait()
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func (g *GUI) Message(data interface{}) messages.MessageResponse {
|
|
r := g.router.Handler(data)
|
|
if r.Ok || r.Data != nil {
|
|
return r
|
|
}
|
|
|
|
r = messages.MessageResponse{
|
|
Ok: false,
|
|
Data: nil,
|
|
}
|
|
|
|
switch data.(type) {
|
|
case messages.CanShowImages:
|
|
r.Ok = true
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
func (g *GUI) AuthPopup(gtx layout.Context) layout.Dimensions {
|
|
gtx.Constraints.Max = gtx.Constraints.Max.Div(2)
|
|
return layout.Center.Layout(gtx, material.Body1(g.router.Theme, g.authPopupText).Layout)
|
|
}
|
|
|
|
func (g *GUI) LoginWithMicrosoftCallback(r io.Reader) {
|
|
g.authPopup = true
|
|
b := bufio.NewReader(r)
|
|
for {
|
|
line, _, err := b.ReadLine()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
println(string(line))
|
|
g.authPopupText += string(line) + "\n"
|
|
g.router.Invalidate()
|
|
if string(line) == "Authentication successful." {
|
|
break
|
|
}
|
|
}
|
|
g.authPopup = false
|
|
}
|
|
|
|
func init() {
|
|
utils.MakeGui = func() utils.UI {
|
|
return &GUI{}
|
|
}
|
|
}
|