diff --git a/pkg/balance/runtime.go b/pkg/balance/runtime.go new file mode 100644 index 0000000..2864832 --- /dev/null +++ b/pkg/balance/runtime.go @@ -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, + } +} diff --git a/pkg/editor_ui.go b/pkg/editor_ui.go index 7fcfc35..22ffe67 100644 --- a/pkg/editor_ui.go +++ b/pkg/editor_ui.go @@ -98,7 +98,7 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI { Text: "Play (P)", 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.Supervisor.Add(u.PlayButton) @@ -276,6 +276,10 @@ func (u *EditorUI) Loop(ev *event.State) error { // Present the UI to the screen. 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 // 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. @@ -286,7 +290,6 @@ func (u *EditorUI) Present(e render.Engine) { u.MenuBar.Present(e, u.MenuBar.Point()) u.StatusBar.Present(e, u.StatusBar.Point()) u.ToolBar.Present(e, u.ToolBar.Point()) - u.Workspace.Present(e, u.Workspace.Point()) u.PlayButton.Present(e, u.PlayButton.Point()) // 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. // NOTE: The drag event begins at editor_ui_doodad.go when configuring the // 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!") var P = ui.AbsolutePosition(drawing) @@ -436,18 +439,18 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame { type menuButton struct { Text string - Click func(render.Point) + Click func(ui.EventData) } buttons := []menuButton{ menuButton{ Text: "New Level", - Click: func(render.Point) { + Click: func(ed ui.EventData) { d.GotoNewMenu() }, }, menuButton{ Text: "New Doodad", - Click: func(render.Point) { + Click: func(ed ui.EventData) { d.Prompt("Doodad size [100]>", func(answer string) { size := balance.DoodadSize if answer != "" { @@ -464,7 +467,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame { }, menuButton{ Text: "Save", - Click: func(render.Point) { + Click: func(ed ui.EventData) { if u.Scene.filename != "" { saveFunc(u.Scene.filename) } else { @@ -478,7 +481,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame { }, menuButton{ Text: "Save as...", - Click: func(render.Point) { + Click: func(ed ui.EventData) { d.Prompt("Save as filename>", func(answer string) { if answer != "" { saveFunc(answer) @@ -488,7 +491,7 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.Frame { }, menuButton{ Text: "Load", - Click: func(render.Point) { + Click: func(ed ui.EventData) { d.GotoLoadMenu() }, }, diff --git a/pkg/editor_ui_doodad.go b/pkg/editor_ui_doodad.go index 6b4046b..b8cbfcc 100644 --- a/pkg/editor_ui_doodad.go +++ b/pkg/editor_ui_doodad.go @@ -77,7 +77,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra Text: "<", Font: balance.MenuFont, })) - leftBtn.Handle(ui.Click, func(p render.Point) { + leftBtn.Handle(ui.Click, func(ed ui.EventData) { u.scrollDoodadFrame(-1) }) u.Supervisor.Add(leftBtn) @@ -100,7 +100,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra Text: ">", Font: balance.MenuFont, })) - rightBtn.Handle(ui.Click, func(p render.Point) { + rightBtn.Handle(ui.Click, func(ed ui.EventData) { u.scrollDoodadFrame(1) }) u.Supervisor.Add(rightBtn) @@ -179,10 +179,16 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra 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. // NOTE: The drag target is the EditorUI.Canvas in // 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) u.startDragActor(doodad, nil) }) diff --git a/pkg/editor_ui_palette.go b/pkg/editor_ui_palette.go index 5fb0a87..61b2464 100644 --- a/pkg/editor_ui_palette.go +++ b/pkg/editor_ui_palette.go @@ -5,7 +5,6 @@ import ( "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/log" - "git.kirsle.net/go/render" "git.kirsle.net/go/ui" ) @@ -54,7 +53,7 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame { frame.SetBackground(balance.WindowBackground) // Handler function for the radio buttons being clicked. - onClick := func(p render.Point) { + onClick := func(ed ui.EventData) { name := u.selectedSwatch swatch, ok := u.Canvas.Palette.Get(name) if !ok { @@ -95,6 +94,12 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame { btn.Handle(ui.Click, onClick) 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) swFrame.Configure(ui.Config{ Height: label.Size().H, diff --git a/pkg/editor_ui_toolbar.go b/pkg/editor_ui_toolbar.go index de279f2..fe7ae8c 100644 --- a/pkg/editor_ui_toolbar.go +++ b/pkg/editor_ui_toolbar.go @@ -41,13 +41,15 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { // Buttons. var buttons = []struct { - Value string - Icon string - Click func() + Value string + Icon string + Tooltip string + Click func() }{ { - Value: drawtool.PencilTool.String(), - Icon: "assets/sprites/pencil-tool.png", + Value: drawtool.PencilTool.String(), + Icon: "assets/sprites/pencil-tool.png", + Tooltip: "Pencil Tool", Click: func() { u.Canvas.Tool = drawtool.PencilTool showSwatchPalette() @@ -56,8 +58,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { }, { - Value: drawtool.LineTool.String(), - Icon: "assets/sprites/line-tool.png", + Value: drawtool.LineTool.String(), + Icon: "assets/sprites/line-tool.png", + Tooltip: "Line Tool", Click: func() { u.Canvas.Tool = drawtool.LineTool showSwatchPalette() @@ -66,8 +69,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { }, { - Value: drawtool.RectTool.String(), - Icon: "assets/sprites/rect-tool.png", + Value: drawtool.RectTool.String(), + Icon: "assets/sprites/rect-tool.png", + Tooltip: "Rectangle Tool", Click: func() { u.Canvas.Tool = drawtool.RectTool showSwatchPalette() @@ -76,8 +80,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { }, { - Value: drawtool.EllipseTool.String(), - Icon: "assets/sprites/ellipse-tool.png", + Value: drawtool.EllipseTool.String(), + Icon: "assets/sprites/ellipse-tool.png", + Tooltip: "Ellipse Tool", Click: func() { u.Canvas.Tool = drawtool.EllipseTool showSwatchPalette() @@ -86,8 +91,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { }, { - Value: drawtool.ActorTool.String(), - Icon: "assets/sprites/actor-tool.png", + 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 showDoodadPalette() @@ -96,8 +102,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { }, { - Value: drawtool.LinkTool.String(), - Icon: "assets/sprites/link-tool.png", + 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 showDoodadPalette() @@ -106,8 +113,9 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { }, { - Value: drawtool.EraserTool.String(), - Icon: "assets/sprites/eraser-tool.png", + Value: drawtool.EraserTool.String(), + Icon: "assets/sprites/eraser-tool.png", + Tooltip: "Eraser Tool", Click: func() { u.Canvas.Tool = drawtool.EraserTool @@ -140,11 +148,16 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { var btnSize = btn.BoxThickness(2) + toolbarSpriteSize btn.Resize(render.NewRect(btnSize, btnSize)) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { button.Click() }) 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, @@ -166,6 +179,12 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { 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") @@ -237,7 +256,7 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame { Text: button.Label, Font: balance.SmallMonoFont, })) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { button.F() }) u.Supervisor.Add(btn) diff --git a/pkg/guitest_scene.go b/pkg/guitest_scene.go index ff1827d..c450062 100644 --- a/pkg/guitest_scene.go +++ b/pkg/guitest_scene.go @@ -87,7 +87,7 @@ func (s *GUITestScene) Setup(d *Doodle) error { Text: label, Font: balance.StatusFont, })) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { d.Flash("%s clicked", btn) }) s.Supervisor.Add(btn) @@ -138,7 +138,7 @@ func (s *GUITestScene) Setup(d *Doodle) error { Height: 20, BorderStyle: ui.BorderRaised, }) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { d.Flash("%s clicked", btn) }) rowFrame.Pack(btn, ui.Pack{ @@ -215,7 +215,7 @@ func (s *GUITestScene) Setup(d *Doodle) error { Font: balance.StatusFont, })) button1.SetBackground(render.Blue) - button1.Handle(ui.Click, func(p render.Point) { + button1.Handle(ui.Click, func(ed ui.EventData) { d.NewMap() }) @@ -225,7 +225,7 @@ func (s *GUITestScene) Setup(d *Doodle) error { Text: "Load Map", 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.EditDrawing(name) }) diff --git a/pkg/main_scene.go b/pkg/main_scene.go index 30ad72c..596cb61 100644 --- a/pkg/main_scene.go +++ b/pkg/main_scene.go @@ -85,7 +85,7 @@ func (s *MainScene) Setup(d *Doodle) error { 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) }) s.updateButton.Compute(d.Engine) @@ -119,7 +119,7 @@ func (s *MainScene) Setup(d *Doodle) error { Text: button.Name, Font: balance.StatusFont, })) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { button.Func() }) s.Supervisor.Add(btn) diff --git a/pkg/menu_scene.go b/pkg/menu_scene.go index 7842f95..08ebc83 100644 --- a/pkg/menu_scene.go +++ b/pkg/menu_scene.go @@ -191,7 +191,7 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error { 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.Supervisor.Add(radio) @@ -238,7 +238,7 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error { Text: t.Name, 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) if pageType, ok := level.PageTypeFromString(s.newPageType); ok { s.configureCanvas(d.Engine, pageType, t.Value) @@ -271,9 +271,9 @@ func (s *MenuScene) setupNewWindow(d *Doodle) error { var buttons = []struct { 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) pageType, ok := level.PageTypeFromString(s.newPageType) 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{}) }}, } @@ -371,7 +371,7 @@ func (s *MenuScene) setupLoadWindow(d *Doodle) error { Text: lvl, Font: balance.MenuFont, })) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { if s.loadForPlay { d.PlayLevel(lvl) } else { @@ -426,7 +426,7 @@ func (s *MenuScene) setupLoadWindow(d *Doodle) error { Text: dd, Font: balance.MenuFont, })) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { d.EditFile(dd) }) s.Supervisor.Add(btn) @@ -467,9 +467,9 @@ func (s *MenuScene) setupLoadWindow(d *Doodle) error { var buttons = []struct { Label string - F func(render.Point) + F func(ui.EventData) }{ - {"Cancel", func(p render.Point) { + {"Cancel", func(ed ui.EventData) { d.Goto(&MainScene{}) }}, } diff --git a/pkg/play_scene.go b/pkg/play_scene.go index a25a9dd..da4ec86 100644 --- a/pkg/play_scene.go +++ b/pkg/play_scene.go @@ -107,7 +107,7 @@ func (s *PlayScene) Setup(d *Doodle) error { Text: "Edit (E)", Font: balance.PlayButtonFont, })) - s.editButton.Handle(ui.Click, func(p render.Point) { + s.editButton.Handle(ui.Click, func(ed ui.EventData) { s.EditLevel() }) s.supervisor.Add(s.editButton) @@ -277,7 +277,7 @@ func (s *PlayScene) SetupAlertbox() { Font: balance.LabelFont, Text: text, })) - btn.Handle(ui.Click, func(p render.Point) { + btn.Handle(ui.Click, func(ed ui.EventData) { handler() }) bottomFrame.Pack(btn, ui.Pack{