use of android.support.constraint.solver.widgets.ConstraintWidget 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.ConstraintWidget in project android by JetBrains.
the class WidgetMotion method dragWidget.
/**
* Drag widget to a new position
*
* @param widget widget we are moving
* @param x in android coordinate
* @param y in android coordinate
* @param snap true if we want to snap this widget against others
* @param isShiftDown true if the shift button is pressed
* @param transform the view transform
* @return the type of direction (locked in x/y or not)
*/
public int dragWidget(Point startPoint, Selection.Element widget, int x, int y, boolean snap, boolean isShiftDown, ViewTransform transform) {
int directionLockedStatus = Selection.DIRECTION_UNLOCKED;
if (widget == null) {
return directionLockedStatus;
}
Animator.setAnimationEnabled(false);
int dX = startPoint.x - widget.origin.x;
int dY = startPoint.y - widget.origin.y;
int dragX = Math.abs(widget.widget.getDrawX() - widget.origin.x);
int dragY = Math.abs(widget.widget.getDrawY() - widget.origin.y);
if (dragX > SLOPE || dragY > SLOPE) {
// Let's not show the anchors and resize handles if we are dragging
mShowDecorations = false;
}
if (isShiftDown) {
// check which overall direction we are going after enough drag
if (widget.directionLocked == Selection.DIRECTION_UNLOCKED) {
if (dragX > SLOPE || dragY > SLOPE) {
if (dragX > dragY) {
// lock in x
widget.directionLocked = Selection.DIRECTION_LOCKED_X;
directionLockedStatus = Selection.DIRECTION_LOCKED_X;
} else {
widget.directionLocked = Selection.DIRECTION_LOCKED_Y;
directionLockedStatus = Selection.DIRECTION_LOCKED_Y;
}
} else {
// prevent snapping while we are figuring out the locked axis
snap = false;
}
}
} else {
widget.directionLocked = Selection.DIRECTION_UNLOCKED;
}
candidatePoint.setLocation(x - dX, y - dY);
ConstraintWidget base = widget.widget.getParent();
if (base != null) {
// limit motion to inside base
if (candidatePoint.x < base.getDrawX()) {
candidatePoint.x = base.getDrawX();
} else if (candidatePoint.x > base.getDrawRight()) {
candidatePoint.x = base.getDrawRight();
}
if (candidatePoint.y < base.getDrawY()) {
candidatePoint.y = base.getDrawY();
} else if (candidatePoint.y > base.getDrawBottom()) {
candidatePoint.y = base.getDrawBottom();
}
}
mSnapCandidates.clear();
ArrayList<ConstraintWidget> widgetsToCheck = new ArrayList<>();
for (ConstraintWidget w : mWidgetsScene.getWidgets()) {
if (w.hasAncestor(widget.widget)) {
continue;
}
if (mSelection.contains(w)) {
continue;
}
widgetsToCheck.add(w);
}
// lock direction before applying the snap
if (widget.directionLocked == Selection.DIRECTION_LOCKED_X) {
candidatePoint.y = widget.origin.y;
} else if (widget.directionLocked == Selection.DIRECTION_LOCKED_Y) {
candidatePoint.x = widget.origin.x;
}
if (snap) {
SnapPlacement.snapWidget(widgetsToCheck, widget.widget, candidatePoint, false, mSnapCandidates, transform);
}
WidgetCompanion widgetCompanion = (WidgetCompanion) widget.widget.getCompanionWidget();
WidgetInteractionTargets widgetInteraction = widgetCompanion.getWidgetInteractionTargets();
// check if we have centered connections, if so allow moving and snapping
// on specific percentage positions
snapBias(widget.widget, candidatePoint);
widget.widget.setDrawOrigin(candidatePoint.x, candidatePoint.y);
widget.widget.forceUpdateDrawPosition();
widgetInteraction.updatePosition(transform);
mSimilarMargins.clear();
for (SnapCandidate candidate : mSnapCandidates) {
if (candidate.margin != 0) {
mSimilarMargins.add(candidate);
}
}
for (SnapCandidate candidate : mSnapCandidates) {
SnapPlacement.gatherMargins(mWidgetsScene.getWidgets(), mSimilarMargins, candidate.margin, candidate.source.isVerticalAnchor());
}
return directionLockedStatus;
}
use of android.support.constraint.solver.widgets.ConstraintWidget in project android by JetBrains.
the class ConstraintHandle method updatePosition.
/**
* Update the position of the anchor depending on the owner's position
*
*/
void updatePosition() {
if (mOwner == null) {
mX = 0;
mY = 0;
return;
}
ConstraintWidget widget = mOwner.getConstraintWidget();
int x = widget.getDrawX();
int y = widget.getDrawY();
int w = widget.getDrawWidth();
int h = widget.getDrawHeight();
if (mAnchor == null) {
return;
}
switch(mAnchor.getType()) {
case LEFT:
{
mX = x;
mY = y + h / 2;
}
break;
case TOP:
{
mX = x + w / 2;
mY = y;
}
break;
case RIGHT:
{
mX = x + w;
mY = y + h / 2;
}
break;
case BOTTOM:
{
mX = x + w / 2;
mY = y + h;
}
break;
case CENTER:
case CENTER_X:
case CENTER_Y:
{
mX = x + w / 2;
mY = y + h / 2;
}
break;
case BASELINE:
{
mX = x + w / 2;
mY = y + widget.getBaselineDistance();
}
break;
}
}
use of android.support.constraint.solver.widgets.ConstraintWidget in project android by JetBrains.
the class ConstraintHandle method draw.
/**
* Draw function for the ConstraintHandle
*
* @param transform the view transform
* @param g the graphics context
* @param colorSet the current colorset
* @param isSelected if the constraint is selected or not
*/
public void draw(ViewTransform transform, Graphics2D g, ColorSet colorSet, boolean isSelected) {
ConstraintWidget widget = getOwner();
WidgetCompanion companion = (WidgetCompanion) widget.getCompanionWidget();
WidgetDecorator decorator = companion.getWidgetDecorator(colorSet.getStyle());
Color backgroundColor = decorator.getBackgroundColor();
if (mType == ConstraintAnchor.Type.BASELINE) {
int x = transform.getSwingX(getOwner().getDrawX());
int y = transform.getSwingY(getOwner().getDrawY());
int w = transform.getSwingDimension(getOwner().getDrawWidth());
int baseline = transform.getSwingDimension(getOwner().getBaselineDistance());
int padding = (w - getBaselineHandleWidth(transform)) / 2;
int bh = 7;
int by = y + baseline;
if (isSelected) {
Color pre = g.getColor();
Stroke preStroke = g.getStroke();
g.setColor(colorSet.getShadow());
g.setStroke(colorSet.getShadowStroke());
g.drawRoundRect(x + padding, by - bh / 2, w - 2 * padding, bh, bh, bh);
g.setStroke(preStroke);
g.setColor(pre);
}
Color previous = g.getColor();
g.setColor(new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), previous.getAlpha()));
g.fillRoundRect(x + padding, by - bh / 2, w - 2 * padding, bh, bh, bh);
g.setColor(previous);
g.drawRoundRect(x + padding, by - bh / 2, w - 2 * padding, bh, bh, bh);
g.drawLine(x, by, x + padding, by);
g.drawLine(x + w - padding, by, x + w, by);
if (mAnchor.isConnected()) {
int margin = 2;
g.fillRoundRect(x + padding + margin, by - bh / 2 + margin, w - 2 * padding - 2 * margin, bh - 2 * margin, bh, bh);
g.drawRoundRect(x + padding + margin, by - bh / 2 + margin, w - 2 * padding - 2 * margin, bh - 2 * margin, bh, bh);
}
} else {
int innerMargin = 3;
int radius = ConnectionDraw.CONNECTION_ANCHOR_SIZE;
int dimension = radius * 2;
int cx = transform.getSwingFX(mX) - dimension / 2;
int cy = transform.getSwingFY(mY) - dimension / 2;
Ellipse2D.Float outerCircle = new Ellipse2D.Float(cx, cy, dimension, dimension);
if (isSelected) {
Color pre = g.getColor();
Stroke preStroke = g.getStroke();
g.setColor(sShadowColor);
g.setStroke(sShadowStroke);
g.draw(outerCircle);
g.setStroke(preStroke);
g.setColor(pre);
}
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(backgroundColor);
g2.fill(outerCircle);
g2.dispose();
g.draw(outerCircle);
if (mAnchor.isConnected()) {
int d = dimension - innerMargin * 2;
g.fillRoundRect(cx + innerMargin, cy + innerMargin, d, d, d, d);
g.drawRoundRect(cx + innerMargin, cy + innerMargin, d, d, d, d);
}
}
}
use of android.support.constraint.solver.widgets.ConstraintWidget in project android by JetBrains.
the class TableDecorator method mousePressed.
/**
* Handle mouse press event to add click targets. TODO: clean this up.
*
* @param x mouse x coordinate
* @param y mouse y coordinate
* @param transform view transform
* @param selection the current selection of widgets
*/
@Override
public ConstraintWidget mousePressed(float x, float y, ViewTransform transform, Selection selection) {
ConstraintTableLayout table = (ConstraintTableLayout) mWidget;
mTableClickTargets.clear();
ArrayList<Guideline> vertical = table.getVerticalGuidelines();
int l = transform.getSwingX(table.getDrawX());
int t = transform.getSwingY(table.getDrawY());
int column = 0;
TableClickTarget firstTarget = new TableClickTarget(table, column++, l, t - 20 - 4, 20, 20);
mTableClickTargets.add(firstTarget);
for (ConstraintWidget v : vertical) {
int bx = transform.getSwingX(v.getX()) + l;
TableClickTarget target = new TableClickTarget(table, column++, bx, t - 20 - 4, 20, 20);
mTableClickTargets.add(target);
}
ConstraintWidget widgetHit = null;
if (mTableClickTargets.size() > 0) {
for (TableClickTarget tableClickTarget : mTableClickTargets) {
if (tableClickTarget.contains(x, y)) {
widgetHit = tableClickTarget.getTable();
break;
}
}
if (selection.isEmpty()) {
mTableClickTargets.clear();
}
}
return widgetHit;
}
Aggregations