Using the BBjAppLayout Plugin
The BBjAppLayout
is a custom BBj
widget for the DWC
(Dynamic Web Client) that enables building common application layouts. The layout is responsive and automatically adjusts to fit different screen sizes.
It consists of a header
, a footer
, a collapsible drawer
, and a content area
. Each of these sections is, by default an instance of BBjChildWindow. Ususally, the header
and footer
are fixed, the drawer
slides in and out of the viewport, and the content area
is scrollable.
Note
: A DWC
application can have only one BBjAppLayout
instance. Having multiple instances is not supported.
Note
: The BBjTopLevelWindow should set the $00001000$
flag to fill the viewport.
Installation
Follow one of the steps to install BBjAppLayout
.
Features
BBjAppLayout
features:
And much more !
The Gist
The following example demonstrates how to use the BBjAppLayout
widget. Each part of the layout is an instance of BBjChildWindow, which can contain any valid BBjControl.
For the best results, the application should include a viewport meta tag that contains viewport-fit=cover
. This meta tag ensures the viewport is scaled to fill the device display.
Example 1
web! = BBjAPI().getWebManager()
meta$ = "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no"
web!.setMeta("viewport", meta$)
|
Note
: The demos use the [dwc-icon-button]
web component to create a drawer toggle button. The button includes the data-drawer-toggle
attribute, which instructs BBjAppLayout
to listen for click events from that component to toggle the drawer state.
Example 2
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
app! = new BBjAppLayout(wnd!)
header! = app!.getHeader()
toolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
toolbar!.addStyle("dwc-toolbar")
REM - Add a toggle button which works independently in the browser
toolbar!.addStaticText("
:<html>
: <dwc-icon-button name='menu-2' data-drawer-toggle>
: </dwc-icon-button>
:</html>")
toolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
|
Example 3
style! = "
: body,html {overflow: hidden}
:
: .dwc-toolbar {
: display: flex;
: align-items: center;
: gap: var(--dwc-space-m);
: padding: 0 var(--dwc-space-m);
: }
:
: .dwc-logo {
: display: flex;
: align-items: center;
: justify-content: center;
: padding: var(--dwc-space-m) 0;
: margin-bottom: var(--dwc-space-m);
: border-bottom: thin solid var(--dwc-color-default)
: }
:
: .dwc-logo img {
: max-width: 100px;
: }
:"
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
web! = BBjAPI().getWebManager()
rem The app should include a viewport meta tag which contains `viewport-fit=cover`, like the following.
rem This causes the viewport to be scaled to fill the device display.
web!.setMeta("viewport", "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no")
web!.injectStyle(style!, 0)
sysgui! = BBjAPI().openSysGui("X0")
imageManager! = sysgui!.getImageManager()
wnd! = sysgui!.addWindow("BBjAppLayout", $01001000$)
wnd!.setCallback(BBjAPI.ON_CLOSE,"eoj")
app! = new BBjAppLayout(wnd!)
rem Header
rem ==================
header! = app!.getHeader()
toolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
toolbar!.addStyle("dwc-toolbar")
toolbar!.addStaticText("<html><dwc-icon-button name='menu-2' data-drawer-toggle></dwc-icon-button></html>")
toolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
rem Drawer
rem ==================
drawer! = app!.getDrawer()
drawer!.addStyle("dwc-drawer")
logo! = drawer!.addImageCtrl(imageManager!.loadImageFromFile("./assets/logo.png"))
logo!.addStyle("dwc-logo")
drawerMenu! = drawer!.addTabCtrl()
drawerMenu!.setCallback(drawerMenu!.ON_TAB_SELECT,"onPageChanged")
drawerMenu!.setAttribute("nobody","true")
drawerMenu!.setAttribute("borderless","true")
drawerMenu!.setAttribute("placement","left")
drawerMenu!.addTab("<dwc-icon name='dashboard'></dwc-icon> Dashboard" , -1)
drawerMenu!.addTab("<dwc-icon name='shopping-cart'></dwc-icon> Orders" , -1)
drawerMenu!.addTab("<dwc-icon name='users'></dwc-icon> Customers" , -1)
drawerMenu!.addTab("<dwc-icon name='box'></dwc-icon> Products" , -1)
drawerMenu!.addTab("<dwc-icon name='files'></dwc-icon> Documents" , -1)
drawerMenu!.addTab("<dwc-icon name='checklist'></dwc-icon> Tasks" , -1)
drawerMenu!.addTab("<dwc-icon name='chart-dots-2'></dwc-icon> Analytics" , -1)
rem Content
rem ==================
content! = app!.getContent()
content!.addStaticText("<html><h1>Application Title</h1></html>")
pageContent! = content!.addStaticText("<html><p>Content goes here</p></html>")
process_events
onPageChanged:
event! = sysgui!.getLastEvent()
title$ = event!.getTitle().replaceAll("<[^>]*>","").trim()
pageContent!.setText("<html><p>Content for " + title$ + " goes here</p></html>")
return
eoj:
release
|
Full Width Navbars
By default, BBjAppLayout
renders the header and footer in off-screen
mode. In this mode, the header and footer positions are shifted to fit beside the opened drawer. Disabling off-screen
mode causes the header and footer to occupy the full available space, and shifts the drawer's top and bottom positions to align with the header and footer.
Example 4
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
app! = new BBjAppLayout(wnd!)
app!.setHeaderOffscreen(0)
app!.setFooterOffscreen(0)
|
Example 5
style! = "
: body,html {overflow: hidden}
:
: .dwc-toolbar {
: display: flex;
: align-items: center;
: gap: var(--dwc-space-m);
: padding: 0 var(--dwc-space-m);
: }
:
: .dwc-drawer {
: padding-top: var(--dwc-space-m)
: }
:
: .dwc-logo {
: display: flex;
: align-items: center;
: justify-content: center;
: }
:
: .dwc-logo img {
: height: 24px;
: }
:"
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
web! = BBjAPI().getWebManager()
rem The app should include a viewport meta tag which contains `viewport-fit=cover`, like the following.
rem This causes the viewport to be scaled to fill the device display.
web!.setMeta("viewport", "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no")
web!.injectStyle(style!, 0)
sysgui! = BBjAPI().openSysGui("X0")
imageManager! = sysgui!.getImageManager()
wnd! = sysgui!.addWindow("BBjAppLayout", $01001000$)
wnd!.setCallback(BBjAPI.ON_CLOSE,"eoj")
app! = new BBjAppLayout(wnd!)
app!.setHeaderOffscreen(0)
rem Header
rem ==================
header! = app!.getHeader()
toolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
toolbar!.addStyle("dwc-toolbar")
toolbar!.addStaticText("<html><dwc-icon-button name='menu-2' data-drawer-toggle></dwc-icon-button></html>")
logo! = toolbar!.addImageCtrl(imageManager!.loadImageFromFile("./assets/logo.png"))
logo!.addStyle("dwc-logo")
toolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
rem Drawer
rem ==================
drawer! = app!.getDrawer()
drawer!.addStyle("dwc-drawer")
drawerMenu! = drawer!.addTabCtrl()
drawerMenu!.setCallback(drawerMenu!.ON_TAB_SELECT,"onPageChanged")
drawerMenu!.setAttribute("nobody","true")
drawerMenu!.setAttribute("borderless","true")
drawerMenu!.setAttribute("placement","left")
drawerMenu!.addTab("<dwc-icon name='dashboard'></dwc-icon> Dashboard" , -1)
drawerMenu!.addTab("<dwc-icon name='shopping-cart'></dwc-icon> Orders" , -1)
drawerMenu!.addTab("<dwc-icon name='users'></dwc-icon> Customers" , -1)
drawerMenu!.addTab("<dwc-icon name='box'></dwc-icon> Products" , -1)
drawerMenu!.addTab("<dwc-icon name='files'></dwc-icon> Documents" , -1)
drawerMenu!.addTab("<dwc-icon name='checklist'></dwc-icon> Tasks" , -1)
drawerMenu!.addTab("<dwc-icon name='chart-dots-2'></dwc-icon> Analytics" , -1)
rem Content
rem ==================
content! = app!.getContent()
content!.addStaticText("<html><h1>Application Title</h1></html>")
pageContent! = content!.addStaticText("<html><p>Content goes here</p></html>")
process_events
onPageChanged:
event! = sysgui!.getLastEvent()
title$ = event!.getTitle().replaceAll("<[^>]*>","").trim()
pageContent!.setText("<html><p>Content for " + title$ + " goes here</p></html>")
return
eoj:
release
|
Multiple Toolbars
The navbar has no limit on the number of toolbars you can add. Each toolbar is simply a BBjChildWindow.
The following demo shows how to use two toolbars. The first toolbar contains the drawer toggle button and the application title. The second toolbar includes a secondary navigation menu.
Note:
For applications that require multilevel or hierarchical navigation, use the drawer to contain the primary navigation items, and place secondary navigation in a second toolbar within the navbar.
Example 6
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
app! = new BBjAppLayout(wnd!)
header! = app!.getHeader()
toolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
toolbar!.addStyle("dwc-toolbar")
toolbar!.addStaticText("
:<html>
: <dwc-icon-button name='menu-2' data-drawer-toggle>
: </dwc-icon-button>
:</html>")
toolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
secondToolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
empty! = secondToolbar!.addChildWindow("", $00000810$, sysgui!.getAvailableContext())
menu! = secondToolbar!.addTabCtrl()
menu!.setAttribute("nobody","true")
menu!.setAttribute("borderless","true")
menu!.addTab("<dwc-icon name='report-money'></dwc-icon> Sales", empty!)
menu!.addTab("<dwc-icon name='building'></dwc-icon> Enterprise", empty!)
menu!.addTab("<dwc-icon name='credit-card'></dwc-icon> Payments", empty!)
menu!.addTab("<dwc-icon name='history'></dwc-icon> History", empty!)
|
Example 7
style! = "
: body,html {overflow: hidden}
:
: .dwc-toolbar {
: display: flex;
: align-items: center;
: gap: var(--dwc-space-m);
: padding: 0 var(--dwc-space-m);
: }
:
: .dwc-logo {
: display: flex;
: align-items: center;
: justify-content: center;
: padding: var(--dwc-space-m) 0;
: margin-bottom: var(--dwc-space-m);
: border-bottom: thin solid var(--dwc-color-default)
: }
:
: .dwc-logo img {
: max-width: 100px;
: }
:"
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
web! = BBjAPI().getWebManager()
rem The app should include a viewport meta tag which contains `viewport-fit=cover`, like the following.
rem This causes the viewport to be scaled to fill the device display.
web!.setMeta("viewport", "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no")
web!.injectStyle(style!, 0)
sysgui! = BBjAPI().openSysGui("X0")
imageManager! = sysgui!.getImageManager()
wnd! = sysgui!.addWindow("BBjAppLayout", $01001000$)
wnd!.setCallback(BBjAPI.ON_CLOSE,"eoj")
app! = new BBjAppLayout(wnd!)
rem Header
rem ==================
header! = app!.getHeader()
firstToolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
firstToolbar!.addStyle("dwc-toolbar")
firstToolbar!.addStaticText("<html><dwc-icon-button name='menu-2' data-drawer-toggle></dwc-icon-button></html>")
firstToolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
secondToolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
secondToolbarMenu! = secondToolbar!.addTabCtrl()
secondToolbarMenu!.setAttribute("nobody","true")
secondToolbarMenu!.setAttribute("borderless","true")
secondToolbarMenu!.addTab("<dwc-icon name='report-money'></dwc-icon> Sales" , -1)
secondToolbarMenu!.addTab("<dwc-icon name='building'></dwc-icon> Enterprise" , -1)
secondToolbarMenu!.addTab("<dwc-icon name='credit-card'></dwc-icon> Payments" , -1)
secondToolbarMenu!.addTab("<dwc-icon name='history'></dwc-icon> History" , -1)
rem Drawer
rem ==================
drawer! = app!.getDrawer()
drawer!.addStyle("dwc-drawer")
logo! = drawer!.addImageCtrl(imageManager!.loadImageFromFile("./assets/logo.png"))
logo!.addStyle("dwc-logo")
drawerMenu! = drawer!.addTabCtrl()
drawerMenu!.setCallback(drawerMenu!.ON_TAB_SELECT, "onPageChanged")
drawerMenu!.setAttribute("nobody","true")
drawerMenu!.setAttribute("borderless","true")
drawerMenu!.setAttribute("placement","left")
drawerMenu!.addTab("<dwc-icon name='dashboard'></dwc-icon> Dashboard" , -1)
drawerMenu!.addTab("<dwc-icon name='shopping-cart'></dwc-icon> Orders" , -1)
drawerMenu!.addTab("<dwc-icon name='users'></dwc-icon> Customers" , -1)
drawerMenu!.addTab("<dwc-icon name='box'></dwc-icon> Products" , -1)
drawerMenu!.addTab("<dwc-icon name='files'></dwc-icon> Documents" , -1)
drawerMenu!.addTab("<dwc-icon name='checklist'></dwc-icon> Tasks" , -1)
drawerMenu!.addTab("<dwc-icon name='chart-dots-2'></dwc-icon> Analytics" , -1)
rem Content
rem ==================
content! = app!.getContent()
content!.addStaticText("<html><h1>Application Title</h1></html>")
pageContent! = content!.addStaticText("<html><p>Content goes here</p></html>")
process_events
onPageChanged:
event! = sysgui!.getLastEvent()
title$ = event!.getTitle().replaceAll("<[^>]*>","").trim()
pageContent!.setText("<html><p>Content for " + title$ + " goes here</p></html>")
return
eoj:
release
|
Sticky Toolbars
A sticky toolbar is a toolbar that remains visible at the top of the page when the user scrolls down, while the navbar height collapses to maximize space for the page content. This type of toolbar typically contains a fixed navigation menu relevant to the current page.
Sticky toolbars can be created using the CSS custom property --dwc-app-layout-header-collapse-height
and the BBjAppLayout::HeaderReveal
option.
When the BBjAppLayout::HeaderReveal
option is set to true, the header is initially visible on render, then hidden when the user scrolls down. It reappears when the user scrolls back up.
The CSS custom property --dwc-app-layout-header-collapse-height
controls how much of the header navbar is hidden.
Example 8
style! = "
: body,html {overflow: hidden}
:
: :root {
: --dwc-app-layout-header-collapse-height: 45px;
: }
:
: .dwc-toolbar {
: display: flex;
: align-items: center;
: gap: var(--dwc-space-m);
: padding: 0 var(--dwc-space-m);
: }
:
: .dwc-logo {
: display: flex;
: align-items: center;
: justify-content: center;
: padding: var(--dwc-space-m) 0;
: margin-bottom: var(--dwc-space-m);
: border-bottom: thin solid var(--dwc-color-default)
: }
:
: .dwc-logo img {
: max-width: 100px;
: }
:
: .dwc-content {
: max-width: 600px;
: margin: 0 auto;
: }
:
: .dwc-card {
: padding: var(--dwc-space-m);
: margin: var(--dwc-space-m) 0;
: border: thin solid var(--dwc-color-default);
: border-radius: var(--dwc-border-radius-m);
: background-color: var(--dwc-surface-3);
: }
:"
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
web! = BBjAPI().getWebManager()
rem The app should include a viewport meta tag which contains `viewport-fit=cover`, like the following.
rem This causes the viewport to be scaled to fill the device display.
web!.setMeta("viewport", "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no")
web!.injectStyle(style!, 0)
sysgui! = BBjAPI().openSysGui("X0")
imageManager! = sysgui!.getImageManager()
wnd! = sysgui!.addWindow("BBjAppLayout", $01001000$)
wnd!.setCallback(BBjAPI.ON_CLOSE,"eoj")
app! = new BBjAppLayout(wnd!)
app!.setHeaderReveal(1)
rem Header
rem ==================
header! = app!.getHeader()
firstToolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
firstToolbar!.addStyle("dwc-toolbar")
firstToolbar!.addStaticText("<html><dwc-icon-button name='menu-2' data-drawer-toggle></dwc-icon-button></html>")
firstToolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
secondToolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
secondToolbarMenu! = secondToolbar!.addTabCtrl()
secondToolbarMenu!.setAttribute("nobody","true")
secondToolbarMenu!.setAttribute("borderless","true")
secondToolbarMenu!.addTab("<dwc-icon name='report-money'></dwc-icon> Sales" , -1)
secondToolbarMenu!.addTab("<dwc-icon name='building'></dwc-icon> Enterprise" , -1)
secondToolbarMenu!.addTab("<dwc-icon name='credit-card'></dwc-icon> Payments" , -1)
secondToolbarMenu!.addTab("<dwc-icon name='history'></dwc-icon> History" , -1)
rem Drawer
rem ==================
drawer! = app!.getDrawer()
drawer!.addStyle("dwc-drawer")
logo! = drawer!.addImageCtrl(imageManager!.loadImageFromFile("./assets/logo.png"))
logo!.addStyle("dwc-logo")
drawerMenu! = drawer!.addTabCtrl()
drawerMenu!.setCallback(drawerMenu!.ON_TAB_SELECT,"onPageChanged")
drawerMenu!.setAttribute("nobody","true")
drawerMenu!.setAttribute("borderless","true")
drawerMenu!.setAttribute("placement","left")
drawerMenu!.addTab("<dwc-icon name='dashboard'></dwc-icon> Dashboard" , -1)
drawerMenu!.addTab("<dwc-icon name='shopping-cart'></dwc-icon> Orders" , -1)
drawerMenu!.addTab("<dwc-icon name='users'></dwc-icon> Customers" , -1)
drawerMenu!.addTab("<dwc-icon name='box'></dwc-icon> Products" , -1)
drawerMenu!.addTab("<dwc-icon name='files'></dwc-icon> Documents" , -1)
drawerMenu!.addTab("<dwc-icon name='checklist'></dwc-icon> Tasks" , -1)
drawerMenu!.addTab("<dwc-icon name='chart-dots-2'></dwc-icon> Analytics" , -1)
rem Content
rem ==================
content! = app!.getContent()
content!.addStyle("dwc-content")
pageHeader! = content!.addStaticText("<html><h1>Application Title</h1></html>")
lorem! = "
:Lorem Ipsum is simply dummy text of the printing and typesetting
:industry. Lorem Ipsum has been the industry's standard dummy
:text ever since the 1500s when an unknown printer took a galley
:of type and scrambled it to make a type specimen book. It has
:survived not only five centuries, but also the leap into electronic
:typesetting, remaining essentially unchanged. It was popularised
:in the 1960s with the release of Letraset sheets containing Lorem
:Ipsum passages, and more recently with desktop publishing software
: like Aldus PageMaker including versions of Lorem Ipsum.
:"
for i=1 to 10
card! = content!.addChildWindow("", $00108000$, sysgui!.getAvailableContext())
card!.addStyle("dwc-card")
cardTitle! = card!.addStaticText("<html><h2>What is Lorem Ipsum (" + str(i) +")?</h2></html>")
cardContent! = card!.addStaticText("<html><p>" + lorem! + "</p></html>")
next
process_events
onPageChanged:
event! = sysgui!.getLastEvent()
title$ = event!.getTitle().replaceAll("<[^>]*>","").trim()
pageHeader!.setText("<html><h1>" + title$ + " Page</h1></html>")
return
eoj:
release
|
Mobile Navigation Layout
The bottom navbar can be used to provide an alternative navigation experience at the bottom of the application. This type of navigation is especially common in mobile apps.
Note:
Notice how the drawer is hidden in the following demo. The BBjAppLayout
widget supports three drawer positions: DRAWER_PLACEMENT_LEFT
, DRAWER_PLACEMENT_RIGHT
, and DRAWER_PLACEMENT_HIDDEN
.
Example 9
style! = "
: body,html {overflow: hidden}
:
: .dwc-toolbar {
: display: flex;
: align-items: center;
: gap: var(--dwc-space-m);
: padding: 0 var(--dwc-space-m);
: }
:
: .dwc-logo {
: display: flex;
: align-items: center;
: justify-content: center;
: }
:
: .dwc-logo img {
: height: 24px;
: }
:
: @media (max-width: 600px) {
: dwc-tab::part(title) {
: display: none;
: }
: }
:"
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
web! = BBjAPI().getWebManager()
rem The app should include a viewport meta tag which contains `viewport-fit=cover`, like the following.
rem This causes the viewport to be scaled to fill the device display.
web!.setMeta("viewport", "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no")
web!.injectStyle(style!, 0)
sysgui! = BBjAPI().openSysGui("X0")
imageManager! = sysgui!.getImageManager()
wnd! = sysgui!.addWindow("BBjAppLayout", $01001000$)
wnd!.setCallback(BBjAPI.ON_CLOSE,"eoj")
app! = new BBjAppLayout(wnd!)
app!.setHeaderOffscreen(0)
app!.setDrawerPlacement(BBjAppLayout.DRAWER_PLACEMENT_HIDDEN)
rem Header
rem ==================
header! = app!.getHeader()
toolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
toolbar!.addStyle("dwc-toolbar")
logo! = toolbar!.addImageCtrl(imageManager!.loadImageFromFile("./assets/logo.png"))
logo!.addStyle("dwc-logo")
toolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
rem Footer
rem ==================
footer! = app!.getFooter()
footer!.addStyle("dwc-footer")
footerMenu! = footer!.addTabCtrl()
footerMenu!.setCallback(footerMenu!.ON_TAB_SELECT, "onPageChanged")
footerMenu!.setAttribute("nobody","true")
footerMenu!.setAttribute("borderless","true")
footerMenu!.setAttribute("placement","bottom")
footerMenu!.setAttribute("alignment","stretch")
footerMenu!.addTab("<dwc-icon expanse='s' name='dashboard'></dwc-icon> <span part='title'>Dashboard</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='shopping-cart'></dwc-icon> <span part='title'>Orders</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='users'></dwc-icon> <span part='title'>Customers</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='box'></dwc-icon> <span part='title'>Products</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='files'></dwc-icon> <span part='title'>Documents</span>" , -1)
rem Content
rem ==================
content! = app!.getContent()
content!.addStaticText("<html><h1>Application Title</h1></html>")
pageContent! = content!.addStaticText("<html><p>Content goes here</p></html>")
process_events
onPageChanged:
event! = sysgui!.getLastEvent()
title$ = event!.getTitle().replaceAll("<[^>]*>","").trim()
pageContent!.setText("<html><p>Content for " + title$ + " goes here</p></html>")
return
eoj:
release
|
Footer Reveal
Just like BBjAppLayout::HeaderReveal
, BBjAppLayout::FooterReveal
is also supported. When the FooterReveal
option is set to true
, the footer is initially visible on render, then hidden when the user scrolls up. It reappears once the user scrolls down again.
Example 10
style! = "
: body,html {overflow: hidden}
:
: .dwc-toolbar {
: display: flex;
: align-items: center;
: gap: var(--dwc-space-m);
: padding: 0 var(--dwc-space-m);
: background-color: var(--dwc-color-primary);
: color: var(--dwc-color-on-primary-text);
: }
:
: .dwc-logo {
: display: flex;
: align-items: center;
: justify-content: center;
: }
:
: .dwc-logo img {
: height: 24px;
: }
:
: .dwc-content {
: max-width: 600px;
: margin: 0 auto;
: }
:
: .dwc-card {
: padding: var(--dwc-space-m);
: margin: var(--dwc-space-m) 0;
: border: thin solid var(--dwc-color-default);
: border-radius: var(--dwc-border-radius-m);
: background-color: var(--dwc-surface-3);
: }
:
: @media (max-width: 600px) {
: dwc-tab::part(title) {
: display: none;
: }
: }
:"
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
web! = BBjAPI().getWebManager()
rem The app should include a viewport meta tag which contains `viewport-fit=cover`, like the following.
rem This causes the viewport to be scaled to fill the device display.
web!.setMeta("viewport", "width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no")
web!.injectStyle(style!, 0)
sysgui! = BBjAPI().openSysGui("X0")
imageManager! = sysgui!.getImageManager()
wnd! = sysgui!.addWindow("BBjAppLayout", $01001000$)
wnd!.setCallback(BBjAPI.ON_CLOSE,"eoj")
app! = new BBjAppLayout(wnd!)
app!.setFooterReveal(1)
app!.setFooterShadow(BBjAppLayout.SHADOW_SCROLL)
app!.setDrawerPlacement(BBjAppLayout.DRAWER_PLACEMENT_HIDDEN)
rem Header
rem ==================
header! = app!.getHeader()
toolbar! = header!.addChildWindow("", $00108800$, sysgui!.getAvailableContext())
toolbar!.addStyle("dwc-toolbar")
logo! = toolbar!.addImageCtrl(imageManager!.loadImageFromFile("./assets/logo.png"))
logo!.addStyle("dwc-logo")
toolbar!.addStaticText("<html><h3>DWC Application</h3></html>")
rem Footer
rem ==================
footer! = app!.getFooter()
footer!.addStyle("dwc-footer")
footerMenu! = footer!.addTabCtrl()
footerMenu!.setCallback(footerMenu!.ON_TAB_SELECT, "onPageChanged")
footerMenu!.setAttribute("nobody","true")
footerMenu!.setAttribute("borderless","true")
footerMenu!.setAttribute("placement","bottom")
footerMenu!.setAttribute("alignment","stretch")
footerMenu!.addTab("<dwc-icon expanse='s' name='dashboard'></dwc-icon> <span part='title'>Dashboard</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='shopping-cart'></dwc-icon> <span part='title'>Orders</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='users'></dwc-icon> <span part='title'>Customers</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='box'></dwc-icon> <span part='title'>Products</span>" , -1)
footerMenu!.addTab("<dwc-icon expanse='s' name='files'></dwc-icon> <span part='title'>Documents</span>" , -1)
rem Content
rem ==================
content! = app!.getContent()
content!.addStyle("dwc-content")
pageHeader! = content!.addStaticText("<html><h1>Application Title</h1></html>")
lorem! = "
:Lorem Ipsum is simply dummy text of the printing and typesetting
:industry. Lorem Ipsum has been the industry's standard dummy
:text ever since the 1500s when an unknown printer took a galley
:of type and scrambled it to make a type specimen book. It has
:survived not only five centuries, but also the leap into electronic
:typesetting, remaining essentially unchanged. It was popularised
:in the 1960s with the release of Letraset sheets containing Lorem
:Ipsum passages, and more recently with desktop publishing software
: like Aldus PageMaker including versions of Lorem Ipsum.
:"
for i=1 to 10
card! = content!.addChildWindow("", $00108000$, sysgui!.getAvailableContext())
card!.addStyle("dwc-card")
cardTitle! = card!.addStaticText("<html><h2>What is Lorem Ipsum (" + str(i) +")?</h2></html>")
cardContent! = card!.addStaticText("<html><p>" + lorem! + "</p></html>")
next
process_events
onPageChanged:
event! = sysgui!.getLastEvent()
title$ = event!.getTitle().replaceAll("<[^>]*>","").trim()
pageHeader!.setText("<html><h1>" + title$ + " Page</h1></html>")
return
eoj:
release
|
Drawer Breakpoint
By default, when the screen width is 800px
or less, the drawer switches to popover
mode. This is known as breakpoint. In popover
mode, the drawer displays over the content area with an overlay. The breakpoint can be configured using the BBjAppLayout::setDrawerBreakpoint
method, and it must be a valid media query.
For instance, in the following example, the drawer breakpoint is configured to 500px
or less.
Example 11
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
app! = new BBjAppLayout(wnd!)
app!.setDrawerBreakpoint("(max-width: 500px)")
|
Events
The BBjAppLayout
supports three events:
-
ON_DRAWER_OPENED
: Fired when the drawer is opened.
-
ON_DRAWER_CLOSED
: Fired when the drawer is closed.
-
ON_DRAWER_TOGGLED
: Fired when the drawer is toggled.
The event's payload is an instance of the ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayoutEvent
Example 12
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayout
use ::BBjAppLayout/BBjAppLayout.bbj::BBjAppLayoutEvent
app! = new BBjAppLayout(wnd!)
app!.setCallback(BBjAppLayout.ON_DRAWER_TOGGLED, "onDrawerToggled")
onDrawerToggled:
declare auto BBjAppLayoutEvent payload!
event! = sysgui!.getLastEvent()
payload! = event!.getObject()
let x = MSGBOX("Is Opened = " + str(payload!.isDrawerOpened()), 0, "Drawer Toggled")
return
|
See Also
AppLayout Plugin Overview