Example creating dynamically FontAwesome icons for a MenuBar.
This solution, see Sub TextToImage, uses a label which font is set to FontAwesome, add to a pane, followed by a screenshot which creates the image and then make the label invisible.
The image is added to the menu items via a list.
Their might be other ways to create an image from text, but this solution is working fine.
MenuBar1 Menu JSON string defined in the Visual Designer
EDIT: 2018-04-09
Another solution is to define a global label and use it for the snapshot.
EDIT: 2018-04-10
With
the image has a transparent background when selecting the menu item.
This solution, see Sub TextToImage, uses a label which font is set to FontAwesome, add to a pane, followed by a screenshot which creates the image and then make the label invisible.
The image is added to the menu items via a list.
Their might be other ways to create an image from text, but this solution is working fine.
MenuBar1 Menu JSON string defined in the Visual Designer
B4X:
[
{Text: "_Navigation", Children:
[
{Text: "Menu_Navigation_First", Tag: "File_Navigation_First", EventName: "Menu_Navigation_First"},
{Text: "Menu_Navigation_Next", Tag: "File_Navigation_Next", EventName: "Menu_Navigation_Next"},
{Text: "Menu_Navigation_Prev", Tag: "File_Navigation_Prev", EventName: "Menu_Navigation_Prev"},
{Text: "Menu_Navigation_Last", Tag: "File_Navigation_Last", EventName: "Menu_Navigation_Last"}
]
}
]
B4X:
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private Menu_Items As Map
Private MenuBar1 As MenuBar
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
' The layout contains a menubar with JSON string as shared previous
MainForm.RootPane.LoadLayout("Main")
MainForm.Show
AppInit
End Sub
Sub AppInit
Menu_Items.Initialize
Menu_Items = MenuBar_Items(MenuBar1)
MenuBar_MenuItem_SetImage(Menu_Items , "File_Navigation_First", TextToImage(MainForm.RootPane, Chr(0xF0AA), 16))
MenuBar_MenuItem_SetImage(Menu_Items , "File_Navigation_Next", TextToImage(MainForm.RootPane, Chr(0xF063), 16))
MenuBar_MenuItem_SetImage(Menu_Items , "File_Navigation_Prev", TextToImage(MainForm.RootPane, Chr(0xF062), 16))
MenuBar_MenuItem_SetImage(Menu_Items , "File_Navigation_Last", TextToImage(MainForm.RootPane, Chr(0xF0AB), 16))
End Sub
' Build the menubar items as map
Public Sub MenuBar_Items(MnuBar As MenuBar) As Map
Dim menus As Map
menus.Initialize
CollectMenuItems(menus, MnuBar.Menus)
Return menus
End Sub
' Collate the menu items as a list - used by MenuBar_Items
Private Sub CollectMenuItems(Menus As Map, Items As List)
For Each mi As MenuItem In Items
If mi.Tag <> Null And mi.Tag <> "" Then Menus.Put(mi.Tag, mi)
If mi Is Menu Then
Dim mn As Menu = mi
CollectMenuItems(Menus, mn.MenuItems)
End If
Next
End Sub
' Set an image for a menuitem
Public Sub MenuBar_MenuItem_SetImage(MenuItems As Map, Item As String, Img As Image)
Dim mi As MenuItem = MenuItems.Get(Item)
If mi.IsInitialized Then
mi.Image = Img
End If
End Sub
' Convert text string to an image using a hidden label.
' Example with FontAwesome:
' Dim img As Image = TextToImage(MainForm.RootPane, Chr(0xF0AA), 16)
' This can be used to add f.e. a fontawesome icon dynamically to a menu item:
' Dim mi As MenuItem ... mi.Image = img
Sub TextToImage(p As Pane, s As String, FontSize As Double) As Image
Dim img As Image
Dim lbl As Label
lbl.Initialize("lbl")
lbl.Font = fx.CreateFontAwesome(FontSize)
lbl.Text = s
p.AddNode(lbl, -1, -1, -1, -1)
img = lbl.Snapshot
lbl.Visible = False
Return img
End Sub
EDIT: 2018-04-09
Another solution is to define a global label and use it for the snapshot.
B4X:
' Convert fontawesome string to an image using a label created with the visual designer.
' Private Label1 As Label
' Dim img As Image = FontAwesomeToImage(Chr(0xF0AA), 16)
' This can be used to add f.e. a fontawesome icon dynamically to a menu item:
' Dim mi As MenuItem ... mi.Image = img
Sub FontAwesomeToImage(s As String, FontSize As Double) As Image
Dim img As Image
Label1.Text = s
Label1.TextSize = FontSize
Label1.Visible = True
img = Label1.Snapshot
Label1.Visible = False
Return img
End Sub
EDIT: 2018-04-10
With
B4X:
img = Label1.Snapshot2(fx.Colors.Transparent)
Last edited: