Static decorators

This commit is contained in:
Alexander Lobas
2012-04-07 19:38:46 +04:00
parent 36db43a5ab
commit b5d7adfe2f
17 changed files with 273 additions and 59 deletions
@@ -484,7 +484,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
@Override
protected ComponentDecorator getRootSelectionDecorator() {
return new NonResizeSelectionDecorator(Color.RED, 1);
return new NonResizeSelectionDecorator(Color.RED, 2);
}
@Override
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.android.designer.designSurface.layout;
import com.intellij.designer.designSurface.DecorationLayer;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.designer.model.RadComponent;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public class BorderStaticDecorator extends StaticDecorator {
private static final Color COLOR = new Color(47, 67, 96);
public BorderStaticDecorator(RadComponent component) {
super(component);
}
@Override
protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) {
Rectangle bounds = component.getBounds(layer);
g.setColor(COLOR);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.android.designer.designSurface.layout;
import com.intellij.designer.designSurface.DecorationLayer;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.designer.model.RadComponent;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public abstract class FlowStaticDecorator extends StaticDecorator {
private static final BasicStroke STROKE = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{3, 1}, 0);
private static final Color LINE_COLOR = new Color(47, 67, 96);
public FlowStaticDecorator(RadComponent component) {
super(component);
}
@Override
protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) {
Rectangle bounds = component.getBounds(layer);
g.setColor(LINE_COLOR);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
g.setStroke(STROKE);
if (isHorizontal()) {
for (RadComponent child : component.getChildren()) {
Rectangle childBounds = child.getBounds(layer);
g.drawLine(childBounds.x + childBounds.width, bounds.y, childBounds.x + childBounds.width, bounds.y + bounds.height);
}
}
else {
for (RadComponent child : component.getChildren()) {
Rectangle childBounds = child.getBounds(layer);
g.drawLine(bounds.x, childBounds.y + childBounds.height, bounds.x + bounds.width, childBounds.y + childBounds.height);
}
}
}
protected abstract boolean isHorizontal();
}
@@ -185,13 +185,6 @@ public class FrameLayoutMarginOperation implements EditOperation {
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Handlers
//
//////////////////////////////////////////////////////////////////////////////////////////
private static final float[] DASHES = new float[]{1, 2};
public static boolean visible(RadComponent component, DirectionResizePoint point) {
Pair<Gravity, Gravity> gravity = RadFrameLayout.gravity(component);
int direction = point.getDirection();
@@ -211,16 +204,17 @@ public class FrameLayoutMarginOperation implements EditOperation {
return true;
}
private static final BasicStroke STROKE = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{1, 2}, 0);
public static void points(ResizeSelectionDecorator decorator) {
decorator.addPoint(new ResizePoint() {
private final BasicStroke myStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, DASHES, 0);
@Override
protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) {
Rectangle bounds = component.getBounds(layer);
applyMargins(bounds, getMargins(component));
g.setStroke(myStroke);
g.setStroke(STROKE);
g.setColor(Color.red);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
@@ -215,6 +215,12 @@ public class PropertyParser {
return p1.getName().compareTo(p2.getName());
}
});
if (model != null) {
for (String topName : model.getTopProperties()) {
PropertyTable.moveProperty(properties, topName, properties, 0);
}
}
}
}
@@ -16,11 +16,8 @@
package com.intellij.android.designer.model;
import com.android.ide.common.rendering.api.ViewInfo;
import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.propertyTable.Property;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
@@ -156,23 +153,4 @@ public class RadViewComponent extends RadComponent {
child.copyTo(parent);
}
}
@Override
public void addStaticDecorators(List<StaticDecorator> decorators, List<RadComponent> selection) {
RadViewLayout layout = (RadViewLayout)getLayout();
if (layout != null) {
layout.addStaticDecorators(decorators, selection);
}
}
@Override
public void addSelectionActions(DesignerEditorPanel designer,
DefaultActionGroup actionGroup,
JComponent shortcuts,
List<RadComponent> selection) {
RadViewLayout layout = (RadViewLayout)getLayout();
if (layout != null) {
layout.addContainerSelectionActions(designer, actionGroup, shortcuts, selection);
}
}
}
@@ -0,0 +1,48 @@
/*
* 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.DesignerEditorPanel;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.designer.model.RadComponent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import javax.swing.*;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadViewContainer extends RadViewComponent {
@Override
public void addStaticDecorators(List<StaticDecorator> decorators, List<RadComponent> selection) {
RadViewLayout layout = (RadViewLayout)getLayout();
if (layout != null) {
layout.addStaticDecorators(decorators, selection);
}
}
@Override
public void addSelectionActions(DesignerEditorPanel designer,
DefaultActionGroup actionGroup,
JComponent shortcuts,
List<RadComponent> selection) {
RadViewLayout layout = (RadViewLayout)getLayout();
if (layout != null) {
layout.addContainerSelectionActions(designer, actionGroup, shortcuts, selection);
}
}
}
@@ -15,12 +15,32 @@
*/
package com.intellij.android.designer.model;
import com.intellij.android.designer.designSurface.layout.BorderStaticDecorator;
import com.intellij.designer.designSurface.StaticDecorator;
import com.intellij.designer.model.RadComponent;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Alexander Lobas
*/
public abstract class RadViewLayoutWithData extends RadViewLayout {
private BorderStaticDecorator myBorderDecorator;
@NotNull
public abstract String[] getLayoutParams();
private StaticDecorator getBorderDecorator() {
if (myBorderDecorator == null) {
myBorderDecorator = new BorderStaticDecorator(myContainer);
}
return myBorderDecorator;
}
public void addStaticDecorators(List<StaticDecorator> decorators, List<RadComponent> selection) {
if (!selection.contains(myContainer) && myContainer.getParent() != myContainer.getRoot()) {
decorators.add(getBorderDecorator());
}
}
}
@@ -22,10 +22,7 @@ import com.intellij.android.designer.designSurface.layout.ResizeOperation;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.android.designer.model.RadViewLayoutWithData;
import com.intellij.designer.actions.AbstractComboBoxAction;
import com.intellij.designer.designSurface.ComponentDecorator;
import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.designSurface.*;
import com.intellij.designer.designSurface.selection.DirectionResizePoint;
import com.intellij.designer.designSurface.selection.ResizePoint;
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
@@ -15,6 +15,8 @@
*/
package com.intellij.android.designer.model.layout;
import com.intellij.android.designer.designSurface.layout.FlowStaticDecorator;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.android.designer.model.RadViewLayoutWithData;
import com.intellij.designer.designSurface.*;
import com.intellij.designer.model.RadComponent;
@@ -27,9 +29,11 @@ import java.util.List;
/**
* @author Alexander Lobas
*/
public class RadLinearLayout extends RadViewLayoutWithData {
public class RadLinearLayout extends RadViewLayoutWithData implements ILayoutDecorator {
private static final String[] LAYOUT_PARAMS = {"LinearLayout_Layout", "ViewGroup_MarginLayout"};
private FlowStaticDecorator myLineDecorator;
@Override
@NotNull
public String[] getLayoutParams() {
@@ -41,9 +45,34 @@ public class RadLinearLayout extends RadViewLayoutWithData {
return null;
}
private StaticDecorator getLineDecorator() {
if (myLineDecorator == null) {
myLineDecorator = new FlowStaticDecorator(myContainer) {
@Override
protected boolean isHorizontal() {
return !"vertical".equals(((RadViewComponent)myContainer).getTag().getAttributeValue("android:orientation"));
}
};
}
return myLineDecorator;
}
@Override
public void addStaticDecorators(List<StaticDecorator> decorators, List<RadComponent> selection) {
super.addStaticDecorators(decorators, selection); // TODO: Auto-generated method stub
if (selection.contains(myContainer)) {
if (!(myContainer.getParent().getLayout() instanceof ILayoutDecorator)) {
decorators.add(getLineDecorator());
}
}
else {
for (RadComponent component : selection) {
if (component.getParent() == myContainer) {
decorators.add(getLineDecorator());
return;
}
}
super.addStaticDecorators(decorators, selection);
}
}
@Override
@@ -983,7 +983,7 @@
<!-- ================= Layouts ================= -->
<meta model="com.intellij.android.designer.model.RadViewComponent"
<meta model="com.intellij.android.designer.model.RadViewContainer"
layout="com.intellij.android.designer.model.layout.RadLinearLayout"
class="android.widget.LinearLayout"
tag="LinearLayout">
@@ -991,7 +991,9 @@
<palette title="LinearLayout" icon="/com/intellij/android/designer/icons/LinearLayout.png"
tooltip="A Layout that arranges its children in a single column or a single row."/>
<properties important="orientation gravity baselineAligned measureWithLargestChild showDividers"/>
<properties important="orientation gravity baselineAligned measureWithLargestChild showDividers"
top="gravity orientation"
/>
<creation>
<![CDATA[
@@ -1004,7 +1006,7 @@
</creation>
</meta>
<meta model="com.intellij.android.designer.model.RadViewComponent"
<meta model="com.intellij.android.designer.model.RadViewContainer"
layout="com.intellij.android.designer.model.layout.RadFrameLayout"
class="android.widget.FrameLayout"
tag="FrameLayout">
@@ -17,13 +17,13 @@ package com.intellij.designer.designSurface;
import com.intellij.designer.designSurface.tools.InputTool;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadComponentVisitor;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Alexander Lobas
@@ -58,24 +58,26 @@ public class DecorationLayer extends JComponent {
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
paintStatic(g2d);
if (myShowSelection) {
paintSelection(g2d);
if (myArea.getRootComponent() != null) {
Graphics2D g2d = (Graphics2D)g;
paintStaticDecorators(g2d);
if (myShowSelection) {
paintSelection(g2d);
}
}
}
private void paintStatic(Graphics2D g) {
List<StaticDecorator> decorators = new ArrayList<StaticDecorator>();
List<RadComponent> selection = myArea.getSelection();
Set<RadComponent> parents = RadComponent.getParents(selection);
private void paintStaticDecorators(Graphics2D g) {
final List<StaticDecorator> decorators = new ArrayList<StaticDecorator>();
final List<RadComponent> selection = myArea.getSelection();
myArea.getRootComponent().accept(new RadComponentVisitor() {
@Override
public void endVisit(RadComponent component) {
component.addStaticDecorators(decorators, selection);
}
}, true);
for (RadComponent parent : parents) {
parent.getLayout().addStaticDecorators(decorators, selection);
}
for (RadComponent component : selection) {
component.addStaticDecorators(decorators, selection);
}
for (StaticDecorator decorator : decorators) {
decorator.decorate(this, g);
}
@@ -0,0 +1,22 @@
/*
* 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;
/**
* @author Alexander Lobas
*/
public interface ILayoutDecorator {
}
@@ -35,7 +35,7 @@ public abstract class StaticDecorator extends ComponentDecorator {
return null;
}
public void decorate(DecorationLayer layer, Graphics2D host) {
public final void decorate(DecorationLayer layer, Graphics2D host) {
decorate(layer, host, myComponent);
}
}
@@ -29,10 +29,12 @@ import java.awt.*;
public class NonResizeSelectionDecorator extends ComponentDecorator {
private final Color myColor;
private final int myLineWidth;
private final BasicStroke myStroke;
public NonResizeSelectionDecorator(Color color, int lineWidth) {
myColor = color;
myLineWidth = Math.max(lineWidth, 1);
myStroke = myLineWidth > 1 ? new BasicStroke(myLineWidth) : null;
}
@Override
@@ -55,8 +57,8 @@ public class NonResizeSelectionDecorator extends ComponentDecorator {
@Override
protected void paint(DecorationLayer layer, Graphics2D g, RadComponent component) {
g.setColor(myColor);
if (myLineWidth > 1) {
g.setStroke(new BasicStroke(myLineWidth));
if (myStroke != null) {
g.setStroke(myStroke);
}
Rectangle bounds = component.getBounds(layer);
@@ -114,6 +114,11 @@ public abstract class MetaManager {
Element properties = element.getChild("properties");
if (properties != null) {
Attribute top = properties.getAttribute("top");
if (top != null) {
meta.setTopProperties(StringUtil.split(top.getValue(), " "));
}
Attribute normal = properties.getAttribute("normal");
if (normal != null) {
meta.setNormalProperties(StringUtil.split(normal.getValue(), " "));
@@ -39,6 +39,7 @@ public class MetaModel {
private Icon myIcon;
private String myCreation;
private boolean myDelete = true;
private List<String> myTopProperties = Collections.emptyList();
private List<String> myNormalProperties = Collections.emptyList();
private List<String> myImportantProperties = Collections.emptyList();
private List<String> myExpertProperties = Collections.emptyList();
@@ -115,6 +116,14 @@ public class MetaModel {
myPaletteItem.setMetaModel(this);
}
public List<String> getTopProperties() {
return myTopProperties;
}
public void setTopProperties(List<String> topProperties) {
myTopProperties = topProperties;
}
public void setNormalProperties(List<String> normalProperties) {
myNormalProperties = normalProperties;
}