builder method

Widget builder(
  1. BuildContext context,
  2. BoxConstraints constraints
)

Implementation

Widget builder(BuildContext context, BoxConstraints constraints) {

  // get constraints
  double height = constraints.maxHeight.isFinite ? constraints.maxHeight : MediaQuery.of(context).size.height;
  double width  = constraints.maxWidth.isFinite  ? constraints.maxWidth  : MediaQuery.of(context).size.width;

  // set constraints
  widget.model.maxHeight = height;
  widget.model.maxWidth = width;

  // Check if widget is visible before wasting resources on building it
  if (!widget.model.visible) return const Offstage();

  if (activeDrawer == null) {
    fromTop = height;
    fromBottom = height;
    fromLeft = width;
    fromRight = width;
  }

  top = widget.model.top != null ? BoxView(widget.model.top!) : null;
  bottom = widget.model.bottom != null ? BoxView(widget.model.bottom!) : null;
  left = widget.model.left != null ? BoxView(widget.model.left!) : null;
  right = widget.model.right != null ? BoxView(widget.model.right!) : null;

  double screenHeight = height;
  double screenWidth = width;

  // preset the original dimensions
  oldHeight ??= screenHeight;
  oldWidth ??= screenWidth;

  // check the dimensions for changes, if it has changed, close the any open drawer
  if (screenHeight != oldHeight) {
    oldHeight = screenHeight;
    if (activeDrawer != null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        closeDrawer(activeDrawer);
      });
    }
  } else if (screenWidth != oldWidth) {
    oldWidth = screenWidth;
    if (activeDrawer != null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        closeDrawer(activeDrawer);
      });
    }
  }

  // build the child views
  List<Widget> children = widget.model.inflate();
  if (children.isEmpty) children.add(Container());

  BorderRadius drawerHandle = BorderRadius.zero;
  if (activeDrawer == Drawers.top) {
    visibleDrawer = top;
    drawerHandle = widget.model.rounded == false
        ? BorderRadius.zero
        : BorderRadius.only(
            topLeft: const Radius.elliptical(0, 0),
            topRight: const Radius.elliptical(0, 0),
            bottomLeft: Radius.elliptical(
                screenWidth * .5,
                (screenHeight *
                        ((widget.model.sizeTop != null)
                            ? widget.model.sizeBottom! / screenHeight
                            : 1)) *
                    0.05),
            bottomRight: Radius.elliptical(
                screenWidth * .5,
                (screenHeight *
                        ((widget.model.sizeBottom != null)
                            ? widget.model.sizeTop! / screenHeight
                            : 1)) *
                    0.05));
  } else if (activeDrawer == Drawers.bottom) {
    visibleDrawer = bottom;
    drawerHandle = widget.model.rounded == false
        ? BorderRadius.zero
        : BorderRadius.only(
            topLeft: Radius.elliptical(
                screenWidth * .5,
                (screenHeight *
                        ((widget.model.sizeBottom != null)
                            ? widget.model.sizeBottom! / screenHeight
                            : 1)) *
                    0.05),
            topRight: Radius.elliptical(
                screenWidth * .5,
                (screenHeight *
                        ((widget.model.sizeBottom != null)
                            ? widget.model.sizeBottom! / screenHeight
                            : 1)) *
                    0.05),
            bottomLeft: const Radius.elliptical(0, 0),
            bottomRight: const Radius.elliptical(0, 0));
  } else if (activeDrawer == Drawers.left) {
    visibleDrawer = left;
    drawerHandle = widget.model.rounded == false
        ? BorderRadius.zero
        : BorderRadius.only(
            topLeft: const Radius.elliptical(0, 0),
            topRight: Radius.elliptical(
                screenHeight * 0.05,
                (screenWidth *
                        ((widget.model.sizeLeft != null)
                            ? widget.model.sizeLeft! / screenHeight
                            : 1)) *
                    .5),
            bottomLeft: const Radius.elliptical(0, 0),
            bottomRight: Radius.elliptical(
                screenHeight * 0.05,
                (screenWidth *
                        ((widget.model.sizeLeft != null)
                            ? widget.model.sizeLeft! / screenHeight
                            : 1)) *
                    .5));
  } else if (activeDrawer == Drawers.right) {
    visibleDrawer = right;
    drawerHandle = widget.model.rounded == false
        ? BorderRadius.zero
        : BorderRadius.only(
            topLeft: Radius.elliptical(
                screenHeight * 0.05,
                (screenWidth *
                        ((widget.model.sizeRight != null)
                            ? widget.model.sizeRight! / screenHeight
                            : 1)) *
                    .5),
            topRight: const Radius.elliptical(0, 0),
            bottomLeft: Radius.elliptical(
                screenHeight * 0.05,
                (screenWidth *
                        ((widget.model.sizeRight != null)
                            ? widget.model.sizeRight! / screenHeight
                            : 1)) *
                    .5),
            bottomRight: const Radius.elliptical(0, 0));
  }

  double? containerSize(Drawers? drawer) {
    if (drawer == Drawers.left) {
      return widget.model.sizeLeft ?? screenWidth;
    } else if (drawer == Drawers.right) {
      return widget.model.sizeRight ?? screenWidth;
    } else if (drawer == Drawers.top) {
      return widget.model.sizeTop ?? screenHeight;
    } else if (drawer == Drawers.bottom) {
      return widget.model.sizeBottom ?? screenHeight;
    } else {
      return screenWidth as bool? ?? 300 < screenHeight
          ? screenHeight
          : screenWidth;
    }
  }

  AnimatedPositioned leftDrawer = AnimatedPositioned(
    curve: Curves.easeOutCubic,
    duration: Duration(milliseconds: animate ? 400 : 0),
    onEnd: () => finishedAnimation(),
    right: fromRight ?? screenWidth,
    child: GestureDetector(
      behavior: HitTestBehavior.opaque,
      onHorizontalDragUpdate: (dragUpdateDetails) =>
          onDragging(dragUpdateDetails, DragDirection.horizontal, false),
      onHorizontalDragEnd: (dragEndDetails) =>
          onDragEnd(dragEndDetails, DragDirection.horizontal, true),
      child: ClipRRect(
        borderRadius: drawerHandle,
        child: SizedBox(
            width: ((activeDrawer == Drawers.left || activeDrawer == Drawers.right)
                ? containerSize(activeDrawer)
                : screenWidth),
            height: ((activeDrawer == Drawers.top || activeDrawer == Drawers.bottom)
                ? containerSize(activeDrawer)
                : screenHeight),
            child:
                activeDrawer == Drawers.left ? left ?? Container() : const Offstage()),
      ),
    ),
  );

  AnimatedPositioned rightDrawer = AnimatedPositioned(
    curve: Curves.easeOutCubic,
    duration: Duration(milliseconds: animate ? 400 : 0),
    onEnd: () => finishedAnimation(),
    left: fromLeft ?? screenWidth,
    child: GestureDetector(
      behavior: HitTestBehavior.opaque,
      onHorizontalDragUpdate: (dragUpdateDetails) =>
          onDragging(dragUpdateDetails, DragDirection.horizontal, false),
      onHorizontalDragEnd: (dragEndDetails) =>
          onDragEnd(dragEndDetails, DragDirection.horizontal, true),
      child: ClipRRect(
        borderRadius: drawerHandle,
        child: SizedBox(
            width: ((activeDrawer == Drawers.left || activeDrawer == Drawers.right)
                ? containerSize(activeDrawer)
                : screenWidth),
            height: ((activeDrawer == Drawers.top || activeDrawer == Drawers.bottom)
                ? containerSize(activeDrawer)
                : screenHeight),
            child: activeDrawer == Drawers.right
                ? right ?? Container()
                : const Offstage()),
      ),
    ),
  );

  AnimatedPositioned topDrawer = AnimatedPositioned(
    curve: Curves.easeOutCubic,
    duration: Duration(milliseconds: animate ? 400 : 0),
    onEnd: () => finishedAnimation(),
    bottom: fromBottom ?? screenHeight,
    child: GestureDetector(
      behavior: HitTestBehavior.opaque,
      onVerticalDragUpdate: (dragUpdateDetails) =>
          onDragging(dragUpdateDetails, DragDirection.vertical, false),
      onVerticalDragEnd: (dragEndDetails) =>
          onDragEnd(dragEndDetails, DragDirection.vertical, true),
      child: ClipRRect(
        borderRadius: drawerHandle,
        child: SizedBox(
            width: ((activeDrawer == Drawers.left || activeDrawer == Drawers.right)
                ? containerSize(activeDrawer)
                : screenWidth),
            height: ((activeDrawer == Drawers.top || activeDrawer == Drawers.bottom)
                ? containerSize(activeDrawer)
                : screenHeight),
            child:
                activeDrawer == Drawers.top ? top ?? Container() : const Offstage()),
      ),
    ),
  );

  AnimatedPositioned bottomDrawer = AnimatedPositioned(
    curve: Curves.easeOutCubic,
    duration: Duration(milliseconds: animate ? 400 : 0),
    onEnd: () => finishedAnimation(),
    top: fromTop ?? screenHeight,
    child: GestureDetector(
      behavior: HitTestBehavior.opaque,
      onVerticalDragUpdate: (dragUpdateDetails) =>
          onDragging(dragUpdateDetails, DragDirection.vertical, false),
      onVerticalDragEnd: (dragEndDetails) =>
          onDragEnd(dragEndDetails, DragDirection.vertical, true),
      child: ClipRRect(
        borderRadius: drawerHandle,
        child: SizedBox(
            width: ((activeDrawer == Drawers.left || activeDrawer == Drawers.right)
                ? containerSize(activeDrawer)
                : screenWidth),
            height: ((activeDrawer == Drawers.top || activeDrawer == Drawers.bottom)
                ? containerSize(activeDrawer)
                : screenHeight),
            child: activeDrawer == Drawers.bottom
                ? bottom ?? Container()
                : const Offstage()),
      ),
    ),
  );

  Widget leftHandle = Container();
  Widget rightHandle = Container();
  Widget topHandle = Container();
  Widget bottomHandle = Container();

  if (widget.model.handleLeft == true) {
    leftHandle = AnimatedPositioned(
        curve: Curves.easeOutCubic,
        duration: Duration(milliseconds: animate ? 500 : 0),
        right: (fromRight ?? screenWidth) - 10,
        child: SizedBox(
            height: screenHeight,
            child: Center(
                child: ClipRRect(
                    borderRadius: const BorderRadius.all(Radius.circular(2)),
                    child: MouseRegion(
                        cursor: SystemMouseCursors.click,
                        child: Container(
                            width: 4,
                            height: 50,
                            color: Theme.of(context)
                                .colorScheme
                                .onSurfaceVariant))))));
  }

  if (widget.model.handleRight == true) {
    rightHandle = AnimatedPositioned(
        curve: Curves.easeOutCubic,
        duration: Duration(milliseconds: animate ? 500 : 0),
        left: (fromLeft ?? screenWidth) - 10,
        child: SizedBox(
            height: screenHeight,
            child: Center(
                child: ClipRRect(
                    borderRadius: const BorderRadius.all(Radius.circular(2)),
                    child: MouseRegion(
                        cursor: SystemMouseCursors.click,
                        child: Container(
                            width: 4,
                            height: 50,
                            color: Theme.of(context)
                                .colorScheme
                                .onSurfaceVariant))))));
  }

  if (widget.model.handleTop == true) {
    topHandle = AnimatedPositioned(
        curve: Curves.easeOutCubic,
        duration: Duration(milliseconds: animate ? 500 : 0),
        bottom: (fromBottom ?? screenHeight) - 10,
        child: SizedBox(
            width: screenWidth,
            child: Center(
                child: ClipRRect(
                    borderRadius: const BorderRadius.all(Radius.circular(2)),
                    child: MouseRegion(
                        cursor: SystemMouseCursors.click,
                        child: Container(
                            width: 50,
                            height: 4,
                            color: Theme.of(context)
                                .colorScheme
                                .onSurfaceVariant))))));
  }

  if (widget.model.handleBottom == true) {
    bottomHandle = AnimatedPositioned(
        curve: Curves.easeOutCubic,
        duration: Duration(milliseconds: animate ? 500 : 0),
        top: (fromTop ?? screenHeight) - 10,
        child: SizedBox(
            width: screenWidth,
            child: Center(
                child: ClipRRect(
                    borderRadius: const BorderRadius.all(Radius.circular(2)),
                    child: MouseRegion(
                        cursor: SystemMouseCursors.click,
                        child: Container(
                            width: 50,
                            height: 4,
                            color: Theme.of(context)
                                .colorScheme
                                .onSurfaceVariant))))));
  }

 var drawer = activeDrawer != null
     ? GestureDetector(onTap: () => closeDrawer(activeDrawer))
     : Container();

  Widget view = Stack(children: [
    widget.child,
    drawer,
    leftHandle,
    rightHandle,
    topHandle,
    bottomHandle,
    leftDrawer,
    rightDrawer,
    topDrawer,
    bottomDrawer,
  ]); // view;

  // apply user defined constraints
  view = applyConstraints(view, widget.model.constraints);

  // apply visual transforms
  view = applyTransforms(view);

  view = GoBack(canGoBack: () async => preventPop(), child: view);

  return view;
}