doodle/pkg/editor_ui_toolbar.go

258 lines
5.8 KiB
Go
Raw Normal View History

package doodle
import (
"git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/drawtool"
"git.kirsle.net/apps/doodle/pkg/sprites"
"git.kirsle.net/go/render"
"git.kirsle.net/go/ui"
)
// Width of the toolbar frame.
var toolbarWidth = 44 // 38px button (32px sprite + borders) + padding
var toolbarSpriteSize = 32 // 32x32 sprites.
// SetupToolbar configures the UI for the Tools panel.
func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
frame := ui.NewFrame("Tool Bar")
frame.Resize(render.NewRect(toolbarWidth, 100))
frame.Configure(ui.Config{
BorderSize: 2,
BorderStyle: ui.BorderRaised,
Background: render.Grey,
})
btnFrame := ui.NewFrame("Tool Buttons")
frame.Pack(btnFrame, ui.Pack{
Side: ui.N,
})
// Buttons.
var buttons = []struct {
Value string
Icon string
Tooltip string
Click func()
}{
{
Value: drawtool.PencilTool.String(),
Icon: "assets/sprites/pencil-tool.png",
Tooltip: "Pencil Tool",
Click: func() {
u.Canvas.Tool = drawtool.PencilTool
d.Flash("Pencil Tool selected.")
},
},
{
Value: drawtool.LineTool.String(),
Icon: "assets/sprites/line-tool.png",
Tooltip: "Line Tool",
Click: func() {
u.Canvas.Tool = drawtool.LineTool
d.Flash("Line Tool selected.")
},
},
{
Value: drawtool.RectTool.String(),
Icon: "assets/sprites/rect-tool.png",
Tooltip: "Rectangle Tool",
Click: func() {
u.Canvas.Tool = drawtool.RectTool
d.Flash("Rectangle Tool selected.")
},
},
{
Value: drawtool.EllipseTool.String(),
Icon: "assets/sprites/ellipse-tool.png",
Tooltip: "Ellipse Tool",
Click: func() {
u.Canvas.Tool = drawtool.EllipseTool
d.Flash("Ellipse Tool selected.")
},
},
{
Value: drawtool.ActorTool.String(),
Icon: "assets/sprites/actor-tool.png",
Tooltip: "Doodad Tool\nDrag-and-drop objects into your map",
Click: func() {
u.Canvas.Tool = drawtool.ActorTool
u.doodadWindow.Show()
d.Flash("Actor Tool selected. Drag a Doodad from the drawer into your level.")
},
},
{
Value: drawtool.LinkTool.String(),
Icon: "assets/sprites/link-tool.png",
Tooltip: "Link Tool\nConnect doodads to each other",
Click: func() {
u.Canvas.Tool = drawtool.LinkTool
u.doodadWindow.Show()
d.Flash("Link Tool selected. Click a doodad in your level to link it to another.")
},
},
{
Value: drawtool.EraserTool.String(),
Icon: "assets/sprites/eraser-tool.png",
Tooltip: "Eraser Tool",
Click: func() {
u.Canvas.Tool = drawtool.EraserTool
// Set the brush size within range for the eraser.
if u.Canvas.BrushSize < balance.DefaultEraserBrushSize {
u.Canvas.BrushSize = balance.DefaultEraserBrushSize
} else if u.Canvas.BrushSize > balance.MaxEraserBrushSize {
u.Canvas.BrushSize = balance.MaxEraserBrushSize
}
d.Flash("Eraser Tool selected.")
},
},
}
for _, button := range buttons {
button := button
image, err := sprites.LoadImage(d.Engine, button.Icon)
if err != nil {
panic(err)
}
btn := ui.NewRadioButton(
button.Value,
&u.activeTool,
button.Value,
image,
)
var btnSize = btn.BoxThickness(2) + toolbarSpriteSize
btn.Resize(render.NewRect(btnSize, btnSize))
btn.Handle(ui.Click, func(ed ui.EventData) error {
button.Click()
return nil
})
u.Supervisor.Add(btn)
ui.NewTooltip(btn, ui.Tooltip{
Text: button.Tooltip,
Edge: ui.Right,
})
btnFrame.Pack(btn, ui.Pack{
Side: ui.N,
PadY: 2,
})
}
// Spacer frame.
frame.Pack(ui.NewFrame("spacer"), ui.Pack{
Side: ui.N,
PadY: 8,
})
// "Brush Size" label
bsLabel := ui.NewLabel(ui.Label{
Text: "Size:",
Font: balance.LabelFont,
})
frame.Pack(bsLabel, ui.Pack{
Side: ui.N,
})
ui.NewTooltip(bsLabel, ui.Tooltip{
Text: "Set the line thickness for drawing",
Edge: ui.Right,
})
u.Supervisor.Add(bsLabel)
// Brush Size widget
{
sizeFrame := ui.NewFrame("Brush Size Frame")
frame.Pack(sizeFrame, ui.Pack{
Side: ui.N,
PadY: 0,
})
sizeLabel := ui.NewLabel(ui.Label{
IntVariable: &u.Canvas.BrushSize,
Font: balance.SmallMonoFont,
})
sizeLabel.Configure(ui.Config{
BorderSize: 1,
BorderStyle: ui.BorderSunken,
Background: render.Grey,
})
sizeFrame.Pack(sizeLabel, ui.Pack{
Side: ui.N,
FillX: true,
PadY: 2,
})
sizeBtnFrame := ui.NewFrame("Size Increment Button Frame")
sizeFrame.Pack(sizeBtnFrame, ui.Pack{
Side: ui.N,
FillX: true,
})
var incButtons = []struct {
Label string
F func()
}{
{
Label: "-",
F: func() {
// Select next smaller brush size.
for i := len(balance.BrushSizeOptions) - 1; i >= 0; i-- {
if balance.BrushSizeOptions[i] < u.Canvas.BrushSize {
u.Canvas.BrushSize = balance.BrushSizeOptions[i]
break
}
}
},
},
{
Label: "+",
F: func() {
// Select next bigger brush size.
for _, size := range balance.BrushSizeOptions {
if size > u.Canvas.BrushSize {
u.Canvas.BrushSize = size
break
}
}
// Limit the eraser brush size, too big and it's slow because
// the eraser has to scan and remember pixels to be able to
// Undo the erase and restore them.
if u.Canvas.Tool == drawtool.EraserTool && u.Canvas.BrushSize > balance.MaxEraserBrushSize {
u.Canvas.BrushSize = balance.MaxEraserBrushSize
}
},
},
}
for _, button := range incButtons {
button := button
btn := ui.NewButton("BrushSize"+button.Label, ui.NewLabel(ui.Label{
Text: button.Label,
Font: balance.SmallMonoFont,
}))
btn.Handle(ui.Click, func(ed ui.EventData) error {
button.F()
return nil
})
u.Supervisor.Add(btn)
sizeBtnFrame.Pack(btn, ui.Pack{
Side: ui.W,
})
}
}
frame.Compute(d.Engine)
return frame
}