Widget button not displaying where expected on simulator when iPad is selected.

Hi all,

I am trying to display an image that fills 85% of the screen’s width and then put a button next to it (filling the remaining 15%). The code works on the simulator for all the phone types but if I chose one of the iPads in the simulator, the button appears shifted to the right (only half of it appears and the rest is off screen).

Here is my code ( main.lua):

local widget = require("widget") widget.setTheme( "widget\_theme\_android\_holo\_light" ) function handleButtonEvent(event) print("Button pressed") end title\_width = display.safeActualContentWidth \* 0.85 title\_height = 50 local title = display.newImageRect( "language\_selection\_title\_en.png", title\_width, title\_height ) title.x = display.safeScreenOriginX + title.width / 2 title.y = display.safeScreenOriginY + title.height / 2 b\_button = widget.newButton( { width = display.safeActualContentWidth - title\_width, height = title\_height, left = title\_width + 1 , top = display.safeScreenOriginY, id = "b\_btn", label = "B", onEvent = handleButtonEvent, } )

My config.lua file

application = { content = { width = 320, height = 480, scale = "letterbox", fps = 60, }, }

If I print the b_button.x value, it is correct. Is this just a simulator issue or am I doing something wrong?

Also, is the way I am calculating items location OK or is there a better method (e.g. layout manager)?

I have attached a sample file.

Thanks.

After a bit of reading into the coordiante system of Corona, I managed to fix it as follows:

b\_button = widget.newButton( { width = display.actualContentWidth - title\_width, height = title\_height, left = display.safeScreenOriginX + title\_width + 1 , top = display.safeScreenOriginY, id = "b\_btn", label = "B", onEvent = handleButtonEvent, } )

I just needed to position the button using the safeScreenOriginX value.

I made a couple of changes that will help you.

title\_width = display.safeActualContentWidth \* 0.85 title\_height = 50 local title = display.newImageRect( "language\_selection\_title\_en.png", title\_width, title\_height ) title.x = display.safeScreenOriginX + title.width / 2 title.y = display.safeScreenOriginY + title.height / 2 b\_button = widget.newButton( { width = display.safeActualContentWidth \* 0.15, height = title\_height, left = title\_width + 1 + display.safeScreenOriginX, top = display.safeScreenOriginY, id = "b\_btn", label = "B", shape = "rect", onEvent = handleButtonEvent, } )

I made the button width variable and 15% of the viewport since the other graphic is variable and taking up 85%.

Next you need to add the display.safeScreenOriginX to the X location.

If you look at this tutorial: https://coronalabs.com/blog/2018/08/08/understanding-content-scaling-in-corona/  and scroll down to the second image you will see that the iPad screen is wider than the defined content area (You will have to mentally flip the graphic since I drew it in Landscape and you’re app is portrait). X = 0 is right of the left edge by display.safeScreenOriginX points. If you try to draw something around display.safeActualContentWidth, it’s going to be display.safeScreenOriginX points too far to the right. Since display.safeScreenOriginX is going to be a negative value, it pulls the object back to adjust for the iPad’s screen’s left edge being left of X = 0.

Rob

And don’t worry if this makes your head spin. It took me a long time to figure this out. I went through a phase, where I hacked config.lua to detect the device to force display.contentWidth, display.contentHeight to be the bottom, right corner and then just dealt with all the headaches that came with that (which is why we really no longer encourage people to use variable config.lua files).  

The faster you figure out how to use display.screenOriginX, Y, and get used to adding that to edge positioned items, the more successful you will be.

Rob

Thanks Rob. It is a bit confusing but I am slowly getting there.

Maybe this will help. First lets look at an iPhone4S which has an aspect ratio of 1:1.5 (i.e. 640x960 or scaled in our case to 320x480). 0, 0 is the top left, display.contentWidth, display.contentHeight is the bottom right. Those two values will always equal what you set in config.lua, in this case 320, 480.

But you don’t find phones today that are 1:1.5. Most are HDTV’s 16:9 or 1:1.7888888 or something like that. Because you didn’t tell Corona otherwise, it’s going to center the content area on the screen. As a result there is area above the content area and below the content area. When this is scaled based on 320x480, this size screen is actually 320x568. You get 44 points of space above the content area and 44 points below. 

display.actualContentHeight will return 568 which is the physical screen space (480 + the extra 88 points). But 0, 0 isn’t the top of the screen, it’s 44 points down. This means that display.actualContentHeight is 44 points off screen at the bottom. This is where display.screenOriginY comes into play. In this setup, display.screenOriginY will be -44. So the actual bottom of the screen is:  display.actualContentHeight + display.screenOriginY.  The actual top of the screen is 0 + display.screenOriginY (i.e. -44) 

Now lets look at the iPad. In the case of the iPad, 0 will be the actual top and 480 the actual bottom because the content area fits:

Now the iPad is a 1.25:1 aspect ratio, meaning it’s more square than a long rectangle. Now our black areas are left and right of center. After scaling, the screen is 360x480. This means that there is 20 pixels left of the content area and 20 pixels right of the content area.

display.screenOriginY is now 0, since 0, 0 is the top edge, but display.screenOriginX is now -20, representing the left edge. display.actualContentWidth will now be 360, but since 0 on the left-right axis is actually 20 pixels right of the edge, 360 is off screen by 20 pixels. To get the real physical right edge, you need display.actualContentWidth + display.screenOriginX.

You also have the ability to change where the content area starts. By default it’s centered, but if you’re building more of a business like app where everything is going to flow from the top of the screen, there isn’t any reason why you can’t align it to the top left, which will guarantee that 0, 0 will be the top left. And as a benefit, display.actualContentWidth, display.actualContentHeight will be the bottom right. But this creates a problem. Now display.contentCenterX, display.contentCenterY is no longer the center of the screen since you shifted the content area to the left and upward. So if you depend on centering things, you’re going to be miserable doing this. But this can be really helpful if you’re flowing things from the top.

Rob

Thanks again Rob. I (wrongly) assumed that you always start from (0,0) at the top left corner. Now I just have to re-wire my brain to take that into account.