Widget _buildLayout()

in experimental/desktop_photo_search/lib/src/widgets/split.dart [98:189]


  Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
    final width = constraints.maxWidth;
    final height = constraints.maxHeight;
    final axisSize = isHorizontal ? width : height;
    final crossAxisSize = isHorizontal ? height : width;
    const halfDivider = Split.dividerMainAxisSize / 2.0;

    // Determine what fraction to give each child, including enough space to
    // display the divider.
    var firstSize = axisSize * firstFraction;
    var secondSize = axisSize * secondFraction;

    // Clamp the sizes to be sure there is enough space for the dividers.
    firstSize = firstSize.clamp(halfDivider, axisSize - halfDivider);
    secondSize = secondSize.clamp(halfDivider, axisSize - halfDivider);

    // Remove space from each child to place the divider in the middle.
    firstSize = firstSize - halfDivider;
    secondSize = secondSize - halfDivider;

    void updateSpacing(DragUpdateDetails dragDetails) {
      final delta = isHorizontal ? dragDetails.delta.dx : dragDetails.delta.dy;
      final fractionalDelta = delta / axisSize;
      setState(() {
        // Update the fraction of space consumed by the children,
        // being sure not to allocate any negative space.
        firstFraction += fractionalDelta;
        firstFraction = firstFraction.clamp(0.0, 1.0);
      });
    }

    // TODO(https://github.com/flutter/flutter/issues/43747): use an icon.
    // The material icon for a drag handle is not currently available.
    // For now, draw an indicator that is 3 lines running in the direction
    // of the main axis, like a hamburger menu.
    // TODO(https://github.com/flutter/devtools/issues/1265): update mouse
    // to indicate that this is resizable.
    final dragIndicator = Flex(
      direction: isHorizontal ? Axis.vertical : Axis.horizontal,
      mainAxisSize: MainAxisSize.min,
      children: [
        for (var i = 0; i < min(crossAxisSize / 6.0, 3).floor(); i++)
          Padding(
            padding: EdgeInsets.symmetric(
              vertical: isHorizontal ? 2.0 : 0.0,
              horizontal: isHorizontal ? 0.0 : 2.0,
            ),
            child: DecoratedBox(
              decoration: BoxDecoration(
                color: Theme.of(context).dividerColor,
                borderRadius: BorderRadius.circular(Split.dividerMainAxisSize),
              ),
              child: SizedBox(
                height: isHorizontal ? 2.0 : Split.dividerMainAxisSize - 2.0,
                width: isHorizontal ? Split.dividerMainAxisSize - 2.0 : 2.0,
              ),
            ),
          ),
      ],
    );

    final children = [
      SizedBox(
        width: isHorizontal ? firstSize : width,
        height: isHorizontal ? height : firstSize,
        child: widget.firstChild,
      ),
      GestureDetector(
        key: widget.dividerKey,
        behavior: HitTestBehavior.translucent,
        onHorizontalDragUpdate: isHorizontal ? updateSpacing : null,
        onVerticalDragUpdate: isHorizontal ? null : updateSpacing,
        // DartStartBehavior.down is needed to keep the mouse pointer stuck to
        // the drag bar. There still appears to be a few frame lag before the
        // drag action triggers which is't ideal but isn't a launch blocker.
        dragStartBehavior: DragStartBehavior.down,
        child: SizedBox(
          width: isHorizontal ? Split.dividerMainAxisSize : width,
          height: isHorizontal ? height : Split.dividerMainAxisSize,
          child: Center(
            child: dragIndicator,
          ),
        ),
      ),
      SizedBox(
        width: isHorizontal ? secondSize : width,
        height: isHorizontal ? height : secondSize,
        child: widget.secondChild,
      ),
    ];
    return Flex(direction: widget.axis, children: children);
  }