ui calculator

This commit is contained in:
Ilia Denisov
2026-03-30 19:38:24 +02:00
committed by GitHub
parent 17f366cd6b
commit a7793f5416
37 changed files with 2046 additions and 270 deletions
+100 -63
View File
@@ -5,15 +5,16 @@ import (
"sync"
"galaxy/client/updater"
"galaxy/client/widget/calculator"
"galaxy/client/world"
"galaxy/connector"
mc "galaxy/model/client"
"galaxy/model/report"
"galaxy/storage"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
@@ -21,12 +22,22 @@ import (
const version = "1.0.0"
type client struct {
s storage.UIStorage
conn connector.UIConnector
s storage.Storage
conn connector.Connector
app fyne.App
window fyne.Window
loadReportFunc func(uint)
state *mc.State
stateMu sync.RWMutex
reg *registry
calculator *calculator.Calculator
mapSplitter *container.Split
accInfo *widget.AccordionItem
accCalc *widget.AccordionItem
// loadReportFunc func(uint)
world *world.World
drawer *world.GGDrawer
@@ -69,8 +80,6 @@ type client struct {
hits []world.Hit
fullStorage storage.Storage
fullConnector connector.Connector
updater *updater.Manager
backgroundStop chan struct{}
backgroundOnce sync.Once
@@ -81,32 +90,55 @@ type client struct {
onServiceErrFn func(error)
}
func NewClient(s storage.UIStorage, conn connector.UIConnector, app fyne.App) (mc.Client, error) {
func NewClient(s storage.Storage, conn connector.Connector, app fyne.App) (mc.Client, error) {
e := &client{
s: s,
conn: conn,
app: app,
window: app.NewWindow("Galaxy Plus"),
world: nil,
wp: &world.RenderParams{
CameraZoom: 1.0,
Options: &world.RenderOptions{DisableWrapScroll: false},
},
s: s,
conn: conn,
app: app,
window: app.NewWindow("Galaxy Plus"),
reg: newRegistry(),
lastCanvasScale: 1.0,
world: nil,
hits: make([]world.Hit, 5),
backgroundStop: make(chan struct{}),
}
if fullStorage, ok := s.(storage.Storage); ok {
e.fullStorage = fullStorage
}
if fullConnector, ok := conn.(connector.Connector); ok {
e.fullConnector = fullConnector
}
if e.fullStorage != nil && e.fullConnector != nil {
e.updater = updater.NewManager(e.fullStorage, e.fullConnector)
}
e.calculator = calculator.NewCaclulator(calculator.WithCreateHandler(e.createShipClass))
e.updater = updater.NewManager(e.s, e.conn)
e.loadReportFunc = e.loadReport
stateExists, err := e.s.StateExists()
if err != nil {
return nil, err
}
if stateExists {
state, err := e.s.LoadState()
if err != nil {
return nil, err
}
e.state = &state
} else {
e.state = &mc.State{
ClientCurrentVersion: e.Version(),
CameraZoom: 1.0,
MapSplitterOffset: 0.5,
AccordionInfoOpen: false,
AccordionCalcOpen: false,
}
if err := e.s.SaveState(*e.state); err != nil {
return nil, err
}
}
if e.state.CameraZoom <= 0 {
e.state.CameraZoom = 1.0
}
if e.state.MapSplitterOffset <= 0 {
e.state.MapSplitterOffset = 0.5
}
e.wp = &world.RenderParams{
Options: &world.RenderOptions{DisableWrapScroll: false},
CameraZoom: e.state.CameraZoom,
CameraXWorldFp: e.state.CameraXFp,
CameraYWorldFp: e.state.CameraYFp,
}
e.drawer = &world.GGDrawer{DC: nil}
@@ -127,40 +159,13 @@ func NewClient(s storage.UIStorage, conn connector.UIConnector, app fyne.App) (m
return e, nil
}
func (e *client) loadReport(t uint) {
e.conn.FetchReport("GAME_ID", t, func(r report.Report, err error) {
if err != nil {
e.handlerError(err)
} else {
e.setReport(r)
}
})
}
func (e *client) setReport(r report.Report) {
w := world.NewWorld(int(r.Width), int(r.Height))
for i := range r.LocalPlanet {
p := r.LocalPlanet[i]
w.AddCircle(p.X.F(), p.Y.F(), p.Size.F())
}
for i := range r.UnidentifiedPlanet {
p := r.UnidentifiedPlanet[i]
w.AddPoint(p.X.F(), p.Y.F())
}
e.loadWorld(w)
}
func (e *client) BuildUI(w fyne.Window) {
mapCanvas := newInteractiveRaster(e, e.raster, e.onRasterWidgetLayout, e.onScrolled, e.onDragged, e.onDradEnd, e.onTapped)
mapCanvas.SetMinSize(fyne.NewSize(640, 480))
mapCanvasObject := newInteractiveRaster(e.raster, e.onRasterWidgetLayout, e.onScrolled, e.onDragged, e.onDradEnd, e.onTapped)
toolbar := widget.NewToolbar(
widget.NewToolbarAction(
theme.FolderIcon(),
func() {
e.loadReport(0)
// e.loadWorld(mockWorld())
}),
func() { e.initReportAsync("GAME_ID", 0) }),
widget.NewToolbarSeparator(),
widget.NewToolbarAction(
theme.NavigateBackIcon(),
@@ -170,11 +175,24 @@ func (e *client) BuildUI(w fyne.Window) {
func() {}),
)
e.accInfo = widget.NewAccordionItem(lang.L("title.info"), container.NewStack())
e.accInfo.Open = e.state.AccordionInfoOpen
e.accCalc = widget.NewAccordionItem(lang.L("title.calculator"), e.calculator.CanvasObject)
e.accCalc.Open = e.state.AccordionCalcOpen
accordion := widget.NewAccordion()
accordion.MultiOpen = true
accordion.Append(e.accCalc)
accordion.Append(e.accInfo)
e.mapSplitter = container.NewHSplit(mapCanvasObject, container.NewHScroll(accordion))
e.mapSplitter.SetOffset(e.state.MapSplitterOffset)
tabs := container.NewAppTabs(
container.NewTabItemWithIcon(
"Map",
lang.L("title.map"),
theme.GridIcon(),
mapCanvas),
e.mapSplitter),
container.NewTabItemWithIcon(
"Calculator",
theme.ComputerIcon(),
@@ -182,16 +200,33 @@ func (e *client) BuildUI(w fyne.Window) {
),
)
th := tabs.Theme()
icon := canvas.NewImageFromResource(th.Icon(theme.IconNameInfo))
statusLeft := widget.NewTextGridFromString("Status")
statusAd := widget.NewTextGridFromString("")
statusBar := container.NewBorder(
nil, // top
nil, // bottom
container.NewHBox(statusLeft, widget.NewSeparator()), // left
container.NewHBox(widget.NewSeparator(), icon), // right
statusAd, // center
)
content := container.NewBorder(
toolbar, // top
nil, // bottom
nil, // left
nil, // right
tabs, // center
toolbar, // top
statusBar, // bottom
nil, // left
nil, // right
tabs, // center
)
w.CenterOnScreen()
w.SetContent(content)
s := statusBar.Size()
icon.SetMinSize(fyne.NewSize(s.Height, s.Height))
e.initLatestReport()
}
func (e *client) loadWorld(w *world.World) {
@@ -215,16 +250,18 @@ func (e *client) Run() error {
e.window.SetMaster()
e.window.Resize(fyne.NewSize(800, 600))
e.window.CenterOnScreen()
e.window.SetOnClosed(e.Shutdown)
e.window.ShowAndRun()
e.stopBackground()
return nil
}
func (e *client) Shutdown() {
e.stopBackground()
e.ensureStatePersist()
e.window.Close()
}
// TODO: remove func?
func (e *client) Version() string { return version }
func (e *client) OnConnection(isGood bool) {