2021-06-18 02:43:30 +00:00
|
|
|
package doodle
|
|
|
|
|
|
|
|
// Menu Bar features for Edit Mode.
|
|
|
|
// In here is the SetupMenuBar() and menu item functions.
|
|
|
|
// The rest of it is controlled in editor_ui.go
|
|
|
|
|
|
|
|
import (
|
2022-09-24 22:17:25 +00:00
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/balance"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/drawtool"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/enum"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/level/giant_screenshot"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/license"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/log"
|
2023-12-09 03:48:02 +00:00
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/modal"
|
2022-09-24 22:17:25 +00:00
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/native"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/userdir"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/windows"
|
2021-06-18 02:43:30 +00:00
|
|
|
"git.kirsle.net/go/render"
|
|
|
|
"git.kirsle.net/go/ui"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SetupMenuBar sets up the menu bar.
|
|
|
|
func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.MenuBar {
|
|
|
|
menu := ui.NewMenuBar("Main Menu")
|
|
|
|
|
|
|
|
// Save and Save As common menu handler
|
|
|
|
var (
|
2022-01-18 02:51:11 +00:00
|
|
|
saveFunc func(filename string)
|
2021-06-18 02:43:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
switch u.Scene.DrawingType {
|
|
|
|
case enum.LevelDrawing:
|
|
|
|
saveFunc = func(filename string) {
|
|
|
|
if err := u.Scene.SaveLevel(filename); err != nil {
|
2021-10-08 01:24:18 +00:00
|
|
|
d.FlashError("Error: %s", err)
|
2021-06-18 02:43:30 +00:00
|
|
|
} else {
|
|
|
|
d.Flash("Saved level: %s", filename)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case enum.DoodadDrawing:
|
|
|
|
saveFunc = func(filename string) {
|
|
|
|
if err := u.Scene.SaveDoodad(filename); err != nil {
|
2021-10-08 01:24:18 +00:00
|
|
|
d.FlashError("Error: %s", err)
|
2021-06-18 02:43:30 +00:00
|
|
|
} else {
|
|
|
|
d.Flash("Saved doodad: %s", filename)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
2021-10-08 01:24:18 +00:00
|
|
|
d.FlashError("Error: Scene.DrawingType is not a valid type")
|
2021-06-18 02:43:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
////////
|
|
|
|
// File menu
|
|
|
|
fileMenu := menu.AddMenu("File")
|
|
|
|
fileMenu.AddItemAccel("New level", "Ctrl-N", u.Scene.MenuNewLevel)
|
2023-02-17 05:47:18 +00:00
|
|
|
fileMenu.AddItem("New doodad", u.Scene.MenuNewDoodad)
|
2021-06-18 02:43:30 +00:00
|
|
|
fileMenu.AddItemAccel("Save", "Ctrl-S", u.Scene.MenuSave(false))
|
|
|
|
fileMenu.AddItemAccel("Save as...", "Shift-Ctrl-S", func() {
|
|
|
|
d.Prompt("Save as filename>", func(answer string) {
|
|
|
|
if answer != "" {
|
|
|
|
saveFunc(answer)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
fileMenu.AddItemAccel("Open...", "Ctrl-O", u.Scene.MenuOpen)
|
|
|
|
fileMenu.AddSeparator()
|
2022-01-17 04:09:27 +00:00
|
|
|
fileMenu.AddItem("Exit to menu", func() {
|
2021-06-18 02:43:30 +00:00
|
|
|
u.Scene.ConfirmUnload(func() {
|
|
|
|
d.Goto(&MainScene{})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
fileMenu.AddItemAccel("Quit", "Escape", func() {
|
|
|
|
d.ConfirmExit()
|
|
|
|
})
|
|
|
|
|
|
|
|
////////
|
|
|
|
// Edit menu
|
|
|
|
editMenu := menu.AddMenu("Edit")
|
|
|
|
editMenu.AddItemAccel("Undo", "Ctrl-Z", func() {
|
|
|
|
u.Canvas.UndoStroke()
|
|
|
|
})
|
|
|
|
editMenu.AddItemAccel("Redo", "Ctrl-Y", func() {
|
|
|
|
u.Canvas.RedoStroke()
|
|
|
|
})
|
2021-06-20 05:14:41 +00:00
|
|
|
editMenu.AddSeparator()
|
|
|
|
editMenu.AddItem("Settings", func() {
|
|
|
|
if u.settingsWindow == nil {
|
|
|
|
u.settingsWindow = d.MakeSettingsWindow(u.Supervisor)
|
|
|
|
}
|
|
|
|
u.settingsWindow.Show()
|
|
|
|
})
|
2021-06-18 02:43:30 +00:00
|
|
|
|
|
|
|
////////
|
|
|
|
// Level menu
|
|
|
|
if u.Scene.DrawingType == enum.LevelDrawing {
|
|
|
|
levelMenu := menu.AddMenu("Level")
|
2021-09-03 04:26:55 +00:00
|
|
|
levelMenu.AddItem("Level Properties", func() {
|
2021-06-18 02:43:30 +00:00
|
|
|
log.Info("Opening the window")
|
|
|
|
|
|
|
|
// Open the New Level window in edit-settings mode.
|
|
|
|
u.levelSettingsWindow.Hide()
|
|
|
|
u.levelSettingsWindow = nil
|
|
|
|
u.SetupPopups(u.d)
|
|
|
|
u.levelSettingsWindow.Show()
|
|
|
|
})
|
|
|
|
levelMenu.AddItem("Attached files", func() {
|
|
|
|
log.Info("Opening the FileSystem window")
|
|
|
|
u.OpenFileSystemWindow()
|
|
|
|
})
|
|
|
|
levelMenu.AddItemAccel("Playtest", "P", func() {
|
|
|
|
u.Scene.Playtest()
|
|
|
|
})
|
2022-01-18 02:51:11 +00:00
|
|
|
levelMenu.AddItem("Publish", func() {
|
|
|
|
u.OpenPublishWindow()
|
|
|
|
})
|
2021-10-04 00:21:17 +00:00
|
|
|
|
|
|
|
levelMenu.AddSeparator()
|
2023-12-09 03:48:02 +00:00
|
|
|
levelMenu.AddItem("Screenshot", func() {
|
2021-10-08 01:24:18 +00:00
|
|
|
// It takes a LONG TIME to render for medium+ maps.
|
|
|
|
// Do so on a background thread.
|
|
|
|
go func() {
|
2023-12-09 03:48:02 +00:00
|
|
|
filename, err := giant_screenshot.SaveCroppedScreenshot(u.Scene.Level, u.Scene.GetDrawing().Viewport())
|
2021-10-08 01:24:18 +00:00
|
|
|
if err != nil {
|
|
|
|
d.FlashError("Error: %s", err.Error())
|
|
|
|
return
|
|
|
|
}
|
2021-10-04 00:21:17 +00:00
|
|
|
|
2023-12-09 03:48:02 +00:00
|
|
|
d.FlashError("Screenshot saved as: %s", filename)
|
2021-10-08 01:24:18 +00:00
|
|
|
}()
|
2021-10-04 00:21:17 +00:00
|
|
|
})
|
2023-12-09 03:48:02 +00:00
|
|
|
levelMenu.AddItem("Giant Screenshot", func() {
|
|
|
|
// It takes a LONG TIME to render for medium+ maps.
|
|
|
|
modal.Confirm(
|
|
|
|
"Do you want to make a 'Giant Screenshot' of\n" +
|
|
|
|
"your WHOLE level? Note: this may take several\n" +
|
|
|
|
"seconds for very large maps!",
|
|
|
|
).WithTitle("Giant Screenshot").Then(func() {
|
|
|
|
// Show the wait modal and generate the screenshot on a background thread.
|
|
|
|
m := modal.Wait("Generating a giant screenshot...").WithTitle("Please hold")
|
|
|
|
go func() {
|
|
|
|
defer m.Dismiss(true)
|
|
|
|
|
|
|
|
filename, err := giant_screenshot.SaveGiantScreenshot(u.Scene.Level)
|
|
|
|
if err != nil {
|
|
|
|
d.FlashError("Error: %s", err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
d.FlashError("Giant screenshot saved as: %s", filename)
|
|
|
|
}()
|
|
|
|
})
|
|
|
|
})
|
2021-10-04 00:21:17 +00:00
|
|
|
levelMenu.AddItem("Open screenshot folder", func() {
|
|
|
|
native.OpenLocalURL(userdir.ScreenshotDirectory)
|
|
|
|
})
|
2021-10-04 04:18:39 +00:00
|
|
|
|
2022-03-26 20:55:06 +00:00
|
|
|
if balance.Feature.ViewportWindow {
|
2022-01-03 06:36:32 +00:00
|
|
|
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.Scene.Level,
|
|
|
|
Event: u.d.event,
|
2021-10-04 04:18:39 +00:00
|
|
|
|
2022-01-03 06:36:32 +00:00
|
|
|
Tool: &u.Scene.UI.Canvas.Tool,
|
|
|
|
BrushSize: &u.Scene.UI.Canvas.BrushSize,
|
|
|
|
})
|
|
|
|
|
|
|
|
pip.Show()
|
|
|
|
})
|
|
|
|
}
|
2021-06-18 02:43:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-03 04:26:55 +00:00
|
|
|
////////
|
|
|
|
// Doodad Menu
|
|
|
|
if u.Scene.DrawingType == enum.DoodadDrawing {
|
|
|
|
levelMenu := menu.AddMenu("Doodad")
|
|
|
|
levelMenu.AddItem("Doodad Properties", func() {
|
|
|
|
log.Info("Opening the window")
|
|
|
|
|
|
|
|
// Open the New Level window in edit-settings mode.
|
|
|
|
u.doodadPropertiesWindow.Hide()
|
|
|
|
u.doodadPropertiesWindow = nil
|
|
|
|
u.SetupPopups(u.d)
|
|
|
|
u.doodadPropertiesWindow.Show()
|
|
|
|
})
|
|
|
|
|
|
|
|
levelMenu.AddItem("Layers", func() {
|
|
|
|
u.OpenLayersWindow()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-06-18 02:43:30 +00:00
|
|
|
////////
|
|
|
|
// View menu
|
2021-10-07 05:22:34 +00:00
|
|
|
viewMenu := menu.AddMenu("View")
|
|
|
|
viewMenu.AddItemAccel("Zoom in", "+", func() {
|
|
|
|
u.Canvas.Zoom++
|
|
|
|
})
|
|
|
|
viewMenu.AddItemAccel("Zoom out", "-", func() {
|
|
|
|
u.Canvas.Zoom--
|
|
|
|
})
|
|
|
|
viewMenu.AddItemAccel("Reset zoom", "1", func() {
|
|
|
|
u.Canvas.Zoom = 0
|
|
|
|
})
|
|
|
|
viewMenu.AddItemAccel("Scroll drawing to origin", "0", func() {
|
|
|
|
u.Canvas.ScrollTo(render.Origin)
|
|
|
|
})
|
|
|
|
|
|
|
|
viewMenu.AddSeparator()
|
|
|
|
|
|
|
|
viewMenu.AddItemAccel("Close window", "←", func() {
|
|
|
|
u.Supervisor.CloseActiveWindow()
|
|
|
|
})
|
|
|
|
viewMenu.AddItemAccel("Close all windows", "Shift-←", func() {
|
|
|
|
u.Supervisor.CloseAllWindows()
|
|
|
|
})
|
2021-06-18 02:43:30 +00:00
|
|
|
|
|
|
|
////////
|
|
|
|
// Tools menu
|
|
|
|
toolMenu := menu.AddMenu("Tools")
|
|
|
|
toolMenu.AddItemAccel("Debug overlay", "F3", func() {
|
|
|
|
DebugOverlay = !DebugOverlay
|
|
|
|
if DebugOverlay {
|
|
|
|
d.Flash("Debug overlay enabled. Press F3 to turn it off.")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
toolMenu.AddItemAccel("Command shell", "`", func() {
|
|
|
|
d.shell.Open = true
|
|
|
|
})
|
|
|
|
toolMenu.AddSeparator()
|
|
|
|
toolMenu.AddItem("Edit Palette", func() {
|
|
|
|
u.OpenPaletteWindow()
|
|
|
|
})
|
|
|
|
|
|
|
|
// Draw Tools
|
|
|
|
toolMenu.AddItemAccel("Pencil Tool", "F", func() {
|
|
|
|
u.Canvas.Tool = drawtool.PencilTool
|
|
|
|
u.activeTool = u.Canvas.Tool.String()
|
|
|
|
d.Flash("Pencil Tool selected.")
|
|
|
|
})
|
|
|
|
toolMenu.AddItemAccel("Line Tool", "L", func() {
|
|
|
|
u.Canvas.Tool = drawtool.LineTool
|
|
|
|
u.activeTool = u.Canvas.Tool.String()
|
|
|
|
d.Flash("Line Tool selected.")
|
|
|
|
})
|
|
|
|
toolMenu.AddItemAccel("Rectangle Tool", "R", func() {
|
|
|
|
u.Canvas.Tool = drawtool.RectTool
|
|
|
|
u.activeTool = u.Canvas.Tool.String()
|
|
|
|
d.Flash("Rectangle Tool selected.")
|
|
|
|
})
|
|
|
|
toolMenu.AddItemAccel("Ellipse Tool", "C", func() {
|
|
|
|
u.Canvas.Tool = drawtool.EllipseTool
|
|
|
|
u.activeTool = u.Canvas.Tool.String()
|
|
|
|
d.Flash("Ellipse Tool selected.")
|
|
|
|
})
|
|
|
|
toolMenu.AddItemAccel("Eraser Tool", "x", func() {
|
|
|
|
u.Canvas.Tool = drawtool.EraserTool
|
|
|
|
u.activeTool = u.Canvas.Tool.String()
|
|
|
|
d.Flash("Eraser Tool selected.")
|
|
|
|
})
|
|
|
|
|
|
|
|
if u.Scene.DrawingType == enum.LevelDrawing {
|
2021-07-13 05:19:36 +00:00
|
|
|
toolMenu.AddItemAccel("Doodads", "q", func() {
|
2021-06-18 02:43:30 +00:00
|
|
|
log.Info("Open the DoodadDropper")
|
2022-02-20 04:20:58 +00:00
|
|
|
u.OpenDoodadDropper()
|
2021-06-18 02:43:30 +00:00
|
|
|
})
|
|
|
|
toolMenu.AddItem("Link Tool", func() {
|
|
|
|
u.Canvas.Tool = drawtool.LinkTool
|
|
|
|
u.activeTool = u.Canvas.Tool.String()
|
|
|
|
d.Flash("Link Tool selected. Click a doodad in your level to link it to another.")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
////////
|
|
|
|
// Help menu
|
2022-01-03 06:36:32 +00:00
|
|
|
var (
|
|
|
|
helpMenu = u.d.MakeHelpMenu(menu, u.Supervisor)
|
|
|
|
registerText = "Register"
|
|
|
|
)
|
2021-10-07 05:22:34 +00:00
|
|
|
helpMenu.AddSeparator()
|
2022-01-03 06:36:32 +00:00
|
|
|
if license.IsRegistered() {
|
|
|
|
registerText = "Registration"
|
|
|
|
}
|
|
|
|
helpMenu.AddItem(registerText, func() {
|
|
|
|
u.licenseWindow.Show()
|
2022-02-20 04:20:58 +00:00
|
|
|
u.Supervisor.FocusWindow(u.licenseWindow)
|
2021-10-07 05:22:34 +00:00
|
|
|
})
|
2021-06-18 02:43:30 +00:00
|
|
|
|
|
|
|
menu.Supervise(u.Supervisor)
|
|
|
|
menu.Compute(d.Engine)
|
|
|
|
|
|
|
|
return menu
|
|
|
|
}
|
|
|
|
|
|
|
|
// Menu functions that have keybind callbacks below.
|
|
|
|
|
|
|
|
// File->New level, or Ctrl-N
|
|
|
|
func (s *EditorScene) MenuNewLevel() {
|
|
|
|
s.ConfirmUnload(func() {
|
|
|
|
s.d.GotoNewMenu()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-17 05:47:18 +00:00
|
|
|
func (s *EditorScene) MenuNewDoodad() {
|
|
|
|
s.ConfirmUnload(func() {
|
|
|
|
// New doodad size with prompt.
|
|
|
|
s.d.GotoNewDoodadMenu()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-06-18 02:43:30 +00:00
|
|
|
// File->Open, or Ctrl-O
|
|
|
|
func (s *EditorScene) MenuOpen() {
|
|
|
|
s.ConfirmUnload(func() {
|
|
|
|
s.d.GotoLoadMenu()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// File->Save, or Ctrl-S
|
|
|
|
// File->Save As, or Shift-Ctrl-S
|
|
|
|
// NOTICE: this one returns a func() so you need to call that one!
|
|
|
|
func (s *EditorScene) MenuSave(as bool) func() {
|
|
|
|
return func() {
|
|
|
|
var (
|
|
|
|
// drawingType string
|
|
|
|
saveFunc func(filename string)
|
|
|
|
)
|
|
|
|
|
|
|
|
switch s.DrawingType {
|
|
|
|
case enum.LevelDrawing:
|
|
|
|
// drawingType = "level"
|
|
|
|
saveFunc = func(filename string) {
|
|
|
|
if err := s.SaveLevel(filename); err != nil {
|
2021-10-08 01:24:18 +00:00
|
|
|
s.d.FlashError("Error: %s", err)
|
2021-06-18 02:43:30 +00:00
|
|
|
} else {
|
|
|
|
s.d.Flash("Saved level: %s", filename)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case enum.DoodadDrawing:
|
|
|
|
// drawingType = "doodad"
|
|
|
|
saveFunc = func(filename string) {
|
|
|
|
if err := s.SaveDoodad(filename); err != nil {
|
2021-10-08 01:24:18 +00:00
|
|
|
s.d.FlashError("Error: %s", err)
|
2021-06-18 02:43:30 +00:00
|
|
|
} else {
|
|
|
|
s.d.Flash("Saved doodad: %s", filename)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
2021-10-08 01:24:18 +00:00
|
|
|
s.d.FlashError("Error: Scene.DrawingType is not a valid type")
|
2021-06-18 02:43:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// "Save As"?
|
|
|
|
if as {
|
|
|
|
s.d.Prompt("Save as filename>", func(answer string) {
|
|
|
|
if answer != "" {
|
|
|
|
saveFunc(answer)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// "Save", write to existing filename or prompt for it.
|
|
|
|
if s.filename != "" {
|
|
|
|
saveFunc(s.filename)
|
|
|
|
} else {
|
|
|
|
s.d.Prompt("Save filename>", func(answer string) {
|
|
|
|
if answer != "" {
|
|
|
|
saveFunc(answer)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|