in designer/src/com/android/tools/idea/uibuilder/scout/ScoutChains.java [45:151]
public static void pick(ScoutWidget[] list) {
ScoutWidget base = list[0];
ScoutWidget[] children = new ScoutWidget[list.length - 1];
System.arraycopy(list, 1, children, 0, children.length);
ChainMode chain_mode;
// =============== CHECK for horizontal chain ===============
for (int i = 0; i < children.length; i++) {
ScoutWidget child = children[i];
child.mCheckedForChain = child.isConnected(Direction.LEFT) || child.isConnected(Direction.RIGHT);
}
for (int i = 0; i < children.length; i++) {
ScoutWidget child = children[i];
ScoutWidget[] group = getCandiateListX(child, children);
group = removeOverlapsX(group);
if (group != null) { // We have a solid candidate group
Dir dir = Dir.HORIZONTAL;
if (anyNotWrap(group, dir)) { // go with a "normal" chain calc margins
int[] margins = new int[group.length + 1];
getMargins(base, group, margins, dir);
creatHorizontalChain(group, base, ChainMode.CHAIN_SPREAD, margins);
}
else {
int[] marginsSpread = new int[group.length + 1];
int errorSpread = getMarginsSpread(base, group, marginsSpread, dir);
int[] marginsInside = new int[group.length + 1];
int errorInside = getMarginsInside(base, group, marginsInside, dir);
int[] marginsPacked = new int[group.length + 1];
int errorPacked = getMarginsPacked(base, group, marginsPacked, dir);
chain_mode = (errorInside < errorSpread) ?
((errorInside < errorPacked) ? ChainMode.CHAIN_SPREAD_INSIDE : ChainMode.CHAIN_PACKED) :
((errorSpread < errorPacked) ? ChainMode.CHAIN_SPREAD : ChainMode.CHAIN_PACKED);
switch (chain_mode) {
case CHAIN_PACKED:
if (errorPacked > MAX_ERROR) {
return;
}
creatHorizontalChain(group, base, chain_mode, marginsPacked);
break;
case CHAIN_SPREAD:
if (errorSpread > MAX_ERROR) {
return;
}
creatHorizontalChain(group, base, chain_mode, marginsSpread);
break;
case CHAIN_SPREAD_INSIDE:
if (errorInside > MAX_ERROR || group.length < MIN_SPREAD) {
return;
}
creatHorizontalChain(group, base, chain_mode, marginsInside);
break;
}
}
}
}
// =============== CHECK for a vertical chain ===============
for (int i = 0; i < children.length; i++) {
ScoutWidget child = children[i];
child.mCheckedForChain =
child.isConnected(Direction.BOTTOM) || child.isConnected(Direction.TOP) || child.isConnected(Direction.BASELINE);
}
for (int i = 0; i < children.length; i++) {
ScoutWidget child = children[i];
ScoutWidget[] group = getCandiateListY(child, children);
group = removeOverlapsY(group);
if (group != null) {
Dir dir = Dir.VERTICAL;
if (anyNotWrap(group, dir)) { // go with a "normal" chain calc margins
int[] margins = new int[group.length + 1];
getMargins(base, group, margins, dir);
creatVerticalChain(group, base, ChainMode.CHAIN_SPREAD, margins);
}
else {
int[] marginsSpread = new int[group.length + 1];
int errorSpread = getMarginsSpread(base, group, marginsSpread, dir);
int[] marginsInside = new int[group.length + 1];
int errorInside = getMarginsInside(base, group, marginsInside, dir);
int[] marginsPacked = new int[group.length + 1];
int errorPacked = getMarginsPacked(base, group, marginsPacked, dir);
chain_mode = (errorInside < errorSpread) ?
((errorInside < errorPacked) ? ChainMode.CHAIN_SPREAD_INSIDE : ChainMode.CHAIN_PACKED) :
((errorSpread < errorPacked) ? ChainMode.CHAIN_SPREAD : ChainMode.CHAIN_PACKED);
switch (chain_mode) {
case CHAIN_PACKED:
if (errorPacked > MAX_ERROR) {
return;
}
creatVerticalChain(group, base, chain_mode, marginsPacked);
break;
case CHAIN_SPREAD:
if (errorSpread > MAX_ERROR) {
return;
}
creatVerticalChain(group, base, chain_mode, marginsSpread);
break;
case CHAIN_SPREAD_INSIDE:
if (errorInside > MAX_ERROR || group.length < MIN_SPREAD) {
return;
}
creatVerticalChain(group, base, chain_mode, marginsInside);
break;
}
}
}
}
}