public override Offset getPositionForChild(Size size, Size childSize)
        {
            _MenuLimits menuLimits = route.getMenuLimits(buttonRect, size.height, route.selectedIndex ?? 0);

            D.assert(() => {
                Rect container = Offset.zero & size;
                if (container.intersect(buttonRect) == buttonRect)
                {
                    D.assert(menuLimits.top >= 0.0f);
                    D.assert(menuLimits.top + menuLimits.height <= size.height);
                }

                return(true);
            });
            D.assert(textDirection != null);
            float left = 0;

            switch (textDirection)
            {
            case TextDirection.rtl:
                left = (buttonRect.right.clamp(0.0f, size.width)) - childSize.width;
                break;

            case TextDirection.ltr:
                left = buttonRect.left.clamp(0.0f, size.width - childSize.width);
                break;
            }

            return(new Offset(left, menuLimits.top ?? 0));
        }
        void _handleFocusChange(bool focused)
        {
            bool inTraditionalMode = false;

            switch (FocusManager.instance.highlightMode)
            {
            case FocusHighlightMode.touch:
                inTraditionalMode = false;
                break;

            case FocusHighlightMode.traditional:
                inTraditionalMode = true;
                break;
            }

            if (focused && inTraditionalMode)
            {
                _MenuLimits menuLimits = widget.route.getMenuLimits(
                    widget.buttonRect, widget.constraints.maxHeight, widget.itemIndex ?? 0);
                widget.route.scrollController.animateTo(
                    menuLimits.scrollOffset ?? 0,
                    curve: Curves.easeInOut,
                    duration: new TimeSpan(0, 0, 0, 0, 100)
                    );
            }
        }
        public override Widget build(BuildContext context)
        {
            D.assert(WidgetsD.debugCheckHasDirectionality(context));
            if (route.scrollController == null)
            {
                _MenuLimits menuLimits = route.getMenuLimits(buttonRect, constraints.maxHeight, selectedIndex ?? 0);
                route.scrollController = new ScrollController(initialScrollOffset: menuLimits.scrollOffset ?? 0);
            }

            TextDirection textDirection = Directionality.of(context);
            Widget        menu          = new _DropdownMenu <T>(
                route: route,
                padding: padding.resolve(textDirection),
                buttonRect: buttonRect,
                constraints: constraints,
                dropdownColor: dropdownColor
                );

            if (theme != null)
            {
                menu = new Theme(data: theme, child: menu);
            }

            return(MediaQuery.removePadding(
                       context: context,
                       removeTop: true,
                       removeBottom: true,
                       removeLeft: true,
                       removeRight: true,
                       child: new Builder(
                           builder: (BuildContext _context) => {
                return new CustomSingleChildLayout(
                    layoutDelegate: new _DropdownMenuRouteLayout <T>(
                        buttonRect: buttonRect,
                        route: route,
                        textDirection: textDirection
                        ),
                    child: menu
                    );
            }
                           )
                       ));
        }