public static void align()

in designer/src/com/android/tools/idea/uibuilder/scout/ScoutArrange.java [65:683]


  public static void align(Scout.Arrange type, List<NlComponent> widgetList,
                           boolean applyConstraints) {
    if (widgetList == null || widgetList.isEmpty()) {
      return;
    }
    if (widgetList.get(0).getParent() == null) {
      return;
    }

    ScoutWidget parentScoutWidget = new ScoutWidget(widgetList.get(0).getParent(), null);
    ScoutWidget[] scoutWidgets = ScoutWidget.create(widgetList, parentScoutWidget);

    int margin = Scout.getMargin();
    switch (type) {
      case AlignHorizontallyCenter:
      case AlignHorizontallyLeft:
      case AlignHorizontallyRight:
        Arrays.sort(scoutWidgets, sSortRecY);
        if (rootDistance(scoutWidgets[0].mNlComponent) > rootDistance(scoutWidgets[scoutWidgets.length - 1].mNlComponent)) {
          reverse(scoutWidgets);
        }
        break;
      case DistributeVertically:
        Arrays.sort(scoutWidgets, sSortRecY);
        break;
      case AlignVerticallyTop:
      case AlignVerticallyMiddle:
      case AlignBaseline:
      case AlignVerticallyBottom:
        Arrays.sort(scoutWidgets, sSortRecX);
        if (rootDistance(scoutWidgets[0].mNlComponent) > rootDistance(scoutWidgets[scoutWidgets.length - 1].mNlComponent)) {
          reverse(scoutWidgets);
        }
        break;
      case DistributeHorizontally:
        Arrays.sort(scoutWidgets, sSortRecX);
        break;
        default:
    }

    switch (type) {
      case ConnectTop:
        connect(scoutWidgets, parentScoutWidget, Direction.TOP, (applyConstraints) ? 0 : -1);
        break;
      case ConnectBottom:
        connect(scoutWidgets, parentScoutWidget, Direction.BOTTOM, (applyConstraints) ? 0 : -1);
        break;
      case ConnectStart:
        connect(scoutWidgets, parentScoutWidget, Direction.LEFT, (applyConstraints) ? 0 : -1);
        break;
      case ConnectEnd:
        connect(scoutWidgets, parentScoutWidget, Direction.RIGHT, (applyConstraints) ? 0 : -1);
        break;

      case CreateHorizontalChain: {
        Arrays.sort(scoutWidgets, sSortRecX);
        Rectangle rectangle = new Rectangle();
        NlComponent parent = parentScoutWidget.mNlComponent;
        ScoutWidget[] peers = ScoutWidget.create(parent.getChildren(), parentScoutWidget);
        ScoutWidget leftConnect = null;
        for (int i = 0; i < scoutWidgets.length; i++) {
          ScoutWidget widget = scoutWidgets[i];
          ScoutWidget rightConnect;
          if (i + 1 < scoutWidgets.length) {
            rightConnect = scoutWidgets[i + 1];
          }
          else {
            rectangle.x = widget.getDpX();
            rectangle.y = widget.getDpY();
            rectangle.width = widget.getDpWidth();
            rectangle.height = widget.getDpHeight();
            rightConnect = gapWidget(Direction.RIGHT, rectangle, peers, parentScoutWidget);
          }
          if (leftConnect == null) {
            rectangle.x = widget.getDpX();
            rectangle.y = widget.getDpY();
            rectangle.width = widget.getDpWidth();
            rectangle.height = widget.getDpHeight();
            leftConnect = gapWidget(Direction.LEFT, rectangle, peers, parentScoutWidget);
          }
          else {
            leftConnect = scoutWidgets[i - 1];
          }

          Direction dir = Direction.RIGHT;
          if (leftConnect == parentScoutWidget) {
            dir = Direction.LEFT;
          }
          scoutConnect(widget.mNlComponent, Direction.LEFT, leftConnect.mNlComponent, dir, 0);
          dir = Direction.LEFT;
          if (rightConnect == parentScoutWidget) {
            dir = Direction.RIGHT;
          }
          scoutConnect(widget.mNlComponent, Direction.RIGHT, rightConnect.mNlComponent, dir, 0);
          setScoutHorizontalBiasPercent(widget.mNlComponent, .5f);
        }
      }
      break;
      case CreateVerticalChain: {
        Arrays.sort(scoutWidgets, sSortRecY);
        Rectangle rectangle = new Rectangle();
        NlComponent parent = parentScoutWidget.mNlComponent;
        ScoutWidget[] peers = ScoutWidget.create(parent.getChildren(), parentScoutWidget);
        ScoutWidget topConnect = null;
        for (int i = 0; i < scoutWidgets.length; i++) {
          ScoutWidget widget = scoutWidgets[i];
          ScoutWidget bottomConnect;
          if (i + 1 < scoutWidgets.length) {
            bottomConnect = scoutWidgets[i + 1];
          }
          else {
            rectangle.x = widget.getDpX();
            rectangle.y = widget.getDpY();
            rectangle.width = widget.getDpWidth();
            rectangle.height = widget.getDpHeight();
            bottomConnect = gapWidget(Direction.BOTTOM, rectangle, peers, parentScoutWidget);
          }
          if (topConnect == null) {
            rectangle.x = widget.getDpX();
            rectangle.y = widget.getDpY();
            rectangle.width = widget.getDpWidth();
            rectangle.height = widget.getDpHeight();
            topConnect = gapWidget(Direction.TOP, rectangle, peers, parentScoutWidget);
          }
          else {
            topConnect = scoutWidgets[i - 1];
          }

          Direction dir = Direction.BOTTOM;
          if (topConnect == parentScoutWidget) {
            dir = Direction.TOP;
          }
          scoutConnect(widget.mNlComponent, Direction.TOP, topConnect.mNlComponent, dir, 0);
          dir = Direction.TOP;
          if (bottomConnect == parentScoutWidget) {
            dir = Direction.BOTTOM;
          }
          scoutConnect(widget.mNlComponent, Direction.BOTTOM, bottomConnect.mNlComponent, dir, 0);
          setScoutHorizontalBiasPercent(widget.mNlComponent, .5f);
        }
    }
        break;
      case CenterHorizontally: {
        Rectangle rectangle = new Rectangle();
        NlComponent parent = parentScoutWidget.mNlComponent;
        ScoutWidget[] peers = ScoutWidget.create(parent.getChildren(), parentScoutWidget);

        for (ScoutWidget widget : scoutWidgets) {
          rectangle.x = widget.getDpX();
          rectangle.y = widget.getDpY();
          rectangle.width = widget.getDpWidth();
          rectangle.height = widget.getDpHeight();
          int westDistance = gap(Direction.LEFT, rectangle, peers, parentScoutWidget);
          int eastDistance = gap(Direction.RIGHT, rectangle, peers, parentScoutWidget);

          int x = widget.getDpX();

          if (applyConstraints) {
            ScoutWidget westConnect =
              gapWidget(Direction.LEFT, rectangle, peers, parentScoutWidget);
            ScoutWidget eastConnect =
              gapWidget(Direction.RIGHT, rectangle, peers, parentScoutWidget);

            Direction dir = Direction.RIGHT;
            if (westConnect == parentScoutWidget) {
              dir = Direction.LEFT;
            }
            scoutConnect(widget.mNlComponent, Direction.LEFT, westConnect.mNlComponent, dir, 0);
            dir = Direction.LEFT;
            if (eastConnect == parentScoutWidget) {
              dir = Direction.RIGHT;
            }
            scoutConnect(widget.mNlComponent, Direction.RIGHT, eastConnect.mNlComponent, dir, 0);
            setScoutHorizontalBiasPercent(widget.mNlComponent, .5f);
          }
          else {
            setScoutAbsoluteDpX(widget.mNlComponent, x + (eastDistance - westDistance) / 2, true);
          }
        }
      }
      break;
      case CenterVertically: {
        Rectangle rectangle = new Rectangle();
        NlComponent parent = parentScoutWidget.mNlComponent;
        ScoutWidget[] peers = ScoutWidget.create(parent.getChildren(), parentScoutWidget);

        for (ScoutWidget widget : scoutWidgets) {
          rectangle.x = widget.getDpX();
          rectangle.y = widget.getDpY();
          rectangle.width = widget.getDpWidth();
          rectangle.height = widget.getDpHeight();
          int northDistance = gap(Direction.TOP, rectangle, peers, parentScoutWidget);
          int southDistance = gap(Direction.BOTTOM, rectangle, peers, parentScoutWidget);
          int Y = widget.getDpY();

          if (applyConstraints) {
            ScoutWidget northConnect =
              gapWidget(Direction.TOP, rectangle, peers, parentScoutWidget);
            ScoutWidget southConnect =
              gapWidget(Direction.BOTTOM, rectangle, peers, parentScoutWidget);

            Direction dir = Direction.BOTTOM;
            if (northConnect == parentScoutWidget) {
              dir = Direction.TOP;
            }
            scoutConnect(widget.mNlComponent, Direction.TOP, northConnect.mNlComponent, dir, 0);
            dir = Direction.TOP;
            if (southConnect == parentScoutWidget) {
              dir = Direction.BOTTOM;
            }
            scoutConnect(widget.mNlComponent, Direction.BOTTOM, southConnect.mNlComponent, dir, 0);
            setScoutVerticalBiasPercent(widget.mNlComponent, .5f);
          }
          else {
            setScoutAbsoluteDpY(widget.mNlComponent, Y + (southDistance - northDistance) / 2, true);
          }
        }
      }
      break;
      case CenterHorizontallyInParent: {
        for (ScoutWidget widget : scoutWidgets) {
          int parentWidth = parentScoutWidget.getDpWidth();
          int width = widget.getDpWidth();
          setScoutAbsoluteDpX(widget.mNlComponent, (parentWidth - width) / 2, true);
          if (applyConstraints) {
            scoutConnect(widget.mNlComponent, Direction.LEFT, parentScoutWidget.mNlComponent, Direction.LEFT, 0);
            scoutConnect(widget.mNlComponent, Direction.RIGHT, parentScoutWidget.mNlComponent, Direction.RIGHT, 0);
            setScoutHorizontalBiasPercent(widget.mNlComponent, .5f);
          }
        }
      }
      break;
      case CenterVerticallyInParent: {
        for (ScoutWidget widget : scoutWidgets) {
          int parentHeight = parentScoutWidget.getDpHeight();
          int height = widget.getDpHeight();
          setScoutAbsoluteDpY(widget.mNlComponent, (parentHeight - height) / 2, true);
          if (applyConstraints) {
            scoutConnect(widget.mNlComponent, Direction.TOP, parentScoutWidget.mNlComponent, Direction.TOP, 0);
            scoutConnect(widget.mNlComponent, Direction.BOTTOM, parentScoutWidget.mNlComponent, Direction.BOTTOM, 0);
            setScoutVerticalBiasPercent(widget.mNlComponent, .5f);
          }
        }
      }
      break;
      case AlignHorizontallyCenter: {
        int count = 0;
        float avg = 0;

        for (ScoutWidget widget : scoutWidgets) {
          avg += widget.getDpX() + widget.getDpWidth() / 2.0f;
          count++;
        }
        avg /= count;

        NlComponent previousWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          float current = widget.getDpWidth() / 2.0f;
          setScoutAbsoluteDpX(widget.mNlComponent, (int)(avg - current), true);
          if (applyConstraints) {
            if (previousWidget != null) {
              scoutConnect(widget.mNlComponent, Direction.LEFT, previousWidget, Direction.LEFT, 0);
              scoutConnect(widget.mNlComponent, Direction.RIGHT, previousWidget, Direction.RIGHT, 0);
            }
          }
          previousWidget = widget.mNlComponent;
        }
      }
      break;
      case AlignHorizontallyLeft: {
        int min = Integer.MAX_VALUE;
        if (applyConstraints) { // test if already connected to flip directions
          flipConnectionsAndReverse(scoutWidgets, Direction.LEFT, ourLeftAttributes, ourStartAttributes);
        }
        for (ScoutWidget widget : scoutWidgets) {
          min = Math.min(min, widget.getDpX());
        }
        NlComponent previousWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          setScoutAbsoluteDpX(widget.mNlComponent, min, true);
          if (applyConstraints) {
            if (previousWidget != null) {
              scoutClearAttributes(widget.mNlComponent, ourRightAttributes);
              scoutClearAttributes(widget.mNlComponent, ourEndAttributes);

              scoutConnect(widget.mNlComponent, Direction.LEFT, previousWidget,
                           Direction.LEFT, 0);
            }
          }
          previousWidget = widget.mNlComponent;
        }
      }
      break;
      case AlignHorizontallyRight: {
        int max = Integer.MIN_VALUE;
        if (applyConstraints) { // test if already connected to flip directions
          flipConnectionsAndReverse(scoutWidgets, Direction.RIGHT, ourRightAttributes, ourEndAttributes);
        }
        for (ScoutWidget widget : scoutWidgets) {
          max = Math.max(max, widget.getDpX() + widget.getDpWidth());
        }
        NlComponent previousWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          float current = widget.getDpWidth();
          setScoutAbsoluteDpX(widget.mNlComponent, (int)(max - current), true);
          if (applyConstraints) {
            if (previousWidget != null) {
              scoutClearAttributes(widget.mNlComponent, ourLeftAttributes);
              scoutClearAttributes(widget.mNlComponent, ourStartAttributes);
              scoutConnect(widget.mNlComponent, Direction.RIGHT, previousWidget,
                           Direction.RIGHT, 0);
            }
          }
          previousWidget = widget.mNlComponent;
        }
      }
      break;
      case AlignVerticallyTop: {
        int min = Integer.MAX_VALUE;
        if (applyConstraints) { // test if already connected to flip directions
          flipConnectionsAndReverse(scoutWidgets, Direction.TOP, ourTopAttributes, null);
        }
        for (ScoutWidget widget : scoutWidgets) {
          min = Math.min(min, widget.getDpY());
        }
        NlComponent previousWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          setScoutAbsoluteDpY(widget.mNlComponent, min, true);
          if (applyConstraints) {
            if (previousWidget != null) {
              scoutClearAttributes(widget.mNlComponent, ourBottomAttributes);
              scoutConnect(widget.mNlComponent, Direction.TOP, previousWidget,
                           Direction.TOP, 0);
            }
          }
          previousWidget = widget.mNlComponent;
        }
      }
      break;
      case AlignVerticallyMiddle: {
        int count = 0;
        float avg = 0;
        for (ScoutWidget widget : scoutWidgets) {
          avg += widget.getDpY() + widget.getDpHeight() / 2.0f;
          count++;
        }
        avg /= count;
        NlComponent previousWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          float current = widget.getDpHeight() / 2.0f;
          setScoutAbsoluteDpY(widget.mNlComponent, (int)(avg - current), true);
          if (applyConstraints) {
            if (previousWidget != null) {
              scoutConnect(widget.mNlComponent, Direction.TOP, previousWidget, Direction.TOP, 0);
              scoutConnect(widget.mNlComponent, Direction.BOTTOM, previousWidget, Direction.BOTTOM, 0);
            }
          }
          previousWidget = widget.mNlComponent;
        }
      }
      break;
      case AlignBaseline: {
        int count = 0;
        float avg = 0;
        if (applyConstraints) { // test if already connected to flip directions
          flipBaselineAndReverse(scoutWidgets);
        }
        int number_of_constrained = 0;
        NlComponent fixedWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          if (isVerticallyConstrained(widget.mNlComponent)) {
            number_of_constrained++;
            fixedWidget = widget.mNlComponent;
          }
          avg += widget.getDpY() + widget.getDpBaseline();
          count++;
        }
        avg /= count;
        // if one is already constrained move the rest to it
        if (number_of_constrained == 1) {
          avg = getDpX(fixedWidget) + getDpBaseline(fixedWidget);
        }
        NlComponent previousWidget = null;
        if (!applyConstraints || number_of_constrained == 0) {
          for (ScoutWidget widget : scoutWidgets) {
            float baseline = widget.getDpBaseline();
            setScoutAbsoluteDpY(widget.mNlComponent, (int)(avg - baseline), true);
            if (applyConstraints) {
              if (previousWidget != null) {
                scoutConnect(widget.mNlComponent, Direction.BASELINE, previousWidget,
                             Direction.BASELINE, 0);
              }
            }
            previousWidget = widget.mNlComponent;
          }
        }
        else { // if you are creating constraints and some are already constrained
          // Build a list of constrained and unconstrained widgets
          ArrayList<ScoutWidget> unconstrained = new ArrayList<>();
          ArrayList<ScoutWidget> constrained = new ArrayList<>();
          for (ScoutWidget widget : scoutWidgets) {
            if (isVerticallyConstrained(widget.mNlComponent)) {
              constrained.add(widget);
            }
            else {
              unconstrained.add(widget);
            }
          }
          // one by one constrain widgets by finding the closest between the two list
          while (!unconstrained.isEmpty()) {
            ScoutWidget to = null;
            ScoutWidget from = null;
            int min = Integer.MAX_VALUE;

            for (ScoutWidget fromCandidate : unconstrained) {
              for (ScoutWidget toCandidate : constrained) {
                int fromLeft = fromCandidate.getDpX();
                int fromRight = fromLeft + fromCandidate.getDpWidth();
                int toLeft = toCandidate.getDpX();
                int toRight = toLeft + toCandidate.getDpWidth();
                int dist = Math.abs(toLeft - fromLeft);
                dist = Math.min(dist, Math.abs(toLeft - fromRight));
                dist = Math.min(dist, Math.abs(toRight - fromRight));
                dist = Math.min(dist, Math.abs(toRight - fromLeft));
                if (dist < min) {
                  min = dist;
                  to = toCandidate;
                  from = fromCandidate;
                }
              }
            }
            scoutConnect(from.mNlComponent, Direction.BASELINE, to.mNlComponent,
                         Direction.BASELINE, 0);
            constrained.add(from);
            unconstrained.remove(from);
          }
        }
      }
      break;
      case AlignVerticallyBottom: {
        int max = Integer.MIN_VALUE;
        if (applyConstraints) { // test if already connected to flip directions
          flipConnectionsAndReverse(scoutWidgets, Direction.BOTTOM, ourBottomAttributes, null);
        }
        for (ScoutWidget widget : scoutWidgets) {
          max = Math.max(max, widget.getDpY() + widget.getDpHeight());
        }
        NlComponent previousWidget = null;
        for (ScoutWidget widget : scoutWidgets) {
          float current = widget.getDpHeight();
          setScoutAbsoluteDpY(widget.mNlComponent, (int)(max - current), true);
          if (applyConstraints) {
            if (previousWidget != null) {
              scoutClearAttributes(widget.mNlComponent, ourTopAttributes);
              scoutConnect(widget.mNlComponent, Direction.BOTTOM, previousWidget,
                           Direction.BOTTOM, 0);
            }
          }
          previousWidget = widget.mNlComponent;
        }
      }
      break;
      case DistributeVertically: {
        int count = 0;
        int sum = 0;
        int min = getDpY(widgetList.get(0));
        int max = getDpY(widgetList.get(0)) + getDpHeight(widgetList.get(0));
        for (ScoutWidget widget : scoutWidgets) {
          int start = widget.getDpY();
          int size = widget.getDpHeight();
          int end = start + size;
          sum += size;
          min = Math.min(min, start);
          max = Math.max(max, end);
          count++;
        }
        int gaps = count - 1;
        int totalGap = max - min - sum;
        int lastY = min;
        boolean reverse =
          rootDistanceY(scoutWidgets[0].mNlComponent) > rootDistanceY(scoutWidgets[scoutWidgets.length - 1].mNlComponent);
        for (int i = 0; i < count; i++) {
          if (i > 0) {
            int size = scoutWidgets[i - 1].getDpHeight();
            min += size;
            int pos = min + (totalGap * i) / gaps;
            setScoutAbsoluteDpY(scoutWidgets[i].mNlComponent, pos, true);
            if (applyConstraints) {
              if (reverse) {
                scoutConnect(scoutWidgets[i - 1].mNlComponent, Direction.BOTTOM, scoutWidgets[i].mNlComponent,
                             Direction.TOP, pos - lastY - size);
              }
              else {
                scoutConnect(scoutWidgets[i].mNlComponent, Direction.TOP, scoutWidgets[i - 1].mNlComponent,
                             Direction.BOTTOM, pos - lastY - size);
              }
              lastY = pos;
            }
          }
        }
      }
      break;
      case DistributeHorizontally: {
        int count = 0;
        int sum = 0;
        int min = getDpX(widgetList.get(0));
        int max = getDpX(widgetList.get(0)) + getDpHeight(widgetList.get(0));
        for (ScoutWidget widget : scoutWidgets) {
          int start = widget.getDpX();
          int size = widget.getDpWidth();
          int end = start + size;
          sum += size;
          min = Math.min(min, start);
          max = Math.max(max, end);
          count++;
        }
        int gaps = count - 1;
        int totalGap = max - min - sum;
        int lastX = min;
        boolean reverse =
          rootDistanceX(scoutWidgets[0].mNlComponent) > rootDistanceX(scoutWidgets[scoutWidgets.length - 1].mNlComponent);
        for (int i = 0; i < count; i++) {

          if (i > 0) {
            int size = scoutWidgets[i - 1].getDpWidth();
            min += size;
            int pos = min + (totalGap * i) / gaps;
            setScoutAbsoluteDpX(scoutWidgets[i].mNlComponent, pos, true);
            if (applyConstraints) {
              if (reverse) {
                scoutConnect(scoutWidgets[i - 1].mNlComponent, Direction.RIGHT, scoutWidgets[i].mNlComponent,
                             Direction.LEFT, pos - lastX - size);
              }
              else {
                scoutConnect(scoutWidgets[i].mNlComponent, Direction.LEFT, scoutWidgets[i - 1].mNlComponent,
                             Direction.RIGHT, pos - lastX - size);
              }
              lastX = pos;
            }
          }
        }
      }
      break;
      case VerticalPack: {
        NlComponent[] wArray = new NlComponent[widgetList.size()];
        wArray = widgetList.toArray(wArray);
        Arrays.sort(wArray, (w1, w2) -> Integer.compare(getDpY(w1), getDpY(w2)));
        ScoutWidget[] list = ScoutWidget.getWidgetArray(widgetList.get(0).getParent());
        Rectangle bounds = null;
        for (int i = 0; i < wArray.length; i++) {
          String id = SdkConstants.NEW_ID_PREFIX + wArray[i].getId();
          ScoutWidget w = list[0].getChild(id);
          if (bounds == null) {
            bounds = new Rectangle(w.getRectangle());
          }
          else {
            bounds = bounds.union(w.getRectangle());
          }
        }

        for (NlComponent cw : wArray) {
          for (ScoutWidget scoutWidget : list) {
            if (scoutWidget.mNlComponent == cw) {
              int gapN = scoutWidget.gap(Direction.TOP, list);
              int newY = margin + scoutWidget.getDpY() - gapN;
              newY = Math.max(newY, bounds.y);
              scoutWidget.setY(newY);
            }
          }
        }
      }
      break;
      case HorizontalPack: {
        NlComponent[] wArray = new NlComponent[widgetList.size()];
        wArray = widgetList.toArray(wArray);
        Arrays.sort(wArray, (w1, w2) -> Integer.compare(getDpX(w1), getDpX(w2)));
        ScoutWidget[] list = ScoutWidget.getWidgetArray(widgetList.get(0).getParent());
        Rectangle bounds = null;
        for (int i = 0; i < wArray.length; i++) {
          String id = SdkConstants.NEW_ID_PREFIX + wArray[i].getId();
          ScoutWidget w = list[0].getChild(id);
          if (bounds == null) {
            bounds = new Rectangle(w.getRectangle());
          }
          else {
            bounds = bounds.union(w.getRectangle());
          }
        }
        for (NlComponent cw : wArray) {
          for (ScoutWidget scoutWidget : list) {
            if (scoutWidget.mNlComponent == cw) {
              int gapW = scoutWidget.gap(Direction.LEFT, list);
              int newX = margin + getDpX(scoutWidget.mNlComponent) - gapW;
              newX = Math.max(newX, bounds.x);
              scoutWidget.setX(newX);
            }
          }
        }
      }
      break;
      case ExpandVertically: {
        expandVertically(scoutWidgets, parentScoutWidget, margin, true);
      }
      break;
      case ExpandHorizontally: {
        expandHorizontally(scoutWidgets, parentScoutWidget, margin, true);
      }
      break;
      case ChainVerticalRemove:
      case ChainHorizontalRemove:
      case ChainVerticalMoveUp:
      case ChainVerticalMoveDown:
      case ChainHorizontalMoveLeft:
      case ChainHorizontalMoveRight:
      case ChainInsertHorizontal:
      case ChainInsertVertical:
        break; // cases covered by scout
    }
  }