Button touch event NOT propagating through to button underneath

Sure thing, I’m always up for a bit of code hacking!

Let’s assume you have your image sheet configured, named “imageSheet”, and your 9-slice rectangle will go inside a display group called “rectGroup”. For this example, we’ll also assume that the image frames to build it begin at the top-left corner (frame 1) and proceed across to the top-right corner (frame 3), then wrap to the middle “row” (frames 4-6) and finally the bottom “row” (frames 7-9).

[lua]

local rectCenterX = display.contentCenterX

local rectCenterY = display.contentCenterY

local rectWidth = 200

local rectHeight = 300

– Create the left portion of the rectangle

local rectTopLeft = display.newImage( rectGroup, imageSheet, 1 )

local rectMiddleLeft = display.newImage( rectGroup, imageSheet, 4 )

local rectBottomLeft = display.newImage( rectGroup, imageSheet, 7 )

– Create the right portion of the rectangle

local rectTopRight = display.newImage( rectGroup, imageSheet, 3 )

local rectMiddleRight = display.newImage( rectGroup, imageSheet, 6 )

local rectBottomRight = display.newImage( rectGroup, imageSheet, 9 )

– Create the middle portion of the rectangle

local rectTopMiddle = display.newImage( rectGroup, imageSheet, 2 )

local rectMiddle = display.newImage( rectGroup, imageSheet, 5 )

local rectBottomMiddle = display.newImage( rectGroup, imageSheet, 8 )

– Top positioning/sizing

rectTopLeft.x = rectCenterX + ( rectTopLeft.contentWidth * 0.5 )

rectTopLeft.y = rectCenterY + ( rectTopLeft.contentHeight * 0.5 )

rectTopMiddle.width = rectWidth - ( rectTopLeft.contentWidth + rectTopRight.contentWidth )

rectTopMiddle.x = rectTopLeft.x + ( rectTopLeft.contentWidth * 0.5 ) + ( rectTopMiddle.contentWidth * 0.5 )

rectTopMiddle.y = rectTopLeft.y

rectTopRight.x = rectTopMiddle.x + ( rectTopMiddle.contentWidth * 0.5 ) + ( rectTopRight.contentWidth * 0.5 )

rectTopRight.y = rectTopLeft.y

– Middle positioning/sizing

rectMiddleLeft.height = rectHeight - ( rectTopLeft.contentHeight + rectTopRight.contentHeight )

rectMiddleLeft.x = rectTopLeft.x

rectMiddleLeft.y = rectTopLeft.contentBounds.yMax + ( rectMiddleLeft.height * 0.5 )

rectMiddle.width = rectTopMiddle.width

rectMiddle.height = rectHeight - ( rectTopLeft.contentHeight + ( rectTopRight.contentHeight ) )

rectMiddle.x = rectTopMiddle.x

rectMiddle.y = rectMiddleLeft.y

rectMiddleRight.height = rectHeight - ( rectTopLeft.contentHeight + rectTopRight.contentHeight )

rectMiddleRight.x = rectTopRight.x

rectMiddleRight.y = rectMiddleLeft.y

– Bottom positioning/sizing

rectBottomLeft.x = rectTopLeft.x

rectBottomLeft.y = rectMiddle.y + ( rectMiddle.contentHeight * 0.5 ) + ( rectBottomLeft.contentHeight * 0.5 )

rectBottomMiddle.width = rectTopMiddle.width

rectBottomMiddle.x = rectTopMiddle.x

rectBottomMiddle.y = rectBottomLeft.y

rectBottomRight.x = rectTopRight.x

rectBottomRight.y = rectBottomLeft.y

[/lua]

OK, so I lied about it being about 10 lines, but it’s still not bad. :) Toss this into a function and it could potentially be used over and over throughout your code. You could even make it more elegant by passing in an image sheet reference to the function and then you’d have the ability to create different styled rectangles using different image sheets.

Hope this helps,

Brent

That’s awesome and super helpful. Thank you!!

You can, actually, tweak the widget buttons to propagate touch events.  Full example code below (as long as you have a button image file at images/button.png or change the reference to point to a button image somewhere else)

local widget = require("widget") local options = { x = display.screenOriginX + 5, y = display.screenOriginY + 5, defaultFile = "images/button.png", label = "Button!", } local button = widget.newButton(options) button.anchorX, button.anchorY = 0, 0 button.touch = function(self, event) -- Overwrite the widget button's touch field with a new function if event.phase == "began" then print("button") return true -- Don't propagate on "began" phase end -- For anything besides "began", it automatically returns nil, which equates to false, which propogates the touch event end local function globalTouch(event) print("global touch"..event.x..event.y) end Runtime:addEventListener("touch", globalTouch)

This example is just a single touch, but I had to do this for a runtime event multitouch handler in a certain app, because otherwise the runtime touch function would never receive the touch “ended” if you moved your finger over a button before releasing.

I didn’t have to worry about what would happen if the user started a touch on the button and then dragged off of it because if they started a touch on any of my buttons, it would change scenes anyway, but it’s something to keep in mind if you’re not leaving the scene or otherwise disabling your other touch events when pressing the button.

As a note, you can do something similar with some of the other widgets.  For example, I made a “breakable” slider bar widget by jailbreaking the regular slider widget.  My slider’s handle can be broken off of the slider bar by sliding it to the end too quickly, making the handle fall to the bottom of the screen and bounce/roll around.  You can then pick it back up and reattach it to the slider from either end of the slider bar, and the slider is still fully functional (only while the handle is attached)! :slight_smile:

Whenever you want to see the fields in a table, try using this:

local function printTable(table) print("=========================================") for k, v in pairs(table) do print(k, "", v) end print("=========================================") end

Edit: Changed button anchoring and position a bit…forgot to do so first time.