Search in sources :

Example 1 with ConstraintWidgetContainer

use of android.support.constraint.solver.widgets.ConstraintWidgetContainer in project android by JetBrains.

the class WidgetDecorator method updateShowAnchorsPolicy.

/**
     * Update the show anchors policy. Used for unselected widgets.
     *
     * @param selectedWidget the current selected widget (if any)
     * @param selectedAnchor the current selected anchor (if any)
     */
public void updateShowAnchorsPolicy(ConstraintWidget selectedWidget, ConstraintAnchor selectedAnchor) {
    mDisplayAnchorsPolicy.clear();
    mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.NONE);
    if (getLook() != ColorTheme.Look.HIGHLIGHTED) {
        return;
    }
    if (isShowAllConstraints()) {
        if (mWidget.getParent() != null) {
            // the constraints already
            if (mWidget.getParent() instanceof ConstraintWidgetContainer) {
                ConstraintWidgetContainer container = (ConstraintWidgetContainer) mWidget.getParent();
                if (!container.handlesInternalConstraints()) {
                    mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.CONNECTED);
                }
            }
        } else {
            mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.CONNECTED);
        }
    }
    if (selectedWidget != null) {
        if (!isShowAllConstraints()) {
            mDisplayAnchorsPolicy.clear();
            mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.NONE);
        }
        ConstraintAnchor left = isConnectedAnchor(selectedWidget, ConstraintAnchor.Type.LEFT, mWidget);
        ConstraintAnchor right = isConnectedAnchor(selectedWidget, ConstraintAnchor.Type.RIGHT, mWidget);
        ConstraintAnchor top = isConnectedAnchor(selectedWidget, ConstraintAnchor.Type.TOP, mWidget);
        ConstraintAnchor bottom = isConnectedAnchor(selectedWidget, ConstraintAnchor.Type.BOTTOM, mWidget);
        ConstraintAnchor baseline = isConnectedAnchor(selectedWidget, ConstraintAnchor.Type.BASELINE, mWidget);
        updateDisplayAnchorSet(mDisplayAnchorsPolicy, left);
        updateDisplayAnchorSet(mDisplayAnchorsPolicy, top);
        updateDisplayAnchorSet(mDisplayAnchorsPolicy, right);
        updateDisplayAnchorSet(mDisplayAnchorsPolicy, bottom);
        updateDisplayAnchorSet(mDisplayAnchorsPolicy, baseline);
    }
    if (selectedAnchor != null) {
        if (selectedAnchor.isConnectionAllowed(mWidget)) {
            if (selectedAnchor.getType() == ConstraintAnchor.Type.BASELINE) {
                mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.BASELINE);
            } else if (selectedAnchor.getType() == ConstraintAnchor.Type.CENTER) {
                mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.VERTICAL);
                mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.HORIZONTAL);
                if (mWidget == selectedAnchor.getOwner().getParent()) {
                    // only display the center anchor for the parent of the selected widget
                    mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.CENTER);
                }
            } else if (selectedAnchor.isVerticalAnchor()) {
                mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.VERTICAL);
            } else {
                mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.HORIZONTAL);
            }
        }
    }
    if (getLook() == ColorTheme.Look.HIGHLIGHTED) {
        mDisplayAnchorsPolicy.clear();
        mDisplayAnchorsPolicy.add(WidgetDraw.ANCHORS_DISPLAY.CONNECTED);
    }
}
Also used : ConstraintAnchor(android.support.constraint.solver.widgets.ConstraintAnchor) ConstraintWidgetContainer(android.support.constraint.solver.widgets.ConstraintWidgetContainer)

Example 2 with ConstraintWidgetContainer

use of android.support.constraint.solver.widgets.ConstraintWidgetContainer in project android by JetBrains.

the class WidgetInteractionTargets method findClosestConnection.

/**
     * Fill in the ConnectionCandidate structure with the closest anchor found at (x, y).
     * This function will not consider CENTER_X/CENTER_Y anchors.
     *
     * @param viewTransform
     * @param x         x coordinate we are looking at
     * @param y         y coordinate we are looking at
     * @param candidate a structure containing the current best anchor candidate.
     * @param mousePress true if we are in mouse press
     */
