diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/PropertyParser.java b/plugins/android-designer/src/com/intellij/android/designer/model/PropertyParser.java index 72e0fba8c18e..c4b3f18faca9 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/PropertyParser.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/PropertyParser.java @@ -269,7 +269,12 @@ public class PropertyParser { property = new AttributePropertyWithDefault(name, definition, "wrap_content"); } else if (formats.contains(AttributeFormat.Flag)) { - property = new FlagProperty(name, definition); + if ("layout:gravity".equals(name)) { + property = new GravityProperty(name, definition); + } + else { + property = new FlagProperty(name, definition); + } } else { property = new AttributeProperty(name, definition); diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml index e040f92995d9..a94922d56e41 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml +++ b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml @@ -1044,7 +1044,7 @@ tooltip="A Layout that arranges its children in a single column or a single row."/> @@ -1068,7 +1068,7 @@ tooltip="FrameLayout is designed to block out an area on the screen to display a single item."/> @@ -1144,7 +1144,7 @@ implements IPropertyDecorator { private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); - private final AttributeDefinition myDefinition; - private final List> myOptions = new ArrayList>(); + protected final AttributeDefinition myDefinition; + protected final List> myOptions = new ArrayList>(); public FlagProperty(@NotNull String name, @NotNull AttributeDefinition definition) { super(null, name); @@ -114,11 +114,11 @@ public class FlagProperty extends Property implements IPropert } @Nullable - private XmlAttribute getAttribute(RadViewComponent component) { + protected XmlAttribute getAttribute(RadViewComponent component) { return component.getTag().getAttribute("android:" + myDefinition.getName()); } - private Set getOptions(RadViewComponent component) throws Exception { + protected Set getOptions(RadViewComponent component) throws Exception { String value = component.getTag().getAttributeValue("android:" + myDefinition.getName()); if (value == null) { return Collections.emptySet(); @@ -167,9 +167,9 @@ public class FlagProperty extends Property implements IPropert // ////////////////////////////////////////////////////////////////////////////////////////// - private class OptionProperty extends Property { - private PropertyRenderer myRenderer = new BooleanRenderer(); - private PropertyEditor myEditor = new BooleanEditor(); + protected class OptionProperty extends Property { + private final PropertyRenderer myRenderer = new BooleanRenderer(); + private final PropertyEditor myEditor = new BooleanEditor(); private final String myValueName; public OptionProperty(@Nullable Property parent, @NotNull String name, @NotNull String valueName) { diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/GravityProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/GravityProperty.java new file mode 100644 index 000000000000..da93bdff7794 --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/GravityProperty.java @@ -0,0 +1,251 @@ +/* + * 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.propertyTable; + +import com.intellij.android.designer.model.RadViewComponent; +import com.intellij.android.designer.propertyTable.editors.StringsComboEditor; +import com.intellij.designer.propertyTable.Property; +import com.intellij.designer.propertyTable.PropertyEditor; +import com.intellij.designer.propertyTable.PropertyRenderer; +import com.intellij.designer.propertyTable.renderers.LabelPropertyRenderer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.util.ArrayUtil; +import org.jetbrains.android.dom.attrs.AttributeDefinition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Alexander Lobas + */ +public class GravityProperty extends FlagProperty { + private static final String[] CENTER = {"center_horizontal", "center_vertical", "center"}; + private static final String[] FILL = {"fill_horizontal", "fill_vertical", "fill"}; + private static final String[] CLIP = {"clip_horizontal", "clip_vertical"}; + + private static final String[] COMBO_ITEMS = {"horizontal", "vertical", "both"}; + + public GravityProperty(@NotNull String name, @NotNull AttributeDefinition definition) { + super(name, definition); + + myOptions.remove(getProperty("center_horizontal")); + myOptions.remove(getProperty("center_vertical")); + myOptions.set(getProperty("center"), new ComboOptionProperty(this, "center", CENTER) { + @Override + protected void setValue(RadViewComponent component, int index) throws Exception { + if (index == 0) { + setOptions(component, new String[]{"center_horizontal"}, new String[]{"center_vertical", "center"}); + } + else if (index == 1) { + setOptions(component, new String[]{"center_vertical"}, new String[]{"center_horizontal", "center"}); + } + else { + setOptions(component, new String[]{"center"}, new String[]{"center_horizontal", "center_vertical"}); + } + } + }); + + myOptions.remove(getProperty("fill_horizontal")); + myOptions.remove(getProperty("fill_vertical")); + myOptions.set(getProperty("fill"), new ComboOptionProperty(this, "fill", FILL) { + @Override + protected void setValue(RadViewComponent component, int index) throws Exception { + if (index == 0) { + setOptions(component, new String[]{"fill_horizontal"}, new String[]{"fill_vertical", "fill"}); + } + else if (index == 1) { + setOptions(component, new String[]{"fill_vertical"}, new String[]{"fill_horizontal", "fill"}); + } + else { + setOptions(component, new String[]{"fill"}, new String[]{"fill_horizontal", "fill_vertical"}); + } + } + }); + + myOptions.remove(getProperty("clip_vertical")); + myOptions.set(getProperty("clip_horizontal"), new ComboOptionProperty(this, "clip", CLIP) { + @Override + protected void setValue(RadViewComponent component, int index) throws Exception { + if (index == 0) { + setOptions(component, new String[]{"clip_horizontal"}, new String[]{"clip_vertical"}); + } + else if (index == 1) { + setOptions(component, new String[]{"clip_vertical"}, new String[]{"clip_horizontal"}); + } + else { + setOptions(component, CLIP, null); + } + } + }); + } + + private int getProperty(String name) { + int size = myOptions.size(); + for (int i = 0; i < size; i++) { + if (name.equals(myOptions.get(i).getName())) { + return i; + } + } + return -1; + } + + @Override + public Object getValue(RadViewComponent component) throws Exception { + StringBuilder value = new StringBuilder("["); + Set options = getOptions(component); + int index = 0; + for (Property option : myOptions) { + String name = null; + + if (option instanceof OptionProperty) { + if (options.contains(((OptionProperty)option).getValueName())) { + name = option.getName(); + } + } + else { + name = ((ComboOptionProperty)option).getValue(options); + } + + if (name != null) { + if (index++ > 0) { + value.append(", "); + } + value.append(name); + } + } + return value.append("]").toString(); + } + + private void setOptions(final RadViewComponent component, @Nullable String[] setNames, @Nullable String[] unsetNames) throws Exception { + final Set options = new HashSet(getOptions(component)); + if (unsetNames != null) { + for (String name : unsetNames) { + options.remove(name); + } + } + if (setNames != null) { + Collections.addAll(options, setNames); + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + if (options.isEmpty()) { + XmlAttribute attribute = getAttribute(component); + if (attribute != null) { + attribute.delete(); + } + } + else { + component.getTag().setAttribute("android:" + myDefinition.getName(), StringUtil.join(options, "|")); + } + } + }); + } + + private abstract class ComboOptionProperty extends Property { + private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); + private final PropertyEditor myEditor = new StringsComboEditor(COMBO_ITEMS); + private final String[] myValues; + + public ComboOptionProperty(@Nullable Property parent, @NotNull String name, String[] values) { + super(parent, name); + myValues = values; + } + + @Nullable + public String getValue(Set options) { + StringBuilder values = new StringBuilder(); + int index = 0; + for (String value : myValues) { + if (options.contains(value)) { + if (index++ > 0) { + values.append(", "); + } + values.append(value); + } + } + return index == 0 ? null : values.toString(); + } + + @Override + public Object getValue(RadViewComponent component) throws Exception { + Set options = getOptions(component); + int lastIndex = -1; + for (int i = 0; i < myValues.length; i++) { + if (options.contains(myValues[i])) { + lastIndex = i; + } + } + return lastIndex == -1 ? null : COMBO_ITEMS[lastIndex]; + } + + @Override + public void setValue(RadViewComponent component, Object value) throws Exception { + int index = ArrayUtil.indexOf(COMBO_ITEMS, value); + if (index == -1) { + setOptions(component, null, myValues); + } + else { + setValue(component, index); + } + } + + protected abstract void setValue(RadViewComponent component, int index) throws Exception; + + @Override + public boolean isDefaultValue(RadViewComponent component) throws Exception { + Set options = getOptions(component); + for (String value : myValues) { + if (options.contains(value)) { + return false; + } + } + return true; + } + + @Override + public void setDefaultValue(RadViewComponent component) throws Exception { + setValue(component, null); + } + + @Override + public Property createForNewPresentation(@Nullable Property parent, @NotNull String name) { + return null; + } + + @NotNull + @Override + public PropertyRenderer getRenderer() { + return myRenderer; + } + + @Override + public PropertyEditor getEditor() { + return myEditor; + } + + @Override + public boolean needRefreshPropertyList() { + return true; + } + } +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/AttributePropertyWithDefault.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/AttributePropertyWithDefault.java deleted file mode 100644 index 6f9a31b5874d..000000000000 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/AttributePropertyWithDefault.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.intellij.android.designer.propertyTable.renderers; - -/** - * @author Alexander Lobas - */ -public class AttributePropertyWithDefault { -} diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/ResourceRenderer.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/ResourceRenderer.java index 79b1365d0568..6fdf76ee4e70 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/ResourceRenderer.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/renderers/ResourceRenderer.java @@ -17,13 +17,13 @@ package com.intellij.android.designer.propertyTable.renderers; import com.intellij.designer.model.RadComponent; import com.intellij.designer.propertyTable.PropertyRenderer; +import com.intellij.designer.propertyTable.PropertyTable; import com.intellij.designer.propertyTable.renderers.BooleanRenderer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.ArrayUtil; import com.intellij.util.ui.EmptyIcon; -import com.intellij.util.ui.UIUtil; import org.jetbrains.android.dom.attrs.AttributeFormat; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,17 +65,7 @@ public class ResourceRenderer implements PropertyRenderer { } myColoredComponent.clear(); - - if (selected) { - myColoredComponent.setForeground(UIUtil.getTableSelectionForeground()); - Color background = UIUtil.getTableSelectionBackground(); - myColoredComponent.setBackground(background); - } - else { - myColoredComponent.setForeground(UIUtil.getTableForeground()); - myColoredComponent.setBackground(UIUtil.getTableBackground()); - } - + PropertyTable.updateRenderer(myColoredComponent, selected); formatValue(value); return myColoredComponent; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java index 2fe0720f5257..e4c9310dd20a 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java @@ -898,6 +898,17 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi } } + public static void updateRenderer(JComponent component, boolean selected) { + if (selected) { + component.setForeground(UIUtil.getTableSelectionForeground()); + component.setBackground(UIUtil.getTableSelectionBackground()); + } + else { + component.setForeground(UIUtil.getTableForeground()); + component.setBackground(UIUtil.getTableBackground()); + } + } + private class PropertyCellRenderer implements TableCellRenderer { private final ColoredTableCellRenderer myPropertyNameRenderer; private final ColoredTableCellRenderer myErrorRenderer; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/BooleanRenderer.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/BooleanRenderer.java index 87f0ef2da5c0..9c156c01eae2 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/BooleanRenderer.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/BooleanRenderer.java @@ -17,7 +17,7 @@ package com.intellij.designer.propertyTable.renderers; import com.intellij.designer.model.RadComponent; import com.intellij.designer.propertyTable.PropertyRenderer; -import com.intellij.util.ui.UIUtil; +import com.intellij.designer.propertyTable.PropertyTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,15 +30,7 @@ import javax.swing.*; public class BooleanRenderer extends JCheckBox implements PropertyRenderer { @NotNull public JComponent getComponent(@Nullable RadComponent component, @Nullable Object value, boolean selected, boolean hasFocus) { - if (selected) { - setForeground(UIUtil.getTableSelectionForeground()); - setBackground(UIUtil.getTableSelectionBackground()); - } - else { - setForeground(UIUtil.getTableForeground()); - setBackground(UIUtil.getTableBackground()); - } - + PropertyTable.updateRenderer(this, selected); setSelected(value != null && (Boolean)value); return this; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/LabelPropertyRenderer.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/LabelPropertyRenderer.java index ac1117365212..4bdde0ee4aaa 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/LabelPropertyRenderer.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/renderers/LabelPropertyRenderer.java @@ -17,7 +17,7 @@ package com.intellij.designer.propertyTable.renderers; import com.intellij.designer.model.RadComponent; import com.intellij.designer.propertyTable.PropertyRenderer; -import com.intellij.util.ui.UIUtil; +import com.intellij.designer.propertyTable.PropertyTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,14 +47,7 @@ public class LabelPropertyRenderer extends JLabel implements PropertyRenderer { setIcon(null); // Background and foreground - if (selected) { - setForeground(UIUtil.getTableSelectionForeground()); - setBackground(UIUtil.getTableSelectionBackground()); - } - else { - setForeground(UIUtil.getTableForeground()); - setBackground(UIUtil.getTableBackground()); - } + PropertyTable.updateRenderer(this, selected); if (value != null) { customize(value);