B4J Tutorial [ABMaterial] Theming the Framework - ModalSheets

ModalSheets

what are they and what are they for?
From ABMaterial Demo we can read:

An ABMModalSheet component is like a mini ABMPage helper, but it pops up over the existing page. It has two ABMContainers, one that makes up the header and one for the footer section, so you can use everyting an ABMContainer can.
ABMModalSheets and itscomponents have to be added to the page in the PageBuild() method. You can the later load the sheet and modify the content before you open it.


In my "simpler" way of seeing ABMaterial components, an ABMModalSheet is pretty much like a Dialog that we use to get the user attention to Something we rekon important.


Anathomy of a ModalSheet


upload_2019-5-4_19-31-34.png


1 - Container 2 - Header 3 - Content 4 - Footer

Lets take as an example the unthemed Login ModalSheet from ABMTemplate:

upload_2019-5-4_19-41-8.png

Here we have, according to our ModalSheet Anathomy, a ModalSheet composed of a Content and a Footer. Each section can hold any ABM Componets, although some may be impracticle.
In This series I will NOT go over HOW the component in hands works, but only try to deepen the how to change the way it looks. Remember, ABMaterial tries as much as possible to follow the Google Material Guidelines, so "The sky IS NOT the limit"!

Theming (BASIC)
Most Theming is done in the Shared Module, Under the BuildTheme Sub.

The ModalSheet Theming options are:

.Colorize as string - by using this parameter we can set the complete set of colors to use in the component… How?

In our BuildTheme we define ALL the colors and ColorShades we plan to use:

B4X:
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_DARKEN4, "#263A4C", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_DARKEN3, "#354A5E", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_DARKEN2, "#455B71", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_DARKEN1, "#566D84", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_NORMAL, "#6A8096", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_LIGHTEN1, "#8094A9", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_LIGHTEN2, "#97A9BC", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_LIGHTEN3, "#B0BFCE", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_LIGHTEN4, "#CBD6E1", 1.0)
    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_LIGHTEN5, "#E8EEF4", 1.0)

And when we Apply our color definition, we also specify which color intensity we want to use.

B4X:
    MyTheme.NavigationBar("nav1theme").TopBarBackColor = "dragonfly"
    MyTheme.NavigationBar("nav1theme").TopBarBackColorIntensity = ABM.INTENSITY_DARKEN4
.HeaderBackColor as String - Header Back Color
.HeaderBackColorIntensity as String - Header Back Color Intensity
.ContentBackColor as String - Content Back Color
.ContentBackColorIntensity as String - Content Back Color Intensity
.FooterBackColor as String - Footer Back Color
.ContentBackColorIntensity as String - Footer Back Color Intensity

The ModalSheet Theme (as in ABMTheme ) are just these few, and focus mainly in the "Container" visual aspect, targeting its 3 regions. But there is a lot more that can be adjusted to get the ModalSheet to look the way we wish it to look. So next we take a look at some more Advanced Theming Options.






 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
ModalSheets

Theming (Advanced)

In order to use a modal sheet in your project, you need to first add the modal sheet to your page.
This is done in the BuilPage() sub and, in the case of our LogIn form, it looks Something like


B4X:
AppPage.AddModalSheetTemplate(BuildLoginSheet)

BuildLoginSheet is the sub where we put together the bits and pieces that make up our modal sheet.
In this case, no particular size is defined and so, the Normal size is used.


A ModalSheet has 3 predifined sizes:

FULL
upload_2019-5-5_10-19-17.png

LARGE
upload_2019-5-5_10-21-24.png

NORMAL
upload_2019-5-5_10-22-59.png


For a long time there were no other size définitions, but in recent versions, Alain has introduced a few new methods that allow us to have diferent sized modal sheets.

AppPage.ShowModalSheetAbsolute(ModalSheetId as String, Left as String, Top as String, Width as String, Height as String) - Shows the modal sheet at the absolute coordinates of the screen. The values can be percentages or pixel values ( ex; "20%", "100px")

AppPage.ShowModalSheetRelativeCell(ModalSheetId as String, Row as Int, Cell as Int, CellWidth as Int, FixedWidth as Int) - Shows the modal sheet relatively to the specified row/cell. If FixedWidth is used, then CellWidth is overruled.

AppPage.ShowModalSheetRelativeComponent(ModalSheetId as String, Component as ABMComponent, FixedWidth as String) - Shows the modal sheet relatively to the specified Component.

So with these methods, we can better position our modal sheet to be almost anything we want, but we can also use a new set of properties to better fine tune the size.

.MaxHeight as String - This sets the max size for the height.
.MaxWidth as String - This sets the max size for the Width.


Keep in mind that ABMaterial is a responsive Framework. This means that in some devices/screen sizes, our components may assume a diferent position and size on screen.


Extra Properties
Untill now we have only been dealing with the sizing and coloring of the modal sheet, but each region can be further customized.

