blob: 9379d2897d29215770248f352b80b51538b25876 [file] [log] [blame]
/*
* 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);
}
}
}
});
}
}