ui/eg/windows/main_wasm.go

170 lines
3.4 KiB
Go
Raw Permalink Normal View History

// +build js,wasm
// WebAssembly version of the window manager demo.
// To build: make wasm
// To test: make wasm-serve
package main
import (
"fmt"
"time"
"git.kirsle.net/go/render"
"git.kirsle.net/go/render/canvas"
"git.kirsle.net/go/ui"
)
// Program globals.
var (
ThrottleFPS = 1000 / 60
// Size of the MainWindow.
Width = 1024
Height = 768
// Cascade offset for creating multiple windows.
Cascade = render.NewPoint(10, 32)
CascadeStep = render.NewPoint(24, 24)
CascadeLoops = 1
// Colors for each window created.
WindowColors = []render.Color{
render.Blue,
render.Red,
render.DarkYellow,
render.DarkGreen,
render.DarkCyan,
render.DarkBlue,
render.DarkRed,
}
WindowID int
OpenWindows int
)
func main() {
mw, err := canvas.New("canvas")
if err != nil {
panic(err)
}
// Bind DOM event handlers.
mw.AddEventListeners()
supervisor := ui.NewSupervisor()
frame := ui.NewFrame("Main Frame")
frame.Resize(render.NewRect(mw.WindowSize()))
frame.Compute(mw)
_, height := mw.WindowSize()
lbl := ui.NewLabel(ui.Label{
Text: "Window Manager Demo",
Font: render.Text{
FontFilename: "DejaVuSans.ttf",
Size: 32,
Color: render.SkyBlue,
Shadow: render.SkyBlue.Darken(60),
},
})
lbl.Compute(mw)
lbl.MoveTo(render.NewPoint(
20,
height-lbl.Size().H-20,
))
// Menu bar.
menu := ui.NewMenuBar("Main Menu")
file := menu.AddMenu("Options")
file.AddItem("New window", func() {
addWindow(mw, frame, supervisor)
})
file.AddItem("Close all windows", func() {
OpenWindows -= supervisor.CloseAllWindows()
})
menu.Supervise(supervisor)
menu.Compute(mw)
frame.Pack(menu, menu.PackTop())
// Add some windows to play with.
addWindow(mw, frame, supervisor)
addWindow(mw, frame, supervisor)
for {
mw.Clear(render.RGBA(255, 255, 200, 255))
start := time.Now()
ev, err := mw.Poll()
if err != nil {
panic(err)
}
frame.Present(mw, frame.Point())
lbl.Present(mw, lbl.Point())
supervisor.Loop(ev)
supervisor.Present(mw)
var delay uint32
elapsed := time.Now().Sub(start)
tmp := elapsed / time.Millisecond
if ThrottleFPS-int(tmp) > 0 {
delay = uint32(ThrottleFPS - int(tmp))
}
mw.Delay(delay)
}
}
// Add a new child window.
func addWindow(engine render.Engine, parent *ui.Frame, sup *ui.Supervisor) {
var (
color = WindowColors[WindowID%len(WindowColors)]
title = fmt.Sprintf("Window %d", WindowID+1)
)
WindowID++
win1 := ui.NewWindow(title)
win1.SetButtons(ui.CloseButton)
win1.ActiveTitleBackground = color
win1.InactiveTitleBackground = color.Darken(60)
win1.InactiveTitleForeground = render.Grey
win1.Configure(ui.Config{
Width: 320,
Height: 240,
})
win1.Compute(engine)
win1.Supervise(sup)
// Re-open a window when the last one is closed.
OpenWindows++
win1.Handle(ui.CloseWindow, func(ed ui.EventData) error {
OpenWindows--
if OpenWindows <= 0 {
addWindow(engine, parent, sup)
}
return nil
})
// Default placement via cascade.
win1.MoveTo(Cascade)
Cascade.Add(CascadeStep)
if Cascade.Y > Height-240-64 {
CascadeLoops++
Cascade.Y = 24
Cascade.X = 24 * CascadeLoops
}
// Add a window duplicator button.
btn2 := ui.NewButton(title+":Button2", ui.NewLabel(ui.Label{
Text: "New Window",
}))
btn2.Handle(ui.Click, func(ed ui.EventData) error {
addWindow(engine, parent, sup)
return nil
})
sup.Add(btn2)
win1.Place(btn2, ui.Place{
Top: 10,
Right: 10,
})
}