Same aspect-ratio and coordinates for all screen sizes

Share your advanced knowledge/code with the community.
tj1010
Posts: 201
Joined: Wed May 27, 2015 1:36 pm
Contact:

Same aspect-ratio and coordinates for all screen sizes

Post by tj1010 »

This is some helper code for dynamic UI/UX I wrote in some minutes. I don't think I missed anything, but if I did I'll update this post. It's meant to save you a lot of lines of code and uses percentage internally(I've never found a clean way to use font-size with respect to screen size). I believe this is how everyone recommends you do adaptive apps.

NOTE: Assumes raising width is raising height and lowering height is lowering width on all functions(maintains aspect ratios). It's pretty much made to maintain coordinate and aspect for anything across all screen sizes. It supports up to 10,000px where it calculates aspect-ratio which is over two-times UHD/4k, so it's good for at least a decade.

Code: Select all

;pass old width and old screen-width for new image width
Procedure.l DynamicWidth(width.l,screenw.l)
  ExamineDesktops()
  Protected dw=DesktopWidth(0)
  ProcedureReturn Round(((((width * 100) / screenw) * dw) / 100),#PB_Round_Nearest)
EndProcedure
;pass old height and old screen-height for new image height
Procedure.l DynamicHeight(height.l,screenh.l)
  ExamineDesktops()
  Protected dh=DesktopHeight(0)
  ProcedureReturn Round(((((height * 100) / screenh) * dh) / 100),#PB_Round_Nearest)
EndProcedure
;pass old x and old screen-width for new x
Procedure.l DynamicX(x.l,screenw.l)
  ExamineDesktops()
  Protected dx=DesktopWidth(0)
  ProcedureReturn Round(((((x * 100) / screenw) * dx) / 100),#PB_Round_Nearest)
EndProcedure
;pass old y and old screen-height for new y
Procedure.l DynamicY(y.l,screenh.l)
  ExamineDesktops()
  Protected dy=DesktopWidth(0)
  ProcedureReturn Round(((((y * 100) / screenh) * dy) / 100),#PB_Round_Nearest)
EndProcedure
;pass new image-width and aspect-ratio to get new image-height
Procedure.l DynamicAspectHeight(image.l,width.l,aspect.f)
  Protected i.l
  If width<ImageWidth(image)
    For i = ImageHeight(image) To 0 Step -1
      If StrF(width / i,2) = StrF(aspect,2) : ProcedureReturn i : EndIf
    Next
  Else
    For i = ImageHeight(image) To 10000 Step -1
      If StrF(width / i,2) = StrF(aspect,2) : ProcedureReturn i : EndIf
    Next
  EndIf
EndProcedure
;pass new image-height and aspect-ratio to get new image-width
Procedure.l DynamicAspectWidth(image.l,height.l,aspect.f)
  Protected i.l
  If ImageHeight(image)<height
    For i = ImageWidth(image) To 10000
      If StrF(i / height,2) = StrF(aspect,2) : ProcedureReturn i : EndIf
    Next
  Else
    For i = ImageWidth(image) To 0 Step -1
      If StrF(i / height,2) = StrF(aspect,2) : ProcedureReturn i : EndIf
    Next
  EndIf
EndProcedure
;pass old aspect-ratio to get new width for current-height(you want to always use device height but dynamic width)
Procedure.l DynamicScreenWidth(aspect.f)
  Protected i.l
  ExamineDesktops()
  For i = DesktopWidth(0) To 0 Step -1
    If StrF(i / DesktopHeight(0),2) = StrF(aspect,2) : ProcedureReturn i : EndIf
  Next
EndProcedure
Fred
Site Admin
Posts: 1510
Joined: Mon Feb 24, 2014 10:51 am

Re: Same aspect-ratio and coordinates for all screen sizes

Post by Fred »

Sounds interesting, could you post some examples using your code ?
tj1010
Posts: 201
Joined: Wed May 27, 2015 1:36 pm
Contact:

Re: Same aspect-ratio and coordinates for all screen sizes

Post by tj1010 »

You basically use DynamicX and DynamicY to get coordinates based on percentage across screen dimensions, DynamicWidth and DynamicHeight to get percentage based width or height depending on if screen is taller or wider, and DynamicAspect* with the alternate dimension of width or height used in DynamicWidth and DynamicHeight.

I use them in a 300ms window timer and check against globals inside the timer callback to see if screen resolution has changed using ExamineDesktops()

Things I learned:
  • If you use the aspect functions you have to re-map x and y which requires a lot of code and eliminates the purpose of this since it can't be done generically
  • If you just use DynamicWidth and DynamicHeight and DynamicX and DynamicY functions everything works except images are pixelated to do aspect-ratio change when, for example, on mobile you rotate aspect-ratios.
  • The built-in Dialog library is awesome, but it doesn't have scaling support, so on mobile-rotate layouts are broken or panned where you have a lot of images, and maybe other gadgets too. A fix would be some form of auto for width and height for <image> elements in <gridbox>, <singlebox>, or <multibox> elements. The <gridbox> colexpand and rowexpand parameters don't seem to have an effect. Especially when horizontal gets smaller and everything needs scaled down.

    If dialog elements like <image> could be scaled without breaking aspect using some form of parameters the dialog library would work everywhere. I could test more with the min&max parameters and <image> to see what can be done but I assume they don't maintain aspect and that heavily effects UI in the form of pixelation
  • I still need to see if we can use image gadgets behind things but I haven't had time. Like a PNG the dimension of a window behind a dialog or just unbound gadget-list-gadgets
Post Reply