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 0d0ccd7fa8d8..9dfb452b8223 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 @@ -25,8 +25,14 @@ import com.android.sdklib.IAndroidTarget; import com.intellij.android.designer.componentTree.AndroidTreeDecorator; import com.intellij.android.designer.model.RadViewComponent; import com.intellij.designer.componentTree.TreeComponentDecorator; +import com.intellij.designer.designSurface.ComponentDecorator; +import com.intellij.designer.designSurface.DecorationLayer; import com.intellij.designer.designSurface.DesignerEditorPanel; +import com.intellij.designer.designSurface.selection.DirectionResizePoint; +import com.intellij.designer.designSurface.selection.NonResizeSelectionDecorator; +import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; import com.intellij.designer.model.RadComponent; +import com.intellij.designer.utils.Position; import com.intellij.openapi.module.Module; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.android.facet.AndroidFacet; @@ -49,6 +55,7 @@ import java.util.List; * @author Alexander Lobas */ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { + private static final Object RENDERING_LOCK = new Object(); private final TreeComponentDecorator myTreeDecorator = new AndroidTreeDecorator(); private RenderSession mySession; @@ -86,7 +93,9 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { String layoutXmlText = new String(file.contentsToByteArray()); - mySession = RenderUtil.createRenderSession(module.getProject(), layoutXmlText, file, target, facet, config, xdpi, ydpi, theme); + synchronized (RENDERING_LOCK) { + mySession = RenderUtil.createRenderSession(module.getProject(), layoutXmlText, file, target, facet, config, xdpi, ydpi, theme); + } InputStream stream = file.getInputStream(); SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); @@ -182,6 +191,13 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { return myTreeDecorator; } + @Override + protected ComponentDecorator getRootSelectionDecorator() { + return new ResizeSelectionDecorator(Color.RED, 1, new DirectionResizePoint(Position.EAST), + new DirectionResizePoint(Position.SOUTH_EAST), + new DirectionResizePoint(Position.SOUTH)); + } + private static class RootView extends JComponent { private final BufferedImage myImage; diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java index e1395669ee78..2aabdf662c38 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java @@ -39,6 +39,7 @@ public class RadViewComponent extends RadComponent { if (parent != null) { parent.getChildren().add(this); } + setLayout(new RadViewLayout()); } @Override diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java new file mode 100644 index 000000000000..d2ea3d3dc5d5 --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java @@ -0,0 +1,33 @@ +/* + * 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.model; + +import com.intellij.designer.designSurface.ComponentDecorator; +import com.intellij.designer.designSurface.selection.NonResizeSelectionDecorator; +import com.intellij.designer.model.RadComponent; +import com.intellij.designer.model.RadLayout; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class RadViewLayout extends RadLayout { + @Override + public ComponentDecorator getChildSelectionDecorator(RadComponent component) { + return new NonResizeSelectionDecorator(Color.RED, 1); + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/ComponentDecorator.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/ComponentDecorator.java new file mode 100644 index 000000000000..82202b6b3fb9 --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/ComponentDecorator.java @@ -0,0 +1,32 @@ +/* + * 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; + +import com.intellij.designer.designSurface.tools.InputTool; +import com.intellij.designer.model.RadComponent; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public interface ComponentDecorator { + @Nullable + InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y); + + void decorate(DecorationLayer layer, Graphics2D g, RadComponent component); +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DecorationLayer.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DecorationLayer.java index da18beb5e39d..fa0e1ddf9ef1 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DecorationLayer.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DecorationLayer.java @@ -15,7 +15,9 @@ */ package com.intellij.designer.designSurface; +import com.intellij.designer.designSurface.tools.InputTool; import com.intellij.designer.model.RadComponent; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -32,15 +34,42 @@ public class DecorationLayer extends JComponent { @Override public void paint(Graphics g) { - g.setColor(Color.RED); - ((Graphics2D)g).setStroke(new BasicStroke(2)); - - for (RadComponent component : myArea.getSelection()) { - Rectangle bounds = component.getBounds(); - Point location = component.convertPoint(bounds.x, bounds.y, this); - g.drawRect(location.x, location.y, bounds.width, bounds.height); - } - + painSelection((Graphics2D)g); paintChildren(g); } + + @Nullable + public InputTool findTargetTool(int x, int y) { + for (RadComponent component : myArea.getSelection()) { + ComponentDecorator decorator = getDecorator(component); + InputTool tracker = decorator.findTargetTool(this, component, x, y); + if (tracker != null) { + return tracker; + } + } + return null; + } + + private void painSelection(Graphics2D g) { + for (RadComponent component : myArea.getSelection()) { + ComponentDecorator decorator = getDecorator(component); + // TODO: set component clipping + decorator.decorate(this, g, component); + // TODO: restore Graphics state: color, font, stroke etc. + } + } + + private ComponentDecorator getDecorator(RadComponent component) { + RadComponent parent = component.getParent(); + if (parent == null) { + return myArea.getRootSelectionDecorator(); + } + return parent.getLayout().getChildSelectionDecorator(component); + } + + public Rectangle getComponentBounds(RadComponent component) { + Rectangle bounds = component.getBounds(); + Point location = component.convertPoint(bounds.x, bounds.y, this); + return new Rectangle(location.x, location.y, bounds.width, bounds.height); + } } \ No newline at end of file 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 c03325a2b295..1e05421a3c0e 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 @@ -55,6 +55,7 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider private JScrollPane myScrollPane; protected JLayeredPane myLayeredPane; private GlassLayer myGlassLayer; + private DecorationLayer myDecorationLayer; private InputTool myTool; protected EditableArea mySurfaceArea; @@ -89,6 +90,7 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider myDesignerCard.add(myHorizontalCaption, gbc); myLayeredPane = new MyLayeredPane(); + mySurfaceArea = new EditableArea() { @Override public void setCursor(Cursor cursor) { @@ -116,10 +118,23 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider } return null; } + + @Override + public InputTool findTargetTool(int x, int y) { + return myDecorationLayer.findTargetTool(x, y); + } + + @Override + public ComponentDecorator getRootSelectionDecorator() { + return DesignerEditorPanel.this.getRootSelectionDecorator(); + } }; + myGlassLayer = new GlassLayer(this, mySurfaceArea); myLayeredPane.add(myGlassLayer, LAYER_GLASS); - myLayeredPane.add(new DecorationLayer(mySurfaceArea), LAYER_DECORATION); + + myDecorationLayer = new DecorationLayer(mySurfaceArea); + myLayeredPane.add(myDecorationLayer, LAYER_DECORATION); gbc.gridx = 1; gbc.gridy = 1; @@ -144,6 +159,8 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider return mySurfaceArea; } + protected abstract ComponentDecorator getRootSelectionDecorator(); + public InputTool getActiveTool() { return myTool; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/EditableArea.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/EditableArea.java index 83bf074f19b3..b733096a3d56 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/EditableArea.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/EditableArea.java @@ -15,6 +15,7 @@ */ package com.intellij.designer.designSurface; +import com.intellij.designer.designSurface.tools.InputTool; import com.intellij.designer.model.RadComponent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -85,4 +86,9 @@ public abstract class EditableArea { @Nullable public abstract RadComponent findTarget(int x, int y); + + @Nullable + public abstract InputTool findTargetTool(int x, int y); + + public abstract ComponentDecorator getRootSelectionDecorator(); } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/GlassLayer.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/GlassLayer.java index 90c2c6631122..7ecae96e4059 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/GlassLayer.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/GlassLayer.java @@ -37,6 +37,7 @@ public final class GlassLayer extends JComponent implements PopupOwner, DataProv myToolProvider = provider; myArea = area; enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); + // TODO: DND } @Override @@ -44,16 +45,18 @@ public final class GlassLayer extends JComponent implements PopupOwner, DataProv try { InputTool tool = myToolProvider.getActiveTool(); - switch (event.getID()) { - case KeyEvent.KEY_PRESSED: - tool.keyPressed(event, myArea); - break; - case KeyEvent.KEY_TYPED: - tool.keyTyped(event, myArea); - break; - case KeyEvent.KEY_RELEASED: - tool.keyReleased(event, myArea); - break; + if (tool != null) { + switch (event.getID()) { + case KeyEvent.KEY_PRESSED: + tool.keyPressed(event, myArea); + break; + case KeyEvent.KEY_TYPED: + tool.keyTyped(event, myArea); + break; + case KeyEvent.KEY_RELEASED: + tool.keyReleased(event, myArea); + break; + } } } catch (Throwable e) { @@ -72,24 +75,26 @@ public final class GlassLayer extends JComponent implements PopupOwner, DataProv try { InputTool tool = myToolProvider.getActiveTool(); - switch (event.getID()) { - case MouseEvent.MOUSE_PRESSED: - tool.mouseDown(event, myArea); - break; - case MouseEvent.MOUSE_RELEASED: - tool.mouseUp(event, myArea); - break; - case MouseEvent.MOUSE_ENTERED: - tool.mouseEntered(event, myArea); - break; - case MouseEvent.MOUSE_EXITED: - tool.mouseExited(event, myArea); - break; - case MouseEvent.MOUSE_CLICKED: - if (event.getClickCount() == 2) { - tool.mouseDoubleClick(event, myArea); - } - break; + if (tool != null) { + switch (event.getID()) { + case MouseEvent.MOUSE_PRESSED: + tool.mouseDown(event, myArea); + break; + case MouseEvent.MOUSE_RELEASED: + tool.mouseUp(event, myArea); + break; + case MouseEvent.MOUSE_ENTERED: + tool.mouseEntered(event, myArea); + break; + case MouseEvent.MOUSE_EXITED: + tool.mouseExited(event, myArea); + break; + case MouseEvent.MOUSE_CLICKED: + if (event.getClickCount() == 2) { + tool.mouseDoubleClick(event, myArea); + } + break; + } } } catch (Throwable e) { @@ -102,13 +107,15 @@ public final class GlassLayer extends JComponent implements PopupOwner, DataProv try { InputTool tool = myToolProvider.getActiveTool(); - switch (event.getID()) { - case MouseEvent.MOUSE_MOVED: - tool.mouseMove(event, myArea); - break; - case MouseEvent.MOUSE_DRAGGED: - tool.mouseDrag(event, myArea); - break; + if (tool != null) { + switch (event.getID()) { + case MouseEvent.MOUSE_MOVED: + tool.mouseMove(event, myArea); + break; + case MouseEvent.MOUSE_DRAGGED: + tool.mouseDrag(event, myArea); + break; + } } } catch (Throwable e) { 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 new file mode 100644 index 000000000000..038ae1189ba8 --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/DirectionResizePoint.java @@ -0,0 +1,83 @@ +/* + * 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.selection; + +import com.intellij.designer.designSurface.DecorationLayer; +import com.intellij.designer.designSurface.tools.InputTool; +import com.intellij.designer.designSurface.tools.ResizeTracker; +import com.intellij.designer.model.RadComponent; +import com.intellij.designer.utils.Position; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class DirectionResizePoint extends ResizePoint { + private int myDirection; + private double myXSeparator; + private double myYSeparator; + + public DirectionResizePoint(int direction) { + setDirection(direction); + } + + public DirectionResizePoint(Color color, Color border, int direction) { + super(color, border); + setDirection(direction); + } + + private void setDirection(int direction) { + myDirection = direction; + + int yDirection = myDirection & Position.EAST_WEST; + if (yDirection == Position.WEST) { + myXSeparator = 0; + } + else if (yDirection == Position.EAST) { + myXSeparator = 1; + } + else { + myXSeparator = 0.5; + } + + int xDirection = myDirection & Position.NORTH_SOUTH; + if (xDirection == Position.NORTH) { + myYSeparator = 0; + } + else if (xDirection == Position.SOUTH) { + myYSeparator = 1; + } + else { + myYSeparator = 0.5; + } + } + + @Override + protected InputTool createTool(RadComponent component) { + return new ResizeTracker(myDirection); + } + + @Override + protected Point getLocation(DecorationLayer layer, RadComponent component) { + Rectangle bounds = layer.getComponentBounds(component); + int size = (getSize() + 1) / 2; + int x = bounds.x + (int) (bounds.width * myXSeparator) - size; + int y = bounds.y + (int) (bounds.height * myYSeparator) - size; + + return new Point(x, y); + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/NonResizeSelectionDecorator.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/NonResizeSelectionDecorator.java new file mode 100644 index 000000000000..6f076fc7c8fb --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/NonResizeSelectionDecorator.java @@ -0,0 +1,65 @@ +/* + * 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.selection; + +import com.intellij.designer.designSurface.ComponentDecorator; +import com.intellij.designer.designSurface.DecorationLayer; +import com.intellij.designer.designSurface.EditableArea; +import com.intellij.designer.designSurface.tools.DragTracker; +import com.intellij.designer.designSurface.tools.InputTool; +import com.intellij.designer.model.RadComponent; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class NonResizeSelectionDecorator implements ComponentDecorator { + private final Color myColor; + private final int myLineWidth; + + public NonResizeSelectionDecorator(Color color, int lineWidth) { + myColor = color; + myLineWidth = Math.max(lineWidth, 1); + } + + @Override + public InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y) { + Rectangle bounds = layer.getComponentBounds(component); + + Rectangle top = new Rectangle(bounds.x, bounds.y, bounds.width, myLineWidth); + Rectangle bottom = new Rectangle(bounds.x, bounds.y + bounds.height - myLineWidth, bounds.width, myLineWidth); + Rectangle left = new Rectangle(bounds.x, bounds.y, myLineWidth, bounds.height); + Rectangle right = new Rectangle(bounds.x + bounds.width - myLineWidth, bounds.y, myLineWidth, bounds.height); + + if (top.contains(x, y) || bottom.contains(x, y) || left.contains(x, y) || right.contains(x, y)) { + return new DragTracker(); + } + + return null; + } + + @Override + public void decorate(DecorationLayer layer, Graphics2D g, RadComponent component) { + g.setColor(myColor); + if (myLineWidth > 1) { + g.setStroke(new BasicStroke(myLineWidth)); + } + + Rectangle bounds = layer.getComponentBounds(component); + g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000000..e71cb1b1d334 --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizePoint.java @@ -0,0 +1,72 @@ +/* + * 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.selection; + +import com.intellij.designer.designSurface.ComponentDecorator; +import com.intellij.designer.designSurface.DecorationLayer; +import com.intellij.designer.designSurface.tools.InputTool; +import com.intellij.designer.model.RadComponent; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public abstract class ResizePoint implements ComponentDecorator { + private static final int DEFAULT_SIZE = 5; + private final Color myColor; + private final Color myBorder; + + public ResizePoint() { + this(Color.GREEN, Color.BLACK); + } + + public ResizePoint(Color color, Color border) { + myColor = color; + myBorder = border; + } + + @Override + public InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y) { + Point location = getLocation(layer, component); + Rectangle bounds = new Rectangle(location.x, location.y, getSize(), getSize()); + + if (bounds.contains(x, y)) { + return createTool(component); + } + + return null; + } + + @Override + public void decorate(DecorationLayer layer, Graphics2D g, RadComponent component) { + Point location = getLocation(layer, component); + + g.setColor(myColor); + g.fillRect(location.x, location.y, getSize(), getSize()); + + g.setColor(myBorder); + g.drawRect(location.x, location.y, getSize(), getSize()); + } + + protected abstract InputTool createTool(RadComponent component); + + protected abstract Point getLocation(DecorationLayer layer, RadComponent component); + + protected int getSize() { + return DEFAULT_SIZE; + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizeSelectionDecorator.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizeSelectionDecorator.java new file mode 100644 index 000000000000..941e10279109 --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/selection/ResizeSelectionDecorator.java @@ -0,0 +1,55 @@ +/* + * 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.selection; + +import com.intellij.designer.designSurface.DecorationLayer; +import com.intellij.designer.designSurface.tools.InputTool; +import com.intellij.designer.model.RadComponent; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class ResizeSelectionDecorator extends NonResizeSelectionDecorator { + private final ResizePoint[] myPoints; + + public ResizeSelectionDecorator(Color color, int lineWidth, ResizePoint... points) { + super(color, lineWidth); + myPoints = points; + } + + @Override + public InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y) { + for (ResizePoint point : myPoints) { + InputTool tracker = point.findTargetTool(layer, component, x, y); + if (tracker != null) { + return tracker; + } + } + + return super.findTargetTool(layer, component, x, y); + } + + @Override + public void decorate(DecorationLayer layer, Graphics2D g, RadComponent component) { + super.decorate(layer, g, component); + + for (ResizePoint point : myPoints) { + point.decorate(layer, g, component); + } + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/DragTracker.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/DragTracker.java index 7c0a3347ab68..70e0d4667f23 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/DragTracker.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/DragTracker.java @@ -15,8 +15,13 @@ */ package com.intellij.designer.designSurface.tools; +import com.intellij.designer.utils.Cursors; + /** * @author Alexander Lobas */ public class DragTracker extends TargetingTool { + public DragTracker() { + setDefaultCursor(Cursors.RESIZE_ALL); + } } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/InputTool.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/InputTool.java index f33a7931587e..dcb9aefedd73 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/InputTool.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/InputTool.java @@ -34,18 +34,23 @@ public abstract class InputTool { protected static final int STATE_DRAG_IN_PROGRESS = 3; protected static final int STATE_INVALID = 4; - private ToolProvider myToolProvider; + protected ToolProvider myToolProvider; protected EditableArea myArea; + private Object myCommand; + private boolean myActive; private boolean myCanUnload = true; + protected int myState; + protected int myCurrentScreenX; protected int myCurrentScreenY; protected InputEvent myInputEvent; protected int myButton; protected int myStartScreenX; protected int myStartScreenY; + private boolean myCanPastThreshold; ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ResizeTracker.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ResizeTracker.java index da9c21e022ae..5008ad3efff8 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ResizeTracker.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ResizeTracker.java @@ -15,8 +15,13 @@ */ package com.intellij.designer.designSurface.tools; +import com.intellij.designer.utils.Cursors; + /** * @author Alexander Lobas */ public class ResizeTracker extends InputTool { + public ResizeTracker(int direction) { + setDefaultCursor(Cursors.getResizeCursor(direction)); + } } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java index b3a3921edccd..b451ac7cfc51 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java @@ -79,6 +79,19 @@ public class SelectionTool extends InputTool { refreshCursor(); } + @Override + protected void handleMove() { + if (myState == STATE_INIT) { + InputTool tracker = myArea.findTargetTool(myCurrentScreenX, myCurrentScreenY); + if (tracker == null) { + refreshCursor(); + } + else { + myArea.setCursor(tracker.getDefaultCursor()); + } + } + } + protected Cursor calculateCursor() { return myState == STATE_INIT || myState == STATE_DRAG ? getDefaultCursor() diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java index f2b307f7a45b..befc847860b9 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java @@ -18,6 +18,7 @@ package com.intellij.designer.model; import com.intellij.designer.propertyTable.Property; import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -30,6 +31,7 @@ import java.util.Map; */ public abstract class RadComponent { private RadComponent myParent; + private RadLayout myLayout; private final Map myClientProperties = new HashMap(); public RadComponent getRoot() { @@ -69,9 +71,14 @@ public abstract class RadComponent { } public RadLayout getLayout() { - return null; + return myLayout; } + public void setLayout(RadLayout layout) { + myLayout = layout; + } + + @Nullable public RadLayoutData getLayoutData() { return null; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java index 57c9b30d0c73..094b581827a2 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java @@ -15,8 +15,11 @@ */ package com.intellij.designer.model; +import com.intellij.designer.designSurface.ComponentDecorator; + /** * @author Alexander Lobas */ public abstract class RadLayout { + public abstract ComponentDecorator getChildSelectionDecorator(RadComponent component); } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Cursors.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Cursors.java index 858f65f02c52..6eae61c11c08 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Cursors.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Cursors.java @@ -15,12 +15,16 @@ */ package com.intellij.designer.utils; +import org.jetbrains.annotations.Nullable; + import java.awt.*; /** * @author Alexander Lobas */ public final class Cursors { + public static final Cursor RESIZE_ALL = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); + public static Cursor getNoCursor() { try { return Cursor.getSystemCustomCursor("MoveNoDrop.32x32"); @@ -29,4 +33,37 @@ public final class Cursors { return Cursor.getDefaultCursor(); } } + + @Nullable + public static Cursor getResizeCursor(int direction) { + int cursor; + if (direction == Position.NORTH_WEST) { + cursor = Cursor.NW_RESIZE_CURSOR; + } + else if (direction == Position.NORTH) { + cursor = Cursor.N_RESIZE_CURSOR; + } + else if (direction == Position.NORTH_EAST) { + cursor = Cursor.NE_RESIZE_CURSOR; + } + else if (direction == Position.WEST) { + cursor = Cursor.W_RESIZE_CURSOR; + } + else if (direction == Position.EAST) { + cursor = Cursor.E_RESIZE_CURSOR; + } + else if (direction == Position.SOUTH_WEST) { + cursor = Cursor.SW_RESIZE_CURSOR; + } + else if (direction == Position.SOUTH) { + cursor = Cursor.S_RESIZE_CURSOR; + } + else if (direction == Position.SOUTH_EAST) { + cursor = Cursor.SE_RESIZE_CURSOR; + } + else { + return null; + } + return Cursor.getPredefinedCursor(cursor); + } } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Position.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Position.java new file mode 100644 index 000000000000..8c05efacbafc --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/utils/Position.java @@ -0,0 +1,38 @@ +/* + * 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.utils; + +/** + * @author Alexander Lobas + */ +public interface Position { + ////////////////////////////////////////////////////////////////////////////////////////// + // + // Direction + // + ////////////////////////////////////////////////////////////////////////////////////////// + int NONE = 0; + int NORTH = 1 << 0; + int SOUTH = 1 << 1; + int WEST = 1 << 2; + int EAST = 1 << 3; + int NORTH_EAST = NORTH | EAST; + int NORTH_WEST = NORTH | WEST; + int SOUTH_EAST = SOUTH | EAST; + int SOUTH_WEST = SOUTH | WEST; + int NORTH_SOUTH = NORTH | SOUTH; + int EAST_WEST = EAST | WEST; +} \ No newline at end of file