AutoScale Code Module

klaus

Expert
Licensed User
Longtime User
The AutoScale function in the Designer Scripts scales only views added in the Designer but not views added in the code.

To overcome this drawback I wrote a Scale Code module, the first version is already included in the Desiger Scripts & AutoScale Tutorial.

There are two other drawbacks :
  • the internal Labels of ListViews are not scaled.
  • with the Designer Scripts AutoScale function for some smartphone screen sizes especially the 480 x 800 scale 1.5 screen the scaling is not optimal (at least for me).
    With AutoScale on a screen with a resolution of 480 x 800 scale 1.5 (the standard screen is 320 x 480 scale 1) the views are stretched too much horizontally and not enough vertically because of the different width/height ratio.
I added in the Scale Module a new set of equations with two scale factors one for X and one for Y. For smartphone screens (< 6'') the views are scaled according to the screen width and the screen height without the rate factor. For bigger screens the scale factors are modified with the rate factor. For the big screens a rate value of 0 means no scaling and a value of 1 is equivalent to a scaling with %x and %y.

The AutoScale function in the code module scales also the internal views in ScrollViews, ListViews and scales the TextSize property of Spinners.

The Scale code module contains following functions:
  • Initialize Calculates the scale factors
  • SetRate(Rate) Sets a new Rate value and calculates the scale factors
  • ScaleView(View) Scales the given view with its child views
    with the new equations.
  • ScaleViewDS(View) Scales the given view with its child views
    with the Designer Scripts equations
  • ScaleAll(Activity, True) Scales all views of the given Activity or Panel
    with the new equations.
  • ScaleAllDS(Activity, True) Scales all views of the given Activity or Panel
    with the Designer Scripts equations
  • GetDivicePhysicalSize Gets the approximate physical size of the device
  • GetScaleDS Returns the Disigner Scripts scale factor
  • GetScaleX Returns the X scale factor
  • GetScaleX_L Returns the X scale landscape factor
    independant of the current orientation
  • GetScaleX_P Returns the X scale portrait factor
    independant of the current orientation
  • GetScaleY Returns the Y scale factor
  • GetScaleY_L Returns the Y scale landscape factor
    independant of the current orientation
  • GetScaleY_P Returns the Y scale portrait factor
    independant of the current orientation
  • Bottom(View) Returns the Bottom coordinate of the View
  • Right(View) Returns the Right coordinate of the View
  • HorizonzalCenter(View, x1, x2) Centres the View horizontally the view between two coordinates
  • HorizonzalCenter2(V1, V2, V3) Centres the View V1 horizontally between two views V2 and V3
  • VerticalCenter(View, x1, x2) Centres the View horizontally the view between two coordinates
  • VerticalCenter2(V1, V2, V3) Centres the View V1 horizontally between two views V2 and V3
  • IsActivity(View) Returns True if the View is an activity
  • IsPanel(View) Returns True if the View is a Panel
  • SetRight(View, xRight) Sets the Left propety of the view according to the given right coordinate xRight and the views Width property.
  • SetBottom(View, yBottom) Sets the Top propety of the view according to the given bottom coordinate yBottom and the views Height property.
  • SetLeftAndRight(View, xLeft, xRight) Sets the Left and Width properties of view View according to the xLeft and xRight coordinates.
  • SetLeftAndRight2(V1, VL, dxL, VR, dxR) Sets the Left and Width properties of view V1 between the views VL and VR with the given spaces dxL and dxR.
  • SetTopAndBottom(View, yTop, yBottom) Sets the Top and Height properties of view View according to the yTop and yBottom coordinates.
  • SetTopAndBottom2(V1, VT, dyT, VB, dyB) Sets the Top and Height properties of view V1 between the views VT and VB with the given spaces dyT and dyB.
  • SetReferenceLayout(Width, Height, Scale) sets a new layout as the reference layout, allows downscaling. AutoScaleRate has no influence in this case !
The project contains following activities showing different examples of the use of either Designer Scripts AutoScale or scaling with the Code Module.
Activities:
  • Main Main screen with an image and buttons.
  • Setup The setup screen from the GPSExample program.
  • About An about screen example.
  • DBWebView A database table in a WebView with a modified DBUtils version
    scaling the table text size.
  • DBScrollView A database table in a ScrollView.
  • Keyboard A keyboard with views added in the code.
  • ListView A ListView with the internal Labels and Bitmap scaled.
  • Calculator A calculator layout from the RPNCalc project without the functions
    scaled with the new equations.
  • Calculator1 Same as Calculator but scaled with the Designer Scripts equations.
  • Positioning Example with the different positioning routines.
