Smooth scrolling gridview

I'm trying to use a gridview as a message box. I thought it would be a simple way to scroll text in a window, however, the scrolling only update after the up or down button is released and then far less than I would have expected.

NB On the device it scrolls much better. Which is odder, as the simulator is over powered.

local pd <const> = playdate
local gfx <const> = pd.graphics
local ui <const> = pd.ui
local geo <const> = pd.geometry

class('MessageBox').extends(gfx.sprite)

---@param textItems table Array of strings
function MessageBox:init(textItems)
    printTable(#textItems .. ' textItems', textItems)
    self:setCenter(0,0)
    self:setSize(300,100)
    self:moveTo(100, 50)
    self:add()
    local listview <const> = ui.gridview.new(0, 20)
    listview.backgroundImage = gfx.nineSlice.new('simple-nine-slice', 8, 8, 1, 1)
    listview:setNumberOfRows(#textItems)
    listview:setCellPadding(4, 4, 2, 2)
    listview:setContentInset(8, 8, 8, 8)
    listview:setNumberOfRows(#textItems)
    listview:setNumberOfColumns(1)
    function listview:drawCell(section, row, column, selected, x, y, width, height)
        gfx.drawTextInRect(textItems[row], x, y, width, height, nil, '...', kTextAlignment.center)
    end
    self.listview = listview
end

function MessageBox:draw()
    local spriteWidth, spriteHeight = self:getSize()
    self.listview:drawInRect(0, 0, spriteWidth, spriteHeight)
end

function MessageBox:update()
    local scrollSpeed = 10
    local listview <const> = self.listview
    local x, y = listview:getScrollPosition()
    print('Pos', y)
    print(listview:getScrollPosition())
    if (pd.buttonIsPressed(pd.kButtonDown)) then
        listview:setScrollPosition(x, y + scrollSpeed)
    elseif (pd.buttonIsPressed(pd.kButtonUp)) then
        listview:setScrollPosition(x, y - scrollSpeed)
    end
end

Any advise on what's happening or how to fix it?

I think I remember seeing someone talk about this in discord.

I think listview uses timers for the scrolling. So you need to call
playdate.timer:updateTimers() every playdate update.

Yeah like the first line in the docs says this:

Some notes:

That's called in update.

function playdate.update()
    gfx.clear()
    gfx.sprite.update()
    timer.updateTimers()
end

Ah I just realized this has been put inside a sprite.
I don't think draw will get called if the sprite hasn't been marked dirty.
Have you set MessageBox:setAlwaysRedraw ? otherwise you might need too to call self:markDirty() after listview:setScrollPosition.

I hadn't tried that, I have tried it now with no difference in behaviour.
I've tried adding self:markDirty() to the end of MessageBox:update() & MessageBox:draw() functions and also tried adding self:alwaysredraw(true) to the end of the MessageBox:init() function.

Hi, just came... So just to understand, you are trying to make a sort of whatsapp... Right?

WhatsApp, Facebook and Instagram combined. I'm speaking with potential investors in the pub next week. :playdate_wink:

No, I want to be able to display a message to the user in the game. I have something that works now using normal text but I thought that the gridview with a row per line would have been a neat solution and avoid me reinventing the wheel.

How are people communicating? Playdate games only have Internet access in the simulator.

I believe David was making a joke...

However, in the next SDK version (currently in beta) games will be given access to simple TCP and HTTP networking protocols.

2 Likes

Honestly I am not great on coding but on designing or naming , I can 100% help