doodle/pkg/editor_ui_toolbar.go
Noah Petherbridge 0c6c77a423 Lemon-shaped Ellipse Tool (WIP)
* Add initial Ellipse Tool to the Editor Mode. Currently there's
  something wrong with the algorithm and the ellipses have a sort of
  'lemon shape' to them.
* Refactor the IterLine/IterLine2 functions to be more consistent.
  IterLine used to be the raw algorithm that took a bunch of coordinate
  numbers and IterLine2 took two render.Point's and was the main one
  used throughout the app. Now, IterLine takes the two Points and the
  raw algorithm function removed.
2019-07-14 14:18:44 -07:00

254 lines
5.6 KiB
Go

package doodle
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/drawtool"
"git.kirsle.net/apps/doodle/pkg/sprites"
)
// Width of the toolbar frame.
var toolbarWidth int32 = 44 // 38px button (32px sprite + borders) + padding
var toolbarSpriteSize int32 = 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{
Anchor: ui.N,
})
// Helper functions to toggle the correct palette panel.
var (
showSwatchPalette = func() {
u.DoodadTab.Hide()
u.PaletteTab.Show()
}
showDoodadPalette = func() {
u.PaletteTab.Hide()
u.DoodadTab.Show()
}
)
// Buttons.
var buttons = []struct {
Value string
Icon string
Click func()
}{
{
Value: drawtool.PencilTool.String(),
Icon: "assets/sprites/pencil-tool.png",
Click: func() {
u.Canvas.Tool = drawtool.PencilTool
showSwatchPalette()
d.Flash("Pencil Tool selected.")
},
},
{
Value: drawtool.LineTool.String(),
Icon: "assets/sprites/line-tool.png",
Click: func() {
u.Canvas.Tool = drawtool.LineTool
showSwatchPalette()
d.Flash("Line Tool selected.")
},
},
{
Value: drawtool.RectTool.String(),
Icon: "assets/sprites/rect-tool.png",
Click: func() {
u.Canvas.Tool = drawtool.RectTool
showSwatchPalette()
d.Flash("Rectangle Tool selected.")
},
},
{
Value: drawtool.EllipseTool.String(),
Icon: "assets/sprites/ellipse-tool.png",
Click: func() {
u.Canvas.Tool = drawtool.EllipseTool
showSwatchPalette()
d.Flash("Ellipse Tool selected.")
},
},
{
Value: drawtool.ActorTool.String(),
Icon: "assets/sprites/actor-tool.png",
Click: func() {
u.Canvas.Tool = drawtool.ActorTool
showDoodadPalette()
d.Flash("Actor Tool selected. Drag a Doodad from the drawer into your level.")
},
},
{
Value: drawtool.LinkTool.String(),
Icon: "assets/sprites/link-tool.png",
Click: func() {
u.Canvas.Tool = drawtool.LinkTool
showDoodadPalette()
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",
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
}
showSwatchPalette()
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 int32 = btn.BoxThickness(2) + toolbarSpriteSize
btn.Resize(render.NewRect(btnSize, btnSize))
btn.Handle(ui.Click, func(p render.Point) {
button.Click()
})
u.Supervisor.Add(btn)
btnFrame.Pack(btn, ui.Pack{
Anchor: ui.N,
PadY: 2,
})
}
// Spacer frame.
frame.Pack(ui.NewFrame("spacer"), ui.Pack{
Anchor: ui.N,
PadY: 8,
})
// "Brush Size" label
bsLabel := ui.NewLabel(ui.Label{
Text: "Size:",
Font: balance.LabelFont,
})
frame.Pack(bsLabel, ui.Pack{
Anchor: ui.N,
})
// Brush Size widget
{
sizeFrame := ui.NewFrame("Brush Size Frame")
frame.Pack(sizeFrame, ui.Pack{
Anchor: 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{
Anchor: ui.N,
FillX: true,
PadY: 2,
})
sizeBtnFrame := ui.NewFrame("Size Increment Button Frame")
sizeFrame.Pack(sizeBtnFrame, ui.Pack{
Anchor: 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(p render.Point) {
button.F()
})
u.Supervisor.Add(btn)
sizeBtnFrame.Pack(btn, ui.Pack{
Anchor: ui.W,
})
}
}
frame.Compute(d.Engine)
return frame
}