Tooltips Update

* Update code for recent changes in UI toolkit around event handlers for
  buttons.
* Add tooltips to various buttons in the Editor Mode. The left toolbar
  shows the names of each tool, the Doodad Palette shows the title of
  each doodad and the Color Palette shows the swatch attributes (solid,
  fire, water, etc.)
physics
Noah 2020-03-09 22:22:22 -07:00
parent 7142c76b86
commit f8ca9a0921
9 changed files with 112 additions and 50 deletions

29
pkg/balance/runtime.go Normal file
View File

@ -0,0 +1,29 @@
package balance
import "runtime"
// Runtime environment settings.
var Runtime rtc
type rtc struct {
Platform platform
Arch string
}
// Platform type the app was built for.
type platform string
// Runtime.Platform constants.
const (
Linux platform = "linux"
Windows platform = "windows"
Darwin platform = "darwin"
Web platform = "web"
)
func init() {
Runtime = rtc{
Platform: platform(runtime.GOOS),
Arch: runtime.GOARCH,
}
}

View File

@ -98,7 +98,7 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI {
Text: "Play (P)", Text: "Play (P)",
Font: balance.PlayButtonFont, Font: balance.PlayButtonFont,
})) }))
u.PlayButton.Handle(ui.Click, func(p render.Point) { u.PlayButton.Handle(ui.Click, func(ed ui.EventData) {
u.Scene.Playtest() u.Scene.Playtest()
}) })
u.Supervisor.Add(u.PlayButton) u.Supervisor.Add(u.PlayButton)
@ -276,6 +276,10 @@ func (u *EditorUI) Loop(ev *event.State) error {
// Present the UI to the screen. // Present the UI to the screen.
func (u *EditorUI) Present(e render.Engine) { func (u *EditorUI) Present(e render.Engine) {
// Draw the workspace canvas first. Rationale: we want it to have the lowest
// Z-index so Tooltips can pop on top of the workspace.
u.Workspace.Present(e, u.Workspace.Point())
// TODO: if I don't Compute() the palette window, then, whenever the dev console // TODO: if I don't Compute() the palette window, then, whenever the dev console
// is open the window will blank out its contents leaving only the outermost Frame. // is open the window will blank out its contents leaving only the outermost Frame.
// The title bar and borders are gone. But other UI widgets don't do this. // The title bar and borders are gone. But other UI widgets don't do this.
@ -286,7 +290,6 @@ func (u *EditorUI) Present(e render.Engine) {
u.MenuBar.Present(e, u.MenuBar.Point()) u.MenuBar.Present(e, u.MenuBar.Point())
u.StatusBar.Present(e, u.StatusBar.Point()) u.StatusBar.Present(e, u.StatusBar.Point())
u.ToolBar.Present(e, u.ToolBar.Point()) u.ToolBar.Present(e, u.ToolBar.Point())
u.Workspace.Present(e, u.Workspace.Point())
u.PlayButton.Present(e, u.PlayButton.Point()) u.PlayButton.Present(e, u.PlayButton.Point())
// Are we dragging a Doodad canvas? // Are we dragging a Doodad canvas?
@ -351,7 +354,7 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas {
// Set up the drop handler for draggable doodads. // Set up the drop handler for draggable doodads.
// NOTE: The drag event begins at editor_ui_doodad.go when configuring the // NOTE: The drag event begins at editor_ui_doodad.go when configuring the
// Doodad Palette buttons. // Doodad Palette buttons.
drawing.Handle(ui.Drop, func(e render.Point) { drawing.Handle(ui.Drop, func(ed ui.EventData) {
log.Info("Drawing canvas has received a drop!") log.Info("Drawing canvas has received a drop!")
var P = ui.AbsolutePosition(drawing) var P = ui.AbsolutePosition(drawing)
@ -436,18 +439,18 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame {
type menuButton struct { type menuButton struct {
Text string Text string
Click func(render.Point) Click func(ui.EventData)
} }
buttons := []menuButton{ buttons := []menuButton{
menuButton{ menuButton{
Text: "New Level", Text: "New Level",
Click: func(render.Point) { Click: func(ed ui.EventData) {
d.GotoNewMenu() d.GotoNewMenu()
}, },
}, },
menuButton{ menuButton{
Text: "New Doodad", Text: "New Doodad",
Click: func(render.Point) { Click: func(ed ui.EventData) {
d.Prompt("Doodad size [100]>", func(answer string) { d.Prompt("Doodad size [100]>", func(answer string) {
size := balance.DoodadSize size := balance.DoodadSize
if answer != "" { if answer != "" {
@ -464,7 +467,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame {
}, },
menuButton{ menuButton{
Text: "Save", Text: "Save",
Click: func(render.Point) { Click: func(ed ui.EventData) {
if u.Scene.filename != "" { if u.Scene.filename != "" {
saveFunc(u.Scene.filename) saveFunc(u.Scene.filename)
} else { } else {
@ -478,7 +481,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame {
}, },
menuButton{ menuButton{
Text: "Save as...", Text: "Save as...",
Click: func(render.Point) { Click: func(ed ui.EventData) {
d.Prompt("Save as filename>", func(answer string) { d.Prompt("Save as filename>", func(answer string) {
if answer != "" { if answer != "" {
saveFunc(answer) saveFunc(answer)
@ -488,7 +491,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame {
}, },
menuButton{ menuButton{
Text: "Load", Text: "Load",
Click: func(render.Point) { Click: func(ed ui.EventData) {
d.GotoLoadMenu() d.GotoLoadMenu()
}, },
}, },

View File

@ -77,7 +77,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
Text: "<", Text: "<",
Font: balance.MenuFont, Font: balance.MenuFont,
})) }))
leftBtn.Handle(ui.Click, func(p render.Point) { leftBtn.Handle(ui.Click, func(ed ui.EventData) {
u.scrollDoodadFrame(-1) u.scrollDoodadFrame(-1)
}) })
u.Supervisor.Add(leftBtn) u.Supervisor.Add(leftBtn)
@ -100,7 +100,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
Text: ">", Text: ">",
Font: balance.MenuFont, Font: balance.MenuFont,
})) }))
rightBtn.Handle(ui.Click, func(p render.Point) { rightBtn.Handle(ui.Click, func(ed ui.EventData) {
u.scrollDoodadFrame(1) u.scrollDoodadFrame(1)
}) })
u.Supervisor.Add(rightBtn) u.Supervisor.Add(rightBtn)
@ -179,10 +179,16 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
Side: ui.W, Side: ui.W,
}) })
// Tooltip hover to show the doodad's name.
ui.NewTooltip(btn, ui.Tooltip{
Text: doodad.Title,
Edge: ui.Top,
})
// Begin the drag event to grab this Doodad. // Begin the drag event to grab this Doodad.
// NOTE: The drag target is the EditorUI.Canvas in // NOTE: The drag target is the EditorUI.Canvas in
// editor_ui.go#SetupCanvas() // editor_ui.go#SetupCanvas()
btn.Handle(ui.MouseDown, func(e render.Point) { btn.Handle(ui.MouseDown, func(ed ui.EventData) {
log.Warn("MouseDown on doodad %s (%s)", doodad.Filename, doodad.Title) log.Warn("MouseDown on doodad %s (%s)", doodad.Filename, doodad.Title)
u.startDragActor(doodad, nil) u.startDragActor(doodad, nil)
}) })

View File

@ -5,7 +5,6 @@ import (
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/go/render"
"git.kirsle.net/go/ui" "git.kirsle.net/go/ui"
) )
@ -54,7 +53,7 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame {
frame.SetBackground(balance.WindowBackground) frame.SetBackground(balance.WindowBackground)
// Handler function for the radio buttons being clicked. // Handler function for the radio buttons being clicked.
onClick := func(p render.Point) { onClick := func(ed ui.EventData) {
name := u.selectedSwatch name := u.selectedSwatch
swatch, ok := u.Canvas.Palette.Get(name) swatch, ok := u.Canvas.Palette.Get(name)
if !ok { if !ok {
@ -95,6 +94,12 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame {
btn.Handle(ui.Click, onClick) btn.Handle(ui.Click, onClick)
u.Supervisor.Add(btn) u.Supervisor.Add(btn)
// Add a tooltip showing the swatch attributes.
ui.NewTooltip(btn, ui.Tooltip{
Text: "Attributes: " + swatch.Attributes(),
Edge: ui.Left,
})
btn.Compute(u.d.Engine) btn.Compute(u.d.Engine)
swFrame.Configure(ui.Config{ swFrame.Configure(ui.Config{
Height: label.Size().H, Height: label.Size().H,

View File

@ -41,13 +41,15 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
// Buttons. // Buttons.
var buttons = []struct { var buttons = []struct {
Value string Value string
Icon string Icon string
Click func() Tooltip string
Click func()
}{ }{
{ {
Value: drawtool.PencilTool.String(), Value: drawtool.PencilTool.String(),
Icon: "assets/sprites/pencil-tool.png", Icon: "assets/sprites/pencil-tool.png",
Tooltip: "Pencil Tool",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.PencilTool u.Canvas.Tool = drawtool.PencilTool
showSwatchPalette() showSwatchPalette()
@ -56,8 +58,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
}, },
{ {
Value: drawtool.LineTool.String(), Value: drawtool.LineTool.String(),
Icon: "assets/sprites/line-tool.png", Icon: "assets/sprites/line-tool.png",
Tooltip: "Line Tool",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.LineTool u.Canvas.Tool = drawtool.LineTool
showSwatchPalette() showSwatchPalette()
@ -66,8 +69,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
}, },
{ {
Value: drawtool.RectTool.String(), Value: drawtool.RectTool.String(),
Icon: "assets/sprites/rect-tool.png", Icon: "assets/sprites/rect-tool.png",
Tooltip: "Rectangle Tool",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.RectTool u.Canvas.Tool = drawtool.RectTool
showSwatchPalette() showSwatchPalette()
@ -76,8 +80,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
}, },
{ {
Value: drawtool.EllipseTool.String(), Value: drawtool.EllipseTool.String(),
Icon: "assets/sprites/ellipse-tool.png", Icon: "assets/sprites/ellipse-tool.png",
Tooltip: "Ellipse Tool",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.EllipseTool u.Canvas.Tool = drawtool.EllipseTool
showSwatchPalette() showSwatchPalette()
@ -86,8 +91,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
}, },
{ {
Value: drawtool.ActorTool.String(), Value: drawtool.ActorTool.String(),
Icon: "assets/sprites/actor-tool.png", Icon: "assets/sprites/actor-tool.png",
Tooltip: "Doodad Tool\nDrag-and-drop objects into your map",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.ActorTool u.Canvas.Tool = drawtool.ActorTool
showDoodadPalette() showDoodadPalette()
@ -96,8 +102,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
}, },
{ {
Value: drawtool.LinkTool.String(), Value: drawtool.LinkTool.String(),
Icon: "assets/sprites/link-tool.png", Icon: "assets/sprites/link-tool.png",
Tooltip: "Link Tool\nConnect doodads to each other",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.LinkTool u.Canvas.Tool = drawtool.LinkTool
showDoodadPalette() showDoodadPalette()
@ -106,8 +113,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
}, },
{ {
Value: drawtool.EraserTool.String(), Value: drawtool.EraserTool.String(),
Icon: "assets/sprites/eraser-tool.png", Icon: "assets/sprites/eraser-tool.png",
Tooltip: "Eraser Tool",
Click: func() { Click: func() {
u.Canvas.Tool = drawtool.EraserTool u.Canvas.Tool = drawtool.EraserTool
@ -140,11 +148,16 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
var btnSize = btn.BoxThickness(2) + toolbarSpriteSize var btnSize = btn.BoxThickness(2) + toolbarSpriteSize
btn.Resize(render.NewRect(btnSize, btnSize)) btn.Resize(render.NewRect(btnSize, btnSize))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
button.Click() button.Click()
}) })
u.Supervisor.Add(btn) u.Supervisor.Add(btn)
ui.NewTooltip(btn, ui.Tooltip{
Text: button.Tooltip,
Edge: ui.Right,
})
btnFrame.Pack(btn, ui.Pack{ btnFrame.Pack(btn, ui.Pack{
Side: ui.N, Side: ui.N,
PadY: 2, PadY: 2,
@ -166,6 +179,12 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
Side: ui.N, 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 // Brush Size widget
{ {
sizeFrame := ui.NewFrame("Brush Size Frame") sizeFrame := ui.NewFrame("Brush Size Frame")
@ -237,7 +256,7 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
Text: button.Label, Text: button.Label,
Font: balance.SmallMonoFont, Font: balance.SmallMonoFont,
})) }))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
button.F() button.F()
}) })
u.Supervisor.Add(btn) u.Supervisor.Add(btn)

View File

@ -87,7 +87,7 @@ func (s *GUITestScene) Setup(d *Doodle) error {
Text: label, Text: label,
Font: balance.StatusFont, Font: balance.StatusFont,
})) }))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
d.Flash("%s clicked", btn) d.Flash("%s clicked", btn)
}) })
s.Supervisor.Add(btn) s.Supervisor.Add(btn)
@ -138,7 +138,7 @@ func (s *GUITestScene) Setup(d *Doodle) error {
Height: 20, Height: 20,
BorderStyle: ui.BorderRaised, BorderStyle: ui.BorderRaised,
}) })
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
d.Flash("%s clicked", btn) d.Flash("%s clicked", btn)
}) })
rowFrame.Pack(btn, ui.Pack{ rowFrame.Pack(btn, ui.Pack{
@ -215,7 +215,7 @@ func (s *GUITestScene) Setup(d *Doodle) error {
Font: balance.StatusFont, Font: balance.StatusFont,
})) }))
button1.SetBackground(render.Blue) button1.SetBackground(render.Blue)
button1.Handle(ui.Click, func(p render.Point) { button1.Handle(ui.Click, func(ed ui.EventData) {
d.NewMap() d.NewMap()
}) })
@ -225,7 +225,7 @@ func (s *GUITestScene) Setup(d *Doodle) error {
Text: "Load Map", Text: "Load Map",
Font: balance.StatusFont, Font: balance.StatusFont,
})) }))
button2.Handle(ui.Click, func(p render.Point) { button2.Handle(ui.Click, func(ed ui.EventData) {
d.Prompt("Map name>", func(name string) { d.Prompt("Map name>", func(name string) {
d.EditDrawing(name) d.EditDrawing(name)
}) })

View File

@ -85,7 +85,7 @@ func (s *MainScene) Setup(d *Doodle) error {
Padding: 4, Padding: 4,
}, },
})) }))
s.updateButton.Handle(ui.Click, func(p render.Point) { s.updateButton.Handle(ui.Click, func(ed ui.EventData) {
native.OpenURL(s.updateInfo.DownloadURL) native.OpenURL(s.updateInfo.DownloadURL)
}) })
s.updateButton.Compute(d.Engine) s.updateButton.Compute(d.Engine)
@ -119,7 +119,7 @@ func (s *MainScene) Setup(d *Doodle) error {
Text: button.Name, Text: button.Name,
Font: balance.StatusFont, Font: balance.StatusFont,
})) }))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
button.Func() button.Func()
}) })
s.Supervisor.Add(btn) s.Supervisor.Add(btn)

