Is there a way to add a common function to ALL display objects

I’m in the process of changing all of my “setReferencePoint” functions. I agree that having custom anchor points is more useful, but for now the 9 basic points we had before are satisfactory for me. So I’m changing all of my 

obj:setReferencePoint(display.TopLeftReferencePoint)

to

obj.anchorX, obj.anchorY = 0, 0 

I’ve made a function where I can provide an object and a string such as “TopLeft” to make the process of switching to anchor points simpler.

function setAnchors(obj, pos) local x, y = 0.5, 0.5 if pos == "TopLeft" then x, y = 0, 0 elseif pos == "Top" then x, y = 0.5, 0 elseif pos == "TopRight" then x, y = 1, 0 elseif pos == "CenterLeft" then x, y = 0, 0.5 elseif pos == "Center" then x, y = 0.5, 0.5 elseif pos == "CenterRight" then x, y = 1, 0.5 elseif pos == "BottomLeft" then x, y = 0, 1 elseif pos == "Bottom" then x, y = 0.5, 1 elseif pos == "BottomRight" then x, y = 1, 1 end obj.anchorX, obj.anchorY = x, y end

setAnchors(myObj, "TopLeft")

What I want to know is, is there a way I could create a function that can be called by all display objects?

That way I could simply redefine setReferencePoint() to perform my function above, and the calling object would be passed in as an argument automatically.

I’m guessing that either it’s not possible, or it’s really simple and I’ve overlooked something.

I tried to accomplish the same thing but had no luck overriding the display method using all the means that I’m aware of. Perhaps someone else has the secret. I ended up with the same method you’re using. Would be nice to just add it to the display table globally though.

I understand what you’re thinking but I’m guessing Corona’s own code doesn’t allow for easy adding of methods to displayObjects. The safest way to do what you ask is to use wrappers, which is a pretty common approach for bigger projects, ie: roll your own makeAnimal() and add the method to all animals rather than try to make it a core corona method. It’s more work upfront but arguably safer for your codebase.

Makes a lot of sense @richard9. Could easily be a generic mod.

Pseudo code: apologies for any formatting issues, typing from phone

local function myDisplayNewImage( ... ) local img = display.newImage( ... ) function img:setReferenceFunc( refPoint ) myRefPointFunc( self, refPoint ) end return img end -- then you can do: local myImg = myDisplayNewImage( "img.png" ) myImg:setReferenceFunc( "TopLeft" )

Something like that should do the trick.

Thanks everyone. I guess I’ll go with a method like Danny’s.

I’ve done it this way to save me having to change any other code in my apps (for now at least)

function setAnchors(obj, pos) if pos == display.TopLeftReferencePoint then obj.anchorX, obj.anchorY = 0, 0 elseif pos == display.TopCenterReferencePoint then obj.anchorX, obj.anchorY = 0.5, 0 elseif pos == display.TopRightReferencePoint then obj.anchorX, obj.anchorY = 1, 0 elseif pos == display.CenterLeftReferencePoint then obj.anchorX, obj.anchorY = 0, 0.5 elseif pos == display.CenterReferencePoint then obj.anchorX, obj.anchorY = 0.5, 0.5 elseif pos == display.CenterRightReferencePoint then obj.anchorX, obj.anchorY = 1, 0.5 elseif pos == display.BottomLeftReferencePoint then obj.anchorX, obj.anchorY = 0, 1 elseif pos == display.BottomCenterReferencePoint then obj.anchorX, obj.anchorY = 0.5, 1 elseif pos == display.BottomRightReferencePoint then obj.anchorX, obj.anchorY = 1, 1 else obj.anchorX, obj.anchorY = 0.5, 0.5 end end display.defaultNewImageRect = display.newImageRect display.defaultNewRect = display.newRect display.defaultNewRoundedRect = display.newRoundedRect display.defaultNewText = display.newText display.defaultNewGroup = display.newGroup display.newImageRect = function(...) local img = display.defaultNewImageRect(...) function img:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return img end display.newRect = function(...) local rect = display.defaultNewRect(...) function rect:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return rect end display.newRoundedRect = function(...) local rrect = display.defaultNewRoundedRect(...) function rrect:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return rrect end display.newText = function(...) local txt = display.defaultNewText(...) function txt:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return txt end display.newGroup = function() local g = display.defaultNewGroup() function g:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return g end

