aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse/plugins
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2011-05-13 13:25:15 -0700
committerTor Norbye <tnorbye@google.com>2011-05-13 13:31:49 -0700
commitec22f92d53f4bb74313b91aa491acbfbbb6dc9ce (patch)
treec599becdac246961adc3361a4f90bcbbb9f42875 /eclipse/plugins
parentddc754e4650a4b48a82a96f4d38bdeb468059f29 (diff)
downloadsdk-ec22f92d53f4bb74313b91aa491acbfbbb6dc9ce.zip
sdk-ec22f92d53f4bb74313b91aa491acbfbbb6dc9ce.tar.gz
sdk-ec22f92d53f4bb74313b91aa491acbfbbb6dc9ce.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
Diffstat (limited to 'eclipse/plugins')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/icons/view.pngbin0 -> 394 bytes
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/ViewRule.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java31
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java15
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteControl.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ViewMetadataRepository.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java12
8 files changed, 66 insertions, 12 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
new file mode 100644
index 0000000..35c4d8f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png
Binary files differ
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 4613492..24aea33 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
@@ -63,6 +63,15 @@ public final class LayoutDescriptors implements IDescriptorProvider {
public static final String REQUEST_FOCUS = "requestFocus";//$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!
@@ -353,7 +362,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
}
/**
- * Creates and return a new {@code <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.
*/
@@ -379,9 +388,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
}
/**
- * Creates and return a new {@code <requestFocus>} descriptor.
- * @param knownLayouts A list of all known layout view descriptors, used to find the
- * FrameLayout descriptor and extract its layout attributes.
+ * Creates and returns a new {@code <requestFocus>} descriptor.
*/
private ViewElementDescriptor createRequestFocus() {
String xml_name = REQUEST_FOCUS;
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 2227531..4b4bf96 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) {