public void findClosestConnection(ViewTransform viewTransform, float x, float y, ConnectionCandidate candidate, boolean mousePress) {
    // FIXME: should use subclasses this
    if (mWidget instanceof Guideline) {
        float distance;
        Guideline guideline = (Guideline) mWidget;
        ConstraintAnchor anchor = guideline.getAnchor();
        ConstraintHandle handle = constraintHandle(anchor);
        if (handle == null) {
            return;
        }
        if (guideline.getOrientation() == Guideline.VERTICAL) {
            distance = (handle.getDrawX() - x) * (handle.getDrawX() - x);
        } else {
            distance = (handle.getDrawY() - y) * (handle.getDrawY() - y);
        }
        distance = viewTransform.getSwingDimensionF(distance);
        if (distance < candidate.distance) {
            candidate.anchorTarget = anchor;
            candidate.distance = distance;
        }
    } else if (mWidget instanceof ConstraintWidgetContainer) {
        for (ConstraintHandle handle : mConstraintHandles) {
            ConstraintAnchor anchor = handle.getAnchor();
            if (anchor.getType() == ConstraintAnchor.Type.CENTER_X || anchor.getType() == ConstraintAnchor.Type.CENTER_Y) {
                continue;
            }
            float distance = 0;
            boolean computed = false;
            if (!mousePress && anchor.isSideAnchor()) {
                if (!anchor.isVerticalAnchor()) {
                    if (y >= mWidget.getDrawY() && y <= mWidget.getDrawBottom()) {
                        distance = (handle.getDrawX() - x) * (handle.getDrawX() - x);
                        computed = true;
                    }
                } else {
                    if (x >= mWidget.getDrawX() && x <= mWidget.getDrawRight()) {
                        distance = (handle.getDrawY() - y) * (handle.getDrawY() - y);
                        computed = true;
                    }
                }
            }
            if (!computed) {
                distance = (handle.getDrawX() - x) * (handle.getDrawX() - x) + (handle.getDrawY() - y) * (handle.getDrawY() - y);
            }
            distance = viewTransform.getSwingDimensionF(distance);
            if (distance < candidate.distance) {
                candidate.anchorTarget = anchor;
                candidate.distance = distance;
            }
        }
    } else {
        for (ConstraintHandle handle : mConstraintHandles) {
            ConstraintAnchor anchor = handle.getAnchor();
            float distance = (handle.getDrawX() - x) * (handle.getDrawX() - x) + (handle.getDrawY() - y) * (handle.getDrawY() - y);
            if (anchor.getType() == ConstraintAnchor.Type.CENTER_X || anchor.getType() == ConstraintAnchor.Type.CENTER_Y) {
                continue;
            }
            if (anchor.getType() == ConstraintAnchor.Type.BASELINE) {
                if (!anchor.getOwner().hasBaseline()) {
                    continue;
                }
                ConstraintWidget widget = anchor.getOwner();
                int minX = widget.getDrawX();
                int maxX = widget.getDrawRight();
                float d = Math.abs(handle.getDrawY() - y);
                if (x >= minX && x <= maxX && d < 3) {
                    distance = d * d;
                }
            }
            distance = viewTransform.getSwingDimensionF(distance);
            if (distance <= candidate.distance) {
                if (candidate.anchorTarget == null || candidate.anchorTarget.getPriorityLevel() < anchor.getPriorityLevel()) {
                    candidate.anchorTarget = anchor;
                    candidate.distance = distance;
                }
            }
        }
    }
}
Also used : ConstraintAnchor(android.support.constraint.solver.widgets.ConstraintAnchor) ConstraintWidget(android.support.constraint.solver.widgets.ConstraintWidget) ConstraintWidgetContainer(android.support.constraint.solver.widgets.ConstraintWidgetContainer) Guideline(android.support.constraint.solver.widgets.Guideline)

Example 3 with ConstraintWidgetContainer

use of android.support.constraint.solver.widgets.ConstraintWidgetContainer in project android by JetBrains.

the class Scout method inferTableList.

/**
     * Recursive decent of widget tree inferring constraints on ConstraintWidgetContainer
     *
     * @param base
     */
private static ConstraintWidget[] inferTableList(WidgetContainer base) {
    if (base instanceof ConstraintWidgetContainer && ((ConstraintWidgetContainer) base).handlesInternalConstraints()) {
        return null;
    }
    for (ConstraintWidget constraintWidget : base.getChildren()) {
        if (constraintWidget instanceof ConstraintWidgetContainer) {
            inferConstraints((ConstraintWidgetContainer) constraintWidget);
        }
    }
    ArrayList<ConstraintWidget> list = new ArrayList<>(base.getChildren());
    list.add(0, base);
    ConstraintWidget[] widgets = list.toArray(new ConstraintWidget[list.size()]);
    ConstraintWidget[] iw = ScoutGroupInference.computeGroups(ScoutWidget.create(widgets));
    if (iw != null && iw.length > 0) {
        return iw;
    }
    return null;
}
Also used : ConstraintWidget(android.support.constraint.solver.widgets.ConstraintWidget) ConstraintWidgetContainer(android.support.constraint.solver.widgets.ConstraintWidgetContainer) ArrayList(java.util.ArrayList)

