in designer/src/com/android/tools/idea/uibuilder/handlers/constraint/targets/ConstraintDropHandler.java [42:191]
public void updateAttributes(@NotNull NlAttributesHolder attributes,
@NotNull SceneComponent parent,
@AndroidDpCoordinate int x,
@AndroidDpCoordinate int y) {
SceneComponent targetStartComponent = getTargetComponent(parent, ConstraintComponentUtilities.ourStartAttributes);
SceneComponent targetEndComponent = getTargetComponent(parent, ConstraintComponentUtilities.ourEndAttributes);
SceneComponent targetLeftComponent = getTargetComponent(parent, ConstraintComponentUtilities.ourLeftAttributes);
SceneComponent targetRightComponent = getTargetComponent(parent, ConstraintComponentUtilities.ourRightAttributes);
String targetStartMargin = SdkConstants.ATTR_LAYOUT_MARGIN_START;
String targetEndMargin = SdkConstants.ATTR_LAYOUT_MARGIN_END;
boolean useStartEnd = myComponent.useRtlAttributes();
boolean isInRTL = myComponent.getScene().isInRTL();
int dx1 = 0;
int dx2 = 0;
if (targetStartComponent == null && targetEndComponent == null) {
// No start/end, let's use left/right
targetStartComponent = targetLeftComponent;
targetEndComponent = targetRightComponent;
targetStartMargin = SdkConstants.ATTR_LAYOUT_MARGIN_LEFT;
targetEndMargin = SdkConstants.ATTR_LAYOUT_MARGIN_RIGHT;
useStartEnd = false;
isInRTL = false;
if (targetStartComponent != null) {
dx1 = getLeftTargetOrigin(targetStartComponent) + getMarginValue(targetStartMargin);
}
if (targetEndComponent != null) {
dx2 = getRightTargetOrigin(targetEndComponent) - getMarginValue(targetEndMargin);
}
}
else {
if (targetStartComponent != null) {
dx1 = getStartTargetOrigin(targetStartComponent, isInRTL);
int margin = getMarginValue(targetStartMargin);
if (isInRTL) {
dx1 -= margin;
}
else {
dx1 += margin;
}
}
if (targetEndComponent != null) {
dx2 = getEndTargetOrigin(targetEndComponent, isInRTL);
int margin = getMarginValue(targetEndMargin);
if (isInRTL) {
dx2 += margin;
}
else {
dx2 -= margin;
}
}
}
myChainChecker.checkIsInChain(myComponent);
if (targetStartComponent != null && targetEndComponent != null) {
if (!myChainChecker.isInHorizontalChain()) {
float dw = dx2 - dx1 - myComponent.getDrawWidth();
float bias = (x - dx1) / dw;
if (useStartEnd && isInRTL) {
dw = dx1 - dx2 - myComponent.getDrawWidth();
bias = (dw - (x - dx2)) / dw;
}
if (bias < 0) {
bias = 0;
}
if (bias > 1) {
bias = 1;
}
String biasValue = null;
if ((int)(bias * 1000) != 500) {
bias = (int)(bias * 1000) / 1000f;
biasValue = String.valueOf(bias);
if (biasValue.equalsIgnoreCase("NaN")) {
biasValue = null;
}
}
attributes.setAttribute(SdkConstants.SHERPA_URI,
SdkConstants.ATTR_LAYOUT_HORIZONTAL_BIAS, biasValue);
}
}
else if (targetStartComponent != null) {
int dx = x - getLeftTargetOrigin(targetStartComponent);
if (useStartEnd) {
if (isInRTL) {
dx = getStartTargetOrigin(targetStartComponent, true) - (x + myComponent.getDrawWidth());
}
else {
dx = x - getStartTargetOrigin(targetStartComponent, false);
}
}
applyMargin(attributes, targetStartMargin, dx);
}
else if (targetEndComponent != null) {
int dx = getRightTargetOrigin(targetEndComponent) - (x + myComponent.getDrawWidth());
if (useStartEnd) {
if (isInRTL) {
dx = x - getEndTargetOrigin(targetEndComponent, true);
}
else {
dx = getEndTargetOrigin(targetEndComponent, false) - (x + myComponent.getDrawWidth());
}
}
applyMargin(attributes, targetEndMargin, dx);
}
else {
String positionX = String.format(Locale.US, SdkConstants.VALUE_N_DP, x - parent.getDrawX());
attributes.setAttribute(SdkConstants.TOOLS_URI, SdkConstants.ATTR_LAYOUT_EDITOR_ABSOLUTE_X, positionX);
}
SceneComponent targetTopComponent = getTargetComponent(parent, ConstraintComponentUtilities.ourTopAttributes);
SceneComponent targetBottomComponent = getTargetComponent(parent, ConstraintComponentUtilities.ourBottomAttributes);
if (targetTopComponent != null && targetBottomComponent != null) {
if (!myChainChecker.isInVerticalChain()) {
int dy1 = getTopTargetOrigin(targetTopComponent) + getMarginValue(SdkConstants.ATTR_LAYOUT_MARGIN_TOP);
int dy2 = getBottomTargetOrigin(targetBottomComponent) - getMarginValue(SdkConstants.ATTR_LAYOUT_MARGIN_BOTTOM);
float dh = dy2 - dy1 - myComponent.getDrawHeight();
float bias = (y - dy1) / dh;
if (bias < 0) {
bias = 0;
}
if (bias > 1) {
bias = 1;
}
String biasValue = null;
if ((int)(bias * 1000) != 500) {
bias = (int)(bias * 1000) / 1000f;
biasValue = String.valueOf(bias);
if (biasValue.equalsIgnoreCase("NaN")) {
biasValue = null;
}
}
attributes.setAttribute(SdkConstants.SHERPA_URI,
SdkConstants.ATTR_LAYOUT_VERTICAL_BIAS, biasValue);
}
}
else if (targetTopComponent != null) {
int dy = y - getTopTargetOrigin(targetTopComponent);
applyMargin(attributes, SdkConstants.ATTR_LAYOUT_MARGIN_TOP, dy);
}
else if (targetBottomComponent != null) {
int dy = getBottomTargetOrigin(targetBottomComponent) - (y + myComponent.getDrawHeight());
applyMargin(attributes, SdkConstants.ATTR_LAYOUT_MARGIN_BOTTOM, dy);
}
else {
String positionY = String.format(Locale.US, SdkConstants.VALUE_N_DP, y - parent.getDrawY());
attributes.setAttribute(SdkConstants.TOOLS_URI, SdkConstants.ATTR_LAYOUT_EDITOR_ABSOLUTE_Y, positionY);
}
ConstraintComponentUtilities.cleanup(attributes, myComponent.getNlComponent());
}