How to add your own functions to “gc”

Hi all,

As you know, in order to do graphical things in Lua on the Nspire platform, you have to deal with gc and its methods TI created, like drawString, drawRect, fillArc, etc.

Well, what if you wanted to make a drawRoundRect routine ?

You could certainely do something like :

function drawRoundRect(gc, x, y, wd, ht, rd)
        if rd > ht/2 then rd = ht/2 end
        gc:drawLine(x + rd, y, x + wd - (rd), y)
        gc:drawArc(x + wd - (rd*2), y + ht - (rd*2), rd*2, rd*2, 270, 90)
        gc:drawLine(x + wd, y + rd, x + wd, y + ht - (rd))
        gc:drawArc(x + wd - (rd*2), y, rd*2, rd*2,0,90)
        gc:drawLine(x + wd - (rd), y + ht, x + rd, y + ht)
        gc:drawArc(x, y, rd*2, rd*2, 90, 90)
        gc:drawLine(x, y + ht - (rd), x, y + rd)
        gc:drawArc(x, y + ht - (rd*2), rd*2, rd*2, 180, 90)
end
 
function on.paint(gc)
        drawRoundRect(gc, 100, 50, 20, 15, 5)
        ...
end

Indeed, that works.

But wouldn’t it be cool to actually have it like, “gc:drawRoundRect(100,50,20,15,5)”, so it can feel way more natural and wouldn’t need you to explicitely pass gc as an argument ? 😉
Well, here is the definitive solution to this, by Jim Bauwens 😉

function AddToGC(key, func)
        local gcMetatable = platform.withGC(getmetatable)
        gcMetatable[key] = func
end
 
local function drawRoundRect(gc, x, y, wd, ht, rd)
        -- the code above
end
 
AddToGC("drawRoundRect", drawRoundRect)
 
function on.paint(gc)
        gc:drawRoundRect(100, 50, 20, 15, 5)
        ...
end

One more thing :

You may have noticed the use platform.withGC, which is an API “2.0”+ (OS 3.2+) function. Here’s how to “recreate” it for earlier versions :

if not platform.withGC then
        platform.withGC = function(func, ...)
            local gc = platform.gc()
            gc:begin()
            func(..., gc)
            gc:finish()
        end
    end

[Update] : John Powers from TI commented that this definition of platform.withGC has some limitations, and proposed this better version (thanks !) :

if not platform.withGC then
    function platform.withGC(f)
        local gc = platform.gc()
        gc:begin()
        local result = {f(gc)}
        gc:finish()
        return unpack(result)
    end
end

One thought on “How to add your own functions to “gc””

  1. The definition of platform.withGC is problematic. “…” can only be used as the last parameter in function calls. And if func returns values, they are not passed on as the return value of platform.withGC.

    Here is the definition of platform.withGC I use:

    if not platform.withGC then
        function platform.withGC(f)
            local gc = platform.gc()
            gc:begin()
            local result = {f(gc)}
            gc:finish()
            return unpack(result)
        end
    end

Leave a Reply