Noah Petherbridge
9a51ac39f9
* New doodad: Invisible Warp Door * All warp doors require the player to be grounded (if affected by gravity) to open them. No jumping or falling thru and opening a warp door mid-air! * Title Screen now randomly selects from a couple of levels. * Title Screen: if it fails to load a level it sets up a basic blank level with a wallpaper instead. * New developer shell command: titlescreen <level> Opens the MainScene with a custom user level as the background. * Add Auto-save to the Editor to save your drawing every 5 minutes * Add a MenuBar to the Play Scene for easier navigation to other features of the game. * Doodad JS API: time.Since() now available.
225 lines
4.9 KiB
Go
225 lines
4.9 KiB
Go
package windows
|
|
|
|
import (
|
|
"git.kirsle.net/apps/doodle/pkg/balance"
|
|
"git.kirsle.net/apps/doodle/pkg/drawtool"
|
|
"git.kirsle.net/apps/doodle/pkg/level"
|
|
"git.kirsle.net/apps/doodle/pkg/shmem"
|
|
"git.kirsle.net/apps/doodle/pkg/uix"
|
|
"git.kirsle.net/go/render"
|
|
"git.kirsle.net/go/render/event"
|
|
"git.kirsle.net/go/ui"
|
|
)
|
|
|
|
// PiP window.
|
|
type PiP struct {
|
|
// Settings passed in by doodle
|
|
Supervisor *ui.Supervisor
|
|
Engine render.Engine
|
|
Level *level.Level
|
|
Event *event.State
|
|
Tool *drawtool.Tool
|
|
BrushSize *int
|
|
|
|
// Or sensible defaults:
|
|
Width int
|
|
Height int
|
|
|
|
OnCancel func()
|
|
}
|
|
|
|
// MakePiPWindow initializes a license window for any scene.
|
|
// The window width/height are the actual SDL2 window dimensions.
|
|
func MakePiPWindow(windowWidth, windowHeight int, cfg PiP) *ui.Window {
|
|
win := NewPiPWindow(cfg)
|
|
win.Compute(cfg.Engine)
|
|
win.Supervise(cfg.Supervisor)
|
|
|
|
// Center the window.
|
|
size := win.Size()
|
|
win.MoveTo(render.Point{
|
|
X: (windowWidth / 2) - (size.W / 2),
|
|
Y: (windowHeight / 2) - (size.H / 2),
|
|
})
|
|
|
|
return win
|
|
}
|
|
|
|
// NewPiPWindow initializes the window.
|
|
func NewPiPWindow(cfg PiP) *ui.Window {
|
|
var (
|
|
windowWidth = 340
|
|
windowHeight = 300
|
|
)
|
|
|
|
if cfg.Width+cfg.Height > 0 {
|
|
windowWidth = cfg.Width
|
|
windowHeight = cfg.Height
|
|
}
|
|
|
|
var (
|
|
canvasWidth = windowWidth - 8
|
|
canvasHeight = windowHeight - 4 - 48 // for the titlebar?
|
|
)
|
|
|
|
window := ui.NewWindow("Viewport")
|
|
window.SetButtons(ui.CloseButton)
|
|
window.Configure(ui.Config{
|
|
Width: windowWidth,
|
|
Height: windowHeight,
|
|
})
|
|
|
|
canvas := uix.NewCanvas(128, true)
|
|
canvas.Name = "Viewport (WIP)"
|
|
canvas.LoadLevel(cfg.Level)
|
|
canvas.InstallActors(cfg.Level.Actors)
|
|
canvas.Scrollable = true
|
|
canvas.Editable = true
|
|
canvas.Resize(render.NewRect(canvasWidth, canvasHeight))
|
|
|
|
// If we have tool bindings to edit in PiP window
|
|
var (
|
|
editable bool
|
|
curTool drawtool.Tool
|
|
curThicc int
|
|
)
|
|
if cfg.Tool != nil && cfg.BrushSize != nil {
|
|
editable = true
|
|
curTool = *cfg.Tool
|
|
curThicc = *cfg.BrushSize
|
|
canvas.Tool = curTool
|
|
}
|
|
|
|
// NOTE: my UI toolkit calls this every tick, if this is "fixed"
|
|
// in the future make one that does.
|
|
window.Handle(ui.MouseMove, func(ed ui.EventData) error {
|
|
canvas.Loop(cfg.Event)
|
|
|
|
// Did we have tool bindings for an editable PiP?
|
|
if editable {
|
|
// Check if bound values have modified.
|
|
if *cfg.Tool != curTool {
|
|
curTool = *cfg.Tool
|
|
canvas.Tool = curTool
|
|
}
|
|
if *cfg.BrushSize != curThicc {
|
|
curThicc = *cfg.BrushSize
|
|
canvas.BrushSize = curThicc
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
window.Pack(canvas, ui.Pack{
|
|
Side: ui.N,
|
|
FillX: true,
|
|
})
|
|
|
|
/////////////
|
|
// Buttons at bottom of window
|
|
|
|
bottomFrame := ui.NewFrame("Button Frame")
|
|
window.Pack(bottomFrame, ui.Pack{
|
|
Side: ui.N,
|
|
FillX: true,
|
|
PadY: 4,
|
|
})
|
|
|
|
frame := ui.NewFrame("Button frame")
|
|
buttons := []struct {
|
|
label string
|
|
tooltip string
|
|
f func()
|
|
}{
|
|
{"Smaller", "Shrink this viewport window by 20%", func() {
|
|
// Make a smaller version of the same window, and close.
|
|
cfg.Width = int(float64(windowWidth) * 0.8)
|
|
cfg.Height = int(float64(windowHeight) * 0.8)
|
|
pip := MakePiPWindow(cfg.Width, cfg.Height, cfg)
|
|
pip.MoveTo(window.Point())
|
|
window.Close()
|
|
pip.Show()
|
|
}},
|
|
{"Larger", "Grow this viewport window by 20%", func() {
|
|
// Make a smaller version of the same window, and close.
|
|
cfg.Width = int(float64(windowWidth) * 1.2)
|
|
cfg.Height = int(float64(windowHeight) * 1.2)
|
|
pip := MakePiPWindow(cfg.Width, cfg.Height, cfg)
|
|
pip.MoveTo(window.Point())
|
|
window.Close()
|
|
pip.Show()
|
|
}},
|
|
{"Refresh", "Update the state of doodads placed in this level", func() {
|
|
canvas.ClearActors()
|
|
canvas.InstallActors(cfg.Level.Actors)
|
|
}},
|
|
{"Rename", "Give this viewport window a custom name", func() {
|
|
shmem.Prompt("Give this viewport a name: ", func(answer string) {
|
|
if answer == "" {
|
|
return
|
|
}
|
|
window.Title = answer
|
|
})
|
|
}},
|
|
{"???", "Load a different drawing (experimental!)", func() {
|
|
shmem.Prompt("Filename to open: ", func(answer string) {
|
|
if answer == "" {
|
|
return
|
|
}
|
|
|
|
if lvl, err := level.LoadFile(answer); err == nil {
|
|
canvas.ClearActors()
|
|
canvas.LoadLevel(lvl)
|
|
canvas.InstallActors(lvl.Actors)
|
|
} else {
|
|
shmem.Flash(err.Error())
|
|
}
|
|
})
|
|
}},
|
|
}
|
|
for i, button := range buttons {
|
|
// Start axing buttons if window size is too small.
|
|
if windowWidth < 150 && i > 1 {
|
|
break
|
|
} else if windowWidth < 250 && i > 2 {
|
|
break
|
|
}
|
|
|
|
button := button
|
|
|
|
btn := ui.NewButton(button.label, ui.NewLabel(ui.Label{
|
|
Text: button.label,
|
|
Font: balance.SmallFont,
|
|
}))
|
|
|
|
btn.Handle(ui.Click, func(ed ui.EventData) error {
|
|
button.f()
|
|
return nil
|
|
})
|
|
|
|
btn.Compute(cfg.Engine)
|
|
cfg.Supervisor.Add(btn)
|
|
|
|
ui.NewTooltip(btn, ui.Tooltip{
|
|
Text: button.tooltip,
|
|
Edge: ui.Top,
|
|
})
|
|
|
|
frame.Pack(btn, ui.Pack{
|
|
Side: ui.W,
|
|
PadX: 1,
|
|
Expand: true,
|
|
Fill: true,
|
|
})
|
|
}
|
|
|
|
bottomFrame.Pack(frame, ui.Pack{
|
|
Side: ui.N,
|
|
PadX: 8,
|
|
PadY: 0,
|
|
})
|
|
|
|
return window
|
|
}
|