in java/form/src/org/netbeans/modules/form/layoutdesign/LayoutPosition.java [340:605]
static IncludeDesc getInclusionFromOriginal(OriginalPosition orig, int dimension, int alignment) {
if (alignment < 0) {
alignment = getBaseAlignment(orig);
}
int origAlign = orig.getAlignedEdges();
IncludeDesc incl = new IncludeDesc();
LayoutInterval leadingNeighbor = getNeighborInSequence(orig, LEADING);
LayoutInterval trailingNeighbor = getNeighborInSequence(orig, TRAILING);
LayoutInterval parentSeq = getCommonSequence(orig);
LayoutInterval parent;
// determine the parent
InParallel par;
if (orig.inParallel != null) {
par = orig.inParallel[((origAlign==CENTER || origAlign==BASELINE) && alignment != origAlign) ? origAlign : alignment];
} else {
par = null;
}
LayoutInterval parallelComp = par != null ? par.componentNeighbor : null;
if (parallelComp != null) {
parent = parallelComp.getParent();
for (int d=par.componentNeighborDepth; d > 0; d--) {
if (parent.getParent() == null
|| (leadingNeighbor != null && parent.isParentOf(leadingNeighbor))
|| (trailingNeighbor != null && parent.isParentOf(trailingNeighbor))) {
break;
}
parent = parent.getParent();
}
if (parent.isSequential()) {
incl.newSubGroup = true; // parallel with part of the sequence
}
} else if (parentSeq != null) { // sequential neighbors on both sides
parent = parentSeq;
} else if (leadingNeighbor != null || trailingNeighbor != null) { // just one neighbor
LayoutInterval oneNeighbor = leadingNeighbor != null ? leadingNeighbor : trailingNeighbor;
parent = oneNeighbor.getParent();
LayoutInterval seqParent = null;
while (parent != null) {
if (parent.isSequential()) {
seqParent = parent;
}
parent = parent.getParent();
}
if (seqParent != null) {
parent = seqParent;
} else {
parent = oneNeighbor.getParent();
if (parent == null) {
assert oneNeighbor == orig.root;
parent = oneNeighbor;
}
}
} else {
parent = orig.root;
}
if (parent.isParallel()) {
LayoutInterval neighborInSeq;
int neighborDirection;
if (trailingNeighbor != null && parent.isParentOf(trailingNeighbor)) {
neighborInSeq = trailingNeighbor;
neighborDirection = TRAILING;
} else if (leadingNeighbor != null && parent.isParentOf(leadingNeighbor)) {
neighborInSeq = leadingNeighbor;
neighborDirection = LEADING;
} else {
neighborInSeq = null;
neighborDirection = -1;
}
if (neighborInSeq != null) {
List<LayoutInterval> allSeqNeighbors = getSequentialNeighbors(orig, neighborDirection);
boolean compact = neighborInSeq.isParallel() || allSeqNeighbors.size() == 1; // limitation: IncludeDesc.neighbor can be only one
LayoutInterval p = neighborInSeq.getParent();
if (p == parent) { // same level
if (compact) {
incl.neighbor = neighborInSeq;
incl.index = (neighborDirection == TRAILING) ? 0 : 1;
}
} else { // the seq. neighbor is deeper, try to go up as close to parent as possible
do {
if (p.isParallel()) {
List<LayoutInterval> list = LayoutUtils.getSideComponents(p, neighborDirection^1, false, false);
list.removeAll(allSeqNeighbors);
if (!list.isEmpty()) { // going up we'd get in sequence with something that should stay in parallel
parent = p;
if (neighborInSeq.getParent() == p) {
incl.neighbor = neighborInSeq;
incl.index = (neighborDirection == TRAILING) ? 0 : 1;
}
break;
}
}
LayoutInterval pp = p.getParent();
if (pp == parent) {
if (p.isParallel()) {
if (compact) {
incl.neighbor = p;
incl.index = (neighborDirection == TRAILING) ? 0 : 1;
}
} else {
parent = p; // down to sequence
incl.index = (neighborDirection == TRAILING) ? 0 : p.getSubIntervalCount();
}
break;
}
p = pp;
} while (p != null); // (actually should never go to null)
}
}
}
incl.parent = parent;
if (parent.isSequential() && !incl.newSubGroup) {
// multiple selected component might have been each parallel with something else
// example: 3 baseline rows by 3 components, selecting first components of 2nd and 3rd row
if (leadingNeighbor != null && parent.isParentOf(leadingNeighbor)) {
int i = LayoutInterval.getIndexInParent(leadingNeighbor, parent);
LayoutInterval neighborInSeq = LayoutInterval.getDirectNeighbor(parent.getSubInterval(i), TRAILING, true);
if (neighborInSeq != null && neighborInSeq != trailingNeighbor
&& (trailingNeighbor == null || !neighborInSeq.isParentOf(trailingNeighbor))) {
incl.newSubGroup = true; // in the sequence but not in trailingNeighbor
}
}
if (trailingNeighbor != null && parent.isParentOf(trailingNeighbor)) {
int i = LayoutInterval.getIndexInParent(trailingNeighbor, parent);
LayoutInterval neighborInSeq = LayoutInterval.getDirectNeighbor(parent.getSubInterval(i), LEADING, true);
if (neighborInSeq != null && neighborInSeq != leadingNeighbor
&& (leadingNeighbor == null || !neighborInSeq.isParentOf(leadingNeighbor))) {
incl.newSubGroup = true;
}
}
}
// determine alignment and parallel snap
incl.alignment = alignment;
if (origAlign == LEADING || origAlign == TRAILING || origAlign == LayoutRegion.ALL_POINTS) {
if (par != null && par.aligned) {
LayoutInterval parParent = parent.isParallel() ? parent : parent.getParent();
// can we consider parallel snap with this parent?
boolean parentAlign = (parallelComp == null);
if (parallelComp != null && !par.componentNeighborAtBorder && (alignment == LEADING || alignment == TRAILING)) {
parentAlign = true;
InSequence s = orig.inSequence[alignment];
if (s != null && s.componentNeighbors != null) {
for (LayoutInterval li : s.componentNeighbors) {
if (parParent.isParentOf(li)) {
parentAlign = false; // it's not the original par. parent, it's parent of something that was in sequence
break;
}
}
}
}
if (parentAlign) {
if (parParent == orig.root) {
incl.snappedParallel = orig.root;
} else if (LayoutInterval.isAlignedAtBorder(parParent, orig.root, alignment)) {
incl.snappedParallel = parParent;
}
} else if (par.componentNeighborAtBorder) {
LayoutInterval aligned = parallelComp;
LayoutInterval prev = null;
do {
LayoutInterval p = aligned.getParent();
if (p.isSequential()) {
prev = aligned;
aligned = p;
p = p.getParent();
}
if (p == parParent) {
if (parent == parParent && (!aligned.isSequential() || LayoutInterval.isAlignedAtBorder(prev, parent, alignment))) {
incl.snappedParallel = parent;
} else {
incl.snappedParallel = aligned.isSequential() ? prev : aligned;
}
break;
} else if (LayoutInterval.isAlignedAtBorder(aligned, alignment)
&& p.getCurrentSpace().positions[dimension][alignment] == orig.groupSpace.positions[dimension][alignment]) {
// go up
prev = aligned;
aligned = p;
} else {
break; // not aligned
}
} while(aligned.getParent() != null);
}
}
} else if (origAlign == CENTER || origAlign == BASELINE) {
incl.alignment = origAlign;
incl.snappedParallel = parent.getGroupAlignment() == origAlign ? parent : par.componentNeighbor;
}
if (alignment == LEADING || alignment == TRAILING) {
// determine whether need to snap parallel due to indent
if (incl.snappedParallel == null && par != null && par.indent && parent.isSequential()
&& parallelComp != null && parallelComp.getParent() == parent) {
incl.snappedParallel = parallelComp;
}
// determine snappedNextTo
if (incl.snappedParallel == null) {
for (int a=LEADING; a <= TRAILING; a++) {
InSequence s = orig.inSequence[a];
if (a == alignment && s != null && s.snapped) {
LayoutInterval neighborInSeq = (a == LEADING) ? leadingNeighbor : trailingNeighbor;
if (neighborInSeq != null) {
if (parent.isParentOf(neighborInSeq)) {
int index = LayoutInterval.getIndexInParent(neighborInSeq, parent);
if (index > -1) {
incl.snappedNextTo = parent.getSubInterval(index);
incl.paddingType = s.paddingType;
}
} else if (neighborInSeq.getParent().isParentOf(parent)) {
incl.snappedNextTo = neighborInSeq;
incl.paddingType = s.paddingType;
}
} else {
incl.snappedNextTo = orig.root;
}
}
}
}
// determine "fixed position"
for (int a=LEADING; a <= TRAILING; a++) {
InSequence s = orig.inSequence[a];
if (a == alignment && s != null) {
incl.fixedPosition = s.fixedRelativePosition;
}
}
}
// determine index in sequence
if (parent.isSequential() && incl.index < 0 && parent.getSubIntervalCount() > 0) {
int a = alignment;
if (a != LEADING && a != TRAILING) {
a = LEADING;
}
for (int n=2; n > 0; a^=1, n--) {
LayoutInterval neighborInSeq = (a == LEADING) ? leadingNeighbor : trailingNeighbor;
if (neighborInSeq != null) {
int index = LayoutInterval.getIndexInParent(neighborInSeq, parent);
if (index > -1) {
if (a == LEADING) {
index++;
if (index + 1 <= parent.getSubIntervalCount()) {
index++;
}
}
incl.index = index;
break;
}
} else if (incl.newSubGroup) {
int index = (a == LEADING) ? 0 : parent.getSubIntervalCount();
if (parent.getSubInterval(index - (a==TRAILING ? 1:0)).isEmptySpace()
&& orig.inParallel != null && orig.inParallel[a] != null
&& orig.inParallel[a].componentNeighborAtBorder) {
index += (a == LEADING) ? 1 : -1;
}
incl.index = index;
break;
}
}
}
return incl;
}