View File

@ -191,7 +191,7 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
Font: balance.MenuFont, Font: balance.MenuFont,
}), }),
) )
radio.Handle(ui.Click, func(p render.Point) { radio.Handle(ui.Click, func(ed ui.EventData) {
s.configureCanvas(d.Engine, t.Value, s.newWallpaper) s.configureCanvas(d.Engine, t.Value, s.newWallpaper)
}) })
s.Supervisor.Add(radio) s.Supervisor.Add(radio)
@ -238,7 +238,7 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
Text: t.Name, Text: t.Name,
Font: balance.MenuFont, Font: balance.MenuFont,
})) }))
radio.Handle(ui.Click, func(p render.Point) { radio.Handle(ui.Click, func(ed ui.EventData) {
log.Info("Set wallpaper to %s", t.Value) log.Info("Set wallpaper to %s", t.Value)
if pageType, ok := level.PageTypeFromString(s.newPageType); ok { if pageType, ok := level.PageTypeFromString(s.newPageType); ok {
s.configureCanvas(d.Engine, pageType, t.Value) s.configureCanvas(d.Engine, pageType, t.Value)
@ -271,9 +271,9 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
var buttons = []struct { var buttons = []struct {
Label string Label string
F func(render.Point) F func(ui.EventData)
}{ }{
{"Continue", func(p render.Point) { {"Continue", func(ed ui.EventData) {
d.Flash("Create new map with %s page type and %s wallpaper", s.newPageType, s.newWallpaper) d.Flash("Create new map with %s page type and %s wallpaper", s.newPageType, s.newWallpaper)
pageType, ok := level.PageTypeFromString(s.newPageType) pageType, ok := level.PageTypeFromString(s.newPageType)
if !ok { if !ok {
@ -297,7 +297,7 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error {
}) })
}}, }},
{"Cancel", func(p render.Point) { {"Cancel", func(ed ui.EventData) {
d.Goto(&MainScene{}) d.Goto(&MainScene{})
}}, }},
} }
@ -371,7 +371,7 @@ func (s *MenuScene) setupLoadWindow(d *Doodle) error {
Text: lvl, Text: lvl,
Font: balance.MenuFont, Font: balance.MenuFont,
})) }))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
if s.loadForPlay { if s.loadForPlay {
d.PlayLevel(lvl) d.PlayLevel(lvl)
} else { } else {
@ -426,7 +426,7 @@ func (s *MenuScene) setupLoadWindow(d *Doodle) error {
Text: dd, Text: dd,
Font: balance.MenuFont, Font: balance.MenuFont,
})) }))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
d.EditFile(dd) d.EditFile(dd)
}) })
s.Supervisor.Add(btn) s.Supervisor.Add(btn)
@ -467,9 +467,9 @@ func (s *MenuScene) setupLoadWindow(d *Doodle) error {
var buttons = []struct { var buttons = []struct {
Label string Label string
F func(render.Point) F func(ui.EventData)
}{ }{
{"Cancel", func(p render.Point) { {"Cancel", func(ed ui.EventData) {
d.Goto(&MainScene{}) d.Goto(&MainScene{})
}}, }},
} }

View File

@ -107,7 +107,7 @@ func (s *PlayScene) Setup(d *Doodle) error {
Text: "Edit (E)", Text: "Edit (E)",
Font: balance.PlayButtonFont, Font: balance.PlayButtonFont,
})) }))
s.editButton.Handle(ui.Click, func(p render.Point) { s.editButton.Handle(ui.Click, func(ed ui.EventData) {
s.EditLevel() s.EditLevel()
}) })
s.supervisor.Add(s.editButton) s.supervisor.Add(s.editButton)
@ -277,7 +277,7 @@ func (s *PlayScene) SetupAlertbox() {
Font: balance.LabelFont, Font: balance.LabelFont,
Text: text, Text: text,
})) }))
btn.Handle(ui.Click, func(p render.Point) { btn.Handle(ui.Click, func(ed ui.EventData) {
handler() handler()
}) })
bottomFrame.Pack(btn, ui.Pack{ bottomFrame.Pack(btn, ui.Pack{