apply worl loading ui

This commit is contained in:
IliaDenisov
2026-03-08 09:05:00 +02:00
parent c076347d70
commit 672e4a00b4
5 changed files with 77 additions and 66 deletions
+70 -32
View File
@@ -10,7 +10,8 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/iliadenisov/galaxy/client/world"
)
@@ -24,8 +25,7 @@ type editor struct {
raster *canvas.Raster
canvasScale float32
canvas *interactiveRaster
win fyne.Window
win fyne.Window
// Coalescer for latest-wins refresh scheduling.
co *RasterCoalescer[world.RenderParams]
@@ -58,10 +58,6 @@ func (e *editor) ForceFullRedraw() {
e.world.ForceFullRedrawNext()
}
func (e *editor) buildUI() fyne.CanvasObject {
return e.canvas
}
// здесь определяю, изменились ли границы raster, если да - обновляю размеры viewport, margin и корректирую zoom
func (e *editor) updateSizes() {
canvas := fyne.CurrentApp().Driver().CanvasForObject(e.raster)
@@ -75,16 +71,21 @@ func (e *editor) updateSizes() {
width := int(size.Width * e.canvasScale)
height := int(size.Height * e.canvasScale)
if width > 0 && height > 0 && (width != e.wp.ViewportWidthPx || height != e.wp.ViewportHeightPx) {
if width <= 0 || height <= 0 {
return
}
if width != e.wp.ViewportWidthPx || height != e.wp.ViewportHeightPx {
e.wp.ViewportWidthPx = width
e.wp.ViewportHeightPx = height
e.wp.MarginXPx = e.wp.ViewportWidthPx / 4
e.wp.MarginYPx = e.wp.ViewportHeightPx / 4
defer func() { e.co.Request(*e.wp) }()
}
if e.world != nil {
e.wp.CameraZoom = e.world.CorrectCameraZoom(e.wp.CameraZoom, e.wp.ViewportWidthPx, e.wp.ViewportHeightPx)
e.world.IndexOnViewportChange(e.wp.ViewportWidthPx, e.wp.ViewportHeightPx, e.wp.CameraZoom)
e.world.ClampRenderParamsNoWrap(e.wp)
e.co.Request(*e.wp)
}
}
@@ -175,6 +176,9 @@ func (e *editor) onDradEnd() {
}
func (e *editor) onTapped(ev *fyne.PointEvent) {
if e.world == nil {
return
}
hits, err := e.world.HitTest(e.hits, e.wp, int(ev.Position.X*e.canvasScale), int(ev.Position.Y*e.canvasScale))
if err != nil {
panic(err)
@@ -193,34 +197,68 @@ func (e *editor) onTapped(ev *fyne.PointEvent) {
}
}
func (e *editor) InitImage() {
s := fyne.NewSize(292, 292)
e.canvas.SetMinSize(s)
e.updateSizes()
}
func (e *editor) onMapLayout(s fyne.Size) {
e.updateSizes()
}
func (e *editor) BuildUI(w fyne.Window) {
e.win = w
content := container.New(layout.NewStackLayout(), e.buildUI())
mapCanvas := newInteractiveRaster(e, e.raster, e.onMapLayout, e.onScrolled, e.onDragged, e.onDradEnd, e.onTapped)
mapCanvas.SetMinSize(fyne.NewSize(292, 292))
toolbar := widget.NewToolbar(
widget.NewToolbarAction(
theme.FolderIcon(),
func() { e.loadWorld(mockWorld()) }),
widget.NewToolbarSeparator(),
widget.NewToolbarAction(
theme.NavigateBackIcon(),
func() {}),
widget.NewToolbarAction(
theme.NavigateNextIcon(),
func() {}),
)
tabs := container.NewAppTabs(
container.NewTabItemWithIcon(
"Map",
theme.GridIcon(),
mapCanvas),
container.NewTabItemWithIcon(
"Calculator",
theme.ComputerIcon(),
container.NewStack(widget.NewButton("Calc", func() {})),
),
)
content := container.NewBorder(
toolbar, // top
nil, // bottom
nil, // left
nil, // right
tabs, // center
)
w.CenterOnScreen()
w.SetContent(content)
}
func (e *editor) loadWorld(w *world.World) {
e.world = w
// TODO: store camera position in user settings
e.wp.CameraXWorldFp = w.W / 2
e.wp.CameraYWorldFp = w.H / 2
e.updateSizes()
e.RequestRefresh()
}
func NewEditor() *editor {
w := world.NewWorld(300, 300)
testWorldInit(w)
e := &editor{
world: w,
world: nil,
wp: &world.RenderParams{
CameraZoom: 1.0,
CameraXWorldFp: w.W / 2,
CameraYWorldFp: w.H / 2,
// Viewport sizes and margins will be filled from draw(w,h).
Options: &world.RenderOptions{DisableWrapScroll: false},
CameraZoom: 1.0,
Options: &world.RenderOptions{DisableWrapScroll: false},
},
canvasScale: 1.0,
hits: make([]world.Hit, 5),
@@ -234,7 +272,6 @@ func NewEditor() *editor {
return e.draw(wPx, hPx)
})
e.canvas = newInteractiveRaster(e, e.raster, e.onMapLayout, e.onScrolled, e.onDragged, e.onDradEnd, e.onTapped)
e.pan = NewPanController(e)
// Wire coalescer: it schedules raster.Refresh() on UI thread and renders once per draw call.
@@ -251,11 +288,16 @@ func NewEditor() *editor {
// Kick initial draw.
e.RequestRefresh()
e.InitImage()
return e
}
func testWorldInit(w *world.World) {
func mockWorld() *world.World {
w := world.NewWorld(300, 300)
mockWorldInit(w)
return w
}
func mockWorldInit(w *world.World) {
lineStyle := w.AddStyleLine(world.StyleOverride{
StrokeColor: color.RGBA{R: 0, G: 255, B: 0, A: 255},
StrokeWidthPx: new(3.0),
@@ -283,10 +325,6 @@ func testWorldInit(w *world.World) {
panic(err)
}
// if _, err := w.AddLine(100, 20, 200, 30); err != nil {
// panic(err)
// }
if _, err := w.AddLine(100, 20, 200, 30, world.LineWithStyleID(lineStyle), world.LineWithPriority(500)); err != nil {
panic(err)
}