Noah Petherbridge
ddcad27485
Convert the Chunker size to a uint8 so chunk sizes are limited to 255px. This means that inside of a chunk, uint8's can track the relative pixel coordinates and result in a great memory savings since all of these uint8's are currently 64-bits wide apiece. WIP on rectangular shaped doodads: * You can create such a doodad in the editor and draw it normally. * It doesn't draw the right size when dragged into your level however: - In uix.Actor.Size() it gets a rect of the doodad's square Chunker size, instead of getting the proper doodad.Size rect. - If you give it the doodad.Size rect, it draws the Canvas size correctly instead of a square - the full drawing appears and in gameplay its hitbox (assuming the same large rectangle size) works correctly in-game. - But, the doodad has scrolling issues when it gets to the top or left edge of the screen! This old gnarly bug has come back. For some reason square canvas doodads draw correctly but rectangular ones have the drawing scroll just a bit - how far it scrolls is proportional to how big the doodad is, with the Start Flag only scrolling a few pixels before it stops.
352 lines
8.7 KiB
Go
352 lines
8.7 KiB
Go
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 (
|
|
"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"
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/native"
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/userdir"
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/windows"
|
|
"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 (
|
|
saveFunc func(filename string)
|
|
)
|
|
|
|
switch u.Scene.DrawingType {
|
|
case enum.LevelDrawing:
|
|
saveFunc = func(filename string) {
|
|
if err := u.Scene.SaveLevel(filename); err != nil {
|
|
d.FlashError("Error: %s", err)
|
|
} else {
|
|
d.Flash("Saved level: %s", filename)
|
|
}
|
|
}
|
|
case enum.DoodadDrawing:
|
|
saveFunc = func(filename string) {
|
|
if err := u.Scene.SaveDoodad(filename); err != nil {
|
|
d.FlashError("Error: %s", err)
|
|
} else {
|
|
d.Flash("Saved doodad: %s", filename)
|
|
}
|
|
}
|
|
default:
|
|
d.FlashError("Error: Scene.DrawingType is not a valid type")
|
|
}
|
|
|
|
////////
|
|
// File menu
|
|
fileMenu := menu.AddMenu("File")
|
|
fileMenu.AddItemAccel("New level", "Ctrl-N", u.Scene.MenuNewLevel)
|
|
fileMenu.AddItem("New doodad", u.Scene.MenuNewDoodad)
|
|
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()
|
|
fileMenu.AddItem("Exit to menu", func() {
|
|
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()
|
|
})
|
|
editMenu.AddSeparator()
|
|
editMenu.AddItem("Settings", func() {
|
|
if u.settingsWindow == nil {
|
|
u.settingsWindow = d.MakeSettingsWindow(u.Supervisor)
|
|
}
|
|
u.settingsWindow.Show()
|
|
})
|
|
|
|
////////
|
|
// Level menu
|
|
if u.Scene.DrawingType == enum.LevelDrawing {
|
|
levelMenu := menu.AddMenu("Level")
|
|
levelMenu.AddItem("Level Properties", func() {
|
|
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()
|
|
})
|
|
levelMenu.AddItem("Publish", func() {
|
|
u.OpenPublishWindow()
|
|
})
|
|
|
|
levelMenu.AddSeparator()
|
|
levelMenu.AddItem("Giant Screenshot", func() {
|
|
// It takes a LONG TIME to render for medium+ maps.
|
|
// Do so on a background thread.
|
|
go func() {
|
|
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)
|
|
}()
|
|
})
|
|
levelMenu.AddItem("Open screenshot folder", func() {
|
|
native.OpenLocalURL(userdir.ScreenshotDirectory)
|
|
})
|
|
|
|
if balance.Feature.ViewportWindow {
|
|
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,
|
|
|
|
Tool: &u.Scene.UI.Canvas.Tool,
|
|
BrushSize: &u.Scene.UI.Canvas.BrushSize,
|
|
})
|
|
|
|
pip.Show()
|
|
})
|
|
}
|
|
}
|
|
|
|
////////
|
|
// 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()
|
|
})
|
|
}
|
|
|
|
////////
|
|
// View menu
|
|
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()
|
|
})
|
|
|
|
////////
|
|
// 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 {
|
|
toolMenu.AddItemAccel("Doodads", "q", func() {
|
|
log.Info("Open the DoodadDropper")
|
|
u.OpenDoodadDropper()
|
|
})
|
|
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
|
|
var (
|
|
helpMenu = u.d.MakeHelpMenu(menu, u.Supervisor)
|
|
registerText = "Register"
|
|
)
|
|
helpMenu.AddSeparator()
|
|
if license.IsRegistered() {
|
|
registerText = "Registration"
|
|
}
|
|
helpMenu.AddItem(registerText, func() {
|
|
u.licenseWindow.Show()
|
|
u.Supervisor.FocusWindow(u.licenseWindow)
|
|
})
|
|
|
|
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()
|
|
})
|
|
}
|
|
|
|
func (s *EditorScene) MenuNewDoodad() {
|
|
s.ConfirmUnload(func() {
|
|
// New doodad size with prompt.
|
|
s.d.GotoNewDoodadMenu()
|
|
})
|
|
}
|
|
|
|
// 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 {
|
|
s.d.FlashError("Error: %s", err)
|
|
} else {
|
|
s.d.Flash("Saved level: %s", filename)
|
|
}
|
|
}
|
|
case enum.DoodadDrawing:
|
|
// drawingType = "doodad"
|
|
saveFunc = func(filename string) {
|
|
if err := s.SaveDoodad(filename); err != nil {
|
|
s.d.FlashError("Error: %s", err)
|
|
} else {
|
|
s.d.Flash("Saved doodad: %s", filename)
|
|
}
|
|
}
|
|
default:
|
|
s.d.FlashError("Error: Scene.DrawingType is not a valid type")
|
|
}
|
|
|
|
// "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)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|