Designer Script - calling B4X code

Erel

B4X founder
Staff member
Licensed User
Longtime User
java_wvFqHiqRoK.gif


This feature will be included in the next version of B4X. It allows calling B4X code from the designer script. This will allow to extend the designer with all kinds of useful utilities.
Do note that the code will not run at design time.

The designer script for the above example:
B4X:
'Panel, max size, min gap
DesignerUtils.SpreadControlsHorizontally(Pane1, 300dip, 20dip)
'Panel, row height
DesignerUtils.HorizontalFlow(Pane2, 60dip)

The B4X code, which can be packaged as a b4xlib:
B4X:
'Panel, MaxSize, MinGap
Public Sub SpreadControlsHorizontally (DesignerArgs As DesignerArgs)
    Dim Panel As B4XView = DesignerArgs.GetViewFromArgs(0)
    Dim MaxSize As Int = DesignerArgs.Arguments(1)
    Dim MinGap As Int = DesignerArgs.Arguments(2)
    Dim AllWidth As Int = Panel.Width
    Dim w As Int = Min(AllWidth / Panel.NumberOfViews - MinGap, MaxSize)
    Dim gap As Int = (AllWidth - Panel.NumberOfViews * w) / Panel.NumberOfViews
    For i = 0 To Panel.NumberOfViews - 1
        Dim v As B4XView = Panel.GetView(i)
        v.SetLayoutAnimated(0, (i + 0.5) * gap + i * w, v.Top, w, v.Height)
    Next
End Sub

'Panel, RowHeight
Public Sub HorizontalFlow (DesignerArgs As DesignerArgs)
    Dim panel As B4XView = DesignerArgs.GetViewFromArgs(0)
    Dim RowHeight As Int = DesignerArgs.Arguments(1)
    Dim gap As Int = 5dip
    Dim x As Int = gap
    Dim y As Int = gap
    For i = 0 To panel.NumberOfViews - 1
        Dim v As B4XView = panel.GetView(i)
        If x > gap And x + v.Width > panel.Width - gap Then
            x = gap
            y = y + RowHeight
        End If
        v.Left = x
        v.Top = y
        x = x + v.Width + gap
    Next
End Sub
 

AnandGupta

Expert
Licensed User
Longtime User
It is becoming very difficult to program in other programing language ide.

The features of b4x is now way above any other ide I use. 🙏

I have to find a way to program in xbase++ through b4x now.
 

udg

Expert
Licensed User
Longtime User
This feature will be included in the next version of B4X
So, will it available on all the platforms? Great!
Can you show (or describe) how the Designer will know about our DesignerUtils b4xlib (or even some simple code in one of our modules)?
The easiest solution that comes to my mind is that DesignerUtils will be a "reserved" name and the Designer will look for a module or lib named like that. But a more general MyModule.MySub syntax recognized by the designer parser will work even better.

Another question: will the designer script accept a sequence like scriptcode-calltoexternalcode-scriptcode? In other words, will the script be able to make use of values and items produced by the external code? From your demo code it looks there's a one-way only parameters passing (from script to code).

Anyway, thank you very much for this new toy..ehmm..feature
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Can you show (or describe) how the Designer will know about our DesignerUtils b4xlib (or even some simple code in one of our modules)?
The easiest solution that comes to my mind is that DesignerUtils will be a "reserved" name and the Designer will look for a module or lib named like that. But a more general MyModule.MySub syntax recognized by the designer parser will work even better.
Any static module with a sub that matches the expected signature will work.

Another question: will the designer script accept a sequence like scriptcode-calltoexternalcode-scriptcode? In other words, will the script be able to make use of values and items produced by the external code? From your demo code it looks there's a one-way only parameters passing (from script to code).
Yes, the B4X sub can return a simple value.
 

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Longtime User
Thank you ..
I was want to request this wish earlier, but I found myself embarrassed from @Erel , we request everything and he did it.
 

ilan

Expert
Licensed User
Longtime User
it says that it is a b4x feature but i only see it being used in b4j since it only makes sense in a desktop app where you can resize the window.
what would be the benefit of calling it from the designer and not from the _resize event?

thanx
 

jahswant

Well-Known Member
Licensed User
Longtime User
it says that it is a b4x feature but i only see it being used in b4j since it only makes sense in a desktop app where you can resize the window.
what would be the benefit of calling it from the designer and not from the _resize event?

thanx
I think you can use it to create a single layout that perfectly adapts on Tablets and Phones without necessarily having the eye view.
Something like this :
1655201466089.png
 

LucaMs

