diff options
author | Tor Norbye <tnorbye@google.com> | 2011-05-13 13:25:15 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2011-05-17 13:22:01 -0700 |
commit | 9718ea331bfc609927b1ec2a2e7453579666fa4d (patch) | |
tree | 578a32dd794c7d602d3edff3806e0beac72a15d3 /eclipse/plugins | |
parent | 6db93e9e7e8cb1281e3b75d6dfe467126cd9653f (diff) | |
download | sdk-9718ea331bfc609927b1ec2a2e7453579666fa4d.zip sdk-9718ea331bfc609927b1ec2a2e7453579666fa4d.tar.gz sdk-9718ea331bfc609927b1ec2a2e7453579666fa4d.tar.bz2 |
Custom View handling improvements
First and foremost, allow custom views to accept children such that
you can drag & drop children into the custom view in the outline.
Second, prevent an NPE which can occur if you drag into a layout where
the root element is a custom view.
Third, handle <view> (not <View>) better: provide a custom icon, and
inline the view class name in the outline label.
Fourth, allow double clicks (in addition to ctrl-click which is already
supported) on the custom views in the palette to allow jumping to the
custom view code.
Change-Id: I13c2bf2f4169185c9fcc893ce487f2abdac46802
Conflicts:
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java
Diffstat (limited to 'eclipse/plugins')
8 files changed, 65 insertions, 9 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png Binary files differnew file mode 100644 index 0000000..35c4d8f --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/ViewRule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/ViewRule.java index 470b6a4..a7b23ab 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/ViewRule.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/ViewRule.java @@ -24,7 +24,7 @@ import com.android.ide.common.api.IViewRule; * apply. * <p/> * There is no customization here, everything that is common to all views is - * simply implemented in BaseView. + * simply implemented in BaseViewRule. */ public class ViewRule extends BaseViewRule { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java index db72ac6..be9fe34 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java @@ -16,6 +16,8 @@ package com.android.ide.eclipse.adt.internal.editors.layout.descriptors; +import static com.android.sdklib.SdkConstants.CLASS_VIEWGROUP; + import com.android.ide.common.resources.platform.ViewClassInfo; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; @@ -164,7 +166,8 @@ public final class CustomViewDescriptorService { String name = DescriptorsUtils.getBasename(fqcn); ViewElementDescriptor descriptor = new CustomViewDescriptor(name, fqcn, - getAttributeDescriptor(type, parentDescriptor)); + getAttributeDescriptor(type, parentDescriptor), + parentDescriptor.hasChildren()); descriptor.setSuperClass(parentDescriptor); synchronized (mCustomDescriptorMap) { @@ -241,8 +244,14 @@ public final class CustomViewDescriptorService { // parent class is a valid View class with a descriptor, so we create one // for this class. String name = DescriptorsUtils.getBasename(fqcn); + // A custom view accepts children if its parent descriptor also does. + // The only exception to this is ViewGroup, which accepts children even though + // its parent does not. + boolean isViewGroup = fqcn.equals(CLASS_VIEWGROUP); + boolean hasChildren = isViewGroup || parentDescriptor.hasChildren(); ViewElementDescriptor descriptor = new CustomViewDescriptor(name, fqcn, - getAttributeDescriptor(type, parentDescriptor)); + getAttributeDescriptor(type, parentDescriptor), + hasChildren); descriptor.setSuperClass(parentDescriptor); // add it to the map @@ -283,7 +292,10 @@ public final class CustomViewDescriptorService { } private class CustomViewDescriptor extends ViewElementDescriptor { - public CustomViewDescriptor(String name, String fqcn, AttributeDescriptor[] attributes) { + private boolean mHasChildren; + + public CustomViewDescriptor(String name, String fqcn, AttributeDescriptor[] attributes, + boolean hasChildren) { super( fqcn, // xml name name, // ui name @@ -295,8 +307,21 @@ public final class CustomViewDescriptorService { null, // children false // mandatory ); + mHasChildren = hasChildren; + } + + /** + * {@inheritDoc} + * <p> + * Custom views can accept children even if we have no information about + * allowed children. + */ + @Override + public boolean hasChildren() { + return mHasChildren; } + @Override public Image getGenericIcon() { // Java source file icon. We could use the Java class icon here diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java index b61c069..172802e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java @@ -56,6 +56,15 @@ public final class LayoutDescriptors implements IDescriptorProvider { public static final String VIEW_MERGE = "merge"; //$NON-NLS-1$ /** + * The XML name of the special {@code <view>} layout tag. This is used to add generic + * views with a class attribute to specify the view. + * <p> + * TODO: We should add a synthetic descriptor for this, similar to our descriptors for + * include, merge and requestFocus. + */ + public static final String VIEW_VIEWTAG = "view"; //$NON-NLS-1$ + + /** * The attribute name of the include tag's url naming the resource to be inserted * <p> * <b>NOTE</b>: The layout attribute is NOT in the Android namespace! @@ -342,7 +351,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { } /** - * Creates and return a new <merge> descriptor. + * Creates and returns a new {@code <merge>} descriptor. * @param knownLayouts A list of all known layout view descriptors, used to find the * FrameLayout descriptor and extract its layout attributes. */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java index a2cdbe6..a56eb16 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java @@ -674,7 +674,7 @@ public class MoveGesture extends DropGesture { // Update outline to show the target node there OutlinePage outline = mCanvas.getOutlinePage(); TreeSelection newSelection = TreeSelection.EMPTY; - if (mCurrentView != null) { + if (mCurrentView != null && mTargetNode != null) { // Find the view corresponding to the target node. The current view can be a leaf // view whereas the target node is always a parent layout. if (mCurrentView.getUiViewNode() != mTargetNode.getNode()) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteControl.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteControl.java index f7f23da..c8bca9c 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteControl.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteControl.java @@ -23,14 +23,14 @@ import static com.android.ide.common.layout.LayoutConstants.ATTR_TEXT; import static com.android.ide.common.layout.LayoutConstants.VALUE_WRAP_CONTENT; import com.android.ide.common.api.InsertType; -import com.android.ide.common.api.MenuAction.Toggle; import com.android.ide.common.api.Rect; +import com.android.ide.common.api.MenuAction.Toggle; import com.android.ide.common.rendering.LayoutLibrary; import com.android.ide.common.rendering.api.Capability; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderSession; -import com.android.ide.common.rendering.api.SessionParams.RenderingMode; import com.android.ide.common.rendering.api.ViewInfo; +import com.android.ide.common.rendering.api.SessionParams.RenderingMode; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.editors.IconFactory; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; @@ -572,10 +572,16 @@ public class PaletteControl extends Composite { Control item = createItem(parent, desc); // Add control-click listener on custom view items to you can warp to + // (and double click listener too -- the more discoverable, the better.) if (item instanceof IconTextItem) { IconTextItem it = (IconTextItem) item; it.addMouseListener(new MouseAdapter() { @Override + public void mouseDoubleClick(MouseEvent e) { + AdtPlugin.openJavaClass(mEditor.getProject(), fqcn); + } + + @Override public void mouseDown(MouseEvent e) { if ((e.stateMask & SWT.MOD1) != 0) { AdtPlugin.openJavaClass(mEditor.getProject(), fqcn); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java index cf6acba..42b4a16 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java @@ -343,13 +343,17 @@ public class ViewMetadataRepository { String fqcn = view.getFcqn(); ViewElementDescriptor descriptor = fqcnToDescriptor.get(fqcn); if (descriptor != null) { + remaining.remove(descriptor); + if (view.getSkip()) { + continue; + } + if (view.getDisplayName() != null || view.getInitString().length() > 0) { categoryItems.add(new PaletteMetadataDescriptor(descriptor, view.getDisplayName(), view.getInitString(), view.getIconName())); } else { categoryItems.add(descriptor); } - remaining.remove(descriptor); if (view.hasVariations()) { for (ViewData variation : view.getVariations()) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java index 93b6baf..e2b6ccf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java @@ -17,6 +17,7 @@ package com.android.ide.eclipse.adt.internal.editors.uimodel; import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME; +import static com.android.ide.common.layout.LayoutConstants.ATTR_CLASS; import static com.android.ide.common.layout.LayoutConstants.ID_PREFIX; import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX; import static com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor.XMLNS; @@ -288,6 +289,17 @@ public class UiElementNode implements IPropertySource { public StyledString getStyledDescription() { String uiName = mDescriptor.getUiName(); + // Special case: for <view>, show the class attribute value instead. + // This is done here rather than in the descriptor since this depends on + // node instance data. + if (LayoutDescriptors.VIEW_VIEWTAG.equals(uiName) && mXmlNode instanceof Element) { + Element element = (Element) mXmlNode; + String cls = element.getAttribute(ATTR_CLASS); + if (cls != null) { + uiName = cls.substring(cls.lastIndexOf('.') + 1); + } + } + StyledString styledString = new StyledString(); String attr = getDescAttribute(); if (attr != null) { |