doodle/pkg/level/palette.go
Noah Petherbridge 190d4be1b6 Layer Selection Window for Doodad Editor
* When editing a doodad in the Editor Mode, the toolbar has a "Lyr."
  button that opens the Layers window.
* The Layers window allows switching the active doodad layer that you
  are drawing on, as well as create and rename layers.
* With this feature, Doodads may be fully drawn in-game, including
  adding alternate named layers for animations and multiple-state
  doodads.
* Update the Pager component to have a configurable MaxPageButtons.
  Controls that have more pages than this limit will stop having buttons
  drawn after the limit. The "Forward" and "Next" buttons can still
  navigate into the extra pages.
* Refactored and centralized the various popup windows in Editor Mode
  into editor_ui_popups.go; the SetupPopups() and various methods such
  as ShowPaletteWindow() and ShowDoodadDropper() make management of
  popups simple for the editor_ui!
* The Menu Bar in Editor Mode now has context-specific tools in the
  Tools menu: the Doodad Dropper for levels and Layers for doodads.
* Bugfix the Palette Editor window to work equally between Levels and
  Doodads, by only having it care about the Palette and not the Level
  that owns it.
2020-11-16 23:23:21 -08:00

136 lines
2.7 KiB
Go

package level
import (
"fmt"
"git.kirsle.net/go/render"
)
// DefaultPalette returns a sensible default palette.
func DefaultPalette() *Palette {
return &Palette{
Swatches: []*Swatch{
&Swatch{
Name: "solid",
Color: render.Black,
Solid: true,
},
&Swatch{
Name: "decoration",
Color: render.Grey,
},
&Swatch{
Name: "fire",
Color: render.Red,
Fire: true,
},
&Swatch{
Name: "water",
Color: render.RGBA(0, 0, 255, 180),
Water: true,
},
},
}
}
// 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{
Swatches: []*Swatch{},
byName: map[string]int{},
}
}
// Palette holds an index of colors used in a drawing.
type Palette struct {
Swatches []*Swatch `json:"swatches"`
// Private runtime values
ActiveSwatch *Swatch `json:"-"` // name of the actively selected color
byName map[string]int // Cache map of swatches by name
}
// Inflate the palette swatch caches. Always call this method after you have
// initialized the palette (i.e. loaded it from JSON); this will update the
// "color by name" cache and assign the index numbers to each swatch.
func (p *Palette) Inflate() {
p.update()
}
// AddSwatch adds a new swatch to the palette.
func (p *Palette) AddSwatch() *Swatch {
p.update()
var (
index = len(p.Swatches)
name = fmt.Sprintf("color %d", len(p.Swatches))
)
p.Swatches = append(p.Swatches, &Swatch{
Name: name,
Color: render.Magenta,
index: index,
})
p.byName[name] = index
return p.Swatches[index]
}
// Get a swatch by name.
func (p *Palette) Get(name string) (result *Swatch, exists bool) {
p.update()
if index, ok := p.byName[name]; ok && index < len(p.Swatches) {
result = p.Swatches[index]
exists = true
}
return
}
// update the internal caches and such.
func (p *Palette) update() {
// Initialize the name cache if nil or if the size disagrees with the
// length of the swatches available.
if p.byName == nil || len(p.byName) != len(p.Swatches) {
// Initialize the name cache.
p.byName = map[string]int{}
for i, swatch := range p.Swatches {
swatch.index = i
p.byName[swatch.Name] = i
}
}
}