This commit is contained in:
Alexander Lobas
2012-07-12 21:38:23 +04:00
parent 7370fdaf63
commit 7cd47200f9
16 changed files with 454 additions and 359 deletions
@@ -28,6 +28,7 @@ import com.intellij.designer.model.MetaManager;
import com.intellij.designer.model.MetaModel;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadComponentVisitor;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -74,17 +75,27 @@ public class TableLayoutOperation extends GridOperation {
@Override
protected int getMovedIndex(boolean row) {
RadComponent movedComponent = myContext.getComponents().get(0);
List<RadComponent> children = myContainer.getChildren();
if (row) {
List<RadComponent> children = myContainer.getChildren();
if (movedComponent.getParent() == myContainer) {
return children.indexOf(movedComponent);
}
return children.indexOf(movedComponent.getParent());
}
return RadTableLayoutComponent.getCellIndex(movedComponent);
if (movedComponent.getParent() == myContainer) {
return 0;
}
int columnIndex = RadTableLayoutComponent.getCellIndex(movedComponent);
if (columnIndex != -1) {
return columnIndex;
}
int rowIndex = children.indexOf(movedComponent.getParent());
RadComponent[] components = getGridInfo().components[rowIndex];
return ArrayUtil.indexOf(components, movedComponent);
}
@Override
@@ -106,7 +117,7 @@ public class TableLayoutOperation extends GridOperation {
return getSizeInColumn(0, columnCount, movedComponent) == 0;
}
int columnIndex = RadTableLayoutComponent.getCellIndex(movedComponent);
int columnIndex = getMovedIndex(false);
int span = RadTableLayoutComponent.getCellSpan(movedComponent);
for (int i = 0; i < span; i++) {
@@ -16,6 +16,7 @@
package com.intellij.android.designer.model.grid;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.designSurface.EditableArea;
import java.awt.*;
@@ -23,8 +24,8 @@ import java.awt.*;
* @author Alexander Lobas
*/
public abstract class RadCaptionColumn<T extends RadViewComponent> extends RadCaptionComponent<T> {
public RadCaptionColumn(T container, int index, int offset, int width, boolean empty) {
super(container, index, offset, width, empty);
public RadCaptionColumn(EditableArea mainArea, T container, int index, int offset, int width, boolean empty) {
super(mainArea, container, index, offset, width, empty);
}
@Override
@@ -17,24 +17,30 @@ package com.intellij.android.designer.model.grid;
import com.intellij.android.designer.designSurface.layout.CaptionStaticDecorator;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadComponentVisitor;
import com.intellij.designer.model.RadVisualComponent;
import com.intellij.util.containers.hash.HashSet;
import java.awt.*;
import java.util.List;
import java.util.Set;
/**
* @author Alexander Lobas
*/
public abstract class RadCaptionComponent<T extends RadViewComponent> extends RadVisualComponent {
private final StaticDecorator myDecorator;
private final EditableArea myMainArea;
protected final T myContainer;
protected final int myIndex;
protected final int myOffset;
protected final int myWidth;
public RadCaptionComponent(T container, int index, int offset, int width, boolean empty) {
public RadCaptionComponent(EditableArea mainArea, T container, int index, int offset, int width, boolean empty) {
myMainArea = mainArea;
myContainer = container;
myIndex = index;
myOffset = offset;
@@ -58,4 +64,17 @@ public abstract class RadCaptionComponent<T extends RadViewComponent> extends Ra
public void addStaticDecorators(List<StaticDecorator> decorators, List<RadComponent> selection) {
decorators.add(myDecorator);
}
protected final void deselect(List<RadComponent> components) {
final Set<RadComponent> allComponents = new HashSet<RadComponent>();
for (RadComponent component : components) {
component.accept(new RadComponentVisitor() {
@Override
public void endVisit(RadComponent component) {
allComponents.add(component);
}
}, true);
}
myMainArea.deselect(allComponents);
}
}
@@ -16,6 +16,7 @@
package com.intellij.android.designer.model.grid;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.designSurface.EditableArea;
import java.awt.*;
@@ -23,8 +24,8 @@ import java.awt.*;
* @author Alexander Lobas
*/
public abstract class RadCaptionRow<T extends RadViewComponent> extends RadCaptionComponent<T> {
public RadCaptionRow(T container, int index, int offset, int width, boolean empty) {
super(container, index, offset, width, empty);
public RadCaptionRow(EditableArea mainArea, T container, int index, int offset, int width, boolean empty) {
super(mainArea, container, index, offset, width, empty);
}
@Override
@@ -18,27 +18,31 @@ package com.intellij.android.designer.model.layout.grid;
import com.intellij.android.designer.designSurface.layout.GridLayoutOperation;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.grid.RadCaptionColumn;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.model.IGroupDeleteComponent;
import com.intellij.designer.model.RadComponent;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadCaptionGridColumn extends RadCaptionColumn<RadGridLayoutComponent> implements IGroupDeleteComponent {
public RadCaptionGridColumn(RadGridLayoutComponent container, int index, int offset, int width, boolean empty) {
super(container, index, offset, width, empty);
public RadCaptionGridColumn(EditableArea mainArea, RadGridLayoutComponent container, int index, int offset, int width, boolean empty) {
super(mainArea, container, index, offset, width, empty);
}
@Override
public void delete(List<RadComponent> columns) throws Exception {
List<RadComponent> deletedComponents = new ArrayList<RadComponent>();
GridInfo gridInfo = myContainer.getVirtualGridInfo();
RadComponent[][] components = myContainer.getGridComponents(false);
for (RadComponent column : columns) {
delete(gridInfo, components, (RadCaptionGridColumn)column);
delete(deletedComponents, gridInfo, components, (RadCaptionGridColumn)column);
}
for (int i = 0; i < components.length; i++) {
@@ -61,9 +65,14 @@ public class RadCaptionGridColumn extends RadCaptionColumn<RadGridLayoutComponen
}
GridLayoutOperation.validateLayoutParams(components);
deselect(deletedComponents);
}
private static void delete(GridInfo gridInfo, RadComponent[][] components, RadCaptionGridColumn column) throws Exception {
private static void delete(List<RadComponent> deletedComponents,
GridInfo gridInfo,
RadComponent[][] components,
RadCaptionGridColumn column) throws Exception {
if (column.myIndex > 0) {
GridLayoutOperation.shiftColumnSpan(gridInfo, column.myIndex - 1, -1);
}
@@ -76,6 +85,7 @@ public class RadCaptionGridColumn extends RadCaptionColumn<RadGridLayoutComponen
GridInfo.setNull(components, gridInfo.components, cellIndex.y, cellIndex.y + cellIndex.height, cellIndex.x,
cellIndex.x + cellIndex.width);
component.delete();
deletedComponents.add(component);
}
}
}
@@ -18,27 +18,31 @@ package com.intellij.android.designer.model.layout.grid;
import com.intellij.android.designer.designSurface.layout.GridLayoutOperation;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.grid.RadCaptionRow;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.model.IGroupDeleteComponent;
import com.intellij.designer.model.RadComponent;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadCaptionGridRow extends RadCaptionRow<RadGridLayoutComponent> implements IGroupDeleteComponent {
public RadCaptionGridRow(RadGridLayoutComponent container, int index, int offset, int width, boolean empty) {
super(container, index, offset, width, empty);
public RadCaptionGridRow(EditableArea mainArea, RadGridLayoutComponent container, int index, int offset, int width, boolean empty) {
super(mainArea, container, index, offset, width, empty);
}
@Override
public void delete(List<RadComponent> rows) throws Exception {
List<RadComponent> deletedComponents = new ArrayList<RadComponent>();
GridInfo gridInfo = myContainer.getVirtualGridInfo();
RadComponent[][] components = myContainer.getGridComponents(false);
for (RadComponent row : rows) {
delete(gridInfo, components, (RadCaptionGridRow)row);
delete(deletedComponents, gridInfo, components, (RadCaptionGridRow)row);
}
RadComponent[][] newComponents = new RadComponent[components.length - rows.size()][];
@@ -57,9 +61,12 @@ public class RadCaptionGridRow extends RadCaptionRow<RadGridLayoutComponent> imp
}
GridLayoutOperation.validateLayoutParams(newComponents);
deselect(deletedComponents);
}
private static void delete(GridInfo gridInfo, RadComponent[][] components, RadCaptionGridRow row) throws Exception {
private static void delete(List<RadComponent> deletedComponents, GridInfo gridInfo, RadComponent[][] components, RadCaptionGridRow row)
throws Exception {
if (row.myIndex > 0) {
GridLayoutOperation.shiftRowSpan(gridInfo, row.myIndex - 1, -1);
}
@@ -70,6 +77,7 @@ public class RadCaptionGridRow extends RadCaptionRow<RadGridLayoutComponent> imp
GridInfo.setNull(components, gridInfo.components, cellIndex.y, cellIndex.y + cellIndex.height, cellIndex.x,
cellIndex.x + cellIndex.width);
component.delete();
deletedComponents.add(component);
}
}
}
@@ -222,7 +222,8 @@ public class RadGridLayout extends RadViewLayoutWithData implements ILayoutDecor
boolean[] emptyColumns = gridInfo.emptyColumns;
for (int i = 0; i < lines.length - 1; i++) {
components.add(new RadCaptionGridColumn(container,
components.add(new RadCaptionGridColumn(mainArea,
container,
i,
lines[i],
lines[i + 1] - lines[i],
@@ -234,7 +235,8 @@ public class RadGridLayout extends RadViewLayoutWithData implements ILayoutDecor
boolean[] emptyRows = gridInfo.emptyRows;
for (int i = 0; i < lines.length - 1; i++) {
components.add(new RadCaptionGridRow(container,
components.add(new RadCaptionGridRow(mainArea,
container,
i,
lines[i],
lines[i + 1] - lines[i],
@@ -17,20 +17,23 @@ package com.intellij.android.designer.model.layout.table;
import com.intellij.android.designer.model.grid.GridInfo;
import com.intellij.android.designer.model.grid.RadCaptionColumn;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.model.IGroupDeleteComponent;
import com.intellij.designer.model.RadComponent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadCaptionTableColumn extends RadCaptionColumn<RadTableLayoutComponent> {
public RadCaptionTableColumn(RadTableLayoutComponent container, int index, int offset, int width, boolean empty) {
super(container, index, offset, width, empty);
public class RadCaptionTableColumn extends RadCaptionColumn<RadTableLayoutComponent> implements IGroupDeleteComponent {
public RadCaptionTableColumn(EditableArea mainArea, RadTableLayoutComponent container, int index, int offset, int width, boolean empty) {
super(mainArea, container, index, offset, width, empty);
}
@Override
public void delete() throws Exception {
private void deleteColumn(List<RadComponent> deletedComponents) throws Exception {
GridInfo info = myContainer.getVirtualGridInfo();
RadComponent[][] components = info.components;
@@ -51,22 +54,56 @@ public class RadCaptionTableColumn extends RadCaptionColumn<RadTableLayoutCompon
RadComponent parent = component.getParent();
component.delete();
deletedComponents.add(component);
if (parent.getChildren().isEmpty()) {
parent.delete();
}
}
}
for (int i = nextIndex; i < rowComponents.length; i++) {
RadComponent cellComponent = rowComponents[i];
if (cellComponent != null) {
RadTableLayoutComponent.setCellIndex(cellComponent, i - 1);
while (i + 1 < rowComponents.length && cellComponent == rowComponents[i + 1]) {
i++;
deletedComponents.add(parent);
}
}
}
}
}
@Override
public void delete(List<RadComponent> columns) throws Exception {
List<RadComponent> deletedComponents = new ArrayList<RadComponent>();
RadComponent[][] components = myContainer.getGridComponents(false);
for (RadComponent component : columns) {
RadCaptionTableColumn column = (RadCaptionTableColumn)component;
column.deleteColumn(deletedComponents);
}
for (int i = 0; i < components.length; i++) {
RadComponent[] rowComponents = components[i];
RadComponent[] newRowComponents = new RadComponent[rowComponents.length - columns.size()];
components[i] = newRowComponents;
for (int j = 0, index = 0; j < rowComponents.length; j++) {
boolean add = true;
for (RadComponent column : columns) {
if (j == ((RadCaptionTableColumn)column).myIndex) {
add = false;
break;
}
}
if (add) {
newRowComponents[index++] = rowComponents[j];
}
}
}
for (RadComponent[] rowComponents : components) {
for (int j = 0; j < rowComponents.length; j++) {
RadComponent cellComponent = rowComponents[j];
if (cellComponent != null) {
RadTableLayoutComponent.setCellIndex(cellComponent, j);
}
}
}
deselect(deletedComponents);
}
}
@@ -15,59 +15,37 @@
*/
package com.intellij.android.designer.model.layout.table;
import com.intellij.android.designer.designSurface.layout.CaptionStaticDecorator;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.android.designer.model.grid.RadCaptionRow;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.model.IGroupDeleteComponent;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadVisualComponent;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadCaptionTableRow extends RadVisualComponent {
private final RadViewComponent myComponent;
private final StaticDecorator myDecorator;
public RadCaptionTableRow(RadViewComponent component) {
myComponent = component;
if (RadTableRowLayout.is(component)) {
myDecorator = new CaptionStaticDecorator(this);
} else {
myDecorator = new CaptionStaticDecorator(this, Color.PINK);
}
setNativeComponent(component.getNativeComponent());
public class RadCaptionTableRow extends RadCaptionRow<RadViewComponent> implements IGroupDeleteComponent {
public RadCaptionTableRow(EditableArea mainArea, RadViewComponent component) {
super(mainArea, component, -1, 0, component.getBounds().height, !RadTableRowLayout.is(component));
}
public RadViewComponent getComponent() {
return myComponent;
return myContainer;
}
@Override
public Rectangle getBounds() {
Rectangle bounds = myComponent.getBounds();
return new Rectangle(2, bounds.y, 10, bounds.height);
}
public void delete(List<RadComponent> rows) throws Exception {
List<RadComponent> deletedComponents = new ArrayList<RadComponent>();
@Override
public Rectangle getBounds(Component relativeTo) {
Rectangle bounds = super.getBounds(relativeTo);
bounds.x = 2;
bounds.width = 10;
return bounds;
}
for (RadComponent component : rows) {
RadCaptionTableRow row = (RadCaptionTableRow)component;
row.myContainer.delete();
deletedComponents.add(row.myContainer);
}
@Override
public void addStaticDecorators(List<StaticDecorator> decorators, List<RadComponent> selection) {
decorators.add(myDecorator);
}
@Override
public void delete() throws Exception {
myComponent.delete();
deselect(deletedComponents);
}
}
@@ -147,7 +147,8 @@ public class RadTableLayout extends RadViewLayoutWithData implements ILayoutDeco
boolean[] emptyColumns = gridInfo.emptyColumns;
for (int i = 0; i < lines.length - 1; i++) {
components.add(new RadCaptionTableColumn(container,
components.add(new RadCaptionTableColumn(mainArea,
container,
i,
lines[i],
lines[i + 1] - lines[i],
@@ -156,7 +157,7 @@ public class RadTableLayout extends RadViewLayoutWithData implements ILayoutDeco
}
else {
for (RadComponent component : children) {
components.add(new RadCaptionTableRow((RadViewComponent)component));
components.add(new RadCaptionTableRow(mainArea, (RadViewComponent)component));
}
}
@@ -46,7 +46,7 @@ public class RadTableRowLayout extends RadLinearLayout {
}
public static boolean is(RadComponent component) {
return component.getLayout() instanceof RadTableRowLayout;
return component != null && component.getLayout() instanceof RadTableRowLayout;
}
private boolean isTableParent() {
@@ -93,8 +93,17 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider,
return;
}
myDesigner.getToolProvider().loadDefaultTool();
List<RadComponent> components = RadComponent.getPureSelection(selection);
RadComponent newSelection = getNewSelection(components.get(0), selection);
if (newSelection == null) {
area.deselectAll();
}
else {
area.select(newSelection);
}
if (components.get(0) instanceof IGroupDeleteComponent) {
((IGroupDeleteComponent)components.get(0)).delete(components);
@@ -104,13 +113,6 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider,
component.delete();
}
}
if (newSelection == null) {
area.deselectAll();
}
else {
area.select(newSelection);
}
}
}, DesignerBundle.message("command.delete.selection"), true);
}
@@ -124,6 +124,13 @@ public final class TreeEditableArea implements EditableArea, FeedbackTreeLayer,
setRawSelection(components);
}
@Override
public void deselect(@NotNull Collection<RadComponent> components) {
Collection<RadComponent> selection = getRawSelection();
selection.removeAll(components);
setRawSelection(selection);
}
@Override
public void deselectAll() {
setRawSelection(null);
@@ -1,277 +1,285 @@
/*
* 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.actions.CommonEditActionsProvider;
import com.intellij.designer.designSurface.tools.InputTool;
import com.intellij.designer.model.FindComponentVisitor;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadVisualComponent;
import com.intellij.ide.DeleteProvider;
import com.intellij.openapi.actionSystem.*;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SideBorder;
import com.intellij.util.containers.IntArrayList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class CaptionPanel extends JLayeredPane implements DataProvider, DeleteProvider {
private static final int SIZE = 16;
private final boolean myHorizontal;
private final EditableArea myMainArea;
private final EditableArea myArea;
private final DecorationLayer myDecorationLayer;
private final FeedbackLayer myFeedbackLayer;
private DefaultActionGroup myActionGroup;
private final CommonEditActionsProvider myActionsProvider;
private final RadVisualComponent myRootComponent;
private List<RadComponent> myRootChildren = Collections.emptyList();
private ICaption myCaption;
public CaptionPanel(DesignerEditorPanel designer, boolean horizontal) {
setBorder(IdeBorderFactory.createBorder(horizontal ? SideBorder.BOTTOM : SideBorder.RIGHT));
setFocusable(true);
myHorizontal = horizontal;
myMainArea = designer.getSurfaceArea();
myRootComponent = new RadVisualComponent() {
@Override
public List<RadComponent> getChildren() {
return myRootChildren;
}
@Override
public boolean canDelete() {
return false;
}
};
myRootComponent.setNativeComponent(this);
if (horizontal) {
myRootComponent.setBounds(0, 0, 100000, SIZE);
}
else {
myRootComponent.setBounds(0, 0, SIZE, 100000);
}
myArea = new ComponentEditableArea(this) {
@Override
protected void fireSelectionChanged() {
super.fireSelectionChanged();
revalidate();
repaint();
}
@Override
public RadComponent findTarget(int x, int y, @Nullable ComponentTargetFilter filter) {
FindComponentVisitor visitor = new FindComponentVisitor(CaptionPanel.this, filter, x, y);
myRootComponent.accept(visitor, false);
return visitor.getResult();
}
@Override
public InputTool findTargetTool(int x, int y) {
return myDecorationLayer.findTargetTool(x, y);
}
@Override
public void showSelection(boolean value) {
myDecorationLayer.showSelection(value);
}
@Override
public ComponentDecorator getRootSelectionDecorator() {
return EmptyComponentDecorator.INSTANCE;
}
@Override
public EditOperation processRootOperation(OperationContext context) {
return null;
}
@Override
public FeedbackLayer getFeedbackLayer() {
return myFeedbackLayer;
}
@Override
public RadComponent getRootComponent() {
return myRootComponent;
}
@Override
public ActionGroup getPopupActions() {
if (myActionGroup == null) {
myActionGroup = new DefaultActionGroup();
myActionGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_DELETE));
}
return myActionGroup;
}
@Override
public String getPopupPlace() {
return "UIDesigner.CaptionPanel";
}
};
add(new GlassLayer(designer.getToolProvider(), myArea), DesignerEditorPanel.LAYER_GLASS);
myDecorationLayer = new DecorationLayer(designer, myArea);
add(myDecorationLayer, DesignerEditorPanel.LAYER_DECORATION);
myFeedbackLayer = new FeedbackLayer();
add(myFeedbackLayer, DesignerEditorPanel.LAYER_FEEDBACK);
myActionsProvider = new CommonEditActionsProvider(designer) {
@Override
protected EditableArea getArea(DataContext dataContext) {
return myArea;
}
};
myMainArea.addSelectionListener(new ComponentSelectionListener() {
@Override
public void selectionChanged(EditableArea area) {
update();
}
});
}
public void attachToScrollPane(JScrollPane scrollPane) {
scrollPane.getViewport().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
repaint();
}
});
}
public void doLayout() {
for (int i = getComponentCount() - 1; i >= 0; i--) {
Component component = getComponent(i);
component.setBounds(0, 0, getWidth(), getHeight());
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Object getData(@NonNls String dataId) {
if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
return this;
}
return null;
}
@Override
public boolean canDeleteElement(@NotNull DataContext dataContext) {
return myActionsProvider.canDeleteElement(dataContext);
}
@Override
public void deleteElement(@NotNull DataContext dataContext) {
myActionsProvider.deleteElement(dataContext);
}
public void update() {
List<RadComponent> selection = myMainArea.getSelection();
if (selection.size() != 1) {
return;
}
boolean update = !myRootChildren.isEmpty();
IntArrayList oldSelection = null;
if (myCaption != null) {
oldSelection = new IntArrayList();
for (RadComponent component : myArea.getSelection()) {
oldSelection.add(myRootChildren.indexOf(component));
}
}
myArea.deselectAll();
myRootComponent.setLayout(null);
ICaption caption = null;
RadComponent component = selection.get(0);
RadComponent parent = component.getParent();
if (parent != null) {
caption = parent.getLayout().getCaption(component);
}
if (caption == null) {
caption = component.getCaption();
}
if (caption == null) {
myRootChildren = Collections.emptyList();
}
else {
myRootComponent.setLayout(caption.getCaptionLayout(myMainArea, myHorizontal));
myRootChildren = caption.getCaptionChildren(myMainArea, myHorizontal);
for (RadComponent child : myRootChildren) {
child.setParent(myRootComponent);
}
if (myCaption == caption) {
List<RadComponent> newSelection = new ArrayList<RadComponent>();
int componentSize = myRootChildren.size();
int selectionSize = oldSelection.size();
for (int i = 0; i < selectionSize; i++) {
int index = oldSelection.get(i);
if (0 <= index && index < componentSize) {
newSelection.add(myRootChildren.get(index));
}
}
if (!newSelection.isEmpty()) {
myArea.setSelection(newSelection);
}
}
update |= !myRootChildren.isEmpty();
}
myCaption = caption;
if (update) {
revalidate();
repaint();
}
}
/*
* 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.actions.CommonEditActionsProvider;
import com.intellij.designer.designSurface.tools.InputTool;
import com.intellij.designer.model.FindComponentVisitor;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadVisualComponent;
import com.intellij.ide.DeleteProvider;
import com.intellij.openapi.actionSystem.*;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SideBorder;
import com.intellij.util.containers.IntArrayList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class CaptionPanel extends JLayeredPane implements DataProvider, DeleteProvider {
private static final int SIZE = 16;
private final boolean myHorizontal;
private final EditableArea myMainArea;
private final EditableArea myArea;
private final DecorationLayer myDecorationLayer;
private final FeedbackLayer myFeedbackLayer;
private DefaultActionGroup myActionGroup;
private final CommonEditActionsProvider myActionsProvider;
private final RadVisualComponent myRootComponent;
private List<RadComponent> myRootChildren = Collections.emptyList();
private ICaption myCaption;
public CaptionPanel(DesignerEditorPanel designer, boolean horizontal) {
setBorder(IdeBorderFactory.createBorder(horizontal ? SideBorder.BOTTOM : SideBorder.RIGHT));
setFocusable(true);
myHorizontal = horizontal;
myMainArea = designer.getSurfaceArea();
myRootComponent = new RadVisualComponent() {
@Override
public List<RadComponent> getChildren() {
return myRootChildren;
}
@Override
public boolean canDelete() {
return false;
}
};
myRootComponent.setNativeComponent(this);
if (horizontal) {
myRootComponent.setBounds(0, 0, 100000, SIZE);
}
else {
myRootComponent.setBounds(0, 0, SIZE, 100000);
}
myArea = new ComponentEditableArea(this) {
@Override
protected void fireSelectionChanged() {
super.fireSelectionChanged();
revalidate();
repaint();
}
@Override
public RadComponent findTarget(int x, int y, @Nullable ComponentTargetFilter filter) {
FindComponentVisitor visitor = new FindComponentVisitor(CaptionPanel.this, filter, x, y);
myRootComponent.accept(visitor, false);
return visitor.getResult();
}
@Override
public InputTool findTargetTool(int x, int y) {
return myDecorationLayer.findTargetTool(x, y);
}
@Override
public void showSelection(boolean value) {
myDecorationLayer.showSelection(value);
}
@Override
public ComponentDecorator getRootSelectionDecorator() {
return EmptyComponentDecorator.INSTANCE;
}
@Override
public EditOperation processRootOperation(OperationContext context) {
return null;
}
@Override
public FeedbackLayer getFeedbackLayer() {
return myFeedbackLayer;
}
@Override
public RadComponent getRootComponent() {
return myRootComponent;
}
@Override
public ActionGroup getPopupActions() {
if (myActionGroup == null) {
myActionGroup = new DefaultActionGroup();
myActionGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_DELETE));
}
return myActionGroup;
}
@Override
public String getPopupPlace() {
return "UIDesigner.CaptionPanel";
}
};
add(new GlassLayer(designer.getToolProvider(), myArea), DesignerEditorPanel.LAYER_GLASS);
myDecorationLayer = new DecorationLayer(designer, myArea);
add(myDecorationLayer, DesignerEditorPanel.LAYER_DECORATION);
myFeedbackLayer = new FeedbackLayer();
add(myFeedbackLayer, DesignerEditorPanel.LAYER_FEEDBACK);
myActionsProvider = new CommonEditActionsProvider(designer) {
@Override
protected EditableArea getArea(DataContext dataContext) {
return myArea;
}
};
myMainArea.addSelectionListener(new ComponentSelectionListener() {
@Override
public void selectionChanged(EditableArea area) {
update();
}
});
}
public void attachToScrollPane(JScrollPane scrollPane) {
scrollPane.getViewport().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
repaint();
}
});
}
public void doLayout() {
for (int i = getComponentCount() - 1; i >= 0; i--) {
Component component = getComponent(i);
component.setBounds(0, 0, getWidth(), getHeight());
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Object getData(@NonNls String dataId) {
if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
return this;
}
return null;
}
@Override
public boolean canDeleteElement(@NotNull DataContext dataContext) {
return myActionsProvider.canDeleteElement(dataContext);
}
@Override
public void deleteElement(@NotNull DataContext dataContext) {
myActionsProvider.deleteElement(dataContext);
}
public void update() {
List<RadComponent> selection = myMainArea.getSelection();
if (selection.size() != 1) {
if (myCaption != null) {
myCaption = null;
myRootComponent.setLayout(null);
myRootChildren = Collections.emptyList();
myArea.deselectAll();
revalidate();
repaint();
}
return;
}
boolean update = !myRootChildren.isEmpty();
IntArrayList oldSelection = null;
if (myCaption != null) {
oldSelection = new IntArrayList();
for (RadComponent component : myArea.getSelection()) {
oldSelection.add(myRootChildren.indexOf(component));
}
}
myArea.deselectAll();
myRootComponent.setLayout(null);
ICaption caption = null;
RadComponent component = selection.get(0);
RadComponent parent = component.getParent();
if (parent != null) {
caption = parent.getLayout().getCaption(component);
}
if (caption == null) {
caption = component.getCaption();
}
if (caption == null) {
myRootChildren = Collections.emptyList();
}
else {
myRootComponent.setLayout(caption.getCaptionLayout(myMainArea, myHorizontal));
myRootChildren = caption.getCaptionChildren(myMainArea, myHorizontal);
for (RadComponent child : myRootChildren) {
child.setParent(myRootComponent);
}
if (myCaption == caption) {
List<RadComponent> newSelection = new ArrayList<RadComponent>();
int componentSize = myRootChildren.size();
int selectionSize = oldSelection.size();
for (int i = 0; i < selectionSize; i++) {
int index = oldSelection.get(i);
if (0 <= index && index < componentSize) {
newSelection.add(myRootChildren.get(index));
}
}
if (!newSelection.isEmpty()) {
myArea.setSelection(newSelection);
}
}
update |= !myRootChildren.isEmpty();
}
myCaption = caption;
if (update) {
revalidate();
repaint();
}
}
}
@@ -24,6 +24,7 @@ import javax.swing.*;
import javax.swing.event.EventListenerList;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
@@ -97,6 +98,12 @@ public abstract class ComponentEditableArea implements EditableArea {
fireSelectionChanged();
}
@Override
public void deselect(@NotNull Collection<RadComponent> components) {
mySelection.removeAll(components);
fireSelectionChanged();
}
@Override
public void deselectAll() {
mySelection = new ArrayList<RadComponent>();
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.List;
/**
@@ -55,6 +56,8 @@ public interface EditableArea {
void setSelection(@NotNull List<RadComponent> components);
void deselect(@NotNull Collection<RadComponent> components);
void deselectAll();
//////////////////////////////////////////////////////////////////////////////////////////