Auto-draw ui.newLabel() thru object-property definitions in Tiled

By adding the following snippet to your lime-enabled code after lime.loadMap() and before lime.createVisual():

[lua]local onUILabelType = function(object)
local colors
if object.textColor then
colors = split(object.textColor,",")
for i,v in ipairs(colors)do colors[i] = tonumber(colors[i]) end
end
local nl = ui.newLabel{
textColor = colors,
bounds = {object.x,object.y,object.width,object.height},
text = object.text or object.name,
align = object.align,
size = object.size and tonumber(object.size),
font = object.font,
offset = object.offset and tonumber(object.offset)
}
object.objectLayer.group:insert(nl)
end

map:addObjectListener(“UILabel”, onUILabelType)[/lua]

You can now add new labels by creating objects in Tiled with a type of “UILabel”.
The object’s x,y,width,height are automatically used for the label’s bound.
The object’s properties font,size,align,text,textColor are used for the label definition.

By default the object name is used for the label text, if no “text” property is defined.

The label display-object is inserted into the object.objectLayer.group (which I think is the correct place (?))

Another little step towards a GUI-designed Corona app…

Enjoy, Frank.

[import]uid: 8093 topic_id: 6695 reply_id: 306695[/import]

Fantastic! I was planning on creating something like this myself when the workload lightened but once again the community has beaten me to it! :slight_smile:

When I get things more feature complete (as if that will ever happen) and we get out of Beta, would having this sort of stuff built into Lime be a popular venture? [import]uid: 5833 topic_id: 6695 reply_id: 23439[/import]

Absolutely!

Having a number of those pre-fab recipes that would come standard with Lime would be fantastic.

By playing a little with a naming convention you could avoid name-clashes - like preconfigure Lime to automatically create Labels only when the object-type is “limeUILabel”.

It would also give us some example code that we could build-on as it is kind of tricky to get it right.

In particular, I’m worried about memory leaks as those Label display-objects should get destroyed when the map is torn down… did I add it to the map/layer tree at the right place (“object.objectLayer.group:insert(nl)”), such that it would get removed correctly?

In the mean time I added a little to the code:
[lua]local onUILabelType = function(object)
local colors
if object.textColor then
colors = split(object.textColor,",")
for i,v in ipairs(colors)do colors[i] = tonumber(colors[i]) end
end
local nl = ui.newLabel{
textColor = colors,
bounds = {object.x,object.y,object.width,object.height},
text = object.text or object.name,
align = object.align,
size = object.size and tonumber(object.size),
font = object.font,
offset = object.offset and tonumber(object.offset)
}
object.objectLayer.group:insert(nl)
object.displayObject = nl
end[/lua]

In that last line of the handler, I added a reference to the Label display-object thru the object’s “displayObject” attribute. In that way I can get to my Label thru the object-name later to change the text, for example.

But it also adds another reference to the display-object, which could give issues with the garbage collection if it doesn’t get removed properly. Can you comment on that?

-FS. [import]uid: 8093 topic_id: 6695 reply_id: 23449[/import]

I just thought I’d add this quick bit of code in as well as one for a button just to sort of test the waters and was thinking about buttons and their event handlers. Without reflection I’m not sure of a way to get the actual function just from a the string that gets passed in through a Tiled property. Any ideas? [import]uid: 5833 topic_id: 6695 reply_id: 23656[/import]

Interesting as I was waiting for the working tile-object support to see if I could make buttons to work.

In preparation I “converted” some of the buttons into a spritesheet already and made some changes to ui.lua to accept realized display-objects for default/over instead of image-fnames…

As far as the button handlers are concerned, they have to be button-instance specific - that’s why the tile-object support is crucial. By giving the tile-object a unique name, you can find the Button instance thru your lime-facilities.

By using a similar lookup table as I used in the other example, you can refer to a button-handler by name: eventHandlerT[“onButtonAPress”] = onButtonAPress

I have a working example where I realize the button default/over images for a “normal” object:

[lua]local eventHandlerT = {}

local onButtonAPress = function(event)
if player.canJump then
player:applyLinearImpulse(0, -5, player.x, player.y)
player.state = STATE_JUMPING
player:prepare(“anim” … player.state)
player:play()
end
end
eventHandlerT[“onButtonAPress”] = onButtonAPress

local onButtonType = function(object)
for k,v in pairs(object) do print(k,v) end
local d = display.newImage(“buttonA.png”)
local o = display.newImage(“buttonA_over.png”)
ui.newButton{
default = d,
over = o,
x = object.x,
y = object.y,
onPress = eventHandlerT[“onButtonAPress”]
}
end
map:addObjectListener(“Button”, onButtonType)[/lua]

It’s a bit of a hack but it should give you an idea where I was going with this… waiting for your tile-object support to do it “right”, which may be very different from what I have here :wink:

Regards, Frank.
[import]uid: 8093 topic_id: 6695 reply_id: 23688[/import]

2.8 is out now with Tile Object support so feel free to go crazy and get it all working :slight_smile: [import]uid: 5833 topic_id: 6695 reply_id: 23693[/import]