right edge smart screen button positioning issues

Hi Corona Peeps.

I’m a rusty php, mysql website developer who picked up Corona SDK for the first time a weekago.
So I’ve started to build my own point and click adventure game. (I like to jump right in).

I’m trying to position a “next” (right arrow pointing) button for users to click on to move to the next backstory description. The code could also be used for scrolling through an inventory in the future as well.

Here’s the thing.

In my config.lua file i’ve set the enviroment to…

    content =
    {
        width = 320,
        height = 480,
        scale = “letterbox”,
        xAlign = “center”,
        yAlign = “center”,
        fps = 30,

    }

So when I print the results of the various different display width settings, they all say… 480 or bigger if viewing in iPhone X etc.

In order to get my right arrow to sit 10 units in from the right edge of any smart devices I’ve put the following line of code:

    local btnRightSettings = {
        left = display.viewableContentWidth - 10,
        top = display.safeScreenOriginY + 40,
        id = “btnNext”,
        label = “Next”,
        onEvent = handleRightButtonEvent,
        defaultFile = “UI/ArrowRIGHT_W500xX500_Default.png”,
        overFile = “UI/ArrowRIGHT_W500xX500_OnClick.png”,
        width = 40,
        height = 40
        }
 

This positions the button perfectly on the following devices.

  • HTC Sensation
  • Samsung Galaxy S3 & S5
  • Amazon TV
  • Ouya
  • Apple TV
  • HTC Windows Phone 8S
  • Nokia Lumia 920
  • Samsung ATVIS

But with these devices it’s positioned all over the place

  • Kindle 7" & 8.9" (the tip of the button is off screen on both these devices.)
  • iPhone 4S, iPad Air, Pro, & Mini (half of the button is off screen)
  • iPhone 5 (button is positioned to far into the centre of the screen)
  • iPhone 6 & 6Plus (positioned to far into the centre of the screen but less then the iPhone 5)
  • iPhone X (positioned around 20% to far into the screen)
    I’ve not yet tested everything else, but you get the idea.

Is there a method call I should be using instead of display.viewableContentWidth - 10?
Is there a way to write a settings function that identifies the device in use and then runs code relevant to it, to position the button accordingly? (I’m a perfectionist and normally just CSS my way out of these issues in other coding environments).
Is this “life” with Lua and something I just put up with?

Advice and guideance please :slight_smile:

You might want to read this:

https://coronalabs.com/blog/2018/08/08/understanding-content-scaling-in-corona/

It will help with all kinds of topics understanding positioning topics.

Rob

Hi Rob,

Thanks for taking the time to reply.
I had followed this before messaging.

Thanks anyhow.
Ange

You want display.actualContentWidth instead.

You can use  display.screenOriginX  and  display.screenOriginY  to always find the coordinates for the left and top edges of the screen. If you position your display objects using them, they’ll always be by those edges.

For right and bottom edges, you’d need to apply some basic math. There are two methods that I can think of.

First, if you substract display.contentWidth from display.actualContentWidth, you’ll find out how much shorter (or wider) the current device is compared to your config.lua states. As the displays expand to both left and right, you can divide the difference by 2 (or multiply by 0.5) to find out how much the screen expands to both left and right.

Second, you could simply add display.actualContentWidth to display.screenOriginX and you’d reach approximately the same point as above.

The curious thing is that these should yield the same exact answer, but there is slight variance. For instance, the right edge on iPhone X by using methods:
1) (display.contentWidth-display.actualContentWidth)*0.5+display.actualContentWidth = 586.45 ≈ 586.
2) display.screenOriginX+display.actualContentWidth = 586.91 ≈  587.

If Corona uses math.ceil with coordinates, then there’s no difference. If it uses math.round, then there is.

The reason for this that display.actualContentWidth has fractions of pixels, so the resulting calculations aren’t pixel perfect using either method. I’m sure it is due to scaling, but this shouldn’t really be happening as the display can’t have fractions of pixels. I’d really appreciate it if someone could chime in on why this is as it has been bothering me for years. :smiley:

Also! You may want to use the safe area APIsfor placing buttons thanks to all the notches and rounded edges in current devices.
 

Perhaps the blog post wasn’t as clear as I thought.

