[EDIT: This thread started as my approach to delegating complex components creation, including events.
@alwaysbusy then proposed a better system, that he needs us to say if we want it implemented on the upcoming release of v 3.75, SO let's create a Poll!
Hi Gurus...
This time I come Not with questions, but with MY answer to one of my biggest problems with this amazing framework : ABMaterial!
And to me, the main problem is, a simple webapp can get quite complex very quickly UI wise, so maintainability can be a very hard business...
So I thought... what if I could divide my code into "complex components" and treat them as a unit, instead of going through all of a pages lines to find a prop to change, and risk breaking the code beyond repair!
So I obviously thought of a ClassModule and treat it like a custom view... and it almost worked...
I only had 2 issues with it... both related to theming...
Going the Class route I just couldn't figure out how to theme the "complex component", since a class needs to be first initialized, and the theme must be created BEFORE!
Then, as I typed this question I started thinking about a CodeModule...
Main advantages : doesn't need declaring nor initializing!
So, my basic steps were:
Create a Code Module, in my case, I called it "TopBar2"
then declared all that was needed to my Complex Component
Then the "real construction work" takes place at the "CreateTopBar" sub:
(yeah, I know, not the best coding technique, but I'm getting there!)
The more aware of you will notice that I have 2 containers...
The main Container has 3 cells, and inside the 3rd cell we have a SubContainer with another 3 cells...
I did it this way to arrange the positioning of the components more efficiently (in other words, to my liking)
Then we do what we always do, assemble the LEGO! and we return the main Container to the calling sub!
the call resembles something like this:
The way I solved my theming issue was, I first created a "BuildTheme" public sub:
But the real magic in this was the very first line... that extended the existing theme into my Code Module
All I had the to do was call this sub from within the Shared CodeModule BuildTheme sub.
The only issue I still have is, I can't figure out how to theme the subcontainer.
Then, to make things a bit cleaner on the events side...
This way we can have the events declared inside our CodeModule keeping it all nice and neat!
Hope this helps somebody!
@alwaysbusy then proposed a better system, that he needs us to say if we want it implemented on the upcoming release of v 3.75, SO let's create a Poll!
Hi Gurus...
This time I come Not with questions, but with MY answer to one of my biggest problems with this amazing framework : ABMaterial!
And to me, the main problem is, a simple webapp can get quite complex very quickly UI wise, so maintainability can be a very hard business...
So I thought... what if I could divide my code into "complex components" and treat them as a unit, instead of going through all of a pages lines to find a prop to change, and risk breaking the code beyond repair!
So I obviously thought of a ClassModule and treat it like a custom view... and it almost worked...
I only had 2 issues with it... both related to theming...
Going the Class route I just couldn't figure out how to theme the "complex component", since a class needs to be first initialized, and the theme must be created BEFORE!
Then, as I typed this question I started thinking about a CodeModule...
Main advantages : doesn't need declaring nor initializing!
So, my basic steps were:
Create a Code Module, in my case, I called it "TopBar2"
then declared all that was needed to my Complex Component
B4X:
Sub Process_Globals
Private ABM As ABMaterial 'ignore
Private MyTheme As ABMTheme
Private TargetPage As ABMPage
Private ObjectId As String
Private LogoFilename As String
Private TopBarThemeName As String
Private TopBarContainer As ABMContainer
Private TopBarSubContainer As ABMContainer
Private TopBarLogo As ABMImage
Private TopBarSearch As ABMInput
Private TopBarBtn1 As ABMButton
Private TopBarBtn2 As ABMButton
Private TopBarBtn3 As ABMButton
Private LogoTheme As String
Private SearchTheme As String
Private BtnTheme As String
Private Btn3Theme As String
End Sub
Then the "real construction work" takes place at the "CreateTopBar" sub:
B4X:
Public Sub CreateTopBar(page As ABMPage, id As String, filename As String, Theme As String) As ABMContainer
TargetPage = page
ObjectId = id
LogoFilename = filename
TopBarThemeName = Theme
LogoTheme = TopBarThemeName & "Logo"
SearchTheme = TopBarThemeName & "Search"
BtnTheme = TopBarThemeName & "Btn"
Btn3Theme = TopBarThemeName & "Btn3"
TopBarContainer.Initialize ( TargetPage, ObjectId, "" )
TopBarSubContainer.Initialize ( TargetPage, ObjectId & "SubCntr", "")
TopBarLogo.Initialize ( TargetPage, ObjectId & "Logo", LogoFilename, 1 )
TopBarSearch.Initialize ( TargetPage, ObjectId & "Search", ABM.INPUT_SEARCH, "Pesquizar", False, SearchTheme )
TopBarBtn1.InitializeRaised ( TargetPage, ObjectId & "Btn1", "", "", "Registar", BtnTheme )
TopBarBtn2.InitializeRaised( TargetPage, ObjectId & "Btn2", "", "", "Login", BtnTheme)
TopBarBtn3.InitializeFlat ( TargetPage, ObjectId & "Btn3", "settings", ABM.ICONALIGN_CENTER, "", Btn3Theme)
LogError ("LogoTheme : " & LogoTheme)
LogError ("SearchTheme : " & SearchTheme)
LogError ("BtnTheme : " & BtnTheme)
LogError ("Btn3Theme : " & Btn3Theme)
'then we build the grid
TopBarContainer.AddRowsMV(1, False,7,7, ABM.VISIBILITY_SHOW_ON_LARGE_ONLY,"").AddCellsOS(1,0,0,0,2,2,2,"").AddCellsOS(1,0,0,0,7,7,7,"").AddCellsOS(1,0,0,0,3,3,3,"")
TopBarContainer.BuildGrid ' IMPORTANT!
TopBarSubContainer.AddRowsMV(1, False,0,0, ABM.VISIBILITY_SHOW_ON_LARGE_ONLY,"").AddCellsOSMP(1,0,0,0,5,5,5,0,0,0,5,"").AddCellsOSMP(1,0,0,0,5,5,5,0,0,5,0,"").AddCellsOS(1,0,0,0,1,1,1,"")
TopBarSubContainer.BuildGrid ' IMPORTANT!
'and we set the cell height
TopBarContainer.Row(1).SetFixedHeight(70, False)
' TopBarSubContainer.Row(1).SetFixedHeight(60, False)
'we then add the picture Logo and set its theme
TopBarContainer.Cell(1,1).AddComponent(TopBarLogo)
TopBarContainer.Cell(1,1).UseTheme(LogoTheme)
'Now we add the search field and set its theme
TopBarSearch.Narrow = True
TopBarContainer.Cell(1,2).AddComponent(TopBarSearch)
TopBarContainer.Cell(1,2).UseTheme(SearchTheme)
'now we add the SubContainer for Buttons 1 & 2
TopBarContainer.Cell(1,3).AddComponent(TopBarSubContainer)
'finaly we start adding the buttons
TopBarBtn1.UseFullCellWidth =True
TopBarSubContainer.Cell(1,1).AddComponent(TopBarBtn1)
TopBarBtn2.UseFullCellWidth =True
TopBarSubContainer.Cell(1,2).AddComponent(TopBarBtn2)
TopBarContainer.Cell(1,3).UseTheme(BtnTheme)
TopBarSubContainer.Cell(1,3).AddComponent(TopBarBtn3)
Return TopBarContainer
End Sub
The more aware of you will notice that I have 2 containers...
The main Container has 3 cells, and inside the 3rd cell we have a SubContainer with another 3 cells...
I did it this way to arrange the positioning of the components more efficiently (in other words, to my liking)
Then we do what we always do, assemble the LEGO! and we return the main Container to the calling sub!
the call resembles something like this:
B4X:
Page.Cell(1,1).AddComponent(TopBar2.CreateTopBar(AppPage,"TopBar","../web/images/topbarlogo60.gif","TopBar"))
The way I solved my theming issue was, I first created a "BuildTheme" public sub:
B4X:
Public Sub BuildTheme
MyTheme =ABMShared.MyTheme
MyTheme.AddCellTheme("TopBarLogo")
MyTheme.Cell("TopBarLogo").Align = ABM.CELL_ALIGN_CENTER
MyTheme.Cell("TopBarLogo").VerticalAlign = True
MyTheme.AddInputTheme("TopBarSearch")
MyTheme.Input("TopBarSearch").BackColor = ABM.COLOR_GREY
MyTheme.Input("TopBarSearch").BackColorIntensity = ABM.INTENSITY_LIGHTEN2
MyTheme.Input("TopBarSearch").ForeColor = ABM.COLOR_BLUE
MyTheme.Input("TopBarSearch").ForeColorIntensity = ABM.INTENSITY_DARKEN4
MyTheme.Input("TopBarSearch").FocusForeColor = ABM.COLOR_BLUE
MyTheme.Input("TopBarSearch").FocusForeColorIntensity = ABM.INTENSITY_DARKEN4
MyTheme.Input("TopBarSearch").AutoCompleteBackColor = ABM.COLOR_DEEPPURPLE
MyTheme.AddCellTheme("TopBarSearch")
MyTheme.Cell("TopBarSearch").Align = ABM.CELL_ALIGN_CENTER
MyTheme.Cell("TopBarSearch").VerticalAlign = True
MyTheme.AddCellTheme("TopBarBtn")
MyTheme.Cell("TopBarBtn").Align = ABM.CELL_ALIGN_CENTER
MyTheme.Cell("TopBarBtn").VerticalAlign = True
MyTheme.AddButtonTheme("TopBarBtn")
MyTheme.Button("TopBarBtn").WavesCircle = True
MyTheme.AddCellTheme("TopBarBtn3")
MyTheme.Cell("TopBarBtn3").Align = ABM.CELL_ALIGN_CENTER
MyTheme.Cell("TopBarBtn3").VerticalAlign = True
MyTheme.AddButtonTheme("TopBarBtn3")
MyTheme.Button("TopBarBtn3").BackColor = ABM.COLOR_GREY
MyTheme.Button("TopBarBtn3").BackColorIntensity = ABM.INTENSITY_LIGHTEN2
MyTheme.Button("TopBarBtn3").WavesCircle = False
MyTheme.Button("TopBarBtn3").WavesEffect = ABM.WAVESEFFECT_NONE
MyTheme.Button("TopBarBtn3").ForeColor = ABM.COLOR_BLUE
MyTheme.Button("TopBarBtn3").ForeColorIntensity = ABM.INTENSITY_DARKEN4
End Sub
All I had the to do was call this sub from within the Shared CodeModule BuildTheme sub.
The only issue I still have is, I can't figure out how to theme the subcontainer.
Then, to make things a bit cleaner on the events side...
B4X:
Sub Page_ParseEvent(Params As Map)
Dim eventName As String = Params.Get("eventname")
Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
...
If eventName = "topbarbtn1_clicked" Then
CallSub2 (myTopBar, "TopBarBtn1_Clicked",Params.Get(eventParams(0)))
End If
Hope this helps somebody!
Last edited: