feat: scrolling
This commit is contained in:
@@ -162,6 +162,11 @@ struct Gui : GuiProvider {
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
void clear(int32_t) override { trace += "clear;"; }
|
||||
void setClip(int32_t x, int32_t y, int32_t w, int32_t h) override {
|
||||
trace += "clip(" + std::to_string(x) + "," + std::to_string(y) + "," +
|
||||
std::to_string(w) + "," + std::to_string(h) + ");";
|
||||
}
|
||||
void clearClip() override { trace += "unclip;"; }
|
||||
void fillRect(int32_t, int32_t, int32_t, int32_t, int32_t) override {
|
||||
trace += "fillRect;";
|
||||
}
|
||||
|
||||
@@ -198,6 +198,56 @@ int main() {
|
||||
"tree.draw(root)\n"
|
||||
"assert(painted == 320)");
|
||||
|
||||
// A scrolling box: children measure past its edges, panning moves them and is
|
||||
// clamped to the content, and what is scrolled out of the box is neither hit
|
||||
// nor painted outside it.
|
||||
bench.gui.trace.clear();
|
||||
run(state,
|
||||
"tree.reset()\n"
|
||||
"local list = tree.create(nil, {type = 'box', w = 'fill', h = 'fill',\n"
|
||||
" scrollX = true, scrollY = true})\n"
|
||||
"local rows = {}\n"
|
||||
"for i = 1, 5 do rows[i] = tree.create(list, {type = 'box', w = 400, h = "
|
||||
"100, interactive = true}) end\n"
|
||||
"tree.setStyle(list, {background = 0xFFFFFF, fill = 0xFFFFFF, border = "
|
||||
"0x333333})\n"
|
||||
// The box is the panel; the content is deliberately larger on both axes.
|
||||
"assert(tree.layout(list, 0, 0, 320, 240))\n"
|
||||
"local maxX, maxY = tree.getScrollRange(list)\n"
|
||||
"assert(maxX == 400 - 320, 'content is wider than the box')\n"
|
||||
"assert(maxY == 5 * 100 - 240, 'content is taller than the box')\n"
|
||||
// Panning shifts the children, and getRect keeps answering screen space.
|
||||
"tree.setScroll(list, 30, 150)\n"
|
||||
"local x, y = tree.getRect(rows[1])\n"
|
||||
"assert(x == -30 and y == -150, 'row moved by the scroll')\n"
|
||||
"local sx, sy = tree.getScroll(list)\n"
|
||||
"assert(sx == 30 and sy == 150)\n"
|
||||
// The box itself does not move, only what it holds.
|
||||
"local bx, by = tree.getRect(list)\n"
|
||||
"assert(bx == 0 and by == 0)\n"
|
||||
// Row 1 is scrolled above the box, so a tap at the top hits row 2.
|
||||
"assert(tree.hit(list, 10, 10) == rows[2], 'scrolled-out row is not hit')\n"
|
||||
// Clamped, never past the content's far edge or before its start.
|
||||
"tree.setScroll(list, 9999, 9999)\n"
|
||||
"local cx, cy = tree.getScroll(list)\n"
|
||||
"assert(cx == maxX and cy == maxY, 'clamped to the content')\n"
|
||||
"tree.setScroll(list, -50, -50)\n"
|
||||
"local zx, zy = tree.getScroll(list)\n"
|
||||
"assert(zx == 0 and zy == 0, 'clamped at the origin')\n"
|
||||
"tree.draw(list)\n"
|
||||
"tree.dropScratch()");
|
||||
// The subtree is scissored to the box, so a row hanging past it cannot paint
|
||||
// over whatever sits outside.
|
||||
assert(bench.gui.trace.find("clip(0,0,320,240);") != std::string::npos);
|
||||
assert(bench.gui.trace.find("unclip;") != std::string::npos);
|
||||
|
||||
// A scrolled axis has no size to hand down, so the box needs one of its own.
|
||||
expectError(state, "tree.reset()\n"
|
||||
"local l = tree.create(nil, {type = 'box', scrollY = "
|
||||
"true})\n"
|
||||
"tree.create(l, {type = 'box', w = 10, h = 10})\n"
|
||||
"assert(tree.layout(l, 0, 0, 320, 240))");
|
||||
|
||||
// A timer firing inside draw is still one batch.
|
||||
run(state, "function draw() timer.after(1, function() end) end\n"
|
||||
"nested = timer.after(1, function() draw() end)");
|
||||
|
||||
Reference in New Issue
Block a user