buildMenu method
Given the items and possibly a builder , build the actual menu. Uses a SingleChildScrollView if performance mode is off, or uses a ListView for lazy loading if performance mode is on. The builder can be used to completely customize the menu actually shown.
Implementation
dynamic buildMenu({void Function(MapEntry<int, SMenuItem> element)? onTap}) {
final Widget menu;
// If builder is given, use it.
if (widget.builder != null) {
menu = widget.builder!(context, widget.items);
} else {
// Otherwise create the menu
// Wrap items in inkwell if clickable
final items = widget.items.asMap().entries.map((element) {
final SMenuItem item = element.value;
// Add a button effect only if item is clickable or switchable
// && item.type != SMenuItemType.switchable
if (item.type != SMenuItemType.clickable) {
return item;
}
return Material(
shape: item.style.shape ??
RoundedRectangleBorder(
side: item.style.side ?? BorderSide.none,
borderRadius: item.style.borderRadius),
color: item.style.bgColor ?? Colors.transparent,
child: InkWell(
// TODO: Allow changing of colors, not just apply opacity
highlightColor: item.style.accentColor?.withOpacity(0.2),
hoverColor: item.style.accentColor?.withOpacity(0.1),
splashColor: item.style.accentColor?.withOpacity(0.05),
customBorder: item.style.shape,
mouseCursor: item.style.mouseCursor,
borderRadius: item.style.borderRadius,
onTap: () {
// TODO: Flip?
// Internal handling of onTap
if (onTap != null) onTap(element);
// Followed by user handling of onTap
if (item.onPressed != null) item.onPressed!();
// if (element.value.onToggle != null) {
// setState(() {
// if (element.value.toggled == null) {
// element.value.onToggle!(true);
// } else {
// element.value.onToggle!(!element.value.toggled!);
// }
// });
// }
},
child: item,
),
);
}).toList();
// In performance mode, we use a ListView to be able to lazy load
if (widget.performanceMode) {
// TODO: what to do on style.padding?
menu = ListView(
shrinkWrap: true,
children: items,
);
} else {
// Otherwise, if performance mode is off, use a SingleChildScrollView
menu = SingleChildScrollView(
// TODO: implement scroll direction
// scrollDirection: widget.scrollDirection,
child: Flex(
mainAxisSize: MainAxisSize.min,
direction: Axis.vertical, //widget.scrollDirection,
children: items,
),
);
}
}
// TODO: Change column to flex
// Add in the header and footer in a flex widget
return Column(
// TODO: what to do on style.alignment?
// crossAxisAlignment: widget.style.alignment ?? CrossAxisAlignment.center,
children: [
// Header
if (widget.header != null) widget.header!,
// Menu
Expanded(
child: menu,
),
// Footer
if (widget.footer != null) widget.footer!,
],
);
}