Example 4 with ConstraintWidgetContainer

use of android.support.constraint.solver.widgets.ConstraintWidgetContainer in project android by JetBrains.

the class Scout method inferConstraints.

/**
     * Recursive decent of widget tree inferring constraints on ConstraintWidgetContainer
     *
     * @param base
     */
private static void inferConstraints(WidgetContainer base) {
    if (base == null) {
        return;
    }
    if (base instanceof ConstraintWidgetContainer && ((ConstraintWidgetContainer) base).handlesInternalConstraints()) {
        return;
    }
    int preX = base.getX();
    int preY = base.getY();
    base.setX(0);
    base.setY(0);
    for (ConstraintWidget constraintWidget : base.getChildren()) {
        if (constraintWidget instanceof ConstraintWidgetContainer) {
            ConstraintWidgetContainer container = (ConstraintWidgetContainer) constraintWidget;
            if (!container.getChildren().isEmpty()) {
                inferConstraints(container);
            }
        }
    }
    ArrayList<ConstraintWidget> list = new ArrayList<>(base.getChildren());
    list.add(0, base);
    ConstraintWidget[] widgets = list.toArray(new ConstraintWidget[list.size()]);
    ScoutWidget.computeConstraints(ScoutWidget.create(widgets));
    base.setX(preX);
    base.setY(preY);
}
Also used : ConstraintWidget(android.support.constraint.solver.widgets.ConstraintWidget) ConstraintWidgetContainer(android.support.constraint.solver.widgets.ConstraintWidgetContainer) ArrayList(java.util.ArrayList)

Example 5 with ConstraintWidgetContainer

use of android.support.constraint.solver.widgets.ConstraintWidgetContainer in project android by JetBrains.

the class WidgetDraw method drawWidgetFrame.

/**
     * Draw the widget frame (resizable area...) as well as
     * the constraints anchors and their state.
     * The color and style used for the drawing will be the current ones in the graphics context.
     *
     * @param transform         view transform
     * @param g                 Graphics context
     * @param widget            the widget we are drawing
     * @param showAnchors       determinate how to display the Constraints anchors points
     * @param showResizeHandles pass true to show Resize handles
     * @param isSelected        if the widget is currently selected
     */
