2020-04-07 06:21:17 +00:00
|
|
|
package windows
|
|
|
|
|
|
|
|
import (
|
2022-03-26 20:55:06 +00:00
|
|
|
"fmt"
|
|
|
|
"regexp"
|
2021-10-10 03:45:38 +00:00
|
|
|
"strconv"
|
|
|
|
|
2020-04-07 06:21:17 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/balance"
|
2022-03-07 06:16:09 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/enum"
|
2020-04-07 06:21:17 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/level"
|
2022-03-07 06:16:09 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/log"
|
2021-06-06 03:50:56 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/modal"
|
2021-06-07 01:59:04 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/native"
|
2020-04-07 06:21:17 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/shmem"
|
2022-03-07 06:16:09 +00:00
|
|
|
magicform "git.kirsle.net/apps/doodle/pkg/uix/magic-form"
|
2021-06-07 01:59:04 +00:00
|
|
|
"git.kirsle.net/apps/doodle/pkg/wallpaper"
|
2020-04-07 06:21:17 +00:00
|
|
|
"git.kirsle.net/go/render"
|
|
|
|
"git.kirsle.net/go/ui"
|
|
|
|
)
|
|
|
|
|
|
|
|
// AddEditLevel is the "Create New Level & Edit Level Properties" window
|
|
|
|
type AddEditLevel struct {
|
|
|
|
Supervisor *ui.Supervisor
|
|
|
|
Engine render.Engine
|
|
|
|
|
|
|
|
// Editing settings for an existing level?
|
|
|
|
EditLevel *level.Level
|
|
|
|
|
|
|
|
// Callback functions.
|
|
|
|
OnChangePageTypeAndWallpaper func(pageType level.PageType, wallpaper string)
|
|
|
|
OnCreateNewLevel func(*level.Level)
|
2021-12-31 00:31:45 +00:00
|
|
|
OnCreateNewDoodad func(size int)
|
2021-09-12 04:18:22 +00:00
|
|
|
OnReload func()
|
2020-04-07 06:21:17 +00:00
|
|
|
OnCancel func()
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewAddEditLevel initializes the window.
|
|
|
|
func NewAddEditLevel(config AddEditLevel) *ui.Window {
|
2021-12-31 00:31:45 +00:00
|
|
|
// Default options.
|
|
|
|
var (
|
|
|
|
title = "New Drawing"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Given a level to edit?
|
|
|
|
if config.EditLevel != nil {
|
|
|
|
title = "Level Properties"
|
|
|
|
}
|
|
|
|
|
|
|
|
window := ui.NewWindow(title)
|
|
|
|
window.SetButtons(ui.CloseButton)
|
|
|
|
window.Configure(ui.Config{
|
|
|
|
Width: 400,
|
2022-03-26 20:55:06 +00:00
|
|
|
Height: 290,
|
2021-12-31 00:31:45 +00:00
|
|
|
Background: render.Grey,
|
|
|
|
})
|
|
|
|
|
|
|
|
// Tabbed UI for New Level or New Doodad.
|
|
|
|
tabframe := ui.NewTabFrame("Level Tabs")
|
|
|
|
window.Pack(tabframe, ui.Pack{
|
|
|
|
Side: ui.N,
|
|
|
|
Fill: true,
|
|
|
|
Expand: true,
|
|
|
|
})
|
|
|
|
|
|
|
|
// Add the tabs.
|
2022-03-26 20:55:06 +00:00
|
|
|
config.setupLevelFrame(tabframe) // Level Properties (always)
|
|
|
|
if config.EditLevel == nil {
|
|
|
|
// New Doodad properties (New window only)
|
|
|
|
config.setupDoodadFrame(tabframe)
|
|
|
|
} else {
|
|
|
|
// Additional Level tabs (existing level only)
|
|
|
|
config.setupGameRuleFrame(tabframe)
|
|
|
|
}
|
2021-12-31 00:31:45 +00:00
|
|
|
|
|
|
|
tabframe.Supervise(config.Supervisor)
|
|
|
|
|
|
|
|
window.Hide()
|
|
|
|
return window
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates the Create/Edit Level tab ("index").
|
|
|
|
func (config AddEditLevel) setupLevelFrame(tf *ui.TabFrame) {
|
2020-04-07 06:21:17 +00:00
|
|
|
// Default options.
|
|
|
|
var (
|
2022-03-26 20:55:06 +00:00
|
|
|
tabLabel = "New Level"
|
2020-04-07 06:21:17 +00:00
|
|
|
newPageType = level.Bounded.String()
|
|
|
|
newWallpaper = "notebook.png"
|
2021-06-06 03:50:56 +00:00
|
|
|
paletteName = level.DefaultPaletteNames[0]
|
2020-04-07 06:21:17 +00:00
|
|
|
isNewLevel = config.EditLevel == nil
|
2021-06-06 03:50:56 +00:00
|
|
|
|
2021-06-07 01:59:04 +00:00
|
|
|
// Default text for the Palette drop-down for already-existing levels.
|
|
|
|
// (needs --experimental feature flag to enable the UI).
|
2021-06-06 03:50:56 +00:00
|
|
|
textCurrentPalette = "Keep current palette"
|
2021-06-07 01:59:04 +00:00
|
|
|
|
|
|
|
// For NEW levels, if a custom wallpaper is selected from disk, cache
|
|
|
|
// it in these vars. For pre-existing levels, the wallpaper updates
|
|
|
|
// immediately in the live config.EditLevel object.
|
|
|
|
newWallpaperB64 string
|
2020-04-07 06:21:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Given a level to edit?
|
2022-03-07 06:16:09 +00:00
|
|
|
if !isNewLevel {
|
2022-03-26 20:55:06 +00:00
|
|
|
tabLabel = "Properties"
|
2020-04-07 06:21:17 +00:00
|
|
|
newPageType = config.EditLevel.PageType.String()
|
|
|
|
newWallpaper = config.EditLevel.Wallpaper
|
2021-06-06 03:50:56 +00:00
|
|
|
paletteName = textCurrentPalette
|
2020-04-07 06:21:17 +00:00
|
|
|
}
|
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
frame := tf.AddTab("index", ui.NewLabel(ui.Label{
|
2022-03-26 20:55:06 +00:00
|
|
|
Text: tabLabel,
|
2021-12-31 00:31:45 +00:00
|
|
|
Font: balance.TabFont,
|
|
|
|
}))
|
|
|
|
|
|
|
|
/******************
|
|
|
|
* Frame for selecting Page Type
|
|
|
|
******************/
|
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
// Selected "Page Type" property.
|
|
|
|
var pageType = level.Bounded
|
|
|
|
if !isNewLevel {
|
|
|
|
pageType = config.EditLevel.PageType
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
form := magicform.Form{
|
|
|
|
Supervisor: config.Supervisor,
|
|
|
|
Engine: config.Engine,
|
|
|
|
Vertical: true,
|
|
|
|
LabelWidth: 120,
|
|
|
|
PadY: 2,
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2022-03-07 06:16:09 +00:00
|
|
|
fields := []magicform.Field{
|
|
|
|
{
|
|
|
|
Label: "Page type:",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
Options: []magicform.Option{
|
|
|
|
{
|
|
|
|
Label: "Bounded",
|
|
|
|
Value: level.Bounded,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Unbounded",
|
|
|
|
Value: level.Unbounded,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "No Negative Space",
|
|
|
|
Value: level.NoNegativeSpace,
|
|
|
|
},
|
2021-12-31 00:31:45 +00:00
|
|
|
},
|
2022-03-07 06:16:09 +00:00
|
|
|
SelectValue: pageType,
|
|
|
|
OnSelect: func(v interface{}) {
|
|
|
|
value, _ := v.(level.PageType)
|
|
|
|
newPageType = value.String() // for the "New" screen background
|
|
|
|
config.OnChangePageTypeAndWallpaper(value, newWallpaper)
|
2021-12-31 00:31:45 +00:00
|
|
|
},
|
2022-03-07 06:16:09 +00:00
|
|
|
},
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
/******************
|
2022-03-07 06:16:09 +00:00
|
|
|
* Wallpaper settings
|
2021-12-31 00:31:45 +00:00
|
|
|
******************/
|
2021-06-06 21:32:52 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
var selectedWallpaper = "notebook.png"
|
2021-12-31 00:31:45 +00:00
|
|
|
if config.EditLevel != nil {
|
2022-03-07 06:16:09 +00:00
|
|
|
selectedWallpaper = config.EditLevel.Wallpaper
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
fields = append(fields, []magicform.Field{
|
|
|
|
{
|
|
|
|
Label: "Wallpaper:",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
SelectValue: selectedWallpaper,
|
|
|
|
Options: []magicform.Option{
|
|
|
|
{
|
|
|
|
Label: "Notebook",
|
|
|
|
Value: "notebook.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Legal Pad",
|
|
|
|
Value: "legal.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Graph paper",
|
|
|
|
Value: "graph.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Dotted paper",
|
|
|
|
Value: "dots.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Blueprint",
|
|
|
|
Value: "blueprint.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Pure white",
|
|
|
|
Value: "white.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Separator: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Custom wallpaper...",
|
|
|
|
Value: balance.CustomWallpaperFilename,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
OnSelect: func(v interface{}) {
|
|
|
|
if filename, ok := v.(string); ok {
|
|
|
|
// Picking the Custom option?
|
|
|
|
if filename == balance.CustomWallpaperFilename {
|
|
|
|
filename, err := native.OpenFile("Choose a custom wallpaper:", "*.png *.jpg *.gif")
|
|
|
|
if err == nil {
|
|
|
|
b64data, err := wallpaper.FileToB64(filename)
|
|
|
|
if err != nil {
|
|
|
|
shmem.Flash("Error loading wallpaper: %s", err)
|
|
|
|
return
|
|
|
|
}
|
2021-12-31 00:31:45 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
// If editing a level, apply the update straight away.
|
|
|
|
if config.EditLevel != nil {
|
|
|
|
config.EditLevel.SetFile(balance.CustomWallpaperEmbedPath, []byte(b64data))
|
|
|
|
newWallpaper = balance.CustomWallpaperFilename
|
|
|
|
|
|
|
|
// Trigger the page type change to the caller.
|
|
|
|
if pageType, ok := level.PageTypeFromString(newPageType); ok {
|
|
|
|
config.OnChangePageTypeAndWallpaper(pageType, balance.CustomWallpaperFilename)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Hold onto the new wallpaper until the level is created.
|
|
|
|
newWallpaper = balance.CustomWallpaperFilename
|
|
|
|
newWallpaperB64 = b64data
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2021-10-10 03:45:38 +00:00
|
|
|
}
|
2022-03-07 06:16:09 +00:00
|
|
|
return
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2021-10-10 03:45:38 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
if pageType, ok := level.PageTypeFromString(newPageType); ok {
|
|
|
|
config.OnChangePageTypeAndWallpaper(pageType, filename)
|
|
|
|
newWallpaper = filename
|
|
|
|
}
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2022-03-07 06:16:09 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}...)
|
2021-10-10 03:45:38 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
/******************
|
|
|
|
* Frame for picking a default color palette.
|
|
|
|
******************/
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
// For new level or --experimental only.
|
|
|
|
if config.EditLevel == nil || balance.Feature.ChangePalette {
|
2022-03-07 06:16:09 +00:00
|
|
|
var (
|
|
|
|
palettes = []magicform.Option{}
|
|
|
|
)
|
2021-06-06 21:32:52 +00:00
|
|
|
|
|
|
|
if config.EditLevel != nil {
|
2022-03-07 06:16:09 +00:00
|
|
|
palettes = append(palettes, []magicform.Option{
|
|
|
|
{
|
|
|
|
Label: paletteName, // "Keep current palette"
|
|
|
|
Value: paletteName,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Separator: true,
|
|
|
|
},
|
|
|
|
}...)
|
2021-06-06 21:32:52 +00:00
|
|
|
}
|
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
for _, palName := range level.DefaultPaletteNames {
|
2022-03-07 06:16:09 +00:00
|
|
|
palettes = append(palettes, magicform.Option{
|
|
|
|
Label: palName,
|
|
|
|
Value: palName,
|
|
|
|
})
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2021-06-06 21:32:52 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
// Add form fields.
|
|
|
|
fields = append(fields, []magicform.Field{
|
|
|
|
{
|
|
|
|
Label: "Palette:",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
Options: palettes,
|
|
|
|
OnSelect: func(v interface{}) {
|
|
|
|
value, _ := v.(string)
|
|
|
|
paletteName = value
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}...)
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
/******************
|
2022-03-07 06:16:09 +00:00
|
|
|
* Extended options for editing existing level (vs. Create New screen)
|
2021-12-31 00:31:45 +00:00
|
|
|
******************/
|
2021-06-06 03:50:56 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
if config.EditLevel != nil {
|
2022-03-26 20:55:06 +00:00
|
|
|
var (
|
|
|
|
levelSizeStr = fmt.Sprintf("%dx%d", config.EditLevel.MaxWidth, config.EditLevel.MaxHeight)
|
|
|
|
levelSizeRegexp = regexp.MustCompile(`^(\d+)x(\d+)$`)
|
|
|
|
)
|
2022-03-07 06:16:09 +00:00
|
|
|
fields = append(fields, []magicform.Field{
|
|
|
|
{
|
2022-03-26 20:55:06 +00:00
|
|
|
Label: "Limits (bounded):",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
TextVariable: &levelSizeStr,
|
|
|
|
OnClick: func() {
|
|
|
|
shmem.Prompt(fmt.Sprintf("Enter new limits in WxH format or [%s]: ", levelSizeStr), func(answer string) {
|
|
|
|
if answer == "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
match := levelSizeRegexp.FindStringSubmatch(answer)
|
|
|
|
if match == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
levelSizeStr = match[0]
|
|
|
|
width, _ := strconv.Atoi(match[1])
|
|
|
|
height, _ := strconv.Atoi(match[2])
|
|
|
|
|
|
|
|
config.EditLevel.MaxWidth = int64(width)
|
|
|
|
config.EditLevel.MaxHeight = int64(height)
|
|
|
|
})
|
2022-03-07 06:16:09 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Metadata",
|
|
|
|
Font: balance.LabelFont,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Title:",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
TextVariable: &config.EditLevel.Title,
|
|
|
|
PromptUser: func(answer string) {
|
|
|
|
config.EditLevel.Title = answer
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Author:",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
TextVariable: &config.EditLevel.Author,
|
|
|
|
PromptUser: func(answer string) {
|
|
|
|
config.EditLevel.Author = answer
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}...)
|
|
|
|
}
|
2021-06-06 03:50:56 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
// The confirm/cancel buttons.
|
2022-03-26 20:55:06 +00:00
|
|
|
var okLabel = "Apply"
|
2022-03-07 06:16:09 +00:00
|
|
|
if config.EditLevel == nil {
|
|
|
|
okLabel = "Continue"
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2022-03-07 06:16:09 +00:00
|
|
|
fields = append(fields, []magicform.Field{
|
|
|
|
{
|
|
|
|
Buttons: []magicform.Field{
|
|
|
|
{
|
|
|
|
ButtonStyle: &balance.ButtonPrimary,
|
|
|
|
Label: okLabel,
|
|
|
|
Font: balance.UIFont,
|
|
|
|
OnClick: func() {
|
|
|
|
// Is it a NEW level?
|
|
|
|
if config.EditLevel == nil {
|
|
|
|
shmem.Flash("Create new map with %s page type and %s wallpaper", newPageType, newWallpaper)
|
|
|
|
pageType, ok := level.PageTypeFromString(newPageType)
|
|
|
|
if !ok {
|
|
|
|
shmem.Flash("Invalid Page Type '%s'", newPageType)
|
|
|
|
return
|
|
|
|
}
|
2021-06-06 03:50:56 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
lvl := level.New()
|
|
|
|
lvl.Palette = level.DefaultPalettes[paletteName]
|
|
|
|
lvl.Wallpaper = newWallpaper
|
|
|
|
lvl.PageType = pageType
|
2021-06-06 03:50:56 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
// Was a custom wallpaper selected for our NEW level?
|
|
|
|
if lvl.Wallpaper == balance.CustomWallpaperFilename && len(newWallpaperB64) > 0 {
|
|
|
|
lvl.SetFile(balance.CustomWallpaperEmbedPath, []byte(newWallpaperB64))
|
|
|
|
}
|
2021-06-06 03:50:56 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
if config.OnCreateNewLevel != nil {
|
|
|
|
config.OnCreateNewLevel(lvl)
|
|
|
|
} else {
|
|
|
|
shmem.FlashError("OnCreateNewLevel not attached")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Editing an existing level.
|
|
|
|
|
|
|
|
// If we're editing a level, did we select a new palette?
|
|
|
|
// Warn the user about if they want to change palettes.
|
|
|
|
if paletteName != textCurrentPalette {
|
|
|
|
modal.Confirm(
|
|
|
|
"Are you sure you want to change the level palette?\n" +
|
|
|
|
"Existing pixels drawn on your level may change, and\n" +
|
|
|
|
"if the new palette is smaller, some pixels may be\n" +
|
|
|
|
"lost from your level. OK to continue?",
|
|
|
|
).WithTitle("Change Level Palette").Then(func() {
|
|
|
|
// Install the new level palette.
|
|
|
|
config.EditLevel.ReplacePalette(level.DefaultPalettes[paletteName])
|
|
|
|
if config.OnReload != nil {
|
|
|
|
config.OnReload()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
2021-12-31 00:31:45 +00:00
|
|
|
|
2022-03-07 06:16:09 +00:00
|
|
|
config.OnCancel()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Cancel",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
OnClick: func() {
|
|
|
|
config.OnCancel()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}...)
|
|
|
|
|
|
|
|
form.Create(frame, fields)
|
2021-12-31 00:31:45 +00:00
|
|
|
}
|
2021-03-31 06:33:25 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
// Creates the "New Doodad" frame.
|
|
|
|
func (config AddEditLevel) setupDoodadFrame(tf *ui.TabFrame) {
|
|
|
|
// Default options.
|
|
|
|
var (
|
|
|
|
doodadSize = 64
|
|
|
|
)
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
frame := tf.AddTab("doodad", ui.NewLabel(ui.Label{
|
|
|
|
Text: "New Doodad",
|
|
|
|
Font: balance.TabFont,
|
|
|
|
}))
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
/******************
|
|
|
|
* Frame for selecting Page Type
|
|
|
|
******************/
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
typeFrame := ui.NewFrame("Doodad Options Frame")
|
|
|
|
frame.Pack(typeFrame, ui.Pack{
|
|
|
|
Side: ui.N,
|
|
|
|
FillX: true,
|
|
|
|
})
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
label1 := ui.NewLabel(ui.Label{
|
|
|
|
Text: "Doodad sprite size (square):",
|
|
|
|
Font: balance.LabelFont,
|
|
|
|
})
|
|
|
|
typeFrame.Pack(label1, ui.Pack{
|
|
|
|
Side: ui.W,
|
|
|
|
})
|
2021-06-07 01:59:04 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
// A selectbox to suggest some sizes or let the user enter a custom.
|
|
|
|
sizeBtn := ui.NewSelectBox("Size Select", ui.Label{
|
|
|
|
Font: ui.MenuFont,
|
|
|
|
})
|
|
|
|
typeFrame.Pack(sizeBtn, ui.Pack{
|
|
|
|
Side: ui.W,
|
|
|
|
Expand: true,
|
|
|
|
})
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
for _, row := range []struct {
|
|
|
|
Name string
|
|
|
|
Value int
|
|
|
|
}{
|
|
|
|
{"32", 32},
|
|
|
|
{"64", 64},
|
|
|
|
{"96", 96},
|
|
|
|
{"128", 128},
|
|
|
|
{"200", 200},
|
|
|
|
{"256", 256},
|
|
|
|
{"Custom...", 0},
|
|
|
|
} {
|
|
|
|
row := row
|
|
|
|
sizeBtn.AddItem(row.Name, row.Value, func() {})
|
|
|
|
}
|
|
|
|
|
|
|
|
sizeBtn.SetValue(doodadSize)
|
|
|
|
sizeBtn.Handle(ui.Change, func(ed ui.EventData) error {
|
|
|
|
if selection, ok := sizeBtn.GetValue(); ok {
|
|
|
|
if size, ok := selection.Value.(int); ok {
|
|
|
|
if size == 0 {
|
|
|
|
shmem.Prompt("Enter a custom size for the doodad width and height: ", func(answer string) {
|
|
|
|
if a, err := strconv.Atoi(answer); err == nil && a > 0 {
|
|
|
|
doodadSize = a
|
|
|
|
} else {
|
|
|
|
shmem.FlashError("Doodad size should be a number greater than zero.")
|
2021-09-12 04:18:22 +00:00
|
|
|
}
|
2021-06-06 03:50:56 +00:00
|
|
|
})
|
2021-12-31 00:31:45 +00:00
|
|
|
} else {
|
|
|
|
doodadSize = size
|
2021-06-06 03:50:56 +00:00
|
|
|
}
|
2020-04-07 06:21:17 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-31 00:31:45 +00:00
|
|
|
return nil
|
|
|
|
})
|
2020-04-07 06:21:17 +00:00
|
|
|
|
2021-12-31 00:31:45 +00:00
|
|
|
sizeBtn.Supervise(config.Supervisor)
|
|
|
|
config.Supervisor.Add(sizeBtn)
|
|
|
|
|
|
|
|
/******************
|
|
|
|
* Confirm/cancel buttons.
|
|
|
|
******************/
|
|
|
|
|
|
|
|
bottomFrame := ui.NewFrame("Button Frame")
|
|
|
|
frame.Pack(bottomFrame, ui.Pack{
|
|
|
|
Side: ui.N,
|
|
|
|
FillX: true,
|
|
|
|
PadY: 8,
|
|
|
|
})
|
|
|
|
|
|
|
|
var buttons = []struct {
|
|
|
|
Label string
|
|
|
|
F func(ui.EventData) error
|
|
|
|
}{
|
|
|
|
{"Continue", func(ed ui.EventData) error {
|
|
|
|
if config.OnCreateNewDoodad != nil {
|
|
|
|
config.OnCreateNewDoodad(doodadSize)
|
|
|
|
} else {
|
|
|
|
shmem.FlashError("OnCreateNewDoodad not attached")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}},
|
|
|
|
|
|
|
|
{"Cancel", func(ed ui.EventData) error {
|
|
|
|
config.OnCancel()
|
|
|
|
return nil
|
|
|
|
}},
|
|
|
|
}
|
|
|
|
for _, t := range buttons {
|
|
|
|
btn := ui.NewButton(t.Label, ui.NewLabel(ui.Label{
|
|
|
|
Text: t.Label,
|
|
|
|
Font: balance.MenuFont,
|
|
|
|
}))
|
|
|
|
btn.Handle(ui.Click, t.F)
|
|
|
|
config.Supervisor.Add(btn)
|
|
|
|
bottomFrame.Pack(btn, ui.Pack{
|
|
|
|
Side: ui.W,
|
|
|
|
PadX: 4,
|
|
|
|
PadY: 8,
|
|
|
|
})
|
|
|
|
}
|
2020-04-07 06:21:17 +00:00
|
|
|
}
|
2022-03-26 20:55:06 +00:00
|
|
|
|
|
|
|
// Creates the Game Rules frame for existing level (set difficulty, etc.)
|
|
|
|
func (config AddEditLevel) setupGameRuleFrame(tf *ui.TabFrame) {
|
|
|
|
frame := tf.AddTab("GameRules", ui.NewLabel(ui.Label{
|
|
|
|
Text: "Game Rules",
|
|
|
|
Font: balance.TabFont,
|
|
|
|
}))
|
|
|
|
|
|
|
|
form := magicform.Form{
|
|
|
|
Supervisor: config.Supervisor,
|
|
|
|
Engine: config.Engine,
|
|
|
|
Vertical: true,
|
|
|
|
LabelWidth: 120,
|
|
|
|
PadY: 2,
|
|
|
|
}
|
|
|
|
fields := []magicform.Field{
|
|
|
|
{
|
|
|
|
Label: "Game Rules are specific to this level and can change some of\n" +
|
|
|
|
"the game's default behaviors.",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Difficulty:",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
SelectValue: config.EditLevel.GameRule.Difficulty,
|
|
|
|
Tooltip: ui.Tooltip{
|
|
|
|
Text: "Peaceful: enemies may not attack\n" +
|
|
|
|
"Normal: default difficulty\n" +
|
|
|
|
"Hard: enemies may be more aggressive",
|
|
|
|
Edge: ui.Top,
|
|
|
|
},
|
|
|
|
Options: []magicform.Option{
|
|
|
|
{
|
|
|
|
Label: "Peaceful",
|
|
|
|
Value: enum.Peaceful,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Normal (recommended)",
|
|
|
|
Value: enum.Normal,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Hard",
|
|
|
|
Value: enum.Hard,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
OnSelect: func(v interface{}) {
|
|
|
|
value, _ := v.(enum.Difficulty)
|
|
|
|
config.EditLevel.GameRule.Difficulty = value
|
|
|
|
log.Info("Set level difficulty to: %d (%s)", value, value)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Survival Mode (silver high score)",
|
|
|
|
Font: balance.UIFont,
|
|
|
|
BoolVariable: &config.EditLevel.GameRule.Survival,
|
|
|
|
Tooltip: ui.Tooltip{
|
|
|
|
Text: "Use for levels where dying at least once is very likely\n" +
|
|
|
|
"(e.g. Azulian Tag). The silver high score will be for\n" +
|
|
|
|
"longest time rather than fastest time. The gold high\n" +
|
|
|
|
"score will still be for fastest time.",
|
|
|
|
Edge: ui.Top,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
form.Create(frame, fields)
|
|
|
|
}
|