doodle/pkg/play_scene_menubar.go
Noah Petherbridge a06787411d Resolve circular import errors for Doodle++ plugin
* pkg/plus/dpp is the main plugin bridge, and defines nothing but an interface
  that defines the Doodle++ surface area (referring to internal game types such
  as doodad.Doodad or level.Level), but not their implementations.
  * dpp.Driver (an interface) is the main API that other parts of the game will
    call, for example "dpp.Driver.IsLevelSigned()"
  * plus_dpp.go and plus_foss.go provide the dpp.Driver implementation for their
    build; with plus_dpp.go generally forwarding function calls directly to the
    proprietary dpp package and plus_foss.go generally returning false/errors.
  * The bootstrap package simply assigns the above stub function to dpp.Driver
* pkg/plus/bootstrap is a package directly imported by main (in the doodle and
  doodad programs) and it works around circular dependency issues: this package
  simply assigns dpp.Driver to the DPP or FOSS version.

Miscellaneous fixes:

* File->Open in the editor and PlayScene will use the new Open Level window
  instead of loading the legacy GotoLoadMenu scene.
* Deprecated legacy scenes: d.GotoLoadMenu() and d.GotoPlayMenu().
* The doodle-admin program depends on the private dpp package, so can not be
  compiled in FOSS mode.
2024-04-18 22:12:56 -07:00

118 lines
3.0 KiB
Go

package doodle
import (
"git.kirsle.net/SketchyMaze/doodle/pkg/levelpack"
"git.kirsle.net/SketchyMaze/doodle/pkg/shmem"
"git.kirsle.net/SketchyMaze/doodle/pkg/usercfg"
"git.kirsle.net/SketchyMaze/doodle/pkg/windows"
"git.kirsle.net/go/render"
"git.kirsle.net/go/ui"
)
// Set up the menu bar for Play Scene.
func (u *PlayScene) setupMenuBar(d *Doodle) *ui.MenuBar {
menu := ui.NewMenuBar("Main Menu")
////////
// Game menu
gameMenu := menu.AddMenu("Game")
gameMenu.AddItem("Story Mode", func() {
// TODO: de-duplicate code from MainScene
if u.winLevelPacks == nil {
u.winLevelPacks = windows.NewLevelPackWindow(windows.LevelPack{
Supervisor: u.Supervisor,
Engine: d.Engine,
OnPlayLevel: func(lp *levelpack.LevelPack, which levelpack.Level) {
if err := d.PlayFromLevelpack(lp, which); err != nil {
shmem.FlashError(err.Error())
}
},
OnCloseWindow: func() {
u.winLevelPacks.Hide()
},
})
}
u.winLevelPacks.MoveTo(render.Point{
X: (d.width / 2) - (u.winLevelPacks.Size().W / 2),
Y: (d.height / 2) - (u.winLevelPacks.Size().H / 2),
})
u.winLevelPacks.Show()
})
gameMenu.AddItemAccel("New drawing", "Ctrl-N", d.GotoNewMenu)
gameMenu.AddItemAccel("Open drawing", "Ctrl-O", func() {
if u.winOpenLevel == nil {
u.winOpenLevel = windows.NewOpenDrawingWindow(windows.OpenDrawing{
Supervisor: u.Supervisor,
Engine: shmem.CurrentRenderEngine,
OnOpenDrawing: func(filename string) {
d.EditFile(filename)
},
OnCloseWindow: func() {
u.winOpenLevel.Destroy()
u.winOpenLevel = nil
},
})
}
u.winOpenLevel.MoveTo(render.Point{
X: (d.width / 2) - (u.winOpenLevel.Size().W / 2),
Y: (d.height / 2) - (u.winOpenLevel.Size().H / 2),
})
u.winOpenLevel.Show()
})
gameMenu.AddSeparator()
gameMenu.AddItem("Quit to menu", func() {
d.Goto(&MainScene{})
})
gameMenu.AddItemAccel("Quit", "Escape", func() {
d.ConfirmExit()
})
////////
// Level menu
levelMenu := menu.AddMenu("Level")
levelMenu.AddItem("Restart level", u.RestartLevel)
levelMenu.AddItem("Retry from checkpoint", func() {
u.SetImperfect()
u.RetryCheckpoint()
})
levelMenu.AddSeparator()
levelMenu.AddItemAccel("Edit level", "E", u.EditLevel)
// Hilariously broken, someday!
if usercfg.Current.EnableFeatures {
levelMenu.AddSeparator()
levelMenu.AddItemAccel("New viewport", "v", func() {
pip := windows.MakePiPWindow(d.width, d.height, windows.PiP{
Supervisor: u.Supervisor,
Engine: u.d.Engine,
Level: u.Level,
Event: u.d.event,
})
pip.Show()
})
}
helpMenu := d.MakeHelpMenu(menu, u.Supervisor)
if usercfg.Current.EnableCheatsMenu {
helpMenu.AddSeparator()
helpMenu.AddItem("Cheats Menu", func() {
if u.cheatsWindow != nil {
u.cheatsWindow.Hide()
u.cheatsWindow.Destroy()
u.cheatsWindow = nil
}
u.cheatsWindow = u.d.MakeCheatsWindow(u.Supervisor)
u.cheatsWindow.Show()
})
}
menu.Supervise(u.Supervisor)
menu.Compute(d.Engine)
return menu
}