I just stored and then redeclared the display functions, this way everything else can stay the same.

You don’t need to unpack the arguments in your function call.

Just pass the 3 periods to the function. Ex func( … )

You’re quite right, I’ve edited the post.

Awesome.
Glad it all worked out for you :slight_smile:

I’ve also added a file to the code exchange:

http://developer.coronalabs.com/node/38649

Just require it to re-enable the setReferencePoint function, saves people having to manually switch everything over from setRef to anchor points.

@AlanPlantPot  Nice!

Wow!  Thanks for sharing that, AlanPlantPot!  

I tried to accomplish the same thing but had no luck overriding the display method using all the means that I’m aware of. Perhaps someone else has the secret. I ended up with the same method you’re using. Would be nice to just add it to the display table globally though.

I understand what you’re thinking but I’m guessing Corona’s own code doesn’t allow for easy adding of methods to displayObjects. The safest way to do what you ask is to use wrappers, which is a pretty common approach for bigger projects, ie: roll your own makeAnimal() and add the method to all animals rather than try to make it a core corona method. It’s more work upfront but arguably safer for your codebase.

Makes a lot of sense @richard9. Could easily be a generic mod.

Pseudo code: apologies for any formatting issues, typing from phone

local function myDisplayNewImage( ... ) local img = display.newImage( ... ) function img:setReferenceFunc( refPoint ) myRefPointFunc( self, refPoint ) end return img end -- then you can do: local myImg = myDisplayNewImage( "img.png" ) myImg:setReferenceFunc( "TopLeft" )

Something like that should do the trick.

Thanks everyone. I guess I’ll go with a method like Danny’s.

I’ve done it this way to save me having to change any other code in my apps (for now at least)

function setAnchors(obj, pos) if pos == display.TopLeftReferencePoint then obj.anchorX, obj.anchorY = 0, 0 elseif pos == display.TopCenterReferencePoint then obj.anchorX, obj.anchorY = 0.5, 0 elseif pos == display.TopRightReferencePoint then obj.anchorX, obj.anchorY = 1, 0 elseif pos == display.CenterLeftReferencePoint then obj.anchorX, obj.anchorY = 0, 0.5 elseif pos == display.CenterReferencePoint then obj.anchorX, obj.anchorY = 0.5, 0.5 elseif pos == display.CenterRightReferencePoint then obj.anchorX, obj.anchorY = 1, 0.5 elseif pos == display.BottomLeftReferencePoint then obj.anchorX, obj.anchorY = 0, 1 elseif pos == display.BottomCenterReferencePoint then obj.anchorX, obj.anchorY = 0.5, 1 elseif pos == display.BottomRightReferencePoint then obj.anchorX, obj.anchorY = 1, 1 else obj.anchorX, obj.anchorY = 0.5, 0.5 end end display.defaultNewImageRect = display.newImageRect display.defaultNewRect = display.newRect display.defaultNewRoundedRect = display.newRoundedRect display.defaultNewText = display.newText display.defaultNewGroup = display.newGroup display.newImageRect = function(...) local img = display.defaultNewImageRect(...) function img:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return img end display.newRect = function(...) local rect = display.defaultNewRect(...) function rect:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return rect end display.newRoundedRect = function(...) local rrect = display.defaultNewRoundedRect(...) function rrect:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return rrect end display.newText = function(...) local txt = display.defaultNewText(...) function txt:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return txt end display.newGroup = function() local g = display.defaultNewGroup() function g:setReferencePoint(refPoint) setAnchors( self, refPoint ) end return g end

I just stored and then redeclared the display functions, this way everything else can stay the same.

You don’t need to unpack the arguments in your function call.

Just pass the 3 periods to the function. Ex func( … )