public static void drawWidgetFrame(ViewTransform transform, Graphics2D g, ConstraintWidget widget, EnumSet<ANCHORS_DISPLAY> showAnchors, boolean showResizeHandles, boolean showSizeIndicator, boolean isSelected) {
    g.setStroke(SnapDraw.sNormalStroke);
    int l = transform.getSwingX(widget.getDrawX());
    int t = transform.getSwingY(widget.getDrawY());
    int w = transform.getSwingDimension(widget.getDrawWidth());
    int h = transform.getSwingDimension(widget.getDrawHeight());
    int r = transform.getSwingX(widget.getDrawX() + widget.getDrawWidth());
    int b = transform.getSwingY(widget.getDrawY() + widget.getDrawHeight());
    int radius = ConnectionDraw.CONNECTION_ANCHOR_SIZE;
    int radiusRect = ConnectionDraw.CONNECTION_RESIZE_SIZE;
    int rectDimension = radiusRect * 2;
    int midX = transform.getSwingX((int) (widget.getDrawX() + widget.getDrawWidth() / 2f));
    int midY = transform.getSwingY((int) (widget.getDrawY() + widget.getDrawHeight() / 2f));
    if (widget.getParent() instanceof ConstraintWidgetContainer) {
        ConstraintWidgetContainer parent = (ConstraintWidgetContainer) widget.getParent();
        if (widget instanceof Guideline) {
            if (parent.isRootContainer()) {
                drawRootGuideline(transform, g, parent, (Guideline) widget, isSelected);
            }
            return;
        }
    }
    if (widget.getVisibility() == ConstraintWidget.INVISIBLE) {
        g.setStroke(SnapDraw.sDashedStroke);
    }
    ConstraintAnchor leftAnchor = widget.getAnchor(ConstraintAnchor.Type.LEFT);
    ConstraintAnchor rightAnchor = widget.getAnchor(ConstraintAnchor.Type.RIGHT);
    ConstraintAnchor topAnchor = widget.getAnchor(ConstraintAnchor.Type.TOP);
    ConstraintAnchor bottomAnchor = widget.getAnchor(ConstraintAnchor.Type.BOTTOM);
    boolean leftAnchorIsConnected = leftAnchor.isConnected();
    boolean rightAnchorIsConnected = rightAnchor.isConnected();
    boolean topAnchorIsConnected = topAnchor.isConnected();
    boolean bottomAnchorIsConnected = bottomAnchor.isConnected();
    boolean baselineAnchorIsConnected = widget.getAnchor(ConstraintAnchor.Type.BASELINE).isConnected();
    boolean centerAnchorIsConnected = (leftAnchorIsConnected && rightAnchorIsConnected && leftAnchor.getTarget() == rightAnchor.getTarget()) || (topAnchorIsConnected && bottomAnchorIsConnected && topAnchor.getTarget() == bottomAnchor.getTarget());
    // First, resize handles...
    if (showResizeHandles) {
        g.fillRect(l - radiusRect, t - radiusRect, rectDimension, rectDimension);
        g.fillRect(r - radiusRect, t - radiusRect, rectDimension, rectDimension);
        g.fillRect(l - radiusRect, b - radiusRect, rectDimension, rectDimension);
        g.fillRect(r - radiusRect, b - radiusRect, rectDimension, rectDimension);
        if (showSizeIndicator) {
            ConnectionDraw.drawHorizontalMarginIndicator(g, String.valueOf(widget.getWidth()), l, r, t - 20);
            ConnectionDraw.drawVerticalMarginIndicator(g, String.valueOf(widget.getHeight()), l - 20, t, b);
        }
    }
    // Then, let's draw the constraints anchors
    boolean displayAllAnchors = showAnchors.contains(ANCHORS_DISPLAY.ALL);
    boolean showLeftAnchor = displayAllAnchors || showAnchors.contains(ANCHORS_DISPLAY.LEFT) || showAnchors.contains(ANCHORS_DISPLAY.HORIZONTAL);
    boolean showRightAnchor = displayAllAnchors || showAnchors.contains(ANCHORS_DISPLAY.RIGHT) || showAnchors.contains(ANCHORS_DISPLAY.HORIZONTAL);
    boolean showTopAnchor = displayAllAnchors || showAnchors.contains(ANCHORS_DISPLAY.TOP) || showAnchors.contains(ANCHORS_DISPLAY.VERTICAL);
    boolean showBottomAnchor = displayAllAnchors || showAnchors.contains(ANCHORS_DISPLAY.BOTTOM) || showAnchors.contains(ANCHORS_DISPLAY.VERTICAL);
    boolean showCenterAnchor = displayAllAnchors || showAnchors.contains(ANCHORS_DISPLAY.CENTER);
    boolean showBaselineAnchor = displayAllAnchors || showAnchors.contains(ANCHORS_DISPLAY.BASELINE);
    if (!showAnchors.contains(ANCHORS_DISPLAY.NONE) && showAnchors.contains(ANCHORS_DISPLAY.CONNECTED)) {
        showLeftAnchor |= leftAnchorIsConnected;
        showRightAnchor |= rightAnchorIsConnected;
        showTopAnchor |= topAnchorIsConnected;
        showBottomAnchor |= bottomAnchorIsConnected;
        showCenterAnchor |= centerAnchorIsConnected;
        showBaselineAnchor |= baselineAnchorIsConnected;
    }
    if (showBaselineAnchor && !(widget instanceof ConstraintWidgetContainer) && widget.getBaselineDistance() > 0) {
        int baselineY = transform.getSwingY(WidgetInteractionTargets.constraintHandle(widget.getAnchor(ConstraintAnchor.Type.BASELINE)).getDrawY());
        g.drawLine(l, baselineY, r, baselineY);
    }
    // Now, let's draw the widget's frame
    boolean horizontalSpring = widget.getHorizontalDimensionBehaviour() == ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT;
    boolean verticalSpring = widget.getVerticalDimensionBehaviour() == ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT;
    Graphics2D g2 = (Graphics2D) g.create();
    if (widget instanceof ConstraintWidgetContainer) {
        g2.setStroke(SnapDraw.sLongDashedStroke);
        if (widget instanceof ConstraintTableLayout) {
            drawTableLayoutGuidelines(transform, g2, (ConstraintTableLayout) widget);
        }
    }
    if (!widget.isRootContainer() && (horizontalSpring || verticalSpring)) {
        int x = l;
        int y = t;
        Stroke previousStroke = g.getStroke();
        if (baselineAnchorIsConnected) {
            g2.setStroke(ConnectionDraw.sSpreadDashedStroke);
        }
        if (horizontalSpring) {
            if (showTopAnchor) {
                drawHorizontalZigZagLine(g2, l, midX - radius, t, ZIGZAG, 0);
                drawHorizontalZigZagLine(g2, midX + radius, r, t, ZIGZAG, 0);
            } else {
                drawHorizontalZigZagLine(g2, l, r, t, ZIGZAG, 0);
            }
            if (showBottomAnchor) {
                drawHorizontalZigZagLine(g2, l, midX - radius, b, -ZIGZAG, 0);
                drawHorizontalZigZagLine(g2, midX + radius, r, b, -ZIGZAG, 0);
            } else {
                drawHorizontalZigZagLine(g2, l, r, b, -ZIGZAG, 0);
            }
        } else {
            g2.drawLine(x, y, x + w, y);
            g2.drawLine(x, y + h, x + w, y + h);
        }
        g2.setStroke(previousStroke);
        if (verticalSpring) {
            if (showLeftAnchor) {
                drawVerticalZigZagLine(g2, l, t, midY - radius, ZIGZAG, 0);
                drawVerticalZigZagLine(g2, l, midY + radius, b, ZIGZAG, 0);
            } else {
                drawVerticalZigZagLine(g2, l, t, b, ZIGZAG, 0);
            }
            if (showRightAnchor) {
                drawVerticalZigZagLine(g2, r, t, midY - radius, -ZIGZAG, 0);
                drawVerticalZigZagLine(g2, r, midY + radius, b, -ZIGZAG, 0);
            } else {
                drawVerticalZigZagLine(g2, r, t, b, -ZIGZAG, 0);
            }
        } else {
            g2.drawLine(x, y, x, y + h);
            g2.drawLine(x + w, y, x + w, y + h);
        }
    } else {
        Stroke previousStroke = g.getStroke();
        if (baselineAnchorIsConnected) {
            g2.setStroke(ConnectionDraw.sSpreadDashedStroke);
        }
        if (showTopAnchor) {
            g2.drawLine(l, t, midX - radius, t);
            g2.drawLine(midX + radius, t, r, t);
        } else {
            g2.drawLine(l, t, r, t);
        }
        if (showBottomAnchor) {
            g2.drawLine(l, b, midX - radius, b);
            g2.drawLine(midX + radius, b, r, b);
        } else {
            g2.drawLine(l, b, r, b);
        }
        g2.setStroke(previousStroke);
        if (showLeftAnchor) {
            g2.drawLine(l, t, l, midY - radius);
            g2.drawLine(l, midY + radius, l, b);
        } else {
            g2.drawLine(l, t, l, b);
        }
        if (showRightAnchor) {
            g2.drawLine(r, t, r, midY - radius);
            g2.drawLine(r, midY + radius, r, b);
        } else {
            g2.drawLine(r, t, r, b);
        }
    }
    g2.dispose();
    if (DEBUG) {
        // Draw diagonals
        g.drawLine(l, t, r, b);
        g.drawLine(l, b, r, t);
    }
    g.setStroke(SnapDraw.sNormalStroke);
}
Also used : ConstraintAnchor(android.support.constraint.solver.widgets.ConstraintAnchor) ConstraintWidgetContainer(android.support.constraint.solver.widgets.ConstraintWidgetContainer) ConstraintTableLayout(android.support.constraint.solver.widgets.ConstraintTableLayout) Guideline(android.support.constraint.solver.widgets.Guideline)

Aggregations

ConstraintWidgetContainer (android.support.constraint.solver.widgets.ConstraintWidgetContainer)6 ConstraintAnchor (android.support.constraint.solver.widgets.ConstraintAnchor)3 ConstraintWidget (android.support.constraint.solver.widgets.ConstraintWidget)3 Guideline (android.support.constraint.solver.widgets.Guideline)2 ArrayList (java.util.ArrayList)2 ConstraintTableLayout (android.support.constraint.solver.widgets.ConstraintTableLayout)1