B4x and "cross platform"

D

Deleted member 103

Guest
Hi everyone,

B4x is supposed to become a "cross platfrom" and that's part of it too.
Many thanks to Erel for his continuous commitment.

Erel does everything possible to realize that, but for me that's partly the wrong direction.
It should not be a criticism, it's just my opinion and wish that maybe it can be wrong.

I know that you can manipulate many views with B4xView, but why change a "label" with a "B4XView" just to use it in B4i? Or add a lot of "#IF B4a" in the code?
The whole code seems too confusing.

What I want is that you can use exactly the same code for B4a and B4i without having to keep track of the platform differences.
For example: if I write "label.textsize = 20", then internally it should handle the IDE for B4a and B4i and not the programmer.
There are little things that would simplify the programmer's work.

Here is a code of a menu-class for B4a and B4i.
It does not look very clear, right?

B4X:
#Event: Click

Sub Class_Globals
#if B4a
    Private clvMenu As CustomListView
#else
    Private clvMenu As CustomScrollView
#End If
    Private pnlMenuBackground, pnlMenu As Panel
    Private pnlSeparator, pnlTitel As Panel
    Private lblTitel As Label
    Private menuWidth As Int = 250dip
    Private itemHeight As Int = 50dip
    Private haederHeight As Int
    Private ySpace As Int = 10dip

    Private CallBack As Object
    Private myParent As B4XView
End Sub

#if B4a
Public Sub Initialize(vCallback As Object, Parent As Activity)
    CallBack = vCallback
    myParent = Parent
    Init
End Sub
    
#else
Public Sub Initialize(vCallback As Object, Parent As Panel)
    CallBack = vCallback
    myParent = Parent
    Init   
End Sub
#End If

'Initializes the object. You can add parameters to this method if needed.
Public Sub Init
    pnlMenuBackground.Initialize("pnlMenuBackground")
    pnlMenuBackground.Color = Colors.ARGB(50, 0 , 0, 0)
    myParent.AddView(pnlMenuBackground, 0 , 0 , myParent.Width, myParent.Height)
    pnlMenuBackground.Visible = False

    pnlMenu.Initialize("")
    pnlMenu.color = 0xFF607D8B
    
    pnlTitel.Initialize("")
    SetGradient(pnlTitel, 0xFF98BCD0, 0xFF607D8B)
    
    lblTitel.Initialize("Titel")
    lblTitel.TextColor = Colors.White
    lblTitel.Text = "Titel"
#if b4a
    lblTitel.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
    lblTitel.SingleLine = False
#else
    lblTitel.TextAlignment = lblTitel.ALIGNMENT_CENTER
    lblTitel.Multiline = True
#End If
    
    pnlSeparator.Initialize("")
    pnlSeparator.Color = 0xFFD3D3D3

#if b4a
    clvMenu.Initialize(Me, "clvMenu")
#else   
    clvMenu.Initialize(Me, "clvMenu", 250dip)
#End If
    clvMenu.AsView.Color = Colors.Transparent

    pnlMenuBackground.AddView(pnlMenu, 0, 0, menuWidth, 300dip)
    
    pnlMenu.AddView(pnlTitel, ySpace, ySpace, menuWidth - ySpace * 2, 90dip)
    pnlTitel.AddView(lblTitel, 0, 0, pnlTitel.Width, pnlTitel.Height)
    pnlMenu.AddView(pnlSeparator, ySpace, pnlTitel.Height + ySpace * 2, menuWidth - ySpace * 2, 1)
    pnlMenu.AddView(clvMenu.AsView, ySpace, pnlTitel.Height + pnlSeparator.Height + ySpace * 2, menuWidth - ySpace * 2, 209dip)
    haederHeight = pnlTitel.Height + pnlSeparator.Height + ySpace * 2
End Sub

Private Sub pnlMenuBackground_Resize(Width As Int, Height As Int)
#if b4a
    pnlMenuBackground.SetLayoutAnimated(0, 0, 0, Width, Height)
