[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 SubThen 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 SubThe 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 SubAll 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 IfHope this helps somebody!
			
				Last edited: 
			
		
	
							 
				 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		