use of com.android.tools.sherpa.structure.Selection in project android by JetBrains.
the class MouseInteraction method mouseReleased.
/**
* Mouse release handling
*
* @param x mouse x coordinate
* @param y mouse y coordinate
*/
public void mouseReleased(int x, int y) {
for (ConstraintWidget widget : mWidgetsScene.getWidgets()) {
getDecorator(widget).setShowActions(true);
}
boolean longPress = false;
if (System.currentTimeMillis() - mPressTime > LONG_PRESS_THRESHOLD) {
longPress = true;
}
if (mMouseMode == MouseMode.INACTIVE) {
return;
}
if (mAutoConnect) {
// Auto-connect to candidates
for (SnapCandidate candidate : mWidgetMotion.getSnapCandidates()) {
if (!candidate.source.isConnectionAllowed(candidate.target.getOwner())) {
continue;
}
int margin = candidate.margin;
if (candidate.padding != 0) {
margin = candidate.padding;
}
margin = Math.abs(margin);
ConstraintWidget widget = candidate.source.getOwner();
widget.connect(candidate.source, candidate.target, margin, ConstraintAnchor.AUTO_CONSTRAINT_CREATOR);
mSelection.addModifiedWidget(candidate.source.getOwner());
}
// it's safer to do it this way)
for (ConstraintWidget widget : mSelection.getModifiedWidgets()) {
for (ConstraintAnchor anchor : widget.getAnchors()) {
if (!anchor.isConnected()) {
continue;
}
if (anchor.getConnectionCreator() != ConstraintAnchor.AUTO_CONSTRAINT_CREATOR) {
continue;
}
WidgetDecorator.getConstraintHandle(anchor).startLock();
}
}
}
mWidgetMotion.mouseReleased();
mWidgetResize.mouseReleased();
mSceneDraw.mouseReleased();
// First check anchors that are not guidelines, to deal with the case
// where we want to delete the connection
mClickListener.clearSelection();
mClickListener.find(mViewTransform.getSwingFX(x), mViewTransform.getSwingFY(y));
ConstraintAnchor anchor = mClickListener.getConstraintAnchor();
if (mSelection.getSelectedAnchor() != null && mSelection.getConnectionCandidateAnchor() == null && anchor == mSelection.getSelectedAnchor() && !longPress) {
// delete the anchor connection
if (mSelection.getSelectedAnchor().isConnected() && mSelection.getSelectedAnchor().getTarget() == mSelection.getSelectedAnchorInitialTarget()) {
ConstraintWidget widget = mSelection.getSelectedAnchor().getOwner();
ConstraintAnchor selectedAnchor = mSelection.getSelectedAnchor();
if (selectedAnchor.isVerticalAnchor()) {
widget.setVerticalBiasPercent(0.5f);
} else {
widget.setHorizontalBiasPercent(0.5f);
}
widget.resetAnchor(selectedAnchor);
ConstraintHandle selectedHandle = WidgetInteractionTargets.constraintHandle(selectedAnchor);
if (mSelection.getSelectedAnchor().getType() == ConstraintAnchor.Type.BASELINE) {
mSceneDraw.getChoreographer().addAnimation(new AnimatedDestroyLine(selectedHandle));
} else {
mSceneDraw.getChoreographer().addAnimation(new AnimatedDestroyCircle(selectedHandle));
}
mSelection.addModifiedWidget(widget);
}
}
// If we hit a widget, update the selection
ConstraintWidget widget = mClickListener.mHitWidget;
if (widget != null) {
if (mMouseMode == MouseMode.SELECT) {
if (!mSelection.contains(widget)) {
// replace the current selection
if (!(isShiftDown() || isControlDown())) {
mSelection.clear();
}
mSelection.add(widget);
} else if (isControlDown()) {
mSelection.remove(widget);
}
}
}
if (mSelection.isEmpty() && mSelection.getSelectedAnchor() == null) {
int x1 = Math.min(getStartPoint().x, getLastPoint().x);
int x2 = Math.max(getStartPoint().x, getLastPoint().x);
int y1 = Math.min(getStartPoint().y, getLastPoint().y);
int y2 = Math.max(getStartPoint().y, getLastPoint().y);
Rectangle selectionRect = new Rectangle();
selectionRect.setBounds(x1, y1, x2 - x1, y2 - y1);
if (selectionRect.width > 0 && selectionRect.height > 0) {
ArrayList<ConstraintWidget> selection = mWidgetsScene.findWidgets(mWidgetsScene.getRoot(), selectionRect.x, selectionRect.y, selectionRect.width, selectionRect.height);
for (ConstraintWidget w : selection) {
mSelection.add(w);
}
}
}
if (mSelection.getSelectedGuideline() != null) {
Rectangle head = mSelection.getSelectedGuideline().getHead();
if (head.contains(getStartPoint().x, getStartPoint().y)) {
Selection.Element element = mSelection.get(mSelection.getSelectedGuideline());
if (element != null) {
if (mSelection.getSelectedGuideline().getOrientation() == Guideline.VERTICAL) {
if (element.origin.x == mSelection.getSelectedGuideline().getDrawX()) {
mSelection.getSelectedGuideline().cyclePosition();
mSelection.addModifiedWidget(mSelection.getSelectedGuideline());
}
} else {
if (element.origin.y == mSelection.getSelectedGuideline().getDrawY()) {
mSelection.getSelectedGuideline().cyclePosition();
mSelection.addModifiedWidget(mSelection.getSelectedGuideline());
}
}
}
}
}
// give a chance to widgets to respond to a mouse press
for (Selection.Element selection : mSelection.getElements()) {
getDecorator(selection.widget).mouseRelease(x, y, mViewTransform, mSelection);
}
for (Selection.Element selection : mSelection.getElements()) {
selection.directionLocked = Selection.DIRECTION_UNLOCKED;
}
mSceneDraw.setCurrentUnderneathAnchor(null);
mMouseMode = MouseMode.INACTIVE;
mSelection.setSelectedAnchor(null);
mSelection.setSelectedResizeHandle(null);
mSelection.setConnectionCandidateAnchor(null);
mSelection.clearBounds();
// in case something did change...
mSelection.selectionHasChanged();
mLastMousePosition.setLocation(0, 0);
mSnapshot = null;
mMouseDown = false;
Animator.setAnimationEnabled(true);
}
use of com.android.tools.sherpa.structure.Selection in project android by JetBrains.
the class SceneDraw method paintWidgets.
/**
* Main painting function
*
*
* @param rootDrawComponent the component we want to draw (with its children)
* @param width width of the canvas we paint on
* @param height height of the canvas we paint on
* @param transform
* @param g
* @param showAllConstraints
* @param mouseInteraction
* @return true if need to be called again (animation...)
*/
public boolean paintWidgets(ConstraintWidget rootDrawComponent, int width, int height, ViewTransform transform, Graphics2D g, boolean showAllConstraints, MouseInteraction mouseInteraction) {
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
WidgetContainer root = mWidgetsScene.getRoot();
if (root == null) {
return false;
}
mViewWidth = width;
mViewHeight = height;
if (mApplyConstraints) {
root.layout();
}
// Adapt the anchor size
ConnectionDraw.CONNECTION_ANCHOR_SIZE = (int) getAnchorSize(transform.getScale());
ConstraintAnchor selectedAnchor = mSelection.getSelectedAnchor();
ResizeHandle selectedResizeHandle = mSelection.getSelectedResizeHandle();
// Let's draw the widgets and their constraints.
boolean needsRepaint = false;
WidgetDecorator.setShowAllConstraints(showAllConstraints);
// First, mark which widgets is selected.
for (ConstraintWidget widget : mWidgetsScene.getWidgets()) {
WidgetCompanion widgetCompanion = (WidgetCompanion) widget.getCompanionWidget();
WidgetDecorator decorator = widgetCompanion.getWidgetDecorator(getCurrentStyle());
WidgetInteractionTargets widgetInteraction = widgetCompanion.getWidgetInteractionTargets();
widgetInteraction.updatePosition(transform);
decorator.setColorSet(mColorSet);
if (mSelection.contains(widget)) {
decorator.setIsSelected(true);
} else {
decorator.setIsSelected(false);
}
}
// Then, mark highlighted widgets
animateInCandidateAnchors(selectedAnchor);
for (ConstraintWidget widget : mWidgetsScene.getWidgets()) {
WidgetCompanion widgetCompanion = (WidgetCompanion) widget.getCompanionWidget();
WidgetDecorator decorator = widgetCompanion.getWidgetDecorator(getCurrentStyle());
decorator.applyLook();
}
// Draw the constraints
for (ConstraintWidget widget : mWidgetsScene.getWidgets()) {
WidgetCompanion widgetCompanion = (WidgetCompanion) widget.getCompanionWidget();
WidgetDecorator decorator = widgetCompanion.getWidgetDecorator(getCurrentStyle());
if (widget.getVisibility() == ConstraintWidget.GONE || (widget.getParent() != null && widget.getParent().getVisibility() == ConstraintWidget.GONE)) {
continue;
}
if (DRAW_ENTIRE_TREE || widget == rootDrawComponent || widget.getParent() == rootDrawComponent) {
if (decorator.isVisible() && !decorator.isSelected() && decorator.getLook() != ColorTheme.Look.HIGHLIGHTED) {
decorator.onPaintConstraints(transform, g);
}
}
}
// Draw all the widgets
ConstraintWidget selectedWidget = null;
if (mSelection.hasSingleElement()) {
selectedWidget = mSelection.getFirstElement().widget;
}
needsRepaint |= paintWidgets(transform, g, rootDrawComponent, mWidgetsScene.getRoot(), selectedWidget, selectedAnchor, selectedResizeHandle);
// Draw the selected constraints
for (ConstraintWidget widget : mWidgetsScene.getWidgets()) {
WidgetCompanion widgetCompanion = (WidgetCompanion) widget.getCompanionWidget();
WidgetDecorator decorator = widgetCompanion.getWidgetDecorator(getCurrentStyle());
ConstraintWidget parent = widget.getParent();
if (DRAW_ENTIRE_TREE || widget == rootDrawComponent || parent == rootDrawComponent) {
if (decorator.isVisible() && (decorator.isSelected() || decorator.getLook() == ColorTheme.Look.HIGHLIGHTED)) {
decorator.onPaintConstraints(transform, g);
decorator.onPaintAnchors(transform, g);
decorator.onPaintActions(transform, g);
}
}
}
// Draw snap candidates
g.setColor(mColorSet.getHighlightedSnapGuides());
for (SnapCandidate candidate : mWidgetMotion.getSimilarMargins()) {
SnapDraw.drawSnapIndicator(transform, g, candidate);
}
g.setColor(mColorSet.getSnapGuides());
for (SnapCandidate candidate : mWidgetMotion.getSnapCandidates()) {
SnapDraw.drawSnapIndicator(transform, g, candidate);
}
for (SnapCandidate candidate : mWidgetResize.getSnapCandidates()) {
SnapDraw.drawSnapIndicator(transform, g, candidate);
}
if (mSelection.hasSingleElement() && selectedAnchor != null) {
ConstraintAnchor anchor = mSelection.getConnectionCandidateAnchor();
ConstraintHandle selectedHandle = WidgetInteractionTargets.constraintHandle(selectedAnchor);
g.setColor(mColorSet.getHighlightedConstraints());
if (!selectedHandle.getAnchor().isConnected() || selectedHandle.getAnchor().getTarget() != anchor) {
Point lastPoint = mouseInteraction.getLastPoint();
if (lastPoint.x != 0 && lastPoint.y != 0) {
selectedHandle.drawConnection(transform, g, mColorSet, true, mouseInteraction.getLastPoint());
}
}
}
if (selectedResizeHandle != null) {
g.setColor(mColorSet.getSelectionColor());
WidgetDraw.drawResizeHandleSelection(transform, g, selectedResizeHandle);
}
if (mSelection.isEmpty() && mouseInteraction.isMouseDown()) {
Point startPoint = mouseInteraction.getStartPoint();
Point lastMousePosition = mouseInteraction.getLastPoint();
// draw a selection rect
int x1 = Math.min(startPoint.x, lastMousePosition.x);
int x2 = Math.max(startPoint.x, lastMousePosition.x);
int y1 = Math.min(startPoint.y, lastMousePosition.y);
int y2 = Math.max(startPoint.y, lastMousePosition.y);
int ax1 = transform.getSwingX(x1);
int ax2 = transform.getSwingX(x2);
int ay1 = transform.getSwingY(y1);
int ay2 = transform.getSwingY(y2);
int w = x2 - x1;
int h = y2 - y1;
if (w > 0 || h > 0) {
g.setColor(mColorSet.getSelectionColor());
g.setStroke(SnapDraw.sDashedStroke);
if (w >= 8 && h >= 8) {
g.drawRect(ax1, ay1, ax2 - ax1, ay2 - ay1);
} else if (w >= 8 && h < 8) {
g.drawLine(ax1, ay1, ax2, ay1);
} else {
g.drawLine(ax1, ay1, ax1, ay2);
}
g.setStroke(SnapDraw.sNormalStroke);
if (w >= 8) {
ConnectionDraw.drawHorizontalMarginIndicator(g, String.valueOf(w), ax1, ax2, ay1 - 20);
}
if (h >= 8) {
ConnectionDraw.drawVerticalMarginIndicator(g, String.valueOf(h), ax1 - 20, ay1, ay2);
}
}
}
if (mSelection.getSelectionBounds() != null) {
Selection.Element bounds = mSelection.getSelectionBounds();
g.setColor(mColorSet.getSelectionColor());
g.setStroke(SnapDraw.sDashedStroke);
int x = transform.getSwingX(bounds.widget.getDrawX());
int y = transform.getSwingY(bounds.widget.getDrawY());
int w = transform.getSwingDimension(bounds.widget.getDrawWidth());
int h = transform.getSwingDimension(bounds.widget.getDrawHeight());
g.drawRect(x, y, w, h);
}
needsRepaint |= mChoreographer.onPaint(transform, g);
if (!needsRepaint && !mSelection.isEmpty()) {
for (Selection.Element element : mSelection.getElements()) {
needsRepaint |= element.widget.isAnimating();
}
}
if (!needsRepaint) {
for (ConstraintWidget widget : mWidgetsScene.getWidgets()) {
needsRepaint |= widget.isAnimating();
}
}
if (needsRepaint) {
repaint();
}
return needsRepaint;
}
use of com.android.tools.sherpa.structure.Selection in project android by JetBrains.
the class ConstraintModel method onSelectionChanged.
/**
* Something has changed in our selection
*
* @param selection our internal selection object
*/
@Override
public void onSelectionChanged(Selection selection) {
SelectionModel selectionModel = myNlModel.getSelectionModel();
if (selection.isEmpty()) {
selectionModel.clear();
return;
}
List<NlComponent> components = new ArrayList<>();
for (Selection.Element selectedElement : mySelection.getElements()) {
if (selectedElement.widget == myDragDropWidget) {
continue;
}
WidgetCompanion companion = (WidgetCompanion) selectedElement.widget.getCompanionWidget();
NlComponent component = (NlComponent) companion.getWidgetModel();
components.add(component);
}
if (!components.isEmpty()) {
selectionModel.setSelection(components);
} else {
selectionModel.clear();
}
}
use of com.android.tools.sherpa.structure.Selection in project android by JetBrains.
the class ConstraintModel method saveToXML.
/**
* Always save the model to xml
*/
public void saveToXML(boolean forceSave) {
Selection selection = getSelection();
if (forceSave || !selection.getModifiedWidgets().isEmpty()) {
ourLock.lock();
myModificationCount++;
ourLock.unlock();
if (DEBUG) {
System.out.println("Model Saved to XML -> " + myModificationCount + "(" + selection.getModifiedWidgets().size() + " elements modified)");
}
ConstraintUtilities.saveModelToXML(myNlModel, true);
selection.clearModifiedWidgets();
requestRender();
}
}
Aggregations