Code modules:
  • Scale The scaling module
  • DBUtils The modified DBUtils module
If you run Calculator and Calculator1 on a 480 x 800 scale 1.5 device you'll see the difference between Designer Scripts scaling and the scaling with the new equations.

If you don't need all routines in the Scale module you can remove those not needed.
The Scale module scales also ScrollView2D views, if you don't use such a view you must comment the corresponding lines or remove them.

I think the code is enough self explanatory.

Best regards.

EDIT: 2013.09.27
Added SetReferenceLayout
Added HorizontalScrollView

EDIT: 2014.11.20
Amended error reported HERE.
 

Attachments

  • AutoScaleExample7.zip
    74 KB · Views: 2,495
Last edited:

moster67

Expert
Licensed User
Longtime User
Thank you Klaus!

I had a quick look at it here in the office testing in particular the ListView-example. Very nice and impressive.

I will test further with my apps this evening.
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Using the AutoScaleExample4, I modified the text portion of the sample for ListView.

In each, (single line, twoline and twoline with bitmap), the test "wraps" in each line. Worse, the twoline pushes the wrapped text to the top of the view so it can't be seen.

Is there an easy way to prevent long lines from wrapping within the listview (like a wrap property)?

Thanks
 

Attachments

  • shot_000005.png
    shot_000005.png
    84.6 KB · Views: 1,922
Upvote 0

klaus

Expert
Licensed User
Longtime User
The problem is not directly in relation with the AutoScale Code Module.
Because the Width, Height and TextSize properties are multiplied by the same factor. So the text will be wrapped with and without AutoScale.

The problem is the same with the standard ListViews.
Unfortunately I haven't found a solution.
I tried using ellipsizing for the internal Labels of the ScrollView but unfortunately it doesn't work.
The only solution I see is to adapt the Label height to the text height and set Gravity to Top

Attached the test program I played with.

Best regards.
 

Attachments

  • LabelEllipsize.zip
    7.8 KB · Views: 945
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
AutoScaleExample4 Test

Hi Klaus,
I 'm just test your AutoScaleExample4,but I have error,How do I correct?

Best Regards
Theera
 
Last edited:
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
I downloaded the zip file from post#1 to make sure that it works OK and it compiles OK.
So without knowing what you have changed in the program it's impossible to help you !

Best regards.

Hi Klaus,
I don't change your code,only test. I've just reinstall B4A2.30 and copy old anysoftware's folder which include the Libraries folder to replace. I think it might make me terrible this thread and another thread.

Best Regards
Theera
 
Last edited:
Upvote 0

palmaf

Member
Licensed User
Longtime User
The AutoScale function in the Designer Scripts scales only views added in the Designer but not views added in the code.

To overcome this drawback I wrote a Scale Code module, the first version is already included in the Desiger Scripts & AutoScale Tutorial.

Sorry Klaus , i didnt understood how to autoscale line e circle create in the code. Thanks Francesco Palma
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
What exactly do you want to do ?
AutoScale scales and repositions only views according to the screen size!
If you draw anything with a canvas it's up to you to scale the coordinates.
Then it depends on what you want to display.
You could define the coordinates proportional to the width and height of the bitmap (view) you draw on.

Best regards.
 
Upvote 0

palmaf

Member
Licensed User
Longtime User
I'll try to explain better. I've developed an app on a phone 3,2" res. 320x480 and I draw a line to create A frame exactly on the four sides. I installed the app in a phone 3,7" res. 480x854 And the frame and the contained objects remained in the size of the phone 3.2. The question is I have to develop a new layout for every different phone ? Thank you for your patience and expertise
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
You can AutoScale either in the DesignerScripts or in the code with the Scale module.
You might have a look at the Beginner's Guide chapters 8.9 and 8.10.

For the drawing, you should use the width and height properties of the view you draw on, and draw after AutoScale.Somethig like:
cvsView.DrawLine(0, 0, View.Width, View.Height, Color, 1dip)
etc.

Best regards.
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
I have hard time to grasp how to make my app suitable for more than one tablet, despite Klaus recommendations (in other discussion) and reading the relevant material on the Beginner's manual (it seems that somehow my mind can't process fluently this piece of info :)), so decided to use the AutoScaleExample7 module.
My device is Nexus7 2ndGen, scale 2. My layout I use is (900x552x1) and it contains one label and on-air I'm creating 2 buttons butdon't know how to convert these numbers to %x and %y values:
Activity.AddView(Buttons(1), 260dip, 380dip, 140dip, 100dip)


Activity.AddView(Buttons(2), 540dip, 380dip, 140dip, 100dip)

