/* * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.android.designer.designSurface.layout; import com.android.SdkConstants; import com.intellij.android.designer.AndroidDesignerUtils; import com.intellij.android.designer.designSurface.AbstractEditOperation; import com.intellij.android.designer.model.RadViewComponent; import com.intellij.designer.designSurface.EditableArea; import com.intellij.designer.designSurface.FeedbackLayer; import com.intellij.designer.designSurface.OperationContext; import com.intellij.designer.designSurface.feedbacks.AlphaFeedback; import com.intellij.designer.model.RadComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.xml.XmlTag; import java.awt.*; import java.util.Iterator; /** * @author Alexander Lobas */ public class AbsoluteLayoutOperation extends AbstractEditOperation { private AlphaFeedback myFeedback; private Rectangle myBounds; private Point myStartLocation; public AbsoluteLayoutOperation(RadComponent container, OperationContext context) { super(container, context); } private void createFeedback() { if (myFeedback == null) { FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); if (myContext.isCreate() || myContext.isPaste()) { myBounds = new Rectangle(0, 0, 64, 32); } else { Iterator<RadComponent> I = myComponents.iterator(); myBounds = I.next().getBounds(layer); while (I.hasNext()) { myBounds.add(I.next().getBounds(layer)); } if (myBounds.width == 0) { myBounds.width = 64; } if (myBounds.height == 0) { myBounds.height = 32; } myStartLocation = myBounds.getLocation(); } myFeedback = new AlphaFeedback(myComponents.size() == 1 ? Color.green : Color.orange); myFeedback.setSize(myBounds.width, myBounds.height); layer.add(myFeedback); layer.repaint(); } } @Override public void showFeedback() { createFeedback(); Point location = myContext.getLocation(); Dimension delta = myContext.getSizeDelta(); if (delta == null || (delta.width == 0 && delta.height == 0) || myComponents.size() > 1) { myBounds.x = location.x - myBounds.width / 2; myBounds.y = location.y - myBounds.height / 2; myFeedback.setLocation(myBounds.x, myBounds.y); } else { myBounds.width = location.x - myBounds.x; myBounds.height = location.y - myBounds.y; myFeedback.setSize(myBounds.width, myBounds.height); } } @Override public void eraseFeedback() { if (myFeedback != null) { FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); layer.remove(myFeedback); layer.repaint(); myFeedback = null; } } @Override public void execute() throws Exception { if (!myContext.isMove()) { super.execute(); } ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { EditableArea area = myContext.getArea(); FeedbackLayer layer = area.getFeedbackLayer(); Rectangle parentBounds = myContainer.getBounds(); if (myContext.isCreate() || myContext.isPaste()) { Point location = myContainer.convertPoint(layer, myBounds.x, myBounds.y); Dimension delta = myContext.getSizeDelta(); for (RadComponent component : myComponents) { XmlTag tag = ((RadViewComponent)component).getTag(); String x = AndroidDesignerUtils.pxToDpWithUnits(area, location.x - parentBounds.x); String y = AndroidDesignerUtils.pxToDpWithUnits(area, location.y - parentBounds.y); tag.setAttribute("layout_x", SdkConstants.NS_RESOURCES, x); tag.setAttribute("layout_y", SdkConstants.NS_RESOURCES, y); if (delta != null && myComponents.size() == 1) { Rectangle modelBounds = component.toModel(layer, myBounds); if (delta.width > 0) { String width = AndroidDesignerUtils.pxToDpWithUnits(area, modelBounds.width); tag.setAttribute("layout_width", SdkConstants.NS_RESOURCES, width); } if (delta.height > 0) { String height = AndroidDesignerUtils.pxToDpWithUnits(area, modelBounds.height); tag.setAttribute("layout_height", SdkConstants.NS_RESOURCES, height); } } } } else { int moveDeltaX = myBounds.x - myStartLocation.x; int moveDeltaY = myBounds.y - myStartLocation.y; for (RadComponent component : myComponents) { Rectangle bounds = component.getBounds(layer); Point location = component.convertPoint(layer, bounds.x + moveDeltaX, bounds.y + moveDeltaY); XmlTag tag = ((RadViewComponent)component).getTag(); String x = AndroidDesignerUtils.pxToDpWithUnits(area, location.x - parentBounds.x); String y = AndroidDesignerUtils.pxToDpWithUnits(area, location.y - parentBounds.y); tag.setAttribute("layout_x", SdkConstants.NS_RESOURCES, x); tag.setAttribute("layout_y", SdkConstants.NS_RESOURCES, y); } } } }); } }