Editor: Doodad Properties Window
The Doodad Properties window brings many features that used to be available only in the `doodad` CLI tool into the Doodad Editor. * In the Doodad Editor there is a new menubar item: "Doodad" which corresponds to the "Level" menu when you're editing a level. * The "Doodad" menu has two items: - "Doodad Properties" (NEW) - "Layers" (moved here from the Tools menu) * The Doodad Properties window lets you edit the Title and Author values of the doodad, as well as modify its Tags and manage its Script. * Its script can be attached (browse for .js file on disk), its existing script saved back to disk (dev shell prompt) or deleted altogether from the doodad. * You can create, modify, and delete Tags on the doodad. Other changes: * In the Level Editor, the "Level->Page Settings" menu is renamed to "Level->Level Properties" to match with "Doodad->Doodad Properties" and the pop-up window is retitled accordingly. * The Exit Flag only exits if the Player touches it - not just any mobile doodad!
This commit is contained in:
parent
0cc1d17f4f
commit
0fa1bf8a76
|
@ -1,12 +1,17 @@
|
||||||
// Exit Flag.
|
// Exit Flag.
|
||||||
function main() {
|
function main() {
|
||||||
Self.SetHitbox(22+16, 16, 75-16, 86);
|
Self.SetHitbox(22 + 16, 16, 75 - 16, 86);
|
||||||
|
|
||||||
Events.OnCollide(function(e) {
|
Events.OnCollide(function (e) {
|
||||||
if (!e.Settled) {
|
if (!e.Settled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only care if it's the player.
|
||||||
|
if (!e.Actor.IsPlayer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.InHitbox) {
|
if (e.InHitbox) {
|
||||||
EndLevel();
|
EndLevel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,13 @@ var (
|
||||||
Color: render.Black,
|
Color: render.Black,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LargeLabelFont = render.Text{
|
||||||
|
Size: 18,
|
||||||
|
FontFilename: "DejaVuSans-Bold.ttf",
|
||||||
|
Padding: 4,
|
||||||
|
Color: render.Black,
|
||||||
|
}
|
||||||
|
|
||||||
// SmallMonoFont for cramped spaces like the +/- buttons on Toolbar.
|
// SmallMonoFont for cramped spaces like the +/- buttons on Toolbar.
|
||||||
SmallMonoFont = render.Text{
|
SmallMonoFont = render.Text{
|
||||||
Size: 14,
|
Size: 14,
|
||||||
|
|
|
@ -44,6 +44,7 @@ type EditorUI struct {
|
||||||
|
|
||||||
// Popup windows.
|
// Popup windows.
|
||||||
levelSettingsWindow *ui.Window
|
levelSettingsWindow *ui.Window
|
||||||
|
doodadPropertiesWindow *ui.Window
|
||||||
aboutWindow *ui.Window
|
aboutWindow *ui.Window
|
||||||
doodadWindow *ui.Window
|
doodadWindow *ui.Window
|
||||||
paletteEditor *ui.Window
|
paletteEditor *ui.Window
|
||||||
|
|
|
@ -117,7 +117,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.MenuBar {
|
||||||
// Level menu
|
// Level menu
|
||||||
if u.Scene.DrawingType == enum.LevelDrawing {
|
if u.Scene.DrawingType == enum.LevelDrawing {
|
||||||
levelMenu := menu.AddMenu("Level")
|
levelMenu := menu.AddMenu("Level")
|
||||||
levelMenu.AddItem("Page settings", func() {
|
levelMenu.AddItem("Level Properties", func() {
|
||||||
log.Info("Opening the window")
|
log.Info("Opening the window")
|
||||||
|
|
||||||
// Open the New Level window in edit-settings mode.
|
// Open the New Level window in edit-settings mode.
|
||||||
|
@ -135,6 +135,25 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.MenuBar {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////
|
||||||
|
// 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
|
// View menu
|
||||||
if balance.Feature.Zoom {
|
if balance.Feature.Zoom {
|
||||||
|
@ -169,11 +188,6 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.MenuBar {
|
||||||
toolMenu.AddItem("Edit Palette", func() {
|
toolMenu.AddItem("Edit Palette", func() {
|
||||||
u.OpenPaletteWindow()
|
u.OpenPaletteWindow()
|
||||||
})
|
})
|
||||||
if u.Scene.DrawingType == enum.DoodadDrawing {
|
|
||||||
toolMenu.AddItem("Layers", func() {
|
|
||||||
u.OpenLayersWindow()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw Tools
|
// Draw Tools
|
||||||
toolMenu.AddItemAccel("Pencil Tool", "F", func() {
|
toolMenu.AddItemAccel("Pencil Tool", "F", func() {
|
||||||
|
|
|
@ -140,6 +140,28 @@ func (u *EditorUI) SetupPopups(d *Doodle) {
|
||||||
configure(u.levelSettingsWindow)
|
configure(u.levelSettingsWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doodad Properties
|
||||||
|
if u.doodadPropertiesWindow == nil {
|
||||||
|
scene, _ := d.Scene.(*EditorScene)
|
||||||
|
|
||||||
|
cfg := &windows.DoodadProperties{
|
||||||
|
Supervisor: u.Supervisor,
|
||||||
|
Engine: d.Engine,
|
||||||
|
EditDoodad: scene.Doodad,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild the window. TODO: hacky af.
|
||||||
|
cfg.OnRefresh = func() {
|
||||||
|
u.doodadPropertiesWindow.Hide()
|
||||||
|
u.doodadPropertiesWindow = nil
|
||||||
|
u.SetupPopups(u.d)
|
||||||
|
u.doodadPropertiesWindow.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
u.doodadPropertiesWindow = windows.NewDoodadPropertiesWindow(cfg)
|
||||||
|
configure(u.doodadPropertiesWindow)
|
||||||
|
}
|
||||||
|
|
||||||
// Publish Level (embed doodads)
|
// Publish Level (embed doodads)
|
||||||
if u.publishWindow == nil {
|
if u.publishWindow == nil {
|
||||||
scene, _ := d.Scene.(*EditorScene)
|
scene, _ := d.Scene.(*EditorScene)
|
||||||
|
|
|
@ -50,7 +50,7 @@ func NewAddEditLevel(config AddEditLevel) *ui.Window {
|
||||||
newPageType = config.EditLevel.PageType.String()
|
newPageType = config.EditLevel.PageType.String()
|
||||||
newWallpaper = config.EditLevel.Wallpaper
|
newWallpaper = config.EditLevel.Wallpaper
|
||||||
paletteName = textCurrentPalette
|
paletteName = textCurrentPalette
|
||||||
title = "Page Settings"
|
title = "Level Properties"
|
||||||
}
|
}
|
||||||
|
|
||||||
window := ui.NewWindow(title)
|
window := ui.NewWindow(title)
|
||||||
|
@ -272,7 +272,7 @@ func NewAddEditLevel(config AddEditLevel) *ui.Window {
|
||||||
|
|
||||||
if config.EditLevel != nil {
|
if config.EditLevel != nil {
|
||||||
palBtn.AddItem(paletteName, paletteName, func() {})
|
palBtn.AddItem(paletteName, paletteName, func() {})
|
||||||
palBtn.AddSeparator();
|
palBtn.AddSeparator()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, palName := range level.DefaultPaletteNames {
|
for _, palName := range level.DefaultPaletteNames {
|
||||||
|
@ -406,12 +406,12 @@ func NewAddEditLevel(config AddEditLevel) *ui.Window {
|
||||||
// If we're editing a level, did we select a new palette?
|
// If we're editing a level, did we select a new palette?
|
||||||
if paletteName != textCurrentPalette {
|
if paletteName != textCurrentPalette {
|
||||||
modal.Confirm(
|
modal.Confirm(
|
||||||
"Are you sure you want to change the level palette?\n"+
|
"Are you sure you want to change the level palette?\n" +
|
||||||
"Existing pixels drawn on your level may change, and\n"+
|
"Existing pixels drawn on your level may change, and\n" +
|
||||||
"if the new palette is smaller, some pixels may be\n"+
|
"if the new palette is smaller, some pixels may be\n" +
|
||||||
"lost from your level. OK to continue?",
|
"lost from your level. OK to continue?",
|
||||||
).WithTitle("Change Level Palette").Then(func() {
|
).WithTitle("Change Level Palette").Then(func() {
|
||||||
config.OnCancel();
|
config.OnCancel()
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
455
pkg/windows/doodad_properties.go
Normal file
455
pkg/windows/doodad_properties.go
Normal file
|
@ -0,0 +1,455 @@
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"git.kirsle.net/apps/doodle/pkg/balance"
|
||||||
|
"git.kirsle.net/apps/doodle/pkg/doodads"
|
||||||
|
"git.kirsle.net/apps/doodle/pkg/log"
|
||||||
|
"git.kirsle.net/apps/doodle/pkg/modal"
|
||||||
|
"git.kirsle.net/apps/doodle/pkg/native"
|
||||||
|
"git.kirsle.net/apps/doodle/pkg/shmem"
|
||||||
|
"git.kirsle.net/go/render"
|
||||||
|
"git.kirsle.net/go/ui"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DoodadProperties window.
|
||||||
|
type DoodadProperties struct {
|
||||||
|
// Settings passed in by doodle
|
||||||
|
Supervisor *ui.Supervisor
|
||||||
|
Engine render.Engine
|
||||||
|
|
||||||
|
// Configuration options.
|
||||||
|
EditDoodad *doodads.Doodad
|
||||||
|
ActiveTab string // specify the tab to open
|
||||||
|
OnRefresh func() // caller should rebuild the window
|
||||||
|
|
||||||
|
// Widgets.
|
||||||
|
TabFrame *ui.TabFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACKY GLOBAL VARIABLE
|
||||||
|
var showTagsOnRefreshDoodadPropertiesWindow bool
|
||||||
|
|
||||||
|
// NewSettingsWindow initializes the window.
|
||||||
|
func NewDoodadPropertiesWindow(cfg *DoodadProperties) *ui.Window {
|
||||||
|
var (
|
||||||
|
Width = 400
|
||||||
|
Height = 300
|
||||||
|
)
|
||||||
|
|
||||||
|
window := ui.NewWindow("Doodad Properties")
|
||||||
|
window.SetButtons(ui.CloseButton)
|
||||||
|
window.Configure(ui.Config{
|
||||||
|
Width: Width,
|
||||||
|
Height: Height,
|
||||||
|
Background: render.Grey,
|
||||||
|
})
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Tab Bar
|
||||||
|
tabFrame := ui.NewTabFrame("Tab Frame")
|
||||||
|
tabFrame.SetBackground(render.DarkGrey)
|
||||||
|
window.Pack(tabFrame, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
cfg.TabFrame = tabFrame
|
||||||
|
|
||||||
|
// Make the tabs.
|
||||||
|
cfg.makeMetaTab(tabFrame, Width, Height)
|
||||||
|
cfg.makeTagsTab(tabFrame, Width, Height)
|
||||||
|
|
||||||
|
if showTagsOnRefreshDoodadPropertiesWindow {
|
||||||
|
tabFrame.SetTab("Tags")
|
||||||
|
showTagsOnRefreshDoodadPropertiesWindow = false
|
||||||
|
}
|
||||||
|
|
||||||
|
tabFrame.Supervise(cfg.Supervisor)
|
||||||
|
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoodadProperties Window "Metadata" Tab
|
||||||
|
func (c DoodadProperties) makeMetaTab(tabFrame *ui.TabFrame, Width, Height int) *ui.Frame {
|
||||||
|
tab := tabFrame.AddTab("Metadata", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Metadata",
|
||||||
|
Font: balance.TabFont,
|
||||||
|
}))
|
||||||
|
tab.Resize(render.NewRect(Width-4, Height-tab.Size().H-46))
|
||||||
|
|
||||||
|
if c.EditDoodad == nil {
|
||||||
|
return tab
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Draw the editable metadata form.
|
||||||
|
for _, data := range []struct {
|
||||||
|
Label string
|
||||||
|
Variable *string
|
||||||
|
Update func(string)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Label: "Title:",
|
||||||
|
Variable: &c.EditDoodad.Title,
|
||||||
|
Update: func(v string) {
|
||||||
|
c.EditDoodad.Title = v
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "Author:",
|
||||||
|
Variable: &c.EditDoodad.Author,
|
||||||
|
Update: func(v string) {
|
||||||
|
c.EditDoodad.Author = v
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
data := data
|
||||||
|
frame := ui.NewFrame("Metadata " + data.Label + " Frame")
|
||||||
|
tab.Pack(frame, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
PadY: 4,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// The label
|
||||||
|
label := ui.NewLabel(ui.Label{
|
||||||
|
Text: data.Label,
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
})
|
||||||
|
label.Configure(ui.Config{
|
||||||
|
Width: 75,
|
||||||
|
})
|
||||||
|
frame.Pack(label, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
})
|
||||||
|
|
||||||
|
// The button.
|
||||||
|
btn := ui.NewButton(data.Label, ui.NewLabel(ui.Label{
|
||||||
|
TextVariable: data.Variable,
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
btn.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
shmem.Prompt("Enter a new "+data.Label+" ", func(answer string) {
|
||||||
|
if answer != "" {
|
||||||
|
data.Update(answer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(btn)
|
||||||
|
frame.Pack(btn, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
Expand: true,
|
||||||
|
PadX: 2,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Draw the JavaScript management
|
||||||
|
|
||||||
|
scriptHeader := ui.NewLabel(ui.Label{
|
||||||
|
Text: "Doodad Script",
|
||||||
|
Font: balance.LargeLabelFont,
|
||||||
|
})
|
||||||
|
tab.Pack(scriptHeader, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
PadY: 8,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Frame for if a script does exist on the doodad.
|
||||||
|
var (
|
||||||
|
ifScript *ui.Frame
|
||||||
|
elseScript *ui.Frame
|
||||||
|
)
|
||||||
|
|
||||||
|
// "If Script" Frame
|
||||||
|
{
|
||||||
|
ifScript = ui.NewFrame("If Script")
|
||||||
|
tab.Pack(ifScript, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
label := ui.NewLabel(ui.Label{
|
||||||
|
Text: "This Doodad has a script attached.",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
})
|
||||||
|
ifScript.Pack(label, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Delete Button
|
||||||
|
deleteBtn := ui.NewButton("Save", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Delete",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
deleteBtn.SetStyle(&balance.ButtonDanger)
|
||||||
|
deleteBtn.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
modal.Confirm("Are you sure you want to delete this script?").Then(func() {
|
||||||
|
c.EditDoodad.Script = ""
|
||||||
|
ifScript.Hide()
|
||||||
|
elseScript.Show()
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(deleteBtn)
|
||||||
|
ifScript.Pack(deleteBtn, ui.Pack{
|
||||||
|
Side: ui.E,
|
||||||
|
PadX: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Save Button
|
||||||
|
saveBtn := ui.NewButton("Save", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Save",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
saveBtn.SetStyle(&balance.ButtonPrimary)
|
||||||
|
saveBtn.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
shmem.Prompt("Save script as (*.js): ", func(answer string) {
|
||||||
|
if answer != "" {
|
||||||
|
cwd, _ := os.Getwd()
|
||||||
|
err := ioutil.WriteFile(answer, []byte(c.EditDoodad.Script), 0644)
|
||||||
|
if err != nil {
|
||||||
|
shmem.Flash(err.Error())
|
||||||
|
} else {
|
||||||
|
shmem.Flash("Written to: %s (%d bytes)", filepath.Join(cwd, answer), len(c.EditDoodad.Script))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(saveBtn)
|
||||||
|
ifScript.Pack(saveBtn, ui.Pack{
|
||||||
|
Side: ui.E,
|
||||||
|
PadX: 2,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Else Script" Frame
|
||||||
|
{
|
||||||
|
elseScript = ui.NewFrame("If Script")
|
||||||
|
tab.Pack(elseScript, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
label := ui.NewLabel(ui.Label{
|
||||||
|
Text: "There is no script attached to this doodad.",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
})
|
||||||
|
elseScript.Pack(label, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Browse Script button.
|
||||||
|
btnBrowse := ui.NewButton("Browse Script", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Attach a script...",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
btnBrowse.SetStyle(&balance.ButtonPrimary)
|
||||||
|
btnBrowse.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
filename, err := native.OpenFile("Choose a .js file", "*.js")
|
||||||
|
if err != nil {
|
||||||
|
shmem.Flash("Couldn't show file dialog: %s", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
shmem.Flash("Couldn't read file: %s", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.EditDoodad.Script = string(data)
|
||||||
|
shmem.Flash("Attached %d-byte script to this doodad.", len(c.EditDoodad.Script))
|
||||||
|
|
||||||
|
// Toggle the if/else frames.
|
||||||
|
ifScript.Show()
|
||||||
|
elseScript.Hide()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(btnBrowse)
|
||||||
|
tab.Pack(btnBrowse, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
Padding: 4,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show/hide appropriate frames.
|
||||||
|
if c.EditDoodad.Script == "" {
|
||||||
|
ifScript.Hide()
|
||||||
|
elseScript.Show()
|
||||||
|
} else {
|
||||||
|
ifScript.Show()
|
||||||
|
elseScript.Hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
return tab
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoodadProperties Window "Tags" Tab
|
||||||
|
func (c DoodadProperties) makeTagsTab(tabFrame *ui.TabFrame, Width, Height int) *ui.Frame {
|
||||||
|
tab := tabFrame.AddTab("Tags", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Tags",
|
||||||
|
Font: balance.TabFont,
|
||||||
|
}))
|
||||||
|
tab.Resize(render.NewRect(Width-4, Height-tab.Size().H-46))
|
||||||
|
|
||||||
|
if c.EditDoodad == nil {
|
||||||
|
return tab
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a table view of the current tags on this doodad.
|
||||||
|
var (
|
||||||
|
headers = []string{"Name", "Value", "Del."}
|
||||||
|
columns = []int{150, 150, 80} // TODO, Width=400
|
||||||
|
height = 24
|
||||||
|
row = ui.NewFrame("HeaderRow")
|
||||||
|
)
|
||||||
|
tab.Pack(row, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
for i, value := range headers {
|
||||||
|
cell := ui.NewLabel(ui.Label{
|
||||||
|
Text: value,
|
||||||
|
Font: balance.MenuFontBold,
|
||||||
|
})
|
||||||
|
cell.Resize(render.NewRect(columns[i], height))
|
||||||
|
row.Pack(cell, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// No tags?
|
||||||
|
if len(c.EditDoodad.Tags) == 0 {
|
||||||
|
label := ui.NewLabel(ui.Label{
|
||||||
|
Text: "There are no tags on this doodad.",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
})
|
||||||
|
tab.Pack(label, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Draw the rows for each tag.
|
||||||
|
var sortedTags []string
|
||||||
|
for name := range c.EditDoodad.Tags {
|
||||||
|
sortedTags = append(sortedTags, name)
|
||||||
|
}
|
||||||
|
sort.Strings(sortedTags)
|
||||||
|
|
||||||
|
for _, tagName := range sortedTags {
|
||||||
|
var (
|
||||||
|
name = tagName
|
||||||
|
value = c.EditDoodad.Tags[name]
|
||||||
|
)
|
||||||
|
|
||||||
|
row = ui.NewFrame("Tag Row")
|
||||||
|
tab.Pack(row, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
PadY: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
lblName := ui.NewLabel(ui.Label{
|
||||||
|
Text: name,
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
})
|
||||||
|
lblName.Resize(render.NewRect(columns[0], height))
|
||||||
|
|
||||||
|
btnValue := ui.NewButton("Tag Button", ui.NewLabel(ui.Label{
|
||||||
|
Text: value,
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
btnValue.Resize(render.NewRect(columns[1], height))
|
||||||
|
btnValue.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
shmem.Prompt("Enter new value: ", func(answer string) {
|
||||||
|
if answer == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.EditDoodad.Tags[name] = answer
|
||||||
|
btnValue.SetText(answer)
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(btnValue)
|
||||||
|
|
||||||
|
btnDelete := ui.NewButton("Delete Button", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Delete",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
btnDelete.Resize(render.NewRect(columns[2], height))
|
||||||
|
btnDelete.SetStyle(&balance.ButtonDanger)
|
||||||
|
btnDelete.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
modal.Confirm("Delete tag %s?", name).Then(func() {
|
||||||
|
log.Info("Delete tag: %s", name)
|
||||||
|
delete(c.EditDoodad.Tags, name)
|
||||||
|
|
||||||
|
// Trigger a refresh.
|
||||||
|
if c.OnRefresh != nil {
|
||||||
|
showTagsOnRefreshDoodadPropertiesWindow = true
|
||||||
|
c.OnRefresh()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(btnDelete)
|
||||||
|
|
||||||
|
// Pack the widgets.
|
||||||
|
row.Pack(lblName, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
})
|
||||||
|
row.Pack(btnValue, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
PadX: 4,
|
||||||
|
})
|
||||||
|
row.Pack(btnDelete, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Tag button.
|
||||||
|
row = ui.NewFrame("Button Frame")
|
||||||
|
tab.Pack(row, ui.Pack{
|
||||||
|
Side: ui.N,
|
||||||
|
FillX: true,
|
||||||
|
})
|
||||||
|
btnAdd := ui.NewButton("New Tag", ui.NewLabel(ui.Label{
|
||||||
|
Text: "Add Tag",
|
||||||
|
Font: balance.MenuFont,
|
||||||
|
}))
|
||||||
|
btnAdd.SetStyle(&balance.ButtonPrimary)
|
||||||
|
btnAdd.Handle(ui.Click, func(ed ui.EventData) error {
|
||||||
|
shmem.Prompt("Enter name of the new tag: ", func(answer string) {
|
||||||
|
if answer == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Adding doodad tag: %s", answer)
|
||||||
|
c.EditDoodad.Tags[answer] = ""
|
||||||
|
if c.OnRefresh != nil {
|
||||||
|
showTagsOnRefreshDoodadPropertiesWindow = true
|
||||||
|
c.OnRefresh()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
c.Supervisor.Add(btnAdd)
|
||||||
|
row.Pack(btnAdd, ui.Pack{
|
||||||
|
Side: ui.E,
|
||||||
|
})
|
||||||
|
|
||||||
|
return tab
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DoodadProperties) reloadTagFrame() {
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user