#else   
    pnlMenuBackground.SetLayoutAnimated(0, 1, 0, 0, Width, Height)
#End If
End Sub

Public Sub AddMenuItem(Title As String, EventName As String, Bitmap As String, TextColor As Int)
    clvMenu.Add(CreateMenuItem(Bitmap, Title, TextColor), itemHeight, EventName)
End Sub

Public Sub AddMenuText(Title As String, EventName As String, Awesometext As String, TextColor As Int, IconColor As Int)
    clvMenu.Add(CreateMenuText(Awesometext, Title, TextColor, IconColor), itemHeight, EventName)
End Sub

Public Sub AddMenuCheckbox(Title As String, EventName As String, Awesometext As String, TextColor As Int, IconColor As Int, Checked As Boolean)
    clvMenu.Add(CreateMenuCheckbox(Awesometext, Title, TextColor, IconColor, Checked), itemHeight, EventName)
End Sub

Public Sub AddSeparator
    Dim p As Panel
    p.Initialize("")
    p.Color = Colors.LightGray
    clvMenu.Add(p, 1dip, "")
End Sub

Public Sub Show
    UpdatePanelBackground
End Sub

Private Sub UpdatePanelBackground
    pnlMenuBackground.Width = myParent.Width
    pnlMenuBackground.Height = myParent.Height

    pnlMenu.Height = myParent.Height
    clvMenu.AsView.Height = pnlMenu.Height - haederHeight
    clvMenu.AsView.Width = pnlMenu.Width
    
    If Not(pnlMenuBackground.Visible) Then
        pnlMenu.Left = - pnlMenu.Width
        #if b4a
        pnlMenu.SetLayoutAnimated(300, 0, 0, pnlMenu.Width, pnlMenu.Height)
        #else
        pnlMenu.SetLayoutAnimated(300, 1, 0, 0, pnlMenu.Width, pnlMenu.Height)
        #End If
    Else
        #if b4a
        pnlMenu.SetLayoutAnimated(300, - pnlMenu.Width, 0, pnlMenu.Width, pnlMenu.Height)
        #else
        pnlMenu.SetLayoutAnimated(300, 1, - pnlMenu.Width, 0, pnlMenu.Width, pnlMenu.Height)
        #End If
        Sleep(300)
    End If
    pnlMenuBackground.Visible = Not(pnlMenuBackground.Visible)
End Sub

