buildMenu method

dynamic buildMenu({
  1. void onTap(
    1. MapEntry<int, SMenuItem> element
    )?,
})

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!,
    ],
  );
}