use of com.android.tools.sherpa.drawing.decorator.WidgetDecorator in project android by JetBrains.
the class WidgetCompanion method create.
public static WidgetCompanion create(ConstraintWidget widget) {
WidgetCompanion companion = new WidgetCompanion();
WidgetDecorator blueprintDecorator = new WidgetDecorator(widget);
blueprintDecorator.setStyle(WidgetDecorator.BLUEPRINT_STYLE);
WidgetDecorator androidDecorator = new WidgetDecorator(widget);
androidDecorator.setStyle(WidgetDecorator.ANDROID_STYLE);
companion.addDecorator(blueprintDecorator);
companion.addDecorator(androidDecorator);
companion.setWidgetInteractionTargets(new WidgetInteractionTargets(widget));
return companion;
}
use of com.android.tools.sherpa.drawing.decorator.WidgetDecorator in project android by JetBrains.
the class WidgetsScene method findWidgetInSelection.
/**
* Find a widget at the coordinate (x, y) in the current selection,
* taking the decorator visibility in account
*
* @param x x position
* @param y y position
* @return a widget if found, null otherwise
*/
public ConstraintWidget findWidgetInSelection(float x, float y) {
ConstraintWidget found = null;
ArrayList<ConstraintWidget> selection = mSelection.getWidgets();
for (ConstraintWidget widget : selection) {
WidgetCompanion companion = (WidgetCompanion) widget.getCompanionWidget();
WidgetDecorator decorator = companion.getWidgetDecorator(WidgetDecorator.BLUEPRINT_STYLE);
if (!decorator.isVisible()) {
continue;
}
if (widget instanceof ConstraintWidgetContainer) {
ConstraintWidget f = findWidget((ConstraintWidgetContainer) widget, x, y);
if (f != null) {
found = f;
}
} else {
int l = widget.getDrawX();
int t = widget.getDrawY();
int r = l + widget.getWidth();
int b = t + widget.getHeight();
if (x >= l && x <= r && y >= t && y <= b) {
found = widget;
}
}
}
return found;
}
use of com.android.tools.sherpa.drawing.decorator.WidgetDecorator in project android by JetBrains.
the class ConstraintUtilities method updateWidgetFromComponent.
/**
* Update the constraint widget with the component information (coming from XML)
*
* @param scene the scene of components. Can be null.
* @param constraintModel the constraint model we are working with
* @param widget constraint widget
* @param component the model component
* @return true if need to save the xml
*/
static boolean updateWidgetFromComponent(@Nullable Scene scene, @NotNull ConstraintModel constraintModel, @Nullable ConstraintWidget widget, @Nullable NlComponent component) {
if (component == null || widget == null) {
return false;
}
if (!(widget instanceof Guideline)) {
widget.setVisibility(component.getAndroidViewVisibility());
}
widget.setDebugName(component.getId());
Insets padding = component.getPadding(true);
WidgetsScene widgetsScene = constraintModel.getScene();
if (scene != null) {
// If the scene exists, use the bounds from it instead of from the NlComponent.
// This gives us animation on layout changes.
// Note: this is temporary, once the Scene interaction / painting is fully done we'll switch to it.
long time = System.currentTimeMillis();
SceneComponent sceneComponent = scene.getSceneComponent(component);
if (sceneComponent != null) {
widget.setDrawOrigin(sceneComponent.getDrawX(time), sceneComponent.getDrawY(time));
int w = sceneComponent.getDrawWidth(time);
int h = sceneComponent.getDrawHeight(time);
widget.setDimension(w, h);
return false;
}
}
if (widget instanceof ConstraintWidgetContainer) {
int paddingLeft = constraintModel.pxToDp(padding.left);
int paddingTop = constraintModel.pxToDp(padding.top);
int paddingRight = constraintModel.pxToDp(padding.right);
int paddingBottom = constraintModel.pxToDp(padding.bottom);
((ConstraintWidgetContainer) widget).setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
widget.setDimension(constraintModel.pxToDp(component.w) - paddingLeft - paddingRight, constraintModel.pxToDp(component.h) - paddingTop - paddingBottom);
} else {
widget.setDimension(constraintModel.pxToDp(component.w), constraintModel.pxToDp(component.h));
}
String absoluteWidth = component.getAttribute(SdkConstants.TOOLS_URI, ConvertToConstraintLayoutAction.ATTR_LAYOUT_CONVERSION_ABSOLUTE_WIDTH);
if (absoluteWidth != null) {
Configuration configuration = component.getModel().getConfiguration();
ResourceResolver resourceResolver = configuration.getResourceResolver();
int size = ViewEditor.resolveDimensionPixelSize(resourceResolver, absoluteWidth, configuration);
size = constraintModel.pxToDp(size);
widget.setWidth(size);
}
String absoluteHeight = component.getAttribute(SdkConstants.TOOLS_URI, ConvertToConstraintLayoutAction.ATTR_LAYOUT_CONVERSION_ABSOLUTE_HEIGHT);
if (absoluteHeight != null) {
Configuration configuration = component.getModel().getConfiguration();
ResourceResolver resourceResolver = configuration.getResourceResolver();
int size = ViewEditor.resolveDimensionPixelSize(resourceResolver, absoluteHeight, configuration);
size = constraintModel.pxToDp(size);
widget.setHeight(size);
}
widget.setMinWidth(constraintModel.pxToDp(component.getMinimumWidth()));
widget.setMinHeight(constraintModel.pxToDp(component.getMinimumHeight()));
NlComponent parent = component.getParent();
NlModel model = component.getModel();
if (parent != null) {
ConstraintWidget parentWidget = widgetsScene.getWidget(parent);
if (parentWidget instanceof WidgetContainer) {
WidgetContainer parentContainerWidget = (WidgetContainer) parentWidget;
if (widget.getParent() != parentContainerWidget) {
parentContainerWidget.add(widget);
}
}
}
// First set the origin of the widget
int x = constraintModel.pxToDp(component.x);
int y = constraintModel.pxToDp(component.y);
if (widget instanceof ConstraintWidgetContainer) {
x += constraintModel.pxToDp(padding.left);
y += constraintModel.pxToDp(padding.top);
}
WidgetContainer parentContainer = (WidgetContainer) widget.getParent();
if (parentContainer != null) {
if (!(parentContainer instanceof ConstraintWidgetContainer)) {
x = constraintModel.pxToDp(component.x - component.getParent().x);
y = constraintModel.pxToDp(component.y - component.getParent().y);
} else {
x -= parentContainer.getDrawX();
y -= parentContainer.getDrawY();
}
}
String absoluteX = component.getAttribute(SdkConstants.TOOLS_URI, ConvertToConstraintLayoutAction.ATTR_LAYOUT_CONVERSION_ABSOLUTE_X);
if (absoluteX != null) {
Configuration configuration = component.getModel().getConfiguration();
ResourceResolver resourceResolver = configuration.getResourceResolver();
int position = ViewEditor.resolveDimensionPixelSize(resourceResolver, absoluteX, configuration);
x = constraintModel.pxToDp(position);
}
String absoluteY = component.getAttribute(SdkConstants.TOOLS_URI, ConvertToConstraintLayoutAction.ATTR_LAYOUT_CONVERSION_ABSOLUTE_Y);
if (absoluteY != null) {
Configuration configuration = component.getModel().getConfiguration();
ResourceResolver resourceResolver = configuration.getResourceResolver();
int position = ViewEditor.resolveDimensionPixelSize(resourceResolver, absoluteY, configuration);
y = constraintModel.pxToDp(position);
}
if (scene == null) {
if (widget.getX() != x || widget.getY() != y) {
widget.setOrigin(x, y);
widget.forceUpdateDrawPosition();
}
}
boolean overrideDimension = false;
// FIXME: need to agree on the correct magic value for this rather than simply using zero.
String layout_width = component.getAttribute(SdkConstants.ANDROID_URI, SdkConstants.ATTR_LAYOUT_WIDTH);
if (component.w == 0 || getLayoutDimensionDpValue(component, layout_width) == 0) {
widget.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
} else if (layout_width != null && layout_width.equalsIgnoreCase(SdkConstants.VALUE_WRAP_CONTENT)) {
if (APPLY_MINIMUM_SIZE && widget.getWidth() < MINIMUM_SIZE && widget instanceof WidgetContainer && ((WidgetContainer) widget).getChildren().size() == 0) {
widget.setWidth(MINIMUM_SIZE);
widget.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.FIXED);
overrideDimension = true;
} else {
widget.setWrapWidth(widget.getWidth());
widget.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.WRAP_CONTENT);
}
} else if (layout_width != null && layout_width.equalsIgnoreCase(SdkConstants.VALUE_MATCH_PARENT)) {
if (isWidgetInsideConstraintLayout(widget)) {
if (widget.getAnchor(ConstraintAnchor.Type.LEFT).isConnected() && widget.getAnchor(ConstraintAnchor.Type.RIGHT).isConnected()) {
widget.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
} else {
widget.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.FIXED);
widget.setWidth(MINIMUM_SIZE_EXPAND);
int height = widget.getHeight();
ConstraintWidget.DimensionBehaviour verticalBehaviour = widget.getVerticalDimensionBehaviour();
if (height <= 1 && widget instanceof WidgetContainer) {
widget.setHeight(MINIMUM_SIZE_EXPAND);
}
ArrayList<ConstraintWidget> widgets = new ArrayList<>();
widgets.add(widget);
Scout.arrangeWidgets(Scout.Arrange.ExpandHorizontally, widgets, true);
widget.setHeight(height);
widget.setVerticalDimensionBehaviour(verticalBehaviour);
overrideDimension = true;
}
}
} else {
widget.setHorizontalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.FIXED);
}
String layout_height = component.getAttribute(SdkConstants.ANDROID_URI, SdkConstants.ATTR_LAYOUT_HEIGHT);
if (component.h == 0 || getLayoutDimensionDpValue(component, layout_height) == 0) {
widget.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
} else if (layout_height != null && layout_height.equalsIgnoreCase(SdkConstants.VALUE_WRAP_CONTENT)) {
if (APPLY_MINIMUM_SIZE && widget.getHeight() < MINIMUM_SIZE && widget instanceof WidgetContainer && ((WidgetContainer) widget).getChildren().size() == 0) {
widget.setHeight(MINIMUM_SIZE);
widget.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.FIXED);
overrideDimension = true;
} else {
widget.setWrapHeight(widget.getHeight());
widget.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.WRAP_CONTENT);
}
} else if (layout_height != null && layout_height.equalsIgnoreCase(SdkConstants.VALUE_MATCH_PARENT)) {
if (isWidgetInsideConstraintLayout(widget)) {
if ((widget.getAnchor(ConstraintAnchor.Type.TOP).isConnected() && widget.getAnchor(ConstraintAnchor.Type.BOTTOM).isConnected())) {
widget.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
} else {
widget.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.FIXED);
widget.setHeight(MINIMUM_SIZE_EXPAND);
int width = widget.getWidth();
ConstraintWidget.DimensionBehaviour horizontalBehaviour = widget.getHorizontalDimensionBehaviour();
if (width <= 1 && widget instanceof WidgetContainer) {
widget.setWidth(MINIMUM_SIZE_EXPAND);
}
ArrayList<ConstraintWidget> widgets = new ArrayList<>();
widgets.add(widget);
Scout.arrangeWidgets(Scout.Arrange.ExpandVertically, widgets, true);
widget.setWidth(width);
widget.setHorizontalDimensionBehaviour(horizontalBehaviour);
overrideDimension = true;
}
}
} else {
widget.setVerticalDimensionBehaviour(ConstraintWidget.DimensionBehaviour.FIXED);
}
widget.setBaselineDistance(constraintModel.pxToDp(component.getBaseline()));
widget.resetAnchors();
String left1 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_LEFT_TO_LEFT_OF);
String left2 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_LEFT_TO_RIGHT_OF);
String right1 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_RIGHT_TO_LEFT_OF);
String right2 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_RIGHT_TO_RIGHT_OF);
String top1 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_TOP_TO_TOP_OF);
String top2 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_TOP_TO_BOTTOM_OF);
String bottom1 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_BOTTOM_TO_TOP_OF);
String bottom2 = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_BOTTOM_TO_BOTTOM_OF);
String baseline = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_BASELINE_TO_BASELINE_OF);
String ratio = component.getAttribute(SdkConstants.SHERPA_URI, SdkConstants.ATTR_LAYOUT_DIMENSION_RATIO);
WidgetCompanion companion = (WidgetCompanion) widget.getCompanionWidget();
companion.getWidgetProperties().clear();
companion.getWidgetProperties().setDimensionRatio(ratio);
setMarginType(ConstraintAnchor.Type.LEFT, component, widget);
setMarginType(ConstraintAnchor.Type.RIGHT, component, widget);
setMarginType(ConstraintAnchor.Type.TOP, component, widget);
setMarginType(ConstraintAnchor.Type.BOTTOM, component, widget);
setTarget(model, widgetsScene, left1, widget, ConstraintAnchor.Type.LEFT, ConstraintAnchor.Type.LEFT);
setStartMargin(left1, component, widget);
setTarget(model, widgetsScene, left2, widget, ConstraintAnchor.Type.LEFT, ConstraintAnchor.Type.RIGHT);
setStartMargin(left2, component, widget);
setTarget(model, widgetsScene, right1, widget, ConstraintAnchor.Type.RIGHT, ConstraintAnchor.Type.LEFT);
setEndMargin(right1, component, widget);
setTarget(model, widgetsScene, right2, widget, ConstraintAnchor.Type.RIGHT, ConstraintAnchor.Type.RIGHT);
setEndMargin(right2, component, widget);
setTarget(model, widgetsScene, top1, widget, ConstraintAnchor.Type.TOP, ConstraintAnchor.Type.TOP);
setTopMargin(top1, component, widget);
setTarget(model, widgetsScene, top2, widget, ConstraintAnchor.Type.TOP, ConstraintAnchor.Type.BOTTOM);
setTopMargin(top2, component, widget);
setTarget(model, widgetsScene, bottom1, widget, ConstraintAnchor.Type.BOTTOM, ConstraintAnchor.Type.TOP);
setBottomMargin(bottom1, component, widget);
setTarget(model, widgetsScene, bottom2, widget, ConstraintAnchor.Type.BOTTOM, ConstraintAnchor.Type.BOTTOM);
setBottomMargin(bottom2, component, widget);
setTarget(model, widgetsScene, baseline, widget, ConstraintAnchor.Type.BASELINE, ConstraintAnchor.Type.BASELINE);
setBias(SdkConstants.ATTR_LAYOUT_HORIZONTAL_BIAS, component, widget);
setBias(SdkConstants.ATTR_LAYOUT_VERTICAL_BIAS, component, widget);
setDimensionRatio(SdkConstants.ATTR_LAYOUT_DIMENSION_RATIO, component, widget);
setChainStyle(SdkConstants.ATTR_LAYOUT_HORIZONTAL_CHAIN_STYLE, component, widget);
setChainStyle(SdkConstants.ATTR_LAYOUT_VERTICAL_CHAIN_STYLE, component, widget);
setChainWeight(SdkConstants.ATTR_LAYOUT_HORIZONTAL_WEIGHT, component, widget);
setChainWeight(SdkConstants.ATTR_LAYOUT_VERTICAL_WEIGHT, component, widget);
if (widget instanceof Guideline) {
Guideline guideline = (Guideline) widget;
setGuideline(component, guideline);
}
// Update text decorator
WidgetDecorator decorator = companion.getWidgetDecorator(WidgetDecorator.BLUEPRINT_STYLE);
if (decorator != null && decorator instanceof TextWidget) {
TextWidget textWidget = (TextWidget) decorator;
textWidget.setText(getResolvedText(component));
Configuration configuration = component.getModel().getConfiguration();
ResourceResolver resourceResolver = configuration.getResourceResolver();
Integer size = null;
if (resourceResolver != null) {
String textSize = component.getAttribute(SdkConstants.ANDROID_URI, SdkConstants.ATTR_TEXT_SIZE);
if (textSize != null) {
size = ViewEditor.resolveDimensionPixelSize(resourceResolver, textSize, configuration);
}
}
if (size == null) {
// With the specified string, this method cannot return null
//noinspection ConstantConditions
size = ViewEditor.resolveDimensionPixelSize(resourceResolver, "15sp", configuration);
}
String alignment = component.getAttribute(SdkConstants.ANDROID_URI, SdkConstants.ATTR_TEXT_ALIGNMENT);
textWidget.setTextAlignment((alignment == null) ? TextWidget.TEXT_ALIGNMENT_VIEW_START : alignmentMap.get(alignment));
String single = component.getAttribute(SdkConstants.ANDROID_URI, SdkConstants.ATTR_SINGLE_LINE);
textWidget.setSingleLine(Boolean.parseBoolean(single));
// Cannot be null, see previous condition
//noinspection ConstantConditions
textWidget.setTextSize(constraintModel.pxToDp(size));
}
// if true, need to update the XML
return overrideDimension;
}
use of com.android.tools.sherpa.drawing.decorator.WidgetDecorator in project android by JetBrains.
the class WidgetMotion method snapBias.
/**
* Snap the widget's horizontal or vertical bias if we have horizontal/vertical
* centered connections
*
* @param widget the current widget
* @param candidatePoint the candidate point containing the current location
*/
private void snapBias(ConstraintWidget widget, Point candidatePoint) {
WidgetCompanion widgetCompanion = (WidgetCompanion) widget.getCompanionWidget();
int currentStyle = WidgetDecorator.BLUEPRINT_STYLE;
if (mSceneDraw != null) {
currentStyle = mSceneDraw.getCurrentStyle();
}
WidgetDecorator decorator = widgetCompanion.getWidgetDecorator(currentStyle);
ConstraintAnchor leftAnchor = widget.getAnchor(ConstraintAnchor.Type.LEFT);
ConstraintAnchor rightAnchor = widget.getAnchor(ConstraintAnchor.Type.RIGHT);
if (leftAnchor != null && rightAnchor != null && leftAnchor.isConnected() && rightAnchor.isConnected() && leftAnchor.getTarget() != rightAnchor.getTarget()) {
int begin = WidgetInteractionTargets.constraintHandle(leftAnchor.getTarget()).getDrawX();
int end = WidgetInteractionTargets.constraintHandle(rightAnchor.getTarget()).getDrawX();
int width = widget.getDrawWidth();
int delta = candidatePoint.x - begin;
float percent = delta / (float) (end - begin - width);
percent = Math.max(0, Math.min(1, percent));
percent = snapPercent(percent);
widget.setHorizontalBiasPercent(percent);
decorator.updateBias();
}
ConstraintAnchor topAnchor = widget.getAnchor(ConstraintAnchor.Type.TOP);
ConstraintAnchor bottomAnchor = widget.getAnchor(ConstraintAnchor.Type.BOTTOM);
if (topAnchor != null && bottomAnchor != null && topAnchor.isConnected() && bottomAnchor.isConnected() && topAnchor.getTarget() != bottomAnchor.getTarget()) {
int begin = WidgetInteractionTargets.constraintHandle(topAnchor.getTarget()).getDrawY();
int end = WidgetInteractionTargets.constraintHandle(bottomAnchor.getTarget()).getDrawY();
int height = widget.getDrawHeight();
int delta = candidatePoint.y - begin;
float percent = delta / (float) (end - begin - height);
percent = Math.max(0, Math.min(1, percent));
percent = snapPercent(percent);
widget.setVerticalBiasPercent(percent);
decorator.updateBias();
}
}
use of com.android.tools.sherpa.drawing.decorator.WidgetDecorator 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);
}
}
}
Aggregations