Expert
Licensed User
Longtime User
it says that it is a b4x feature but i only see it being used in b4j since it only makes sense in a desktop app where you can resize the window.
what would be the benefit of calling it from the designer and not from the _resize event?

thanx
The example is very indicative: align, correctly space N Views; how many times have you (we) had to do this with the internal script? If the source code was in your own library, you would get it with only one line in the script.

That said, if that functionality, spacing, were already part of the Designer (as requested in the past) it would be even better.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
it says that it is a b4x feature but i only see it being used in b4j since it only makes sense in a desktop app where you can resize the window.
Check the example on the very first post. It is relevant with B4A / B4i exactly as it is relevant with B4J.
It is relevant whenever your app can run on more than a single screen size.

The second point about the resize event cannot be disputed. You can do everything from the resize event. You can ask why use the designer script at all.

The new external calls feature allows us to make the designer script much more powerful.
The fact that you have a layout file that holds the views properties and everything else related to the layout of these views, means that you have much better encapsulation. A single layout file that you can load in million places and it will "automatically" adopt to the parent size. This is a big thing.

It will be easier to answer in a few months from now :)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
That said, if that functionality, spacing, were already part of the Designer (as requested in the past) it would be even better.
Not really. There are too many small details and different use cases to make it useful without adding many parameters, and making it too complex to use.
This is why it was never implemented as an internal feature.

With the external call feature developers can modify the behavior as they need.
 

LucaMs

Expert
Licensed User
Longtime User
Not really. There are too many small details and different use cases to make it useful without adding many parameters, and making it too complex to use.
This is why it was never implemented as an internal feature.

With the external call feature developers can modify the behavior as they need.
That new feature is certainly "powerful", very useful and I'm sure we will realize it.

The fact remains that some things are very common, frequent, just that of aligning vertically / horizontally is one of them. This and others are usually provided with other designers.

Anyway, I think it will be enough to develop an official library (B4XLib), with just these basic functionalities.
 

ilan

Expert
Licensed User
Longtime User
I think you can use it to create a single layout that perfectly adapts on Tablets and Phones without necessarily having the eye view.
Something like this :
View attachment 130393
i have difficulties seeing how this result can be done more easier with the new feature than using different variants instead or different layout files for different variants.
anyway, i am sure the new feature can be useful in some specific cases and it gives us now more control from the designer directly. i guess time will make it more understandable.

You can ask why use the designer script at all.
designer script is very important. i use it in every app. so the resize event will never take the place of the designer script at least not for me.

A single layout file that you can load in million places and it will "automatically" adopt to the parent size. This is a big thing.

i agree but this is also very dangerous. in your example it can ruin the whole app if the views are sent to next row if the screen resized. i know it is just an example of showing the idea but no one would want to have such a layout:

1655207592405.png


again, i am not complaining. i am happy for every new feature in b4x just need to understand how to use effeciently :)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
i agree but this is also very dangerous. in your example it can ruin the whole app if the views are sent to next row if the screen resized. i know it is just an example of showing the idea but no one would want to have such a layout:
I'm giving you tools. It is up for the developer to use them in the correct place.

i am happy for every new feature in b4x just need to understand how to use effeciently
Understanding how to use any feature efficiently requires time. For all of us. Don't worry :)
 

ilan

Expert
Licensed User
Longtime User

Erel

B4X founder
Staff member
Licensed User
Longtime User
iOS:
1655297370244.png


Android:
1655297406169.png


Desktop:
B4J_oSEkdUxy6u.gif


Almost complete code:
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    For i = 1 To 100
        Dim p As B4XView = xui.CreatePanel("")
        p.SetLayoutAnimated(0, 0, 0, Root.Width, 200dip)
        p.LoadLayout("Item")
        CustomListView1.Add(p, "")
    Next
End Sub
And designer script:
B4X:
DDD.SpreadControlsHorizontally(Pane1, 200dip, 5dip)
DDD.SetText(Button1, "Sunday", "Sun", "Su", "S")
DDD.SetText(Button2, "Monday", "Mon", "Mo", "M")
DDD.SetText(Button3, "Tuesday", "Tue", "Tu", "T")
DDD.SetText(Button4, "Wednesday", "Wed", "We", "W")
DDD.SetText(Button5, "Thurdsay", "Thu", "Th", "T")
DDD.SetText(Button6, "Friday", "Fri", "Fr", "F")
DDD.SetText(Button7, "Saturday", "Sat", "Sa", "S")

Now try to do everything in the the resize event (which doesn't exist in B4A) and you will end up writing several pages of complex code.
And this is a simple case where all items are from the same type. This is of course not necessary.
 
Top