Blueprint Theme Palette
* Fix the EditorUI not showing the correct palette baked into the level and only showing the default. This was tricky because the palette UI can only be configured at setup time but not updated later. * Add a new default palette for the Blueprint theme. Blueprint has a dark background, so the palette colors should be bright. This palette is chosen when you start a map with the blueprint wallpaper. * Add a background Canvas to the MenuScene. In the "New Level" screen, the background canvas will update to show the wallpaper settings you've chosen as a preview of the level theme you're about to create.
This commit is contained in:
parent
7281fcbf91
commit
3d3561b8e6
|
@ -32,7 +32,7 @@ var (
|
|||
DebugCanvasLabel = false // Tag the canvas with a label.
|
||||
|
||||
// Pretty-print JSON files when writing.
|
||||
JSONIndent = false
|
||||
JSONIndent = true
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -117,6 +117,9 @@ func (s *EditorScene) Setup(d *Doodle) error {
|
|||
s.UI.Workspace.Compute(d.Engine)
|
||||
}
|
||||
|
||||
// Recompute the UI Palette window for the level's palette.
|
||||
s.UI.FinishSetup(d)
|
||||
|
||||
d.Flash("Editor Mode. Press 'P' to play this map.")
|
||||
|
||||
return nil
|
||||
|
|
|
@ -76,11 +76,8 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI {
|
|||
u.Canvas = u.SetupCanvas(d)
|
||||
u.MenuBar = u.SetupMenuBar(d)
|
||||
u.StatusBar = u.SetupStatusBar(d)
|
||||
u.Palette = u.SetupPalette(d)
|
||||
u.Workspace = u.SetupWorkspace(d) // important that this is last!
|
||||
|
||||
u.Resized(d)
|
||||
|
||||
// Position the Canvas inside the frame.
|
||||
u.Workspace.Pack(u.Canvas, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
|
@ -95,6 +92,14 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI {
|
|||
return u
|
||||
}
|
||||
|
||||
// FinishSetup runs the Setup tasks that must be postponed til the end, such
|
||||
// as rendering the Palette window so that it can accurately show the palette
|
||||
// loaded from a level.
|
||||
func (u *EditorUI) FinishSetup(d *Doodle) {
|
||||
u.Palette = u.SetupPalette(d)
|
||||
u.Resized(d)
|
||||
}
|
||||
|
||||
// Resized handles the window being resized so we can recompute the widgets.
|
||||
func (u *EditorUI) Resized(d *Doodle) {
|
||||
// Menu Bar frame.
|
||||
|
@ -442,84 +447,6 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame {
|
|||
return frame
|
||||
}
|
||||
|
||||
// SetupPalette sets up the palette panel.
|
||||
func (u *EditorUI) SetupPalette(d *Doodle) *ui.Window {
|
||||
window := ui.NewWindow("Palette")
|
||||
window.ConfigureTitle(balance.TitleConfig)
|
||||
window.TitleBar().Font = balance.TitleFont
|
||||
window.Configure(ui.Config{
|
||||
Background: balance.WindowBackground,
|
||||
BorderColor: balance.WindowBorder,
|
||||
})
|
||||
|
||||
// Frame that holds the tab buttons in Level Edit mode.
|
||||
tabFrame := ui.NewFrame("Palette Tabs")
|
||||
for _, name := range []string{"Palette", "Doodads"} {
|
||||
if u.paletteTab == "" {
|
||||
u.paletteTab = name
|
||||
}
|
||||
|
||||
tab := ui.NewRadioButton("Palette Tab", &u.paletteTab, name, ui.NewLabel(ui.Label{
|
||||
Text: name,
|
||||
}))
|
||||
tab.Handle(ui.Click, func(p render.Point) {
|
||||
if u.paletteTab == "Palette" {
|
||||
u.Canvas.Tool = uix.PencilTool
|
||||
u.PaletteTab.Show()
|
||||
u.DoodadTab.Hide()
|
||||
} else {
|
||||
u.Canvas.Tool = uix.ActorTool
|
||||
u.PaletteTab.Hide()
|
||||
u.DoodadTab.Show()
|
||||
}
|
||||
window.Compute(d.Engine)
|
||||
})
|
||||
u.Supervisor.Add(tab)
|
||||
tabFrame.Pack(tab, ui.Pack{
|
||||
Anchor: ui.W,
|
||||
Fill: true,
|
||||
Expand: true,
|
||||
})
|
||||
}
|
||||
window.Pack(tabFrame, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
Fill: true,
|
||||
PadY: 4,
|
||||
})
|
||||
|
||||
// Only show the tab frame in Level drawing mode!
|
||||
if u.Scene.DrawingType != enum.LevelDrawing {
|
||||
tabFrame.Hide()
|
||||
}
|
||||
|
||||
// Doodad frame.
|
||||
{
|
||||
frame, err := u.setupDoodadFrame(d.Engine, window)
|
||||
if err != nil {
|
||||
d.Flash(err.Error())
|
||||
}
|
||||
|
||||
// Even if there was an error (userdir.ListDoodads couldn't read the
|
||||
// config folder on disk or whatever) the Frame is still valid but
|
||||
// empty, which is still the intended behavior.
|
||||
u.DoodadTab = frame
|
||||
u.DoodadTab.Hide()
|
||||
window.Pack(u.DoodadTab, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
Fill: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Color Palette Frame.
|
||||
u.PaletteTab = u.setupPaletteFrame(window)
|
||||
window.Pack(u.PaletteTab, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
Fill: true,
|
||||
})
|
||||
|
||||
return window
|
||||
}
|
||||
|
||||
// SetupStatusBar sets up the status bar widget along the bottom of the window.
|
||||
func (u *EditorUI) SetupStatusBar(d *Doodle) *ui.Frame {
|
||||
frame := ui.NewFrame("Status Bar")
|
||||
|
|
|
@ -4,9 +4,89 @@ import (
|
|||
"git.kirsle.net/apps/doodle/lib/render"
|
||||
"git.kirsle.net/apps/doodle/lib/ui"
|
||||
"git.kirsle.net/apps/doodle/pkg/balance"
|
||||
"git.kirsle.net/apps/doodle/pkg/enum"
|
||||
"git.kirsle.net/apps/doodle/pkg/log"
|
||||
"git.kirsle.net/apps/doodle/pkg/uix"
|
||||
)
|
||||
|
||||
// SetupPalette sets up the palette panel.
|
||||
func (u *EditorUI) SetupPalette(d *Doodle) *ui.Window {
|
||||
window := ui.NewWindow("Palette")
|
||||
window.ConfigureTitle(balance.TitleConfig)
|
||||
window.TitleBar().Font = balance.TitleFont
|
||||
window.Configure(ui.Config{
|
||||
Background: balance.WindowBackground,
|
||||
BorderColor: balance.WindowBorder,
|
||||
})
|
||||
|
||||
// Frame that holds the tab buttons in Level Edit mode.
|
||||
tabFrame := ui.NewFrame("Palette Tabs")
|
||||
for _, name := range []string{"Palette", "Doodads"} {
|
||||
if u.paletteTab == "" {
|
||||
u.paletteTab = name
|
||||
}
|
||||
|
||||
tab := ui.NewRadioButton("Palette Tab", &u.paletteTab, name, ui.NewLabel(ui.Label{
|
||||
Text: name,
|
||||
}))
|
||||
tab.Handle(ui.Click, func(p render.Point) {
|
||||
if u.paletteTab == "Palette" {
|
||||
u.Canvas.Tool = uix.PencilTool
|
||||
u.PaletteTab.Show()
|
||||
u.DoodadTab.Hide()
|
||||
} else {
|
||||
u.Canvas.Tool = uix.ActorTool
|
||||
u.PaletteTab.Hide()
|
||||
u.DoodadTab.Show()
|
||||
}
|
||||
window.Compute(d.Engine)
|
||||
})
|
||||
u.Supervisor.Add(tab)
|
||||
tabFrame.Pack(tab, ui.Pack{
|
||||
Anchor: ui.W,
|
||||
Fill: true,
|
||||
Expand: true,
|
||||
})
|
||||
}
|
||||
window.Pack(tabFrame, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
Fill: true,
|
||||
PadY: 4,
|
||||
})
|
||||
|
||||
// Only show the tab frame in Level drawing mode!
|
||||
if u.Scene.DrawingType != enum.LevelDrawing {
|
||||
tabFrame.Hide()
|
||||
}
|
||||
|
||||
// Doodad frame.
|
||||
{
|
||||
frame, err := u.setupDoodadFrame(d.Engine, window)
|
||||
if err != nil {
|
||||
d.Flash(err.Error())
|
||||
}
|
||||
|
||||
// Even if there was an error (userdir.ListDoodads couldn't read the
|
||||
// config folder on disk or whatever) the Frame is still valid but
|
||||
// empty, which is still the intended behavior.
|
||||
u.DoodadTab = frame
|
||||
u.DoodadTab.Hide()
|
||||
window.Pack(u.DoodadTab, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
Fill: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Color Palette Frame.
|
||||
u.PaletteTab = u.setupPaletteFrame(window)
|
||||
window.Pack(u.PaletteTab, ui.Pack{
|
||||
Anchor: ui.N,
|
||||
Fill: true,
|
||||
})
|
||||
|
||||
return window
|
||||
}
|
||||
|
||||
// setupPaletteFrame configures the Color Palette tab for Edit Mode.
|
||||
// This is a subroutine of editor_ui.go#SetupPalette()
|
||||
func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame {
|
||||
|
@ -32,7 +112,7 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame {
|
|||
Text: swatch.Name,
|
||||
Font: balance.StatusFont,
|
||||
})
|
||||
label.Font.Color = swatch.Color.Darken(40)
|
||||
label.Font.Color = swatch.Color.Darken(128)
|
||||
|
||||
btn := ui.NewRadioButton("palette", &u.selectedSwatch, swatch.Name, label)
|
||||
btn.Handle(ui.Click, onClick)
|
||||
|
|
|
@ -29,6 +29,38 @@ func DefaultPalette() *Palette {
|
|||
}
|
||||
}
|
||||
|
||||
// NewBlueprintPalette returns the blueprint theme's color palette.
|
||||
func NewBlueprintPalette() *Palette {
|
||||
return &Palette{
|
||||
Swatches: []*Swatch{
|
||||
&Swatch{
|
||||
Name: "solid",
|
||||
Color: render.RGBA(254, 254, 254, 255),
|
||||
Solid: true,
|
||||
},
|
||||
&Swatch{
|
||||
Name: "decoration",
|
||||
Color: render.Grey,
|
||||
},
|
||||
&Swatch{
|
||||
Name: "fire",
|
||||
Color: render.RGBA(255, 80, 0, 255),
|
||||
Fire: true,
|
||||
},
|
||||
&Swatch{
|
||||
Name: "water",
|
||||
Color: render.RGBA(0, 153, 255, 255),
|
||||
Water: true,
|
||||
},
|
||||
&Swatch{
|
||||
Name: "electric",
|
||||
Color: render.RGBA(255, 255, 0, 255),
|
||||
Solid: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewPalette initializes a blank palette.
|
||||
func NewPalette() *Palette {
|
||||
return &Palette{
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"git.kirsle.net/apps/doodle/pkg/enum"
|
||||
"git.kirsle.net/apps/doodle/pkg/level"
|
||||
"git.kirsle.net/apps/doodle/pkg/log"
|
||||
"git.kirsle.net/apps/doodle/pkg/uix"
|
||||
"git.kirsle.net/apps/doodle/pkg/userdir"
|
||||
)
|
||||
|
||||
|
@ -29,6 +30,9 @@ type MenuScene struct {
|
|||
// Private widgets.
|
||||
window *ui.Window
|
||||
|
||||
// Background wallpaper canvas.
|
||||
canvas *uix.Canvas
|
||||
|
||||
// Values for the New menu
|
||||
newPageType string
|
||||
newWallpaper string
|
||||
|
@ -61,6 +65,19 @@ func (d *Doodle) GotoLoadMenu() {
|
|||
func (s *MenuScene) Setup(d *Doodle) error {
|
||||
s.Supervisor = ui.NewSupervisor()
|
||||
|
||||
// Set up the background wallpaper canvas.
|
||||
s.canvas = uix.NewCanvas(100, false)
|
||||
s.canvas.Resize(render.Rect{
|
||||
W: int32(d.width),
|
||||
H: int32(d.height),
|
||||
})
|
||||
s.canvas.LoadLevel(d.Engine, &level.Level{
|
||||
Chunker: level.NewChunker(100),
|
||||
Palette: level.NewPalette(),
|
||||
PageType: level.Bounded,
|
||||
Wallpaper: "notebook.png",
|
||||
})
|
||||
|
||||
switch s.StartupMenu {
|
||||
case "new":
|
||||
if err := s.setupNewWindow(d); err != nil {
|
||||
|
@ -77,6 +94,17 @@ func (s *MenuScene) Setup(d *Doodle) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// configureCanvas updates the settings of the background canvas, so a live
|
||||
// preview of the wallpaper and wrapping type can be shown.
|
||||
func (s *MenuScene) configureCanvas(e render.Engine, pageType level.PageType, wallpaper string) {
|
||||
s.canvas.LoadLevel(e, &level.Level{
|
||||
Chunker: level.NewChunker(100),
|
||||
Palette: level.NewPalette(),
|
||||
PageType: pageType,
|
||||
Wallpaper: wallpaper,
|
||||
})
|
||||
}
|
||||
|
||||
// setupNewWindow sets up the UI for the "New" window.
|
||||
func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
||||
// Default scene options.
|
||||
|
@ -85,8 +113,8 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|||
|
||||
window := ui.NewWindow("New Drawing")
|
||||
window.Configure(ui.Config{
|
||||
Width: int32(float64(d.width) * 0.8),
|
||||
Height: int32(float64(d.height) * 0.8),
|
||||
Width: int32(float64(d.width) * 0.75),
|
||||
Height: int32(float64(d.height) * 0.75),
|
||||
Background: render.Grey,
|
||||
})
|
||||
window.Compute(d.Engine)
|
||||
|
@ -118,10 +146,11 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|||
FillX: true,
|
||||
})
|
||||
|
||||
var types = []struct {
|
||||
type typeObj struct {
|
||||
Name string
|
||||
Value level.PageType
|
||||
}{
|
||||
}
|
||||
var types = []typeObj{
|
||||
{"Unbounded", level.Unbounded},
|
||||
{"Bounded", level.Bounded},
|
||||
{"No Negative Space", level.NoNegativeSpace},
|
||||
|
@ -135,19 +164,24 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|||
}
|
||||
}
|
||||
|
||||
radio := ui.NewRadioButton(t.Name,
|
||||
&s.newPageType,
|
||||
t.Value.String(),
|
||||
ui.NewLabel(ui.Label{
|
||||
Text: t.Name,
|
||||
Font: balance.MenuFont,
|
||||
}),
|
||||
)
|
||||
s.Supervisor.Add(radio)
|
||||
typeFrame.Pack(radio, ui.Pack{
|
||||
Anchor: ui.W,
|
||||
PadX: 4,
|
||||
})
|
||||
func(t typeObj) {
|
||||
radio := ui.NewRadioButton(t.Name,
|
||||
&s.newPageType,
|
||||
t.Value.String(),
|
||||
ui.NewLabel(ui.Label{
|
||||
Text: t.Name,
|
||||
Font: balance.MenuFont,
|
||||
}),
|
||||
)
|
||||
radio.Handle(ui.Click, func(p render.Point) {
|
||||
s.configureCanvas(d.Engine, t.Value, s.newWallpaper)
|
||||
})
|
||||
s.Supervisor.Add(radio)
|
||||
typeFrame.Pack(radio, ui.Pack{
|
||||
Anchor: ui.W,
|
||||
PadX: 4,
|
||||
})
|
||||
}(t)
|
||||
}
|
||||
|
||||
/******************
|
||||
|
@ -169,25 +203,34 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|||
FillX: true,
|
||||
})
|
||||
|
||||
var wallpapers = []struct {
|
||||
type wallpaperObj struct {
|
||||
Name string
|
||||
Value string
|
||||
}{
|
||||
}
|
||||
var wallpapers = []wallpaperObj{
|
||||
{"Notebook", "notebook.png"},
|
||||
{"Blueprint", "blueprint.png"},
|
||||
{"Legal Pad", "legal.png"},
|
||||
{"Placemat", "placemat.png"},
|
||||
}
|
||||
for _, t := range wallpapers {
|
||||
radio := ui.NewRadioButton(t.Name, &s.newWallpaper, t.Value, ui.NewLabel(ui.Label{
|
||||
Text: t.Name,
|
||||
Font: balance.MenuFont,
|
||||
}))
|
||||
s.Supervisor.Add(radio)
|
||||
wpFrame.Pack(radio, ui.Pack{
|
||||
Anchor: ui.W,
|
||||
PadX: 4,
|
||||
})
|
||||
func(t wallpaperObj) {
|
||||
radio := ui.NewRadioButton(t.Name, &s.newWallpaper, t.Value, ui.NewLabel(ui.Label{
|
||||
Text: t.Name,
|
||||
Font: balance.MenuFont,
|
||||
}))
|
||||
radio.Handle(ui.Click, func(p render.Point) {
|
||||
log.Info("Set wallpaper to %s", t.Value)
|
||||
if pageType, ok := level.PageTypeFromString(s.newPageType); ok {
|
||||
s.configureCanvas(d.Engine, pageType, t.Value)
|
||||
}
|
||||
})
|
||||
s.Supervisor.Add(radio)
|
||||
wpFrame.Pack(radio, ui.Pack{
|
||||
Anchor: ui.W,
|
||||
PadX: 4,
|
||||
})
|
||||
}(t)
|
||||
}
|
||||
|
||||
/******************
|
||||
|
@ -224,6 +267,11 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|||
lvl.Wallpaper = s.newWallpaper
|
||||
lvl.PageType = pageType
|
||||
|
||||
// Blueprint theme palette for the dark wallpaper color.
|
||||
if lvl.Wallpaper == "blueprint.png" {
|
||||
lvl.Palette = level.NewBlueprintPalette()
|
||||
}
|
||||
|
||||
d.Goto(&EditorScene{
|
||||
DrawingType: enum.LevelDrawing,
|
||||
Level: lvl,
|
||||
|
@ -257,8 +305,8 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|||
func (s *MenuScene) setupLoadWindow(d *Doodle) error {
|
||||
window := ui.NewWindow("Open Drawing")
|
||||
window.Configure(ui.Config{
|
||||
Width: int32(float64(d.width) * 0.8),
|
||||
Height: int32(float64(d.height) * 0.8),
|
||||
Width: int32(float64(d.width) * 0.75),
|
||||
Height: int32(float64(d.height) * 0.75),
|
||||
Background: render.Grey,
|
||||
})
|
||||
window.Compute(d.Engine)
|
||||
|
@ -424,6 +472,9 @@ func (s *MenuScene) Draw(d *Doodle) error {
|
|||
// Clear the canvas and fill it with white.
|
||||
d.Engine.Clear(render.White)
|
||||
|
||||
// Draw the background canvas.
|
||||
s.canvas.Present(d.Engine, render.Origin)
|
||||
|
||||
s.window.Compute(d.Engine)
|
||||
s.window.MoveTo(render.Point{
|
||||
X: (int32(d.width) / 2) - (s.window.Size().W / 2),
|
||||
|
|
Loading…
Reference in New Issue
Block a user