Link Tool UX
* On the Doodads tab is the Link button to enter the Link Tool. * Click Link, then click the 1st doodad on the level, then click the 2nd doodad to complete the link. * The actors struct in the Level holds the link IDs for each actor.
This commit is contained in:
parent
b06c52a705
commit
87416f9740
|
@ -267,6 +267,17 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas {
|
||||||
u.startDragActor(doodad)
|
u.startDragActor(doodad)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A link event to connect two actors together.
|
||||||
|
drawing.OnLinkActors = func(a, b *level.Actor) {
|
||||||
|
d.Flash("Link %s and %s", a.Filename, b.Filename)
|
||||||
|
idA, idB := a.ID(), b.ID()
|
||||||
|
a.AddLink(idB)
|
||||||
|
b.AddLink(idA)
|
||||||
|
|
||||||
|
// Reset the Link tool.
|
||||||
|
drawing.Tool = uix.ActorTool
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
@ -57,7 +57,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
Background: render.Grey,
|
Background: render.Grey,
|
||||||
BorderSize: 2,
|
BorderSize: 2,
|
||||||
BorderStyle: ui.BorderRaised,
|
BorderStyle: ui.BorderRaised,
|
||||||
Height: 20,
|
Height: 24,
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
// Link button.
|
// Link button.
|
||||||
|
@ -65,7 +65,8 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
Text: "Link Doodads",
|
Text: "Link Doodads",
|
||||||
}))
|
}))
|
||||||
linkButton.Handle(ui.Click, func(p render.Point) {
|
linkButton.Handle(ui.Click, func(p render.Point) {
|
||||||
u.d.Flash("Hello world")
|
u.Canvas.LinkStart()
|
||||||
|
u.d.Flash("Click on the first Doodad to link to another one.")
|
||||||
})
|
})
|
||||||
u.Supervisor.Add(linkButton)
|
u.Supervisor.Add(linkButton)
|
||||||
|
|
||||||
|
@ -81,6 +82,9 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
|
|
||||||
// Pager buttons on top of the doodad list.
|
// Pager buttons on top of the doodad list.
|
||||||
pager := ui.NewFrame("Doodad Pager")
|
pager := ui.NewFrame("Doodad Pager")
|
||||||
|
pager.SetBackground(render.RGBA(255, 0, 0, 20)) // TODO: if I don't set a background color,
|
||||||
|
// this frame will light up the same color as the Link button on mouse
|
||||||
|
// over. somewhere some memory might be shared between the recent widgets
|
||||||
{
|
{
|
||||||
leftBtn := ui.NewButton("Prev Page", ui.NewLabel(ui.Label{
|
leftBtn := ui.NewButton("Prev Page", ui.NewLabel(ui.Label{
|
||||||
Text: "<",
|
Text: "<",
|
||||||
|
@ -109,6 +113,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
frame.Pack(pager, ui.Pack{
|
frame.Pack(pager, ui.Pack{
|
||||||
Anchor: ui.N,
|
Anchor: ui.N,
|
||||||
Fill: true,
|
Fill: true,
|
||||||
|
PadY: 5,
|
||||||
})
|
})
|
||||||
|
|
||||||
doodadsAvailable, err := doodads.ListDoodads()
|
doodadsAvailable, err := doodads.ListDoodads()
|
||||||
|
|
|
@ -39,9 +39,21 @@ type Actor struct {
|
||||||
id string // NOTE: read only, use ID() to access.
|
id string // NOTE: read only, use ID() to access.
|
||||||
Filename string `json:"filename"` // like "exit.doodad"
|
Filename string `json:"filename"` // like "exit.doodad"
|
||||||
Point render.Point `json:"point"`
|
Point render.Point `json:"point"`
|
||||||
|
Links []string `json:"links,omitempty"` // IDs of linked actors
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the actor's ID.
|
// ID returns the actor's ID.
|
||||||
func (a *Actor) ID() string {
|
func (a *Actor) ID() string {
|
||||||
return a.id
|
return a.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddLink adds a linked Actor to an Actor. Add the linked actor by its ID.
|
||||||
|
func (a *Actor) AddLink(id string) {
|
||||||
|
// Don't add a duplicate ID to the links array.
|
||||||
|
for _, exist := range a.Links {
|
||||||
|
if exist == id {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.Links = append(a.Links, id)
|
||||||
|
}
|
||||||
|
|
|
@ -65,9 +65,11 @@ type Canvas struct {
|
||||||
OnDeleteActors func([]*level.Actor)
|
OnDeleteActors func([]*level.Actor)
|
||||||
OnDragStart func(filename string)
|
OnDragStart func(filename string)
|
||||||
|
|
||||||
|
// -- WHEN Canvas.Tool is "Link" --
|
||||||
// When the Canvas wants to link two actors together. Arguments are the IDs
|
// When the Canvas wants to link two actors together. Arguments are the IDs
|
||||||
// of the two actors.
|
// of the two actors.
|
||||||
OnLinkActors func(a, b string)
|
OnLinkActors func(a, b *level.Actor)
|
||||||
|
linkFirst *Actor
|
||||||
|
|
||||||
// Tracking pixels while editing. TODO: get rid of pixelHistory?
|
// Tracking pixels while editing. TODO: get rid of pixelHistory?
|
||||||
pixelHistory []*level.Pixel
|
pixelHistory []*level.Pixel
|
||||||
|
|
|
@ -58,7 +58,6 @@ func (w *Canvas) loopEditable(ev *events.State) error {
|
||||||
case ActorTool:
|
case ActorTool:
|
||||||
// See if any of the actors are below the mouse cursor.
|
// See if any of the actors are below the mouse cursor.
|
||||||
var WP = w.WorldIndexAt(cursor)
|
var WP = w.WorldIndexAt(cursor)
|
||||||
_ = WP
|
|
||||||
|
|
||||||
var deleteActors = []*level.Actor{}
|
var deleteActors = []*level.Actor{}
|
||||||
for _, actor := range w.actors {
|
for _, actor := range w.actors {
|
||||||
|
@ -100,6 +99,47 @@ func (w *Canvas) loopEditable(ev *events.State) error {
|
||||||
if len(deleteActors) > 0 && w.OnDeleteActors != nil {
|
if len(deleteActors) > 0 && w.OnDeleteActors != nil {
|
||||||
w.OnDeleteActors(deleteActors)
|
w.OnDeleteActors(deleteActors)
|
||||||
}
|
}
|
||||||
|
case LinkTool:
|
||||||
|
// See if any of the actors are below the mouse cursor.
|
||||||
|
var WP = w.WorldIndexAt(cursor)
|
||||||
|
|
||||||
|
for _, actor := range w.actors {
|
||||||
|
// Permanently color the actor if it's the current subject of the
|
||||||
|
// Link Tool (after 1st click, until 2nd click of other actor)
|
||||||
|
if w.linkFirst == actor {
|
||||||
|
actor.Canvas.Configure(ui.Config{
|
||||||
|
Background: render.RGBA(255, 153, 255, 153),
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
box := render.Rect{
|
||||||
|
X: actor.Actor.Point.X - P.X - w.Scroll.X,
|
||||||
|
Y: actor.Actor.Point.Y - P.Y - w.Scroll.Y,
|
||||||
|
W: actor.Canvas.Size().W,
|
||||||
|
H: actor.Canvas.Size().H,
|
||||||
|
}
|
||||||
|
|
||||||
|
if WP.Inside(box) {
|
||||||
|
actor.Canvas.Configure(ui.Config{
|
||||||
|
BorderSize: 1,
|
||||||
|
BorderColor: render.RGBA(255, 153, 255, 255),
|
||||||
|
BorderStyle: ui.BorderSolid,
|
||||||
|
Background: render.White, // TODO: cuz the border draws a bgcolor
|
||||||
|
})
|
||||||
|
|
||||||
|
// Click handler to start linking this actor.
|
||||||
|
if ev.Button1.Read() {
|
||||||
|
if err := w.LinkAdd(actor); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
actor.Canvas.SetBorderSize(0)
|
||||||
|
actor.Canvas.SetBackground(render.RGBA(0, 0, 1, 0)) // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
28
pkg/uix/canvas_link_tool.go
Normal file
28
pkg/uix/canvas_link_tool.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package uix
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// LinkStart initializes the Link tool.
|
||||||
|
func (w *Canvas) LinkStart() {
|
||||||
|
w.Tool = LinkTool
|
||||||
|
w.linkFirst = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkAdd adds an actor to be linked in the Link tool.
|
||||||
|
func (w *Canvas) LinkAdd(a *Actor) error {
|
||||||
|
if w.linkFirst == nil {
|
||||||
|
// First click, hold onto this actor.
|
||||||
|
w.linkFirst = a
|
||||||
|
} else {
|
||||||
|
// Second click, call the OnLinkActors handler with the two actors.
|
||||||
|
if w.OnLinkActors != nil {
|
||||||
|
w.OnLinkActors(w.linkFirst.Actor, a.Actor)
|
||||||
|
} else {
|
||||||
|
return errors.New("Canvas.LinkAdd: no OnLinkActors handler is ready")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the link state.
|
||||||
|
w.linkFirst = nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user