mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
Component decorations & tool trackers
This commit is contained in:
+17
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ public class RadViewComponent extends RadComponent {
|
||||
if (parent != null) {
|
||||
parent.getChildren().add(this);
|
||||
}
|
||||
setLayout(new RadViewLayout());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+32
@@ -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);
|
||||
}
|
||||
+38
-9
@@ -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);
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -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;
|
||||
}
|
||||
|
||||
+6
@@ -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();
|
||||
}
|
||||
+42
-35
@@ -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) {
|
||||
|
||||
+83
@@ -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);
|
||||
}
|
||||
}
|
||||
+65
@@ -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);
|
||||
}
|
||||
}
|
||||
+72
@@ -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;
|
||||
}
|
||||
}
|
||||
+55
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -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);
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -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;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+5
@@ -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));
|
||||
}
|
||||
}
|
||||
+13
@@ -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()
|
||||
|
||||
+8
-1
@@ -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<Object, Object> myClientProperties = new HashMap<Object, Object>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user