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