myModal.Content.SetBackgroundImage(Color as String, ColorIntensity as String, Source as String, Repeat as String, Position as String) - Color and ColorIntensity are by now old friends, Source is the relative path to the Image, Repeat is one of the ContainerImage_Repeat_ constants, Position is ContainerImage_Position_ or any valid CSS position string.

Each region or section of a modal sheet can have extra properties too, like:


Padding and Margins.

If you're like me, you Always mix up margins and padding, never knowing exactly wich should we change to get the value we desire.

Margins can have negative values, but padding can't… why? let see exactly what we are talking about:

upload_2019-5-9_18-55-31.png

"an image can be Worth a thousand words"... and this is Worth a few hours of trial/error saving!

.Header.PaddingTop .Header.PaddingLeft .Header.PaddingRight .HeaderPaddingBottom
.Content.PaddingTop .Content.PaddingLeft .Content.PaddingRight .Content.PaddingBottom
.Footer.PaddingTop .Footer.PaddingLeft .Footer.PaddingRight .Footer.PaddingBottom


.Header.MarginTop .Header.MarginLeft .Header.MarginRight .Header.MarginBottom
.Content.MarginTop .Content.MarginLeft .Content.MarginRight .Content.MarginBottom
.Footer.MarginTop .Footer.MarginLeft .Footer.MarginRight .Footer.MarginBottom



SetBorder and SetBorderEx

.SetBorder(Color as String, ColorIntensity as String, WidthPx as Int, BorderStyle as String)
.SetBorderEx(Color as String, ColorIntensity as String, Width as Int, BorderSTyle as String, BorderRadius as String)

Again we see our old friends color and color intensity. WidthPx sets the width of our border, and the BorderStyle sets…(drumroll)… its style.
In BorderEx we find an extra setting, BorderRadius, that allows us to set the… hum.. Border… Radius of the … Border. This is set as a String so it expects Something like "20px".


SetExtraStyle

.SetExtraStyle(ExtraStyle as String) - This is not for the faint of heart… This propertie expects a CSS string to be aplied to the concerned region. Results may not be exactly what you expect, since this is done BEFORE rendering and there may be some overruling by the underlying Framework.

I come to get to know ModalSheets a bit better than I anticipated, mainly because I needed to achiev a look that was…. unconventional.
I'll show you what I mean in the 3rd part of this, already too loooong post.
 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
ModalSheet

Conlusion
SO, how diferent of a ModalSheet and mostly what limitations are we to expect when trying to theme them?

In my endeavours, I got to a point were I was almos happy with my theming of my LogIn form.
I had gone from this

upload_2019-5-5_12-53-3.png

To this

upload_2019-5-5_13-15-16.png

And Believe me, it was not easy to get here.
So, what have I done to get this look?

My modal has no header and no footer.
I set the size of my modal using
B4X:
    myModal.MaxHeight = "100%"
myModal.MaxWidth = "380px"
I then set the Border using
B4X:
    myModal.Content.SetBorderex(ABMShared.AppMainColor, ABM.INTENSITY_DARKEN2, 2, ABM.BORDER_GROOVE, "20px")
This took care of MOST of the looks, BUT a I had a BIG issue… The round corners weren't transparent.


SO, how could I get thos pesky round corner to look right?
I turned to Alain, and his first answer was, basicaly, "sorry, no can do!"... this is not how Materialize works, and I started losing hope, but kept trying… I had almost given up when Alain asked me for my code so that he could take a look at it and try to find a solution...
A few days later he got back to me with … you guessed it: A WORKING SOLUTION!

Basically, according to his explanation, we had to wait for the page to fully load before even trying to overrule the Container CSS...
In PageConnect() AFTER PageHasFinishedLoading we add

B4X:
    ' ALAIN: DOING SOME MANUAL CSS TO OVERRULE THE NORMAL MATERIALIZE CSS TO HANDLE THE ROUNDED BORDERS
    ' OUTLINE REMOVES THE 'FOCUS' BOX IN CHROME
    ' BOX-SHADOW REMOVES THE Z-DEPTH

    Dim CSS As String = $"$('#login').css({'background-color': 'transparent', 'outline': 'none', 'box-shadow': 'unset'});
                          $('#login-content').removeClass('transparent').addClass('white');"$

    AppPage.ws.Eval(CSS, Null)
    AppPage.ws.Flush

As we can see, this is some serious mambo-jambo stuff, and only the Great Masters CSS Wizards can achieve such enlightment!

And that got me my Login ModalSheet based Form just the way I dreamed it!

upload_2019-5-5_13-16-31.png

Hope this helps you guys in your endeavours to better theme your ABMaterial WebApps!



################################################################
FOR ALL OF THOSE THAT PREFER A COPY/PAST SOLUTION, HERE YOU GO, ENJOY
################################################################

This is based on the "template" provided in the ABMaterial bundle, all that I changed was as follows:

in the "ABMAplication" Module:
B4X:
public Sub ConnectPage()
 ' you dynamic stuff
 
 AppPage.Refresh ' IMPORTANT
 
 ' Tell the browser we finished loading
 AppPage.FinishedLoading 'IMPORTANT
 Dim CSS As String = $"$('#login').css({'background-color': 'transparent', 'outline': 'none', 'box-shadow': 'unset'});
                          $('#login-content').removeClass('transparent').addClass('white');"$
 AppPage.ws.Eval(CSS, Null)
 AppPage.ws.Flush
 
 AppPage.RestoreNavigationBarPosition
End Sub

Sub BuildLoginSheet() As ABMModalSheet

    Dim myModal As ABMModalSheet
    myModal.Initialize(AppPage, "login", False, ABM.MODALSHEET_TYPE_NORMAL,"loginform")
    myModal.IsDismissible = False
    myModal.MaxHeight = "100%"
    myModal.MaxWidth = "25%"
  
    myModal.Content.AddRows(3,True,"").AddCells12(1,"")
    myModal.Content.BuildGrid ' IMPORTANT!

  
    myModal.Content.Cell(1,1).AddComponent(ABMShared.BuildParagraph(AppPage,"par1","Please login:"))
    myModal.Content.Cell(1,1).UseTheme("loginform")
    Dim inp1 As ABMInput
    inp1.Initialize(AppPage, "inp1", ABM.INPUT_TEXT, "UserName", False, "")
    myModal.Content.Cell(2,1).AddComponent(inp1)
  
    Dim inp2 As ABMInput
    inp2.Initialize(AppPage, "inp2", ABM.INPUT_PASSWORD, "Password", False, "")
    myModal.Content.Cell(2,1).AddComponent(inp2)
  
    Dim msbtn1 As ABMButton
    msbtn1.InitializeFlat(AppPage, "msbtn1", "", "", "Login", "transparent")
    myModal.Content.Cell(3,1).AddComponent(msbtn1)
    myModal.Content.Cell(3,1).UseTheme("loginform")
  
    myModal.Content.SetBorderex(ABM.COLOR_BLACK, ABM.INTENSITY_DARKEN2, 2, ABM.BORDER_GROOVE, "20px")
    Return myModal
End Sub

In the "ABMShared" Module
B4X:
Sub BuildTheme(themeName As String)
    MyTheme.Initialize(themeName)
    
    ' the page theme
    MyTheme.Page.BackColor = ABM.COLOR_WHITE
    
    MyTheme.AddCellTheme("loginform")
    MyTheme.Cell("loginform").Align = ABM.CELL_ALIGN_CENTER   
    
End Sub

This will produce the same basic LogIn form with the same basic fields… to get a more advanced look...
DO YOUR HOMEWORK
upload_2019-8-19_20-18-27.png



 
Last edited:

Bothwell

Member
Licensed User
@Johan Hormaza for some reason don't think the author is willing to share or assist any further. ABMaterial is a good tool, unfortunately lacks proper documentation, we saw this a risk for our client and unfortunatley we had to move to a PHP tool for thier web frontend (https://www.agiletoolkit.org/ui ). Maybe if this was part of the core langauge we could have had a vedio on ETP. challenge is libraries are developed part-time and developers don't have time to come up with tutorials
 

alwaysbusy

Expert
Licensed User
Longtime User
for some reason don't think the author is willing to share or assist any further
Just take into account @Cableguy has announced in July he was going to take a leave for a couple of weeks because he was getting married. So at least give the guy a break. ;) This is a very good tutorial which goes way further than what I originaly had in mind when I made ABM. I'm very grateful he made this.
 

Cableguy

Expert
Licensed User
Longtime User
I am back, but been working overtime in my day job, which gives me much less free time to all the "other little things".
Give just a couple of weeks more and I will have enough to share my code.
 

Cableguy

Expert
Licensed User
Longtime User
@Johan Hormaza for some reason don't think the author is willing to share or assist any further. ABMaterial is a good tool, unfortunately lacks proper documentation, we saw this a risk for our client and unfortunatley we had to move to a PHP tool for thier web frontend (https://www.agiletoolkit.org/ui ). Maybe if this was part of the core langauge we could have had a vedio on ETP. challenge is libraries are developed part-time and developers don't have time to come up with tutorials

I hope to release a freshly modified Template project in which the default LogIn modal-sheet (form) is replaced by this alternative version.
I am available to answer any questions regarding this tutorial, but, basically, this was not meant as an "alternative solution proposal" but as a guide on how one could change a modal-sheet appearance.

As usual, most devs here are more interested on having a piece of code to copy/paste than to have guide lines to help them get the look they want, and content themselves with already available ones.

ABMaterial IS A HIGHLY CUSTOMIZABLE FRAMEWORK! MEANING THAT THE AUTHOR PROVIDES BASIC TOOLS TO THE DEVELOPER SO THAT HE/SHE CAN GET THE DESIRED LOOK! THIS IS NOT A COOKBOOK! WHERE ONE FOLLOWS A RECIPE TO GET A PARTICULAR COOKED PLATE;

This said, the framework, in my opinion, has come to a mature and stable enough state, where one can finally start the gigantic endeavour that it will be to properly document it, not fearing that any new release would break the existing documentation.
 
Top