Private Sub CreateMenuText(Awesometext As String, Text As String, TextColor As Int, IconColor As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    p.Color = Colors.Transparent
    
    Dim lblIcon As Label
    lblIcon.Initialize("")
#if b4a
    lblIcon.Typeface = Typeface.FONTAWESOME
    lblIcon.TextSize = 28
    lblIcon.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
#else
    lblIcon.Font = Font.CreateNew2("fontAwesome", 28)
    lblIcon.TextAlignment = lblIcon.ALIGNMENT_CENTER
#End If
    lblIcon.Text = Awesometext
    lblIcon.TextColor = IconColor
    
    Dim lblText As Label
    lblText.Initialize("lblText")
#if b4a
    lblText.Typeface = Typeface.SANS_SERIF
    lblText.TextSize = 16
    lblText.Gravity = Gravity.LEFT + Gravity.CENTER_VERTICAL
#else
    lblText.TextAlignment = lblText.ALIGNMENT_LEFT
    lblText.Font = Font.CreateNew(16)
#End If
    lblText.TextColor = TextColor
    lblText.Text = Text
    
    p.AddView(lblIcon, 2dip, 2dip, itemHeight - 4dip, itemHeight - 4dip) 'view #0
    p.AddView(lblText, itemHeight + 2dip, 2dip, menuWidth - itemHeight, itemHeight - 4dip) 'view #1
    Return p
End Sub

Private Sub CreateMenuItem(bmp As String, Text As String, TextColor As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    p.Color = Colors.Transparent
    
    Dim Icon As ImageView
    Icon.Initialize("")
    If bmp <> Null And File.Exists(File.DirAssets, bmp) Then Icon.Bitmap = LoadBitmap(File.DirAssets, bmp)
#if b4a
    Icon.Gravity = Gravity.FILL
#else
    Icon.ContentMode = Icon.MODE_FILL
#End If
    
    Dim lblText As Label
    lblText.Initialize("lblText")
#if b4a
    lblText.Typeface = Typeface.SANS_SERIF
    lblText.TextSize = 16
    lblText.Gravity = Gravity.LEFT + Gravity.CENTER_VERTICAL
#else
    lblText.TextAlignment = lblText.ALIGNMENT_LEFT
    lblText.Font = Font.CreateNew(16)
#End If
    lblText.Text = Text
    lblText.TextColor = TextColor
    
    p.AddView(Icon, 2dip, 2dip, itemHeight - 4dip, itemHeight - 4dip) 'view #0
    p.AddView(lblText, itemHeight + 2dip, 2dip, menuWidth - itemHeight, itemHeight - 4dip) 'view #1
    Return p
End Sub

Public Sub CreateMenuCheckbox(Awesometext As String, text As String, textcolor As Int, IconColor As Int, Checked As Boolean) As Panel
    Dim lblText As Label
    Dim cbx As Label

    Dim p As Panel
    p.Initialize("")
    p.Color = Colors.Transparent '.White

    Dim lblIcon As Label
    lblIcon.Initialize("")
#if b4a
    lblIcon.Typeface = Typeface.FONTAWESOME
    lblIcon.TextSize = 28
    lblIcon.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
#else
    lblIcon.Font = Font.CreateNew2("fontAwesome", 28)
    lblIcon.TextAlignment = lblIcon.ALIGNMENT_CENTER
#End If
    lblIcon.Text = Awesometext
    lblIcon.TextColor = IconColor

#if b4a
    lblText = NewLabel(text, Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL, 16)
#Else   
    lblText = NewLabel(text, lblText.ALIGNMENT_CENTER, 16)
#End If
    lblText.TextColor = textcolor

    cbx.Initialize("")
#if b4a
    cbx.Typeface = Typeface.FONTAWESOME
    cbx.TextSize = 16
    cbx.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
#else
    cbx.TextAlignment = cbx.ALIGNMENT_CENTER
    cbx.Font = Font.CreateNew2("fontAwesome", 16)
#End If
    If Checked Then
        cbx.Text = Chr(0xF046)
    Else
        cbx.Text = Chr(0xF096)
    End If
    
    Dim pnl As Panel
    pnl.Initialize("")

    p.AddView(lblIcon, 2dip, 2dip, itemHeight - 4dip, itemHeight - 4dip)
    p.AddView(lblText, itemHeight, 2dip, menuWidth - itemHeight * 2, itemHeight - 4dip)
    p.AddView(cbx, menuWidth - itemHeight, 2dip, itemHeight, itemHeight - 4dip)
    Return p
End Sub

Private Sub clvMenu_ItemClick( Value As Object, Event As String)
    UpdatePanelBackground
#if b4a
    If SubExists(CallBack, Event & "_Click") Then
        CallSub(CallBack, Event & "_Click")
    End If
#else
    If SubExists(CallBack, Event & "_Click", 0) Then
        CallSub(CallBack, Event & "_Click")
    End If
#End If
End Sub

Private Sub pnlMenuBackground_Click
    UpdatePanelBackground
End Sub

#Region Position

Public Sub setColor(Color As Int)
    pnlMenu.Color = Color
End Sub

Public Sub setTitel(Text As String)
    lblTitel.Text = Text
End Sub

Public Sub getVisible As Boolean
    Return pnlMenuBackground.Visible
End Sub

Public Sub setVisible(Value As Boolean)
    pnlMenuBackground.Visible = Value
End Sub

Public Sub setTop(Top As Int)
    pnlMenu.Top = Top
End Sub

Public Sub getTop As Int
    Return pnlMenu.Top
End Sub

Public Sub setWidth(Width As Int)
    menuWidth = Width
    UpdatePanelBackground
End Sub

Public Sub setButtom(Buttom As Int)
    pnlMenu.Top = Buttom + pnlMenu.Height
End Sub

Public Sub getButtom As Int
    Return pnlMenu.Top + pnlMenu.Height
End Sub
#End Region

Sub NewLabel(Text As String, TextAlignment As Int, Textsize As Int) As Label
    Dim lbl As Label
    lbl.Initialize("")
#if b4a
    lbl.Typeface = Typeface.SANS_SERIF
    lbl.TextSize = Textsize
    lbl.Gravity = TextAlignment
#else
    lbl.Font = Font.CreateNew2("AvenirNextCondensed-Medium", Textsize) 'SANS_SERIF.CreateNew(Textsize)
    lbl.TextAlignment = TextAlignment
#End If
    lbl.TextColor=Colors.Black
    lbl.Text=Text
    Return lbl
End Sub

#if B4a
Sub SetGradient(v As View, col1 As Int, col2 As Int)
    Dim cd As GradientDrawable
    Dim Clrs(2) As Int
    Clrs(0) = col1
    Clrs(1) = col2
    cd.Initialize("LEFT_RIGHT", Clrs)
    cd.CornerRadius = 5dip
    v.Background = cd
End Sub
#else
Private Sub SetGradient(v As View, color1 As Int, color2 As Int)
    v.SetBorder(1, Colors.Transparent, 5)

    Dim NaObj As NativeObject = Me
    NaObj.RunMethod("SetGradient:::",Array(v,NaObj.ColorToUIColor(color1),NaObj.ColorToUIColor(color2)))
End Sub

#If OBJC
- (void)SetGradient: (UIView*) View :(UIColor*) Color1 :(UIColor*) Color2{
    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.colors = [NSArray arrayWithObjects:(id)Color1.CGColor, (id)Color2.CGColor, nil];
    gradient.frame = View.bounds;
    gradient.startPoint = CGPointMake(0, 1);
      gradient.endPoint = CGPointMake(1, 1);
    [View.layer insertSublayer:gradient atIndex:0];
}
#end if
#End If
 

LucaMs

Expert
Licensed User
Longtime User
#if B4a
Public Sub Initialize(vCallback As Object, Parent As Activity)
CallBack = vCallback
myParent = Parent
Init

End Sub

#else
Public Sub Initialize(vCallback As Object, Parent As Panel)
CallBack = vCallback
myParent = Parent
Init

End Sub
#End If

Note that, without thinking to B4J, this part can be the same, just the second one (it will work even with B4A):
B4X:
Public Sub Initialize(vCallback As Object, Parent As Panel)
    CallBack = vCallback
    myParent = Parent
    Init 
End Sub
 

LucaMs

Expert
Licensed User
Longtime User
Also, maybe the site should change "und" to "and" automatically:

upload_2018-9-28_12-54-5.png


:p
 

LucaMs

Expert
Licensed User
Longtime User
does not lose the characteristics of the single platform
#if b4a
pnlMenuBackground.SetLayoutAnimated(0, 0, 0, Width, Height)
#else
pnlMenuBackground.SetLayoutAnimated(0, 1, 0, 0, Width, Height)
#End If
Code like the one above is not related to some specific characteristics of one of the two operating systems or hardware; it could be managed during the parsing phase, I think.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Your code will be significantly simpler if you switch to XUI and B4XView.
B4X:
#if B4a
    Private clvMenu As CustomListView
#else
    Private clvMenu As CustomScrollView
#End If
I don't know what is CustomScrollView but you should most probably switch to xCustomListView which is cross platform.

B4X:
#if B4a
Public Sub Initialize(vCallback As Object, Parent As Activity)
    CallBack = vCallback
    myParent = Parent
    Init
End Sub
 
#else
Public Sub Initialize(vCallback As Object, Parent As Panel)
    CallBack = vCallback
    myParent = Parent
    Init
End Sub
#End If

Should be changed to:
B4X:
Public Sub Initialize(vCallback As Object, Parent As B4XView)
    CallBack = vCallback
    myParent = Parent
    Init
End Sub


B4X:
#if b4a
    lblTitel.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
    lblTitel.SingleLine = False
#else
    lblTitel.TextAlignment = lblTitel.ALIGNMENT_CENTER
    lblTitel.Multiline = True
#End If
Should be changed to:
B4X:
lbl.SetTextAlignment("CENTER", "CENTER")
Multiline / SingleLine is currently not implemented in B4XView. It might be added in the future. In the meantime you should cast it to a Label and use the platform specific code (or set them with the designer).
This shows the real power of XUI. You are not limited to the implemented features.

B4X:
 #if b4a
        pnlMenu.SetLayoutAnimated(300, 0, 0, pnlMenu.Width, pnlMenu.Height)
        #else
        pnlMenu.SetLayoutAnimated(300, 1, 0, 0, pnlMenu.Width, pnlMenu.Height)
        #End If
Should be changed to:
B4X:
pnlMenu.SetLayoutAnimated(300, 0, 0, pnlMenu.Width, pnlMenu.Height)

B4X:
#if b4a
    If SubExists(CallBack, Event & "_Click") Then
        CallSub(CallBack, Event & "_Click")
    End If
#else
    If SubExists(CallBack, Event & "_Click", 0) Then
        CallSub(CallBack, Event & "_Click")
    End If
#End If
Should be changed to:
B4X:
    If xui.SubExists(CallBack, Event & "_Click", 0) Then
        CallSub(CallBack, Event & "_Click")
    End If

Stopping here. Almost all of the other platform specific code can also be removed.

Your code shows why it is important to switch to XUI and B4XView. I don't think that you really tried it as you would have seen that it is simpler than using the native views.

I recommend you to start with the two XUI related video tutorials: https://www.b4x.com/etp.html
 

LucaMs

Expert
Licensed User
Longtime User
I don't think that you really tried it
Neither did I try; just in this moment:

dim lbl As B4XView
lbl.Initialize??? not found :D (I have to read/watch a lot).

However, using XUI will be very important to use "standard" prefixes for B4XView variables, since the help of the editor will show you only that a variable is of type B4XView, it can not distinguish between Label, EditText, etc.

xlbl for Labels
xet for EditTexts
xbtn for Buttons
...
 
Last edited:

klaus

Expert
Licensed User
Longtime User
I have used B4X quite a lot the last time.
And, the more I use it, the more I am convinced of it, even for monoplatform developpment !!!
It needs a bit of time to get it, but once you got it, you won't go back.
At least that's my opinion.
 
D

Deleted member 103

Guest
I have used B4X quite a lot the last time.
And, the more I use it, the more I am convinced of it, even for monoplatform developpment !!!
It needs a bit of time to get it, but once you got it, you won't go back.
At least that's my opinion.
I'm not saying that it's bad, on the contrary, it's very good.

My question is why should I, for example, replace an existing "label" with a "B4xView", if that could actually make the IDE in background?

I'm sorry, but I can not understand that. :(

But I do not want to force anything on that, if it is not feasible then it has to be accepted.
 

ThRuST

Well-Known Member
Licensed User
Longtime User
@Filippo As you know each standard have their own strenght and weakness including differences. To merge the B4X language into one platform independent cloud have it's disadvantages. The reason to this is compatibillity for each standard and that will make it too complicated to maintain as new solutions is introduced. Some things however, might benefit from a cloud based concept. Personally I think you are asking for too much instead of appreciate the fact why B4X has so many devoted users, and the reason to that is that B4X is allready so platform friendly, in fact you won't find a better solution at least good luck with that. My two cents in Erels basket, sorry if that hurts :)
 

ThRuST

Well-Known Member
Licensed User
Longtime User
However a dropbox cloud solution to connect and access all available libraries for the B4X frenchise would be most useful. This will make it easier to try others code when you haven't updated your own libraries folder for some time. There could be a webpage to upload and maintain each library instead of having them scattered allover the place. With the very popular ABMaterials around, someone wouldn't find it too difficult to create this service :)
 
Top