Add Scrolling in the Doodad Palette Window
* Rudimentary scrolling shows a Left and Right button at the top of the Doodad Palette if your window is deemed not tall enough to contain all of the doodads. * A "progress bar" is shown between the buttons indicating the percentage of your scroll down the doodad list. When you're able to see the final row of doodads, the progress bar is at 100%.
This commit is contained in:
parent
12d34517e9
commit
22440f436b
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.kirsle.net/apps/doodle/pkg/bindata"
|
"git.kirsle.net/apps/doodle/pkg/bindata"
|
||||||
|
@ -57,6 +58,8 @@ func ListDoodads() ([]string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort.Strings(result)
|
||||||
|
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,12 +174,15 @@ func (s *EditorScene) Loop(d *Doodle, ev *events.State) error {
|
||||||
case "l":
|
case "l":
|
||||||
d.Flash("Line Tool selected.")
|
d.Flash("Line Tool selected.")
|
||||||
s.UI.Canvas.Tool = drawtool.LineTool
|
s.UI.Canvas.Tool = drawtool.LineTool
|
||||||
|
s.UI.activeTool = s.UI.Canvas.Tool.String()
|
||||||
case "f":
|
case "f":
|
||||||
d.Flash("Pencil Tool selected.")
|
d.Flash("Pencil Tool selected.")
|
||||||
s.UI.Canvas.Tool = drawtool.PencilTool
|
s.UI.Canvas.Tool = drawtool.PencilTool
|
||||||
|
s.UI.activeTool = s.UI.Canvas.Tool.String()
|
||||||
case "r":
|
case "r":
|
||||||
d.Flash("Rectangle Tool selected.")
|
d.Flash("Rectangle Tool selected.")
|
||||||
s.UI.Canvas.Tool = drawtool.RectTool
|
s.UI.Canvas.Tool = drawtool.RectTool
|
||||||
|
s.UI.activeTool = s.UI.Canvas.Tool.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -49,8 +49,15 @@ type EditorUI struct {
|
||||||
PaletteTab *ui.Frame
|
PaletteTab *ui.Frame
|
||||||
DoodadTab *ui.Frame
|
DoodadTab *ui.Frame
|
||||||
|
|
||||||
|
// Doodad Palette window variables.
|
||||||
|
doodadSkip int
|
||||||
|
doodadRows []*ui.Frame
|
||||||
|
doodadPager *ui.Frame
|
||||||
|
doodadButtonSize int32
|
||||||
|
doodadScroller *ui.Frame
|
||||||
|
|
||||||
// ToolBar window.
|
// ToolBar window.
|
||||||
activeTool *string
|
activeTool string
|
||||||
|
|
||||||
// Draggable Doodad canvas.
|
// Draggable Doodad canvas.
|
||||||
DraggableActor *DraggableActor
|
DraggableActor *DraggableActor
|
||||||
|
@ -72,8 +79,7 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default tool in the toolbox.
|
// Default tool in the toolbox.
|
||||||
activeTool := drawtool.PencilTool.String()
|
u.activeTool = drawtool.PencilTool.String()
|
||||||
u.activeTool = &activeTool
|
|
||||||
|
|
||||||
// Bind the StatusBoxes arrays to the text variables.
|
// Bind the StatusBoxes arrays to the text variables.
|
||||||
u.StatusBoxes = []*string{
|
u.StatusBoxes = []*string{
|
||||||
|
@ -154,6 +160,8 @@ func (u *EditorUI) Resized(d *Doodle) {
|
||||||
u.MenuBar.BoxSize().H,
|
u.MenuBar.BoxSize().H,
|
||||||
))
|
))
|
||||||
u.Palette.Compute(d.Engine)
|
u.Palette.Compute(d.Engine)
|
||||||
|
|
||||||
|
u.scrollDoodadFrame(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var innerHeight = int32(u.d.height) - u.MenuBar.Size().H - u.StatusBar.Size().H
|
var innerHeight = int32(u.d.height) - u.MenuBar.Size().H - u.StatusBar.Size().H
|
||||||
|
|
|
@ -49,8 +49,6 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
perRow = balance.UIDoodadsPerRow
|
perRow = balance.UIDoodadsPerRow
|
||||||
)
|
)
|
||||||
|
|
||||||
frame.SetBackground(render.RGBA(0, 153, 255, 153))
|
|
||||||
|
|
||||||
// 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,
|
pager.SetBackground(render.RGBA(255, 0, 0, 20)) // TODO: if I don't set a background color,
|
||||||
|
@ -59,28 +57,40 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
{
|
{
|
||||||
leftBtn := ui.NewButton("Prev Page", ui.NewLabel(ui.Label{
|
leftBtn := ui.NewButton("Prev Page", ui.NewLabel(ui.Label{
|
||||||
Text: "<",
|
Text: "<",
|
||||||
|
Font: balance.MenuFont,
|
||||||
}))
|
}))
|
||||||
|
leftBtn.Handle(ui.Click, func(p render.Point) {
|
||||||
|
u.scrollDoodadFrame(-1)
|
||||||
|
})
|
||||||
u.Supervisor.Add(leftBtn)
|
u.Supervisor.Add(leftBtn)
|
||||||
pager.Pack(leftBtn, ui.Pack{
|
pager.Pack(leftBtn, ui.Pack{
|
||||||
Anchor: ui.W,
|
Anchor: ui.W,
|
||||||
})
|
})
|
||||||
|
|
||||||
pageLabel := ui.NewLabel(ui.Label{
|
scroller := ui.NewFrame("Doodad Scroll Progressbar")
|
||||||
Text: " Page 1 of 20",
|
scroller.Configure(ui.Config{
|
||||||
|
Width: 20,
|
||||||
|
Height: 20,
|
||||||
|
Background: render.RGBA(128, 128, 128, 128),
|
||||||
})
|
})
|
||||||
pager.Pack(pageLabel, ui.Pack{
|
pager.Pack(scroller, ui.Pack{
|
||||||
Anchor: ui.W,
|
Anchor: ui.W,
|
||||||
Expand: true,
|
|
||||||
})
|
})
|
||||||
|
u.doodadScroller = scroller
|
||||||
|
|
||||||
rightBtn := ui.NewButton("Next Page", ui.NewLabel(ui.Label{
|
rightBtn := ui.NewButton("Next Page", ui.NewLabel(ui.Label{
|
||||||
Text: ">",
|
Text: ">",
|
||||||
|
Font: balance.MenuFont,
|
||||||
}))
|
}))
|
||||||
|
rightBtn.Handle(ui.Click, func(p render.Point) {
|
||||||
|
u.scrollDoodadFrame(1)
|
||||||
|
})
|
||||||
u.Supervisor.Add(rightBtn)
|
u.Supervisor.Add(rightBtn)
|
||||||
pager.Pack(rightBtn, ui.Pack{
|
pager.Pack(rightBtn, ui.Pack{
|
||||||
Anchor: ui.W,
|
Anchor: ui.E,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
u.doodadPager = pager
|
||||||
frame.Pack(pager, ui.Pack{
|
frame.Pack(pager, ui.Pack{
|
||||||
Anchor: ui.N,
|
Anchor: ui.N,
|
||||||
Fill: true,
|
Fill: true,
|
||||||
|
@ -96,64 +106,138 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
|
||||||
}
|
}
|
||||||
|
|
||||||
var buttonSize = (paletteWidth - window.BoxThickness(2)) / int32(perRow)
|
var buttonSize = (paletteWidth - window.BoxThickness(2)) / int32(perRow)
|
||||||
|
u.doodadButtonSize = buttonSize
|
||||||
|
|
||||||
// Draw the doodad buttons in a grid `perRow` buttons wide.
|
// Draw the doodad buttons in a grid `perRow` buttons wide.
|
||||||
var (
|
var (
|
||||||
row *ui.Frame
|
row *ui.Frame
|
||||||
rowCount int // for labeling the ui.Frame for each row
|
rowCount int // for labeling the ui.Frame for each row
|
||||||
|
btnRows = []*ui.Frame{} // Collect the row frames for the buttons.
|
||||||
)
|
)
|
||||||
for i, filename := range doodadsAvailable {
|
for i, filename := range doodadsAvailable {
|
||||||
|
filename := filename
|
||||||
|
|
||||||
if row == nil || i%perRow == 0 {
|
if row == nil || i%perRow == 0 {
|
||||||
rowCount++
|
rowCount++
|
||||||
row = ui.NewFrame(fmt.Sprintf("Doodad Row %d", rowCount))
|
row = ui.NewFrame(fmt.Sprintf("Doodad Row %d", rowCount))
|
||||||
row.SetBackground(balance.WindowBackground)
|
row.SetBackground(balance.WindowBackground)
|
||||||
|
btnRows = append(btnRows, row)
|
||||||
frame.Pack(row, ui.Pack{
|
frame.Pack(row, ui.Pack{
|
||||||
Anchor: ui.N,
|
Anchor: ui.N,
|
||||||
Fill: true,
|
Fill: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func(filename string) {
|
doodad, err := doodads.LoadFile(filename)
|
||||||
doodad, err := doodads.LoadFile(filename)
|
if err != nil {
|
||||||
if err != nil {
|
log.Error(err.Error())
|
||||||
log.Error(err.Error())
|
doodad = doodads.New(balance.DoodadSize)
|
||||||
doodad = doodads.New(balance.DoodadSize)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
can := uix.NewCanvas(int(buttonSize), true)
|
can := uix.NewCanvas(int(buttonSize), true)
|
||||||
can.Name = filename
|
can.Name = filename
|
||||||
can.SetBackground(render.White)
|
can.SetBackground(render.White)
|
||||||
can.LoadDoodad(doodad)
|
can.LoadDoodad(doodad)
|
||||||
|
|
||||||
btn := ui.NewButton(filename, can)
|
btn := ui.NewButton(filename, can)
|
||||||
btn.Resize(render.NewRect(
|
btn.Resize(render.NewRect(
|
||||||
buttonSize-2, // TODO: without the -2 the button border
|
buttonSize-2, // TODO: without the -2 the button border
|
||||||
buttonSize-2, // rests on top of the window border.
|
buttonSize-2, // rests on top of the window border.
|
||||||
))
|
))
|
||||||
row.Pack(btn, ui.Pack{
|
row.Pack(btn, ui.Pack{
|
||||||
Anchor: ui.W,
|
Anchor: ui.W,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 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(e render.Point) {
|
||||||
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)
|
u.startDragActor(doodad)
|
||||||
})
|
})
|
||||||
u.Supervisor.Add(btn)
|
u.Supervisor.Add(btn)
|
||||||
|
|
||||||
// Resize the canvas to fill the button interior.
|
// Resize the canvas to fill the button interior.
|
||||||
btnSize := btn.Size()
|
btnSize := btn.Size()
|
||||||
can.Resize(render.NewRect(
|
can.Resize(render.NewRect(
|
||||||
btnSize.W-btn.BoxThickness(2),
|
btnSize.W-btn.BoxThickness(2),
|
||||||
btnSize.H-btn.BoxThickness(2),
|
btnSize.H-btn.BoxThickness(2),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
btn.Compute(e)
|
btn.Compute(e)
|
||||||
}(filename)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u.doodadRows = btnRows
|
||||||
|
u.scrollDoodadFrame(0)
|
||||||
|
|
||||||
return frame, nil
|
return frame, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scrollDoodadFrame handles the Page Up/Down buttons to adjust the number of
|
||||||
|
// Doodads visible on screen.
|
||||||
|
//
|
||||||
|
// rows is the number of rows to scroll. Positive values mean scroll *down*
|
||||||
|
// the list.
|
||||||
|
func (u *EditorUI) scrollDoodadFrame(rows int) {
|
||||||
|
u.doodadSkip += rows
|
||||||
|
if u.doodadSkip < 0 {
|
||||||
|
u.doodadSkip = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("scrollDoodadFrame(%d): skip=%d", rows, u.doodadSkip)
|
||||||
|
|
||||||
|
// Calculate about how many rows we can see given our current window size.
|
||||||
|
var (
|
||||||
|
maxVisibleHeight = int32(u.d.height - 86)
|
||||||
|
calculatedHeight int32
|
||||||
|
rowsBefore int // count of rows hidden before
|
||||||
|
rowsVisible int
|
||||||
|
rowsAfter int // count of rows hidden after
|
||||||
|
rowsEstimated = maxVisibleHeight / u.doodadButtonSize // estimated number rows shown
|
||||||
|
maxSkip = ((len(u.doodadRows) * int(u.doodadButtonSize)) - int(u.doodadButtonSize*rowsEstimated)) / int(u.doodadButtonSize)
|
||||||
|
)
|
||||||
|
|
||||||
|
if maxSkip < 0 {
|
||||||
|
maxSkip = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("maxSkip = (%d * %d) - (%d * %d) = %d", len(u.doodadRows), u.doodadButtonSize, u.doodadButtonSize, rowsEstimated, maxSkip)
|
||||||
|
// log.Info("maxSkip: estimate=%d rows=%d - visible=%d => %d", rowsEstimated, len(u.doodadRows), rowsVisible, maxSkip)
|
||||||
|
if u.doodadSkip > maxSkip {
|
||||||
|
u.doodadSkip = maxSkip
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the window is big enough to encompass all the doodads, don't show
|
||||||
|
// the pager toolbar, its just confusing.
|
||||||
|
if maxSkip == 0 {
|
||||||
|
u.doodadPager.Hide()
|
||||||
|
} else {
|
||||||
|
u.doodadPager.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comb through the doodads and show/hide the relevant buttons.
|
||||||
|
for i, row := range u.doodadRows {
|
||||||
|
if i < u.doodadSkip {
|
||||||
|
row.Hide()
|
||||||
|
rowsBefore++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
calculatedHeight += u.doodadButtonSize
|
||||||
|
if calculatedHeight > maxVisibleHeight {
|
||||||
|
row.Hide()
|
||||||
|
rowsAfter++
|
||||||
|
} else {
|
||||||
|
row.Show()
|
||||||
|
rowsVisible++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewPercent = float64(rowsBefore+rowsVisible) / float64(len(u.doodadRows))
|
||||||
|
u.doodadScroller.Configure(ui.Config{
|
||||||
|
Width: int32(float64(paletteWidth-50) * viewPercent), // TODO: hacky magic number
|
||||||
|
})
|
||||||
|
log.Info("v%% = (%d + %d) / %d = %f", rowsBefore, rowsVisible, len(u.doodadRows), viewPercent)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ func (u *EditorUI) SetupToolbar(d *Doodle) *ui.Frame {
|
||||||
|
|
||||||
btn := ui.NewRadioButton(
|
btn := ui.NewRadioButton(
|
||||||
button.Value,
|
button.Value,
|
||||||
u.activeTool,
|
&u.activeTool,
|
||||||
button.Value,
|
button.Value,
|
||||||
image,
|
image,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user