How can I use the autoscale module so my UI to adapt to other screen dimensions, I mean what modification should do in order to use the module? Is it possible?
(my app will run on 7+ tablets,Landsacpe mode only)
Could you please advise me as I have stuck on this matter...???
Thanking the collegues in advance,
mike
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
Can you post your test project as a zip file (IDE menu Files / Export As Zip).
It would be much easier to help you with your test project.

In your case you cannot use AutoScale in the DesignerScripts because the layout variant is based on a non standard screen size.
But you can do it in the AutoScale module where you can set another reference layout.
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
sure...i will do it tonight...do you have a personal email or to put it here. as it is a client version it does not work without the server app but I will modify it for you accordingly.
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
yes, it is for sure. I was sending you the zip in private and I will put the solution here when you would have a look on the code with your recommendations
thank you
mike
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
I had a look at your project.
Unfortunately the positioning.bal file is missing.
I created a layout according to your scaling code.

There were some errors in your code.
Some examples:
You used 'pure' pixel values like
doButtonsListView.TwoLinesLayout.Label.Left = 300
This means different widths with different densities !

With this
Activity.AddView(doButtonsListView, 200, 0, 100%x, 100%y)
Left = 200 without dip ?
Width = 100%x so the right edge is out of the screen !?

You used dip values and TextSizes independant of the screen size.
doButtonsListView.TwoLinesLayout.SecondLabel.Height = 40dip
doButtonsListView.TwoLinesLayout.SecondLabel.TextSize = 18

The width changes according to the screen size but the Height and TextSize properties don't !?

I get an error in the doButtonsListView routine but didn't invetigate in it.
In this routine I call the Positioning Activity to show the button scaling.

Attached you find your modified project.
I tested it on my Asus TF700 10' tablet 1920 * 1080 * 1.5
and on my Sony xperia Z1 5'' phone 1920 * 1080 * 3
The scaling works.
 

Attachments

  • 2KlausTest_1.zip
    14.6 KB · Views: 799
Last edited:
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
Thank you Klaus for your time helping people to develop their projects and make real their ideas.


At the moment I would appreciate some clarification regarding Layout matters.
First when I use LayoutValues.width I get the width of the device. But when I use activity.width & activity.height i get different values.
According to Beginner's Guide the 20%x refers to Activity.
But as I experiment with it I found that my activity width...
On the Designer I put a button where its left side was at the end of the screen, that is 960 pixels which is the width taken by the Layout.Width and not by the Activity.Width.

I think that these is the main reason why I feel confused about Layout matters.

It would be a good idea to create a function that returns the % values of button dimensions in "pure" pixels.

I run your code and got the following error at the beginning, the app continues though (no crash). The error occured in line 534:
v.Left = v.Left of the scale mode

Anyway I will study & experiment with the code and I will see....
thank you again
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
According to Beginner's Guide the 20%x refers to Activity.
Or to the Panel if the view belongs to a Panel.
On the Designer I put a button where its left side was at the end of the screen, that is 960 pixels which is the width taken by the Layout.Width and not by the Activity.Width.
Sorry, but I don't understand the logic. If the Left proprty is set to the end you won't see it !?
In your layout the width is 960 pixels and this is equal to 100%x and Activity.Width with this layout.
If you run the program on another screen, of course, Activity.Width and 100%x are no more 960 pixel but the real width of the device in pixels.
I run your code and got the following error at the beginning, the app continues though (no crash). The error occured in line 534:
v.Left = v.Left of the scale mode
Strange, I downloaded the project back from the forum and ran it on both my devices without any error.
 
Last edited:
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
This is strange because I did run my/your code and no error happened on doButtonListView. Is it a matter of using different B4A libraries or SDK package (my tablet supports last Android version)? I can't explain it.
I get the error only in debug(rapid) mode
(by the way what error did you get in doButtonListView on your device?)

Now, about your comment "Sorry, but I don't understand the logic. If the Left proprty is set to the end you won't see it !?"
Using the Designer, I added a view-button, so its left side to be at the end of the screen just to see the number in pixels and found that Left=960. This number corresponds to 1920/2 (that its width of physical device divided by its scale).

using phone.library the Layout values are:
Screen size : 7
Height: 1104
Width : 1920
Scale : 2
Lanscape Mode
1920 x 1104, scale = 2.0 (320 dpi)

But when I use the command Activity.Width and Activity.Height I take:
activity width : 1920
activity height : 942

so there is a discrepancy regarding Height...Which one should I use to convert pure pixels to %?
If I repeat the same test and add a button and put its top at the bottom of the screen I take a value Top=500.
Is there any build in function that convert the pure pixel to % values automatically?
 
Last edited:
Upvote 0
Top