diff options
author | Raphael Moll <ralf@android.com> | 2010-09-01 15:32:22 -0700 |
---|---|---|
committer | Raphael Moll <ralf@android.com> | 2010-09-01 16:33:22 -0700 |
commit | 44a39167e3f9ee89e495716b7c3f0094ab91f2b1 (patch) | |
tree | debe26f31c1a94b561a25785d90f4e54ddaa47e9 /eclipse/plugins | |
parent | eaba401355cb2258c4ccc0e2456fe1931f272c78 (diff) | |
download | sdk-44a39167e3f9ee89e495716b7c3f0094ab91f2b1.zip sdk-44a39167e3f9ee89e495716b7c3f0094ab91f2b1.tar.gz sdk-44a39167e3f9ee89e495716b7c3f0094ab91f2b1.tar.bz2 |
GLE2 context menu: Handle boolean properties as tri-state.
Also offer a clear option for enums and flags.
Change-Id: I682ba19d9f5a1c1d5da28909b02a90ec01f4fc62
Diffstat (limited to 'eclipse/plugins')
3 files changed, 128 insertions, 42 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/BaseView.groovy b/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/BaseView.groovy index 3a3844a..1ddf717 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/BaseView.groovy +++ b/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/BaseView.groovy @@ -138,21 +138,42 @@ public class BaseView implements IViewRule { if (prop) { node.editXml("Change attribute " + actionId) { if (prop.isToggle) { - node.setAttribute(ANDROID_URI, actionId, newValue ? "true" : ""); - } else if (props.isFlag) { - def values = node.getStringAttr(ANDROID_URI, actionId); - if (!values) values = ""; - values = values.split(","); - if (newValue) { - values << valueId; - } else { - values = values - valueId; + // case of toggle + String value = ""; + switch(valueId) { + case "1t": + value = newValue ? "true" : ""; + break; + case "2f": + value = newValue ? "false" : ""; + break; + } + node.setAttribute(ANDROID_URI, actionId, value); + } else if (prop.isFlag) { + // case of a flag + def values = ""; + if (valueId != "~2clr") { + values = node.getStringAttr(ANDROID_URI, actionId); + if (!values) { + values = [] as Set; + } else { + values = ([] as Set) + (values.split("\\|") as Set); + } + if (newValue) { + values << valueId; + } else { + values = values - valueId; + } + values = values.join("|"); } - values = values.join(",") node.setAttribute(ANDROID_URI, actionId, values); } else { - // it's an enum - node.setAttribute(ANDROID_URI, actionId, valueId); + // case of an enum + def value = ""; + if (valueId != "~2clr") { + value = newValue ? valueId : ""; + } + node.setAttribute(ANDROID_URI, actionId, value); } } } @@ -182,19 +203,22 @@ public class BaseView implements IViewRule { // Prepare the property map props = [:] for (attrInfo in selectedNode.getDeclaredAttributes()) { + def id = attrInfo?.getName(); + if (id == null || id == ATTR_LAYOUT_WIDTH || id == ATTR_LAYOUT_HEIGHT) { + // Layout width/height are already handled at the root level + continue; + } def formats = attrInfo?.getFormats(); if (formats == null) { continue; } + + def title = prettyName(id); + if (IAttributeInfo.Format.BOOLEAN in formats) { - def id = attrInfo.getName(); - def title = prettyName(id); props[id] = [ isToggle: true, title: title ]; } else if (IAttributeInfo.Format.ENUM in formats) { - def id = attrInfo.getName(); - def title = prettyName(id); - // Convert each enum into a map id=>title def values = [:]; attrInfo.getEnumValues().each { e -> values[e] = prettyName(e) } @@ -205,10 +229,7 @@ public class BaseView implements IViewRule { choices: values ]; } else if (IAttributeInfo.Format.FLAG in formats) { - def id = attrInfo.getName(); - def title = prettyName(id); - - // Convert each enum into a map id=>title + // Convert each flag into a map id=>title def values = [:]; attrInfo.getFlagValues().each { e -> values[e] = prettyName(e) }; @@ -226,15 +247,46 @@ public class BaseView implements IViewRule { props.each { id, p -> def a = null; if (p.isToggle) { + // Toggles are handled as a multiple-choice between true, false and nothing (clear) def value = selectedNode.getStringAttr(ANDROID_URI, id); - // is checked if value is defined and is true - value = value != null && Boolean.valueOf(value); - a = new MenuAction.Toggle("@prop@" + id, p.title, value, "properties", onChange); + if (value != null) value = value.toLowerCase(); + switch(value) { + case "true": + value = "1t"; + break; + case "false": + value = "2f"; + break; + default: + value = "4clr"; + break; + } + + a = new MenuAction.Choices( + "@prop@" + id, + p.title, + [ "1t": "True", + "2f": "False", + "3sep": MenuAction.Choices.SEPARATOR, + "4clr": "Clear" ], + value, + "properties", + onChange); } else { - // enum or flag + // Enum or flags. Their possible values are the multiple-choice items, + // with an extra "clear" option to remove everything. def current = selectedNode.getStringAttr(ANDROID_URI, id); + if (!current) { + current = "~2clr"; + } a = new MenuAction.Choices( - "@prop@" + id, p.title, p.choices, current, "properties", onChange); + "@prop@" + id, + p.title, + p.choices + [ "~1sep": MenuAction.Choices.SEPARATOR, + "~2clr": "Clear " + (p.isFlag ? "flag" : "enum") ], + current, + "properties", + onChange); } if (a) list2.add(a); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/MenuAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/MenuAction.java index 9c5f6bb..3674b02 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/MenuAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/MenuAction.java @@ -50,8 +50,11 @@ public abstract class MenuAction { * The unique id of the action. * @see #getId() */ - final private String mId; - final private String mTitle; + private final String mId; + /** + * The UI-visible title of the action. + */ + private final String mTitle; /** * Creates a new {@link MenuAction} with the given id and the given title. @@ -147,17 +150,19 @@ public abstract class MenuAction { */ public static abstract class Action extends MenuAction { + + /** * A closure executed when the action is selected in the context menu. * * @see #getAction() for details on the closure parameters. */ - final private Closure mAction; + private final Closure mAction; /** * An optional group id, to place the action in a given sub-menu. * @null This value can be null. */ - final private String mGroupId; + private final String mGroupId; /** * Constructs a new base {@link MenuAction} with its ID, title and action closure. @@ -289,22 +294,34 @@ public abstract class MenuAction { /** * A "choices" is a one-out-of-many-choices action, displayed as a sub-menu with one or more - * items, with either zero or one of them being checked. + * items, with either zero or more of them being checked. * <p/> * Implementation detail: empty choices will not be displayed in the context menu. * <p/> * Choice items are sorted by their id, using String's natural sorting order. */ public static class Choices extends Action { + + /** + * Special value which will insert a separator in the choices' submenu. + */ + public final static String SEPARATOR = "----"; + /** + * Character used to split multiple checked choices, see {@link #getCurrent()}. + * The pipe character "|" is used, to natively match Android resource flag separators. + */ + public final static String CHOICE_SEP = "|"; + /** * A non-null map of id=>choice-title. The map could be empty but not null. */ - final private Map<String, String> mChoices; + private final Map<String, String> mChoices; /** - * The id of the current choice, the one that will be check marked. + * One or more id for the checked choice(s) that will be check marked. * Can be null. Can be an id not present in the choices map. + * If more than one choice, they must be separated by {@link #CHOICE_SEP}. */ - final private String mCurrent; + private final String mCurrent; /** * Creates a new immutable multiple-choice action. @@ -313,8 +330,9 @@ public abstract class MenuAction { * @param id The unique id of the action. Cannot be null. * @param title The UI-visible title of the context menu item. Cannot be null. * @param choices A map id=>title for all the multiple-choice items. Cannot be null. - * @param current The id of the current choice, the one that will be check marked. + * @param current The id(s) of the current choice(s) that will be check marked. * Can be null. Can be an id not present in the choices map. + * There can be more than one id separated by {@link #CHOICE_SEP}. * @param action A closure to execute when the context menu item is selected. */ public Choices(String id, String title, @@ -330,8 +348,9 @@ public abstract class MenuAction { * @param id The unique id of the action. Cannot be null. * @param title The UI-visible title of the context menu item. Cannot be null. * @param choices A map id=>title for all the multiple-choice items. Cannot be null. - * @param current The id of the current choice, the one that will be check marked. + * @param current The id(s) of the current choice(s) that will be check marked. * Can be null. Can be an id not present in the choices map. + * There can be more than one id separated by {@link #CHOICE_SEP}. * @param groupId The optional group id, to place the action in a given sub-menu. * Can be null. * @param action A closure to execute when the context menu item is selected. @@ -354,8 +373,9 @@ public abstract class MenuAction { } /** - * Returns the id of the current choice, the one that will be check marked. + * Returns the id(s) of the current choice(s) that are check marked. * Can be null. Can be an id not present in the choices map. + * There can be more than one id separated by {@link #CHOICE_SEP}. */ public String getCurrent() { return mCurrent; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java index b640fef..b22999e 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java @@ -113,6 +113,7 @@ import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.awt.image.Raster; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -123,6 +124,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.Map.Entry; +import java.util.regex.Pattern; /** * Displays the image rendered by the {@link GraphicalEditorPart} and handles @@ -1963,8 +1965,7 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { // Closure parameters are action, valueId, newValue action, null, // no valueId for a toggle - !isChecked - ); + !isChecked); } } } @@ -1987,6 +1988,13 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { } String current = ((MenuAction.Choices) action).getCurrent(); + Set<String> currents = null; + if (current.indexOf(MenuAction.Choices.CHOICE_SEP) >= 0) { + currents = new HashSet<String>( + Arrays.asList(current.split( + Pattern.quote(MenuAction.Choices.CHOICE_SEP)))); + current = null; + } for (Entry<String, String> entry : choiceMap.entrySet() ) { final String key = entry.getKey(); @@ -1996,7 +2004,14 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { continue; } - final boolean isChecked = key.equals(current); + if (MenuAction.Choices.SEPARATOR.equals(title)) { + submenu.add(new Separator()); + continue; + } + + final boolean isChecked = + (currents != null && currents.contains(key)) || + key.equals(current); Action a = new Action(title, IAction.AS_CHECK_BOX) { @Override @@ -2009,8 +2024,7 @@ class LayoutCanvas extends Canvas implements ISelectionProvider { // Closure parameters are action, valueId, newValue action, key, - !isChecked - ); + !isChecked); } } } |