In the five years that I have been using my single B4XPage expandable Drawer menu in B4J and B4A, both the IDEs and the B4X components have evolved. The time was ripe to create a new version called m3Menu. Below the result and an overview of the possibilities:
The starting point was that the program should be able to easily adjust the menu groups, the associated menu items and icons. I also added the programming option to block an entire menu group or one or more items of a menu group for those who need more than a simple drop-down menu.
The pragmatic choice for the 719 material design icons is a compromise to be able to give the icons the same color as the menu grep title and menu item titles. I was a bit too lazy to pick out a unique icons from the 719 material design icons for the POC for each menu option. It is best to use Erel's [B4X] MaterialIcons Web Font Chooser program to choose the icon you want to use.
The colors used can be used as HTML hexadecimal color code, as well as standard XUI color palette code.
I have paid a lot of attention to making the reusability and adaptability to personal wishes as great and easy as possible for both the novice and the advanced forum members. The easiest way is to add your B4XPage(s) to the Proof Of Concept(POC) and add the code below to your B4XPage(s). The easiest way is to do the testing in B4J according to the following scheme:
By using B4X components as much as possible, the #IF B4J or #IF B4A constructions are avoided and the developed B4J form(s) can be shared between the two development environments via a copy-paste action.
To add an existing m3Menu to an (existing) B4XPage the following steps are required:
The menu structure is very simple, the icon code Chr(0xfb2d) is a direct paste of the chosen icon from Erel's [B4X] MaterialIcons Web Font Chooser program. Note that the menu group name and group items must be unique to prevent overwriting. The spelling of the status true and false may contain upper and lower case. A False status blocks the use of the menu group or menu item, while the status true is selectable.
To quickly implement a so-called own or external house style in all used B4XPages or to be able to adjust it, you can change the value(s) in the subroutine CreateMenuSettings. As already written, you can use the standard xui color palette and HTML color code interchangeably.
The above steps will allow you to use the m3Menu.
Please note the following limitations:
The starting point was that the program should be able to easily adjust the menu groups, the associated menu items and icons. I also added the programming option to block an entire menu group or one or more items of a menu group for those who need more than a simple drop-down menu.
The pragmatic choice for the 719 material design icons is a compromise to be able to give the icons the same color as the menu grep title and menu item titles. I was a bit too lazy to pick out a unique icons from the 719 material design icons for the POC for each menu option. It is best to use Erel's [B4X] MaterialIcons Web Font Chooser program to choose the icon you want to use.
The colors used can be used as HTML hexadecimal color code, as well as standard XUI color palette code.
I have paid a lot of attention to making the reusability and adaptability to personal wishes as great and easy as possible for both the novice and the advanced forum members. The easiest way is to add your B4XPage(s) to the Proof Of Concept(POC) and add the code below to your B4XPage(s). The easiest way is to do the testing in B4J according to the following scheme:
By using B4X components as much as possible, the #IF B4J or #IF B4A constructions are avoided and the developed B4J form(s) can be shared between the two development environments via a copy-paste action.
To add an existing m3Menu to an (existing) B4XPage the following steps are required:
Step 1: Global variables in each B4XPage:
Sub Class_Globals
Private Root As B4XView
Private xui As XUI
' --- M3Menu Variables
Private drManager As DrawerManager
Private clvMenu As CustomListView
Private lblMenuInfo As B4XView
End Sub
Step 2: Add Drawer initialization:
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
' --- Initialize B4XMenu
drManager.Initialize(Me, "Drawer", Root)
' --- Load the required page layout here
drManager.Drawer.CenterPanel.LoadLayout("frmPage1")
drManager.Drawer.LeftPanel.LoadLayout("frmLeftMenu")
drManager.Drawer.LeftPanel.Color = drManager.tms.MenuColor
clvMenu = drManager.createMenu(clvMenu)
lblMenuInfo.Text = drManager.tms.MenuInfoText
lblMenuInfo.TextColor =drManager.tms.menuTextColor
End Sub
Step 3: Link the Drawer routines add to the B4XPages:
' --- Check Draw Menu
#IF B4J
Public Sub imgHamburger_MouseClicked (EventData As MouseEvent)
drManager.imgHamburger_MouseClicked(EventData)
End Sub
Private Sub lblMenuInfo_MouseClicked (EventData As MouseEvent)
drManager.LogPrt($"Logo clicked!"$)
End Sub
#End If
Private Sub B4XPage_Appear
drManager.B4XPageAppear(clvMenu)
End Sub
Private Sub B4XPage_CloseRequest As ResumableSub
Return drManager.B4XPageCloseRequest
End Sub
Private Sub B4XPage_Disappear
drManager.B4XPageDisappear
End Sub
' --- Needed for DrawerMenu
Private Sub B4XPage_Resize (Width As Int, Height As Int)
drManager.Drawer.Resize(Width, Height)
End Sub
'Check Draw Menu
Private Sub clvMenu_ItemClick(Index As Int, Val As Object)
drManager.CLVMenu_ItemClick(Index, Val, clvMenu)
End Sub
' --- Check drDrawer Menu
Private Sub clvMenuItems_ItemClick (Index As Int, Value As Object)
drManager.CLVMenu_ItemClick(Index, Value, clvMenu)
End Sub
Private Sub lblMenuInfo_Resize (Width As Double, Height As Double)
End Sub
Create the menu group and group items
The menu structure is very simple, the icon code Chr(0xfb2d) is a direct paste of the chosen icon from
Create the menu group and group items:
Public Sub InitMenuMap
LogPrt($"Create new MenuMap content."$)
tms.m3Menucompleted = False
' --- Initialize the OrderedMap
menuMap.Initialize
' --- Create here your menu structure
'Icons taken from materialdesignicons-webfont.ttf please use the bellow tool
' https://www.b4x.com/android/forum/threads/b4x-materialicons-web-font-chooser.103985/
' fnt = xui.CreateFont(LoadWebFont,26)
' --- First menu group (icon code, text item, status)
menuList.Initialize
menuList.Add(CreatemenuType(Chr(0xfb2d), "File", "True")) ' --- menu Page
menuList.Add(CreatemenuType(Chr(0xfb2d), "File 1", "True"))
menuList.Add(CreatemenuType(Chr(0xfd84), "File 2", "FALSE"))
menuList.Add(CreatemenuType(Chr(0xfb2c), "file 3", "false"))
menuList.Add(CreatemenuType(Chr(0xfb1c), "File 4", "TRUE"))
menuList.Add(CreatemenuType(Chr(0xfd84), "file 5", "True"))
menuList.Add(CreatemenuType(Chr(0xfb1c), "File 6", "TRUE"))
menuList.Add(CreatemenuType(Chr(0xfd84), "file 7", "True"))
menuMap.Put("File", menuList)
' --- Second menu group
menuList.Initialize
menuList.Add(CreatemenuType(Chr(0xfd85), "Page", "True")) ' --- menu Page
menuList.Add(CreatemenuType(Chr(0xfbbe), "Page Main", "True")) '--- Crash @@
menuList.Add(CreatemenuType(Chr(0xfbbe), "Page 1", "True"))
menuList.Add(CreatemenuType(Chr(0xfb1c), "Page 2", "True"))
menuList.Add(CreatemenuType(Chr(0xfb1c), "Page 3", "True"))
menuMap.Put("Page", menuList)
' --- Second menu group
menuList.Initialize
menuList.Add(CreatemenuType(Chr(0xfd85), "Small", "false")) ' --- menu Page
menuList.Add(CreatemenuType(Chr(0xfbbe), "Small 1", "True"))
menuMap.Put("Small", menuList)
' --- Third menu group
menuList.Initialize
menuList.Add(CreatemenuType(Chr(0xf01a), "Config", "True")) ' --- menu Page
menuList.Add(CreatemenuType(Chr(0xf01a), "Page 3", "True"))
menuMap.Put("Config", menuList)
' --- Fourth menu group
menuList.Initialize
menuList.Add(CreatemenuType(Chr(0xf01a), "Menu Tests", "True")) ' --- menu Tests
menuList.Add(CreatemenuType(Chr(0xf01a), "Test 1", "True"))
menuMap.Put("Menu Tests", menuList)
' --- Add more menu groups here
tms.m3Menucompleted = True
B4XPages.MainPage.menuMap = menuMap
End Sub
Name the m3Menu action to be performed
Name the m3Menu action to be performed:
Public Sub mainMenu(Index As Int, value As menuType)
Select value.menuItem
Case "Page Main"
B4XPages.ShowPageandRemovePreviousPages("MainPage")
Case "Page 1"
B4XPages.ShowPageandRemovePreviousPages("Page1")
Case "Page 2"
B4XPages.ShowPageandRemovePreviousPages("Page2")
Case "Page 3"
B4XPages.ShowPageandRemovePreviousPages("Page3")
Case "Test 1"
B4XPages.ShowPageandRemovePreviousPages("PageTest")
Case Else
Drawer.LeftOpen = True
End Select
End Sub
Set default m3Menu colors
HTML hexadecimal color code and standard XUI color palette code can be used in the following DrawerManager subroutine:
Set default m3Menu colors:
Public Sub CreateMenuSettings() As menuSettings
tms.Initialize
tms.hamburgerIconColor = xui.Color_Blue
tms.ImageMenuLogoDirectory = $"${File.DirAssets}"$ ' change this to logo directory
tms.ImageMenuLogoFileName =$"Micro3Logo.png"$ ' change this to your logo file name
tms.ImageMenuLogoFileName =$"logo.png"$ ' change this to your logo file name
tms.m3Menucompleted = False
tms.menuColor = 0xFFF0FFFF ' Menu background color
tms.menuItemColor = 0xFF94D8F6 ' Menu group items background color
tms.menuItemDisabledColor = 0xFFF8A1A4 ' Menu disabled option background color
tms.menuTextColor = xui.Color_Black '
tms.menuWidth = 250dip ' Extended horizontal menu width
tms.MenuHeight = 60dip '
tms.logStatus = False ' Logging via logPrt: false = off true = on
tms.menuInfoText = $"M3Menu '
version 1.05"$
Return tms
End Sub
To quickly implement a so-called own or external house style in all used B4XPages or to be able to adjust it, you can change the value(s) in the subroutine CreateMenuSettings. As already written, you can use the standard xui color palette and HTML color code interchangeably.
The above steps will allow you to use the m3Menu.
Interactivity with the m3Menu
For those who need more control over the m3Menu, the m3Menu supports the ability to dynamically customize menu groups and menu items.Please note the following limitations:
- The behavior of the B4XMainPage is different from the added B4XPage(s). Therefore, do not use an m3Menu with interactivity in the B4XMainPage because the result of the used interactivity is not displayed.
- The m3menu configuration is stored as a list in value in a linkedhashmap. See the example of how allowing the previously blocked menu item takes place as an update in this group list. Use the routines present in the #Region M3Menu interactivity:
- ResetMenu
Reset m3Menu to config created by InitMenuMap
- ReturnMenuGroupItemsList
Return all menu items for the given menu group in a list
- ChangeMenuGroupltemStatus
Change the menu item status to the given status true or false. returns logical true if succesfully.
- ReturnMenuGroupList
Return all menu groups in a list
- ReturnStatusGivenMenultem
Return menu status for given menu item
- TestMenuGroupNameExist
Return True if exist, false if unknow menu group name
Frequently Asked Questions (FAQs)
- There are a lot of menus on this site. Why should I use M3Menu?
M3Menu only shows a few horizontal lines (the "hamburger") on the screen with which a menu can be opened. The opened menu slides from the side over the user screen. This minimizes the space occupied on your program screen.
- What does the name M3Memu stand for?
The "M3" in m3Menu refers to the interchangeable Google terms: "Material 3", "Material design 3", "Material you" and "Compose Material 3" for the color combinations to use in this menu. But don't let that stop you from choosing your own color combination that you like.
- Why can I set the "hamburger" icon to a different color than the font color of the menu options?
This will help you fix a poorly visible 'hamburger' icon with an acceptable combination with your chosen foreground and background colors in M3Menu.
- Why is the "hamburger" icon not displayed on a certain B4XPage in B4J, but it is in B4A?
Possibly the "hamburger" icon is "covered" by another component. By moving that component from the "hamburger" icon location it becomes visible again.
- How can I use the M3Menu?
The M3Menu has been redesigned with Erel's advice to use IDE B4J to easily develop and test in a B4XPages environment in the B4J IDE using B4X components. Then in another IDE you can test via the option "Add Existing Modules" and as "Link - relative path" in the other IDE. I did that for the B4A IDE. By using as many B4X components as possible there are very few differences that are or should be solved via the #IF B4A and #IF B4J options.
- Do I need to develop programs with M3Menu in the B4J IDE?
No, but developing and testing in B4J is easier. In my Proof-Of-Concept program the program models are stored in the project folder. In the B4A IDE these program modules are linked via the option: 'Link - relative path'.
This setup method ensures that saved adjustments (by hand or at the start of the run command) in one IDE are also automatically implemented in the other IDE. For each IDE you have to manually set the libraries to be used. The Drawer Manager of M3Menu provides the necessary differences between B4J and B4A such as the difference between pane and panel.
- How can I display my menu options?
You can place 1, 2, 3 or more menu options in a menu group. The different menu groups are placed in a vertical scroll list. When you click or touch a menu group, it is expanded and another expanded menu group is collapsed.
- How can I customize the menu to my wishes?
The first configurable InitMenuMap contains the menu groups and the menu items for each group, the second configurable mainMenu defines what the do for each group item (the group name is used to open and close the drop-down list for a menu group), and the third configurable CreateMenuSettings defines the values of the define menu settings Type for consistent implementation of the desired setting across all B4XPage files.
- Can I also use M3Menu in the B4XMainPage?
M3Menu is designed with the "Develop it once, reuse it as much as possible unchanged" principle in mind. This principle facilitates troubleshooting and implementing improvements in programs and the application and reuse of menu groups that are related to a specific reusable B4XPage.
- How do I get the character codes for the menu options used?
The 719 icon character codes come from materialdesignicons-webfont.ttf in the asset directory. Use the tool below
' https://www.b4x.com/android/forum/threads/b4x-materialicons-web-font-chooser.103985/ to search through these 719 icons and copy the corresponding character code to the menu option.
- Why can't I use a graphic image for a menu option icon?
The choice for a limited size TTF font makes it easy to adjust the color for a displayed menu line to meet the Material Design 3 requirements.
- What makes M3Menu interactive?
The initial menu configuration is stored in and built from a B4XOrderedMap menuMap in the B4XMainPage. An active menu option has the status "True" in this. By setting this status to "False" the menu option is disabled and displayed with a different chosen background color.
In the Proof-Of-Concept B4XPageMenuTest page present test routine are examples of how the display and use of the M3Menu are possible.
- How can logging be switched on and off?
DrawerManger has three relevant routines: A global routine logPrt that is switched on with tms.logStatus = True and switched off with the command tms.logStatus =False in the CreateMenuSettings routine. In addition, you can interactively switch logging on with the routine drManager.LogPrintOn and switch logging off again with the routine drManager.LogPrintOff.