static IncludeDesc getInclusionFromOriginal()

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;
    }