From 648767bd5dfa92bf45dddd1c2837128ff0dd58eb Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Sat, 31 Mar 2012 22:14:28 +0400 Subject: [PATCH] FrameLayout --- .../AndroidDesignerEditorPanel.java | 16 +- .../layout/FrameLayoutMarginOperation.java | 203 ++++++++++++++++++ .../layout/FrameLayoutOperation.java | 47 +--- .../designSurface/layout/ResizeOperation.java | 54 ++--- .../designer/model/layout/RadFrameLayout.java | 50 ++++- .../model/scroll/RadScrollViewComponent.java | 2 +- .../designer/DesignerToolWindowManager.java | 6 +- .../actions/CommonEditActionsProvider.java | 2 +- .../designSurface/DesignerEditorPanel.java | 8 +- .../feedbacks/LineMarginBorder.java | 35 +++ .../designSurface/feedbacks/TextFeedback.java | 57 +++++ .../selection/DirectionResizePoint.java | 19 +- .../designSurface/selection/ResizePoint.java | 2 + .../designSurface/tools/ToolProvider.java | 2 +- .../designer/propertyTable/PropertyTable.java | 6 +- 15 files changed, 414 insertions(+), 95 deletions(-) create mode 100644 plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutMarginOperation.java create mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/LineMarginBorder.java create mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/TextFeedback.java diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java index ec3e3b4df16c..d192cdae870d 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java @@ -96,7 +96,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { myPSIChangeListener.addRequest(new Runnable() { @Override public void run() { - updateRenderer(); + updateRenderer(true); } }); } @@ -147,7 +147,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { myLayeredPane.repaint(); - DesignerToolWindowManager.getInstance(getProject()).refresh(); + DesignerToolWindowManager.getInstance(getProject()).refresh(true); } } catch (Throwable e) { @@ -177,7 +177,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { showDesignerCard(); myLayeredPane.repaint(); - DesignerToolWindowManager.getInstance(getProject()).refresh(); + DesignerToolWindowManager.getInstance(getProject()).refresh(true); } }); } @@ -215,7 +215,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { }); } - private void updateRenderer() { + private void updateRenderer(final boolean updateProperties) { myParseTime = true; final String layoutXmlText = ApplicationManager.getApplication().runReadAction(new Computable() { @Override @@ -240,7 +240,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { myLayeredPane.repaint(); - DesignerToolWindowManager.getInstance(getProject()).refresh(); + DesignerToolWindowManager.getInstance(getProject()).refresh(updateProperties); } }); } @@ -430,11 +430,11 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { } @Override - protected boolean execute(ThrowableRunnable operation) { + protected boolean execute(ThrowableRunnable operation, boolean updateProperties) { try { myPSIChangeListener.stop(); operation.run(); - updateRenderer(); + updateRenderer(updateProperties); return true; } catch (Throwable e) { @@ -453,7 +453,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { for (EditOperation operation : operations) { operation.execute(); } - updateRenderer(); + updateRenderer(true); } catch (Throwable e) { showError("Execute command", e); diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutMarginOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutMarginOperation.java new file mode 100644 index 000000000000..de16f10b98fe --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutMarginOperation.java @@ -0,0 +1,203 @@ +/* + * 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.intellij.android.designer.model.RadViewComponent; +import com.intellij.android.designer.model.layout.RadFrameLayout; +import com.intellij.designer.designSurface.EditOperation; +import com.intellij.designer.designSurface.FeedbackLayer; +import com.intellij.designer.designSurface.OperationContext; +import com.intellij.designer.designSurface.feedbacks.LineMarginBorder; +import com.intellij.designer.designSurface.feedbacks.RectangleComponent; +import com.intellij.designer.designSurface.feedbacks.TextFeedback; +import com.intellij.designer.designSurface.selection.DirectionResizePoint; +import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; +import com.intellij.designer.model.RadComponent; +import com.intellij.designer.utils.Position; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; + +import java.awt.*; +import java.util.List; + +/** + * @author Alexander Lobas + */ +public class FrameLayoutMarginOperation implements EditOperation { + public static final String TYPE = "frame_layout_margin"; + + private final OperationContext myContext; + private RadViewComponent myComponent; + private RectangleComponent myFeedback; + private TextFeedback myTextFeedback; + + public FrameLayoutMarginOperation(OperationContext context) { + myContext = context; + } + + public static void points(ResizeSelectionDecorator decorator) { + decorator.addPoint(new DirectionResizePoint(Color.orange, Color.black, Position.WEST, TYPE)); // left + decorator.addPoint(new DirectionResizePoint(Color.orange, Color.black, Position.EAST, TYPE).move(1, 0.25)); // right + decorator.addPoint(new DirectionResizePoint(Color.orange, Color.black, Position.NORTH, TYPE)); // top + decorator.addPoint(new DirectionResizePoint(Color.orange, Color.black, Position.SOUTH, TYPE).move(0.25, 1)); // bottom + } + + public static boolean visible(RadComponent component, DirectionResizePoint point) { + Pair gravity = RadFrameLayout.gravity(component); + int direction = point.getDirection(); + + if (direction == Position.WEST) { // left + return gravity.first == Gravity.left || gravity.first == Gravity.center; + } + else if (direction == Position.EAST) { // right + return gravity.first == Gravity.right || gravity.first == Gravity.center; + } + else if (direction == Position.NORTH) { // top + return gravity.second == Gravity.top || gravity.second == Gravity.center; + } + else if (direction == Position.SOUTH) { // bottom + return gravity.second == Gravity.bottom || gravity.second == Gravity.center; + } + return true; + } + + @Override + public void setComponent(RadComponent component) { + myComponent = (RadViewComponent)component; + } + + @Override + public void setComponents(List components) { + } + + private void createFeedback() { + if (myFeedback == null) { + FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); + + myTextFeedback = new TextFeedback(); + myTextFeedback.setBorder(new LineMarginBorder(0, 5, 3, 0)); + layer.add(myTextFeedback); + + myFeedback = new RectangleComponent(Color.orange, 2); + layer.add(myFeedback); + + layer.repaint(); + } + } + + @Override + public void showFeedback() { + createFeedback(); + + myFeedback.setBounds(myContext.getTransformedRectangle(myComponent.getBounds(myContext.getArea().getFeedbackLayer()))); + + Point moveDelta = myContext.getMoveDelta(); + Dimension sizeDelta = myContext.getSizeDelta(); + int direction = myContext.getResizeDirection(); + + myTextFeedback.clear(); + + if (direction == Position.WEST) { // left + myTextFeedback.append(Integer.toString(-moveDelta.x)); + } + else if (direction == Position.EAST) { // right + myTextFeedback.append(Integer.toString(sizeDelta.width)); + } + else if (direction == Position.NORTH) { // top + myTextFeedback.append(Integer.toString(-moveDelta.y)); + } + else if (direction == Position.SOUTH) { // bottom + myTextFeedback.append(Integer.toString(sizeDelta.height)); + } + + myTextFeedback.dimension("dp"); + myTextFeedback.locationTo(myContext.getLocation(), 15); + } + + @Override + public void eraseFeedback() { + if (myFeedback != null) { + FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); + layer.remove(myTextFeedback); + layer.remove(myFeedback); + + layer.repaint(); + + myTextFeedback = null; + myFeedback = null; + } + } + + @Override + public boolean canExecute() { + return true; + } + + @Override + public void execute() throws Exception { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + XmlTag tag = myComponent.getTag(); + + XmlAttribute margin = tag.getAttribute("android:layout_margin"); + if (margin != null) { + String value = margin.getValue(); + margin.delete(); + + if (!StringUtil.isEmpty(value)) { + tag.setAttribute("android:layout_marginLeft", value); + tag.setAttribute("android:layout_marginRight", value); + tag.setAttribute("android:layout_marginTop", value); + tag.setAttribute("android:layout_marginBottom", value); + } + } + + Point moveDelta = myContext.getMoveDelta(); + Dimension sizeDelta = myContext.getSizeDelta(); + int direction = myContext.getResizeDirection(); + + if (direction == Position.WEST) { // left + setValue(tag, "android:layout_marginLeft", -moveDelta.x); + } + else if (direction == Position.EAST) { // right + setValue(tag, "android:layout_marginRight", sizeDelta.width); + } + else if (direction == Position.NORTH) { // top + setValue(tag, "android:layout_marginTop", -moveDelta.y); + } + else if (direction == Position.SOUTH) { // bottom + setValue(tag, "android:layout_marginBottom", sizeDelta.height); + } + } + }); + } + + private static void setValue(XmlTag tag, String name, int value) { + if (value == 0) { + XmlAttribute attribute = tag.getAttribute(name); + if (attribute != null) { + attribute.delete(); + } + } + else { + tag.setAttribute(name, Integer.toString(value) + "dp"); + } + } +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutOperation.java index d065b669ea97..aef24ab7b0ce 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/FrameLayoutOperation.java @@ -17,9 +17,11 @@ package com.intellij.android.designer.designSurface.layout; import com.intellij.android.designer.designSurface.AbstractEditOperation; import com.intellij.android.designer.model.RadViewComponent; +import com.intellij.android.designer.model.layout.RadFrameLayout; import com.intellij.designer.designSurface.FeedbackLayer; import com.intellij.designer.designSurface.OperationContext; import com.intellij.designer.designSurface.feedbacks.AlphaComponent; +import com.intellij.designer.designSurface.feedbacks.TextFeedback; import com.intellij.designer.model.RadComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Pair; @@ -28,7 +30,6 @@ import com.intellij.ui.LightColors; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.awt.*; import java.util.Collections; import java.util.Set; @@ -38,7 +39,7 @@ import java.util.Set; */ public class FrameLayoutOperation extends AbstractEditOperation { private GravityFeedback myFeedback; - private JLabel myTextFeedback; + private TextFeedback myTextFeedback; private String myGravity; private Set> myExcludes = Collections.emptySet(); @@ -49,32 +50,7 @@ public class FrameLayoutOperation extends AbstractEditOperation { myExcludes = new HashSet>(); for (RadComponent component : context.getComponents()) { - String value = ((RadViewComponent)component).getTag().getAttributeValue("android:layout_gravity"); - int flags = Gravity.getFlags(value); - - Gravity horizontal = Gravity.left; - if ((flags & Gravity.LEFT) != 0) { - horizontal = Gravity.left; - } - else if ((flags & Gravity.CENTER_HORIZONTAL) != 0) { - horizontal = Gravity.center; - } - else if ((flags & Gravity.RIGHT) != 0) { - horizontal = Gravity.right; - } - - Gravity vertical = Gravity.top; - if ((flags & Gravity.TOP) != 0) { - vertical = Gravity.top; - } - else if ((flags & Gravity.CENTER_VERTICAL) != 0) { - vertical = Gravity.center; - } - else if ((flags & Gravity.BOTTOM) != 0) { - vertical = Gravity.bottom; - } - - myExcludes.add(new Pair(horizontal, vertical)); + myExcludes.add(RadFrameLayout.gravity(component)); } } } @@ -87,11 +63,8 @@ public class FrameLayoutOperation extends AbstractEditOperation { myFeedback.setBounds(bounds); layer.add(myFeedback); - myTextFeedback = new JLabel(); - myTextFeedback.setFont(myTextFeedback.getFont().deriveFont(Font.BOLD)); - myTextFeedback.setBackground(LightColors.YELLOW); + myTextFeedback = new TextFeedback(); myTextFeedback.setBorder(IdeBorderFactory.createEmptyBorder(0, 3, 2, 0)); - myTextFeedback.setOpaque(true); layer.add(myTextFeedback); layer.repaint(); @@ -119,16 +92,16 @@ public class FrameLayoutOperation extends AbstractEditOperation { } private void configureTextFeedback(Rectangle bounds, Gravity horizontal, Gravity vertical) { + myTextFeedback.clear(); + if (horizontal == null || vertical == null) { - myTextFeedback.setText("None"); + myTextFeedback.bold("None"); } else { - myTextFeedback.setText("[" + vertical.name() + ", " + horizontal.name() + "]"); + myTextFeedback.bold("[" + vertical.name() + ", " + horizontal.name() + "]"); } - Dimension textSize = myTextFeedback.getPreferredSize(); - myTextFeedback - .setBounds(bounds.x + bounds.width / 2 - textSize.width / 2, bounds.y - textSize.height - 10, textSize.width, textSize.height); + myTextFeedback.centerTop(bounds); } @Nullable diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/ResizeOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/ResizeOperation.java index 18d46e69b444..fe4bdf363444 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/ResizeOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/ResizeOperation.java @@ -20,20 +20,18 @@ import com.intellij.android.designer.propertyTable.renderers.ResourceRenderer; import com.intellij.designer.designSurface.EditOperation; import com.intellij.designer.designSurface.FeedbackLayer; import com.intellij.designer.designSurface.OperationContext; +import com.intellij.designer.designSurface.feedbacks.LineMarginBorder; import com.intellij.designer.designSurface.feedbacks.RectangleComponent; +import com.intellij.designer.designSurface.feedbacks.TextFeedback; import com.intellij.designer.designSurface.selection.DirectionResizePoint; import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; import com.intellij.designer.model.RadComponent; import com.intellij.designer.utils.Position; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Pair; -import com.intellij.ui.Colors; -import com.intellij.ui.LightColors; -import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.ArrayUtil; -import javax.swing.border.EmptyBorder; import java.awt.*; import java.util.List; @@ -43,8 +41,7 @@ import java.util.List; public class ResizeOperation implements EditOperation { public static final String TYPE = "resize_children"; - private static SimpleTextAttributes DIMENSION_ATTRIBUTES = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Color.lightGray); - private static SimpleTextAttributes SNAP_ATTRIBUTES = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Colors.DARK_GREEN); + private final static Color blue = new Color(0, 50, 255); private static final int SNAP_DELTA = 4; private static final int WRAP_CONTENT = 0 << 30; @@ -54,7 +51,7 @@ public class ResizeOperation implements EditOperation { private RectangleComponent myWrapFeedback; private RectangleComponent myFillFeedback; private RectangleComponent myFeedback; - private SimpleColoredComponent myTextFeedback; + private TextFeedback myTextFeedback; private String myStaticWidth; private String myStaticHeight; @@ -64,16 +61,16 @@ public class ResizeOperation implements EditOperation { private Rectangle myBounds; - public static void points(ResizeSelectionDecorator decorator) { - decorator.addPoint(new DirectionResizePoint(Position.EAST, TYPE)); - decorator.addPoint(new DirectionResizePoint(Position.SOUTH, TYPE)); - decorator.addPoint(new DirectionResizePoint(Position.SOUTH_EAST, TYPE)); - } - public ResizeOperation(OperationContext context) { myContext = context; } + public static void points(ResizeSelectionDecorator decorator) { + decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE)); + decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE)); + decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH_EAST, TYPE)); + } + @Override public void setComponent(RadComponent component) { myComponent = (RadViewComponent)component; @@ -193,17 +190,8 @@ public class ResizeOperation implements EditOperation { myFeedback = new RectangleComponent(Color.blue, 2); layer.add(myFeedback); - myTextFeedback = new SimpleColoredComponent(); - myTextFeedback.setBackground(LightColors.YELLOW); - myTextFeedback.setBorder(new EmptyBorder(0, 5, 3, 0) { - @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - Color oldColor = g.getColor(); - g.setColor(Color.darkGray); - g.drawRect(x, y, width - 1, height - 1); - g.setColor(oldColor); - } - }); + myTextFeedback = new TextFeedback(); + myTextFeedback.setBorder(new LineMarginBorder(0, 5, 3, 0)); layer.add(myTextFeedback); layer.add(myWrapFeedback); layer.add(myFillFeedback); @@ -214,12 +202,9 @@ public class ResizeOperation implements EditOperation { @Override public void showFeedback() { - FeedbackLayer layer = myContext.getArea().getFeedbackLayer(); - createFeedback(); - myBounds = myContext.getTransformedRectangle(myComponent.getBounds(layer)); - + myBounds = myContext.getTransformedRectangle(myComponent.getBounds(myContext.getArea().getFeedbackLayer())); int direction = myContext.getResizeDirection(); if ((direction & Position.EAST) != 0) { @@ -236,26 +221,25 @@ public class ResizeOperation implements EditOperation { myFeedback.setBounds(myBounds); myTextFeedback.clear(); + addTextSize(myStaticWidth, myBounds.width, myWrapSize.width, myFillSize.width); myTextFeedback.append(" x ", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); addTextSize(myStaticHeight, myBounds.height, myWrapSize.height, myFillSize.height); - Dimension textSize = myTextFeedback.getPreferredSize(); - Point location = myContext.getLocation(); - myTextFeedback.setBounds(location.x + 15, location.y + 15, textSize.width, textSize.height); + myTextFeedback.locationTo(myContext.getLocation(), 15); } private void addTextSize(String staticText, int size, int wrap, int fill) { if (staticText == null) { if (size == wrap) { - myTextFeedback.append("wrap_content", SNAP_ATTRIBUTES); + myTextFeedback.snap("wrap_content"); } else if (size == fill) { - myTextFeedback.append("match_parent", SNAP_ATTRIBUTES); + myTextFeedback.snap("match_parent"); } else { myTextFeedback.append(Integer.toString(size)); - myTextFeedback.append("dp", DIMENSION_ATTRIBUTES); + myTextFeedback.dimension("dp"); } } else { @@ -264,7 +248,7 @@ public class ResizeOperation implements EditOperation { String dimension = staticText.substring(index); if (ArrayUtil.indexOf(ResourceRenderer.DIMENSIONS, dimension) != -1) { myTextFeedback.append(staticText.substring(0, index)); - myTextFeedback.append(dimension, DIMENSION_ATTRIBUTES); + myTextFeedback.dimension(dimension); } else { myTextFeedback.append(staticText); diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/RadFrameLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/RadFrameLayout.java index fca8e7060f3f..d53778d4dd61 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/RadFrameLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/RadFrameLayout.java @@ -16,7 +16,9 @@ package com.intellij.android.designer.model.layout; import com.intellij.android.designer.designSurface.TreeDropToOperation; +import com.intellij.android.designer.designSurface.layout.FrameLayoutMarginOperation; import com.intellij.android.designer.designSurface.layout.FrameLayoutOperation; +import com.intellij.android.designer.designSurface.layout.Gravity; import com.intellij.android.designer.designSurface.layout.ResizeOperation; import com.intellij.android.designer.model.RadViewComponent; import com.intellij.android.designer.model.RadViewLayoutWithData; @@ -24,9 +26,12 @@ import com.intellij.designer.designSurface.ComponentDecorator; import com.intellij.designer.designSurface.DesignerEditorPanel; import com.intellij.designer.designSurface.EditOperation; import com.intellij.designer.designSurface.OperationContext; +import com.intellij.designer.designSurface.selection.DirectionResizePoint; +import com.intellij.designer.designSurface.selection.ResizePoint; import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; import com.intellij.designer.model.RadComponent; import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.util.Pair; import javax.swing.*; import java.awt.*; @@ -54,13 +59,27 @@ public class RadFrameLayout extends RadViewLayoutWithData { else if (context.is(ResizeOperation.TYPE)) { return new ResizeOperation(context); } + else if (context.is(FrameLayoutMarginOperation.TYPE)) { + return new FrameLayoutMarginOperation(context); + } return null; } @Override public ComponentDecorator getChildSelectionDecorator(RadComponent component, List selection) { - ResizeSelectionDecorator decorator = new ResizeSelectionDecorator(Color.red, 1); + ResizeSelectionDecorator decorator = new ResizeSelectionDecorator(Color.red, 1) { + @Override + protected boolean visible(RadComponent component, ResizePoint point) { + if (point.getType() == FrameLayoutMarginOperation.TYPE) { + return FrameLayoutMarginOperation.visible(component, (DirectionResizePoint)point); + } + return true; + } + }; ResizeOperation.points(decorator); + if (selection.size() == 1) { + FrameLayoutMarginOperation.points(decorator); + } return decorator; } @@ -71,4 +90,33 @@ public class RadFrameLayout extends RadViewLayoutWithData { List selection) { super.addSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub } + + public static Pair gravity(RadComponent component) { + String value = ((RadViewComponent)component).getTag().getAttributeValue("android:layout_gravity"); + int flags = Gravity.getFlags(value); + + Gravity horizontal = Gravity.left; + if ((flags & Gravity.LEFT) != 0) { + horizontal = Gravity.left; + } + else if ((flags & Gravity.CENTER_HORIZONTAL) != 0) { + horizontal = Gravity.center; + } + else if ((flags & Gravity.RIGHT) != 0) { + horizontal = Gravity.right; + } + + Gravity vertical = Gravity.top; + if ((flags & Gravity.TOP) != 0) { + vertical = Gravity.top; + } + else if ((flags & Gravity.CENTER_VERTICAL) != 0) { + vertical = Gravity.center; + } + else if ((flags & Gravity.BOTTOM) != 0) { + vertical = Gravity.bottom; + } + + return new Pair(horizontal, vertical); + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/scroll/RadScrollViewComponent.java b/plugins/android-designer/src/com/intellij/android/designer/model/scroll/RadScrollViewComponent.java index ec3bb1f1ce0e..945ff4c4d90d 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/scroll/RadScrollViewComponent.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/scroll/RadScrollViewComponent.java @@ -73,7 +73,7 @@ public class RadScrollViewComponent extends RadViewComponent { // TODO: maybe reload properties } - }); + }, true); } }); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java index 690475b3e658..939c388db020 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java @@ -20,7 +20,6 @@ import com.intellij.designer.componentTree.ComponentTreeBuilder; import com.intellij.designer.componentTree.TreeEditableArea; import com.intellij.designer.designSurface.DesignerEditorPanel; import com.intellij.designer.propertyTable.PropertyTablePanel; -import com.intellij.ide.util.treeView.AbstractTreeBuilder; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.components.ProjectComponent; @@ -119,12 +118,15 @@ public final class DesignerToolWindowManager implements ProjectComponent { return project.getComponent(DesignerToolWindowManager.class); } - public void refresh() { + public void refresh(final boolean updateProperties) { if (myTreeBuilder != null) { myTreeBuilder.queueUpdate().doWhenDone(new Runnable() { @Override public void run() { myComponentTree.repaint(); + if (updateProperties) { + myPropertyTablePanel.getPropertyTable().updateProperties(); + } } }); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java index 927ae68ee52f..64843a768ed4 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java @@ -96,7 +96,7 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider, area.select(newSelection); } } - }); + }, true); } }, DesignerBundle.message("command.delete.selection"), null); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java index 50894cdb4e9e..0c812dac1bf2 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java @@ -211,8 +211,8 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider } @Override - public boolean execute(ThrowableRunnable operation) { - return DesignerEditorPanel.this.execute(operation); + public boolean execute(ThrowableRunnable operation, boolean updateProperties) { + return DesignerEditorPanel.this.execute(operation, updateProperties); } @Override @@ -343,7 +343,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider myLayout.show(this, ERROR_CARD); - DesignerToolWindowManager.getInstance(getProject()).refresh(); + DesignerToolWindowManager.getInstance(getProject()).refresh(true); repaint(); } @@ -383,7 +383,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider @Nullable protected abstract EditOperation processRootOperation(OperationContext context); - protected abstract boolean execute(ThrowableRunnable operation); + protected abstract boolean execute(ThrowableRunnable operation, boolean updateProperties); protected abstract void execute(List operations); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/LineMarginBorder.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/LineMarginBorder.java new file mode 100644 index 000000000000..e28f5cfc302a --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/LineMarginBorder.java @@ -0,0 +1,35 @@ +/* + * 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.designer.designSurface.feedbacks; + +import javax.swing.border.EmptyBorder; +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class LineMarginBorder extends EmptyBorder { + public LineMarginBorder(int top, int left, int bottom, int right) { + super(top, left, bottom, right); + } + + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Color oldColor = g.getColor(); + g.setColor(Color.darkGray); + g.drawRect(x, y, width - 1, height - 1); + g.setColor(oldColor); + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/TextFeedback.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/TextFeedback.java new file mode 100644 index 000000000000..134a1f7d76fb --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/feedbacks/TextFeedback.java @@ -0,0 +1,57 @@ +/* + * 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.designer.designSurface.feedbacks; + +import com.intellij.ui.Colors; +import com.intellij.ui.LightColors; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class TextFeedback extends SimpleColoredComponent { + private static SimpleTextAttributes DIMENSION_ATTRIBUTES = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Color.lightGray); + private static SimpleTextAttributes SNAP_ATTRIBUTES = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Colors.DARK_GREEN); + + public TextFeedback() { + setBackground(LightColors.YELLOW); + } + + public void bold(String text) { + append(text, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + } + + public void dimension(String text) { + append(text, DIMENSION_ATTRIBUTES); + } + + public void snap(String text) { + append(text, SNAP_ATTRIBUTES); + } + + public void centerTop(Rectangle bounds) { + Dimension textSize = getPreferredSize(); + setBounds(bounds.x + bounds.width / 2 - textSize.width / 2, bounds.y - textSize.height - 10, textSize.width, textSize.height); + } + + public void locationTo(Point location, int shift) { + Dimension textSize = getPreferredSize(); + setBounds(location.x + shift, location.y + shift, textSize.width, textSize.height); + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/DirectionResizePoint.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/DirectionResizePoint.java index 37ee2c0596a8..d05245e07d1d 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/DirectionResizePoint.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/DirectionResizePoint.java @@ -69,6 +69,21 @@ public class DirectionResizePoint extends ResizePoint { } } + public DirectionResizePoint move(double xSeparator, double ySeparator) { + myXSeparator = xSeparator; + myYSeparator = ySeparator; + return this; + } + + public int getDirection() { + return myDirection; + } + + @Override + public Object getType() { + return myType; + } + @Override protected InputTool createTool(RadComponent component) { return new ResizeTracker(myDirection, myType); @@ -78,8 +93,8 @@ public class DirectionResizePoint extends ResizePoint { protected Point getLocation(DecorationLayer layer, RadComponent component) { Rectangle bounds = component.getBounds(layer); int size = (getSize() + 1) / 2; - int x = bounds.x + (int) (bounds.width * myXSeparator) - size; - int y = bounds.y + (int) (bounds.height * myYSeparator) - size; + int x = bounds.x + (int)(bounds.width * myXSeparator) - size; + int y = bounds.y + (int)(bounds.height * myYSeparator) - size; return new Point(x, y); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizePoint.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizePoint.java index 9bc50ad7a3cd..f2029e9e1dcf 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizePoint.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizePoint.java @@ -62,6 +62,8 @@ public abstract class ResizePoint extends ComponentDecorator { g.drawRect(location.x, location.y, getSize(), getSize()); } + public abstract Object getType(); + protected abstract InputTool createTool(RadComponent component); protected abstract Point getLocation(DecorationLayer layer, RadComponent component); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java index 434fe67c7e1d..371605c6bbd0 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java @@ -130,7 +130,7 @@ public abstract class ToolProvider { public abstract void loadDefaultTool(); - public abstract boolean execute(ThrowableRunnable operation); + public abstract boolean execute(ThrowableRunnable operation, boolean updateProperties); public abstract void execute(List operations); } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java index 54df075ad551..f4b9bf1e5986 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java @@ -187,7 +187,7 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi } } } - }); + }, false); } }, DesignerBundle.message("designer.properties.restore_default"), null); @@ -201,7 +201,7 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi // ////////////////////////////////////////////////////////////////////////////////////////// - private void updateProperties() { + public void updateProperties() { if (mySkipUpdate) { return; } @@ -590,7 +590,7 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi property.setValue(component, newValue); } } - }); + }, false); } }, DesignerBundle.message("command.set.property.value"), null); }