SDK 0.10.1
macOS 10.14.6
in simulator and on hardware
Hey y'all! I'm using several gridviews in our game simultaneously, which slide on and off screen based on user input. They often overlap rapidly, so I need to have all the gridviews created and ready to go at once. There are a couple I'd like to manipulate while they're offscreen, setting their scroll & selection. But I'm running into a bug where trying to scroll one gridview will very often scroll another.
I can't figure out why this is happening, nor can I figure out exactly what determines the order they receive control in our more-complicated game. But I have replicated the bug in a very simple example. Here's a full main.lua which illustrates the problem:
local gfx = playdate.graphics
import 'CoreLibs/ui'
local grid1 = playdate.ui.gridview.new(120, 100)
grid1:setNumberOfColumns(10)
grid1:setNumberOfRows(1)
grid1:setScrollDuration(400)
grid1.scrollCellsToCenter = true
-- section, row, column
grid1:setSelection(1, 1, 1)
grid1:scrollCellToCenter(1, 1, 1, false)
local grid2 = playdate.ui.gridview.new(120, 100)
grid2:setNumberOfColumns(10)
grid2:setNumberOfRows(1)
grid2:setScrollDuration(400)
grid2.scrollCellsToCenter = true
grid2:setSelection(1, 1, 3)
--[[ HERE'S THE BUG: ]]
--[[ This should scroll grid2, but it scrolls grid1 ]]
grid2:scrollCellToCenter(1, 1, 3, false)
gfx.setColor(gfx.kColorBlack)
gfx.setStrokeLocation(gfx.kStrokeInside)
function playdate.update()
gfx.clear()
handleInput()
-- gfx.drawText('test', 0, 0)
grid1:drawInRect(0, 1, 400, 100)
grid2:drawInRect(0, 102, 400, 100)
gfx.drawText('*left/right to move grid1, B/A to move grid2*', 44, 212)
playdate.timer.updateTimers()
end
function handleInput()
if playdate.buttonJustPressed('left') then
grid1:selectPreviousColumn()
end
if playdate.buttonJustPressed('right') then
grid1:selectNextColumn()
end
if playdate.buttonJustPressed('B') then
grid2:selectPreviousColumn()
end
if playdate.buttonJustPressed('A') then
grid2:selectNextColumn()
end
end
function grid1:drawCell(section, row, column, selected, x, y, width, height)
gfx.pushContext()
gfx.drawText('grid1 cell '..column, x + 10, y + 10)
if selected then
gfx.drawText('*selected*', x + 10, y + 38)
gfx.setLineWidth(3)
end
gfx.drawRoundRect(x, y, width, height, 4)
gfx.popContext()
end
function grid2:drawCell(section, row, column, selected, x, y, width, height)
gfx.pushContext()
gfx.drawText('grid2 cell '..column, x + 10, y + 10)
if selected then
gfx.drawText('*selected*', x + 10, y + 38)
gfx.setLineWidth(3)
end
gfx.drawRoundRect(x, y, width, height, 4)
gfx.popContext()
end
Here's what I'd expect to see, with grid2 having selected AND scrolled to column 3:
but instead I see:
Selection is assigned on grid2
, but grid1
is scrolled instead! Here is it in motion, starting with a fresh boot, then pressing right twice to move the upper grid1
, then A A B B to move the lower grid2
:
Now, I've been able to paper over this a few times by manually scrolling another gridview while it's not visible, but I've run into one where I just can't get it to work. The game opens on a view of the room, which is a gridview with each cell showing a different portion of the room. When it boots, I've attempted to scroll the offscreen gridview for the Ingredients Shelf to column 3, attempting to skip 2 empty cells so that the first ingredient appears centered. Here's what that looks like:
Now, no matter what I do, or how many times I try to scroll that second grid's position, I can't do it, unless I run an attempt every frame after activating the ingredients shelf, in which case it scrolls on the SECOND frame. Weird!!! If I try to force the ingredient selection's update loop to try scrolling every frame once it's activated, look at this:
The first update trying to scroll grid2
actually scrolls grid1
to its 3rd cell (the one with the book), while the second update actually scrolls grid2
, moving the coffee bean into position.
I've tried so many things to try and trick this into happening in a different order, but I can't get it to work. It seems to have to do with the order they're created; but I can't make sense of why grid2
ever receives its scroll commands if they're being intercepted in the first place. Except that manually triggering selectNextColumn()
or selectPreviousColumn()
with button input always seems to reach the correct gridview. So it seems like something within gridview:scrollCellToCenter()
.
And the main difference I see between gridview:scrollCellToCenter()
and the methods to select next or previous column is that those methods used the local function scrollToSelectedCell()
, whereas gridview:scrollCellToCenter()
doesn't? That could be where the problem is, now that I'm looking about it? Because I think I've encountered this same bug trying to use gridview:scrollToTop()
, which also uses self:setScrollPosition()
!
BUT, I've also tried using grid2:selectNextColumn() before it comes into view, and for some reason that doesn't seem to work until after it's visible? So, that's all I've figured out so far!
Any help is, of course, much appreciated!