It says:

Getting to the right side in this example is a little bit tricker. While display.actualContentWidth will return 568, which is the actual width of the content area, with the content area being centered, it will be 44 pixels too far to the right. To position a button at the right, bottom, you still have to use the display.screenOrigin* values:

 

 

 

 

 

Lua

1

2

button.x = display.actualContentWidth - 25 + display.screenOriginX

button.y = display.actualContentHeight - 25 + display.screenOriginY

If you have rounded corners or notches, you have to use the safe* versions of these making this:

1

2

button.x = display.safeActualContentWidth - 25 + display.safeScreenOriginX

button.y = display.safeActualContentHeight - 25 + display.safeScreenOriginY

where 25 is the number of pixels you want the center of the button to be from the right, bottom edge. Adjust that to taste.

Keep in mind, the safe* API’s really only work on iOS. We are working on getting them functional for Android, but it requires moving to Android SDK level 28 and we are at 27. It’s a pretty big thing for us to make this change.

The reason why you have to add in the screenOriginX/Y values is that 0, 0 is not the top, left of the physical screen if the device is wider/taller than the defined content area, which it most likely will be on phones. 

Rob

You might want to read this:

https://coronalabs.com/blog/2018/08/08/understanding-content-scaling-in-corona/

It will help with all kinds of topics understanding positioning topics.

Rob

Hi Rob,

Thanks for taking the time to reply.
I had followed this before messaging.

Thanks anyhow.
Ange

You want display.actualContentWidth instead.

You can use  display.screenOriginX  and  display.screenOriginY  to always find the coordinates for the left and top edges of the screen. If you position your display objects using them, they’ll always be by those edges.

For right and bottom edges, you’d need to apply some basic math. There are two methods that I can think of.

First, if you substract display.contentWidth from display.actualContentWidth, you’ll find out how much shorter (or wider) the current device is compared to your config.lua states. As the displays expand to both left and right, you can divide the difference by 2 (or multiply by 0.5) to find out how much the screen expands to both left and right.

Second, you could simply add display.actualContentWidth to display.screenOriginX and you’d reach approximately the same point as above.

The curious thing is that these should yield the same exact answer, but there is slight variance. For instance, the right edge on iPhone X by using methods:
1) (display.contentWidth-display.actualContentWidth)*0.5+display.actualContentWidth = 586.45 ≈ 586.
2) display.screenOriginX+display.actualContentWidth = 586.91 ≈  587.

If Corona uses math.ceil with coordinates, then there’s no difference. If it uses math.round, then there is.

The reason for this that display.actualContentWidth has fractions of pixels, so the resulting calculations aren’t pixel perfect using either method. I’m sure it is due to scaling, but this shouldn’t really be happening as the display can’t have fractions of pixels. I’d really appreciate it if someone could chime in on why this is as it has been bothering me for years. :smiley:

Also! You may want to use the safe area APIsfor placing buttons thanks to all the notches and rounded edges in current devices.
 

Perhaps the blog post wasn’t as clear as I thought.

It says:

Getting to the right side in this example is a little bit tricker. While display.actualContentWidth will return 568, which is the actual width of the content area, with the content area being centered, it will be 44 pixels too far to the right. To position a button at the right, bottom, you still have to use the display.screenOrigin* values:

 

 

 

 

 

Lua

1

2

button.x = display.actualContentWidth - 25 + display.screenOriginX

button.y = display.actualContentHeight - 25 + display.screenOriginY

If you have rounded corners or notches, you have to use the safe* versions of these making this:

1

2

button.x = display.safeActualContentWidth - 25 + display.safeScreenOriginX

button.y = display.safeActualContentHeight - 25 + display.safeScreenOriginY

where 25 is the number of pixels you want the center of the button to be from the right, bottom edge. Adjust that to taste.

Keep in mind, the safe* API’s really only work on iOS. We are working on getting them functional for Android, but it requires moving to Android SDK level 28 and we are at 27. It’s a pretty big thing for us to make this change.

The reason why you have to add in the screenOriginX/Y values is that 0, 0 is not the top, left of the physical screen if the device is wider/taller than the defined content area, which it most likely will be on phones. 

Rob