1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.ide.eclipse.adt.internal.editors.layout.gle2; 17 18 import static com.android.SdkConstants.ANDROID_LAYOUT_RESOURCE_PREFIX; 19 import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutMetadata.KEY_LV_FOOTER; 20 import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutMetadata.KEY_LV_HEADER; 21 import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutMetadata.KEY_LV_ITEM; 22 23 import com.android.annotations.NonNull; 24 import com.android.annotations.Nullable; 25 import com.android.ide.common.rendering.api.Capability; 26 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate; 27 import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; 28 import com.android.ide.eclipse.adt.internal.resources.CyclicDependencyValidator; 29 import com.android.ide.eclipse.adt.internal.ui.ResourceChooser; 30 import com.android.resources.ResourceType; 31 32 import org.eclipse.core.resources.IFile; 33 import org.eclipse.jface.action.Action; 34 import org.eclipse.jface.action.ActionContributionItem; 35 import org.eclipse.jface.action.IAction; 36 import org.eclipse.jface.action.Separator; 37 import org.eclipse.jface.window.Window; 38 import org.eclipse.swt.widgets.Menu; 39 import org.w3c.dom.Node; 40 41 /** 42 * "Preview List Content" context menu which lists available data types and layouts 43 * the user can choose to view the ListView as. 44 */ 45 public class ListViewTypeMenu extends SubmenuAction { 46 /** Associated canvas */ 47 private final LayoutCanvas mCanvas; 48 /** When true, this menu is for a grid rather than a simple list */ 49 private boolean mGrid; 50 /** When true, this menu is for a spinner rather than a simple list */ 51 private boolean mSpinner; 52 53 /** 54 * Creates a "Preview List Content" menu 55 * 56 * @param canvas associated canvas 57 * @param isGrid whether the menu is for a grid rather than a list 58 * @param isSpinner whether the menu is for a spinner rather than a list 59 */ ListViewTypeMenu(LayoutCanvas canvas, boolean isGrid, boolean isSpinner)60 public ListViewTypeMenu(LayoutCanvas canvas, boolean isGrid, boolean isSpinner) { 61 super(isGrid ? "Preview Grid Content" : isSpinner ? "Preview Spinner Layout" 62 : "Preview List Content"); 63 mCanvas = canvas; 64 mGrid = isGrid; 65 mSpinner = isSpinner; 66 } 67 68 @Override addMenuItems(Menu menu)69 protected void addMenuItems(Menu menu) { 70 GraphicalEditorPart graphicalEditor = mCanvas.getEditorDelegate().getGraphicalEditor(); 71 if (graphicalEditor.renderingSupports(Capability.ADAPTER_BINDING)) { 72 IAction action = new PickLayoutAction("Choose Layout...", KEY_LV_ITEM); 73 new ActionContributionItem(action).fill(menu, -1); 74 new Separator().fill(menu, -1); 75 76 String selected = getSelectedLayout(); 77 if (selected != null) { 78 if (selected.startsWith(ANDROID_LAYOUT_RESOURCE_PREFIX)) { 79 selected = selected.substring(ANDROID_LAYOUT_RESOURCE_PREFIX.length()); 80 } 81 } 82 83 if (mSpinner) { 84 action = new SetListTypeAction("Spinner Item", 85 "simple_spinner_item", selected); //$NON-NLS-1$ 86 new ActionContributionItem(action).fill(menu, -1); 87 action = new SetListTypeAction("Spinner Dropdown Item", 88 "simple_spinner_dropdown_item", selected); //$NON-NLS-1$ 89 new ActionContributionItem(action).fill(menu, -1); 90 return; 91 } 92 93 action = new SetListTypeAction("Simple List Item", 94 "simple_list_item_1", selected); //$NON-NLS-1$ 95 new ActionContributionItem(action).fill(menu, -1); 96 action = new SetListTypeAction("Simple 2-Line List Item", 97 "simple_list_item_2", //$NON-NLS-1$ 98 selected); 99 new ActionContributionItem(action).fill(menu, -1); 100 action = new SetListTypeAction("Checked List Item", 101 "simple_list_item_checked", //$NON-NLS-1$ 102 selected); 103 new ActionContributionItem(action).fill(menu, -1); 104 action = new SetListTypeAction("Single Choice List Item", 105 "simple_list_item_single_choice", //$NON-NLS-1$ 106 selected); 107 new ActionContributionItem(action).fill(menu, -1); 108 action = new SetListTypeAction("Multiple Choice List Item", 109 "simple_list_item_multiple_choice", //$NON-NLS-1$ 110 selected); 111 if (!mGrid) { 112 new Separator().fill(menu, -1); 113 action = new SetListTypeAction("Simple Expandable List Item", 114 "simple_expandable_list_item_1", selected); //$NON-NLS-1$ 115 new ActionContributionItem(action).fill(menu, -1); 116 action = new SetListTypeAction("Simple 2-Line Expandable List Item", 117 "simple_expandable_list_item_2", //$NON-NLS-1$ 118 selected); 119 new ActionContributionItem(action).fill(menu, -1); 120 121 new Separator().fill(menu, -1); 122 action = new PickLayoutAction("Choose Header...", KEY_LV_HEADER); 123 new ActionContributionItem(action).fill(menu, -1); 124 action = new PickLayoutAction("Choose Footer...", KEY_LV_FOOTER); 125 new ActionContributionItem(action).fill(menu, -1); 126 } 127 } else { 128 // Should we just hide the menu item instead? 129 addDisabledMessageItem( 130 "Not supported for this SDK version; try changing the Render Target"); 131 } 132 } 133 134 private class SetListTypeAction extends Action { 135 private final String mLayout; 136 SetListTypeAction(String title, String layout, String selected)137 public SetListTypeAction(String title, String layout, String selected) { 138 super(title, IAction.AS_RADIO_BUTTON); 139 mLayout = layout; 140 141 if (layout.equals(selected)) { 142 setChecked(true); 143 } 144 } 145 146 @Override run()147 public void run() { 148 if (isChecked()) { 149 setNewType(KEY_LV_ITEM, ANDROID_LAYOUT_RESOURCE_PREFIX + mLayout); 150 } 151 } 152 } 153 154 /** 155 * Action which brings up a resource chooser to choose an arbitrary layout as the 156 * layout to be previewed in the list. 157 */ 158 private class PickLayoutAction extends Action { 159 private final String mType; 160 PickLayoutAction(String title, String type)161 public PickLayoutAction(String title, String type) { 162 super(title, IAction.AS_PUSH_BUTTON); 163 mType = type; 164 } 165 166 @Override run()167 public void run() { 168 LayoutEditorDelegate delegate = mCanvas.getEditorDelegate(); 169 IFile file = delegate.getEditor().getInputFile(); 170 GraphicalEditorPart editor = delegate.getGraphicalEditor(); 171 ResourceChooser dlg = ResourceChooser.create(editor, ResourceType.LAYOUT) 172 .setInputValidator(CyclicDependencyValidator.create(file)) 173 .setInitialSize(85, 10) 174 .setCurrentResource(getSelectedLayout()); 175 int result = dlg.open(); 176 if (result == ResourceChooser.CLEAR_RETURN_CODE) { 177 setNewType(mType, null); 178 } else if (result == Window.OK) { 179 String newType = dlg.getCurrentResource(); 180 setNewType(mType, newType); 181 } 182 } 183 } 184 185 @Nullable getSelectedLayout()186 private String getSelectedLayout() { 187 String layout = null; 188 SelectionManager selectionManager = mCanvas.getSelectionManager(); 189 for (SelectionItem item : selectionManager.getSelections()) { 190 UiViewElementNode node = item.getViewInfo().getUiViewNode(); 191 if (node != null) { 192 Node xmlNode = node.getXmlNode(); 193 layout = LayoutMetadata.getProperty(xmlNode, KEY_LV_ITEM); 194 if (layout != null) { 195 return layout; 196 } 197 } 198 } 199 200 return null; 201 } 202 setNewType(@onNull String type, @Nullable String layout)203 private void setNewType(@NonNull String type, @Nullable String layout) { 204 LayoutEditorDelegate delegate = mCanvas.getEditorDelegate(); 205 GraphicalEditorPart graphicalEditor = delegate.getGraphicalEditor(); 206 SelectionManager selectionManager = mCanvas.getSelectionManager(); 207 208 for (SelectionItem item : selectionManager.getSnapshot()) { 209 UiViewElementNode node = item.getViewInfo().getUiViewNode(); 210 if (node != null) { 211 Node xmlNode = node.getXmlNode(); 212 LayoutMetadata.setProperty(delegate.getEditor(), xmlNode, type, layout); 213 } 214 } 215 216 // Refresh 217 graphicalEditor.recomputeLayout(); 218 mCanvas.redraw(); 219 } 220 } 221