A simple text class

I made this simple class the create text.

Text = class()

function Text:init(string, x, y)
    -- optional parameters
    self.string = string or ""
    self.x = x or 0
    self.y = y or 0
    -- Codea defaults
    self.fill = fill()
    self.font = font()
    self.fontSize = fontSize()
    self.textAlign = textAlign()
    self.textMode = textMode()
    self.textWrapWidth = textWrapWidth()

function Text:draw()
    if self.fill then
    text(self.string, self.x, self.y)

I can set all the text’s properties and it uses pushStyle() resetStyle() and popStyle() to preserve the properties when drawing. The optional parameters allow me to create a valid object and then set the properties at a later time and all the properties are initially set with Codea’s defaults.

Now I’m trying to set width and height for the class, but I’m having difficulty. The text’s dimensions are accessed using the textSize() function however, the return value are dependent of the style properties applied to it. Therefore, I need to apply the styles before I can set the dimension of my width and height. I thought of simply placing the set of the width and height in the draw function before the pushStyle(). But, if a programmer needs to use the text’s dimensions in another object declaration they won’t be properly set. I also, thought to call the draw function once from the constructor to insure the values are set (dispute this being a silly idea), but even then if a programmer sets the font size after he or she creates the object the dimensions will not be corrected until after the next draw call. Any thoughts or ideas on a solution?

Also, a side note, I was thinking about creating a game making library for Codea. I’ve used Flixel for a while now and would like to create something similar for Codea. If anyone has ideas or wants to get the ball rolling let me know.


So are you thinking of providing width and height purely as getters? You could try the following:

function Text:size()

    -- Set all the styles

    local w,h = textSize( self.string )


    return w,h

Or maybe you could do the following:

function Text:__index( key )
    if key == "width" then
        local w,_ = self:size()
        return w
    elseif key == "height" then
        local _,h = self:size()
        return h

This would allow you to access myText.width and myText.height, each access would compute the size from scratch. You could get clever and cache the size once computed, and then set a dirty flag if one of the Text object’s properties changes.

With your code I get error: [string "function setup()..."]:9: attempt to call method 'draw' (a nil value) Pausing playback. Think it has to do with the __index function not calling functions properly.

Sorry @Roo that’s a big oversight on my part.

Unfortunately rawset and rawget are disabled in Codea. I’ll be re-enabling them after Codea 1.4 but it makes overriding __index impossibly awkward. (Or just impossible)

The __index method should return rawget(self, key) at the end, and __newindex should do rawset(self, key,value) but of course, they can’t.

Edit: Though what about the Text:size() method, do you see any disadvantages to it?