aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eclipse/dictionary.txt1
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java13
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/Segment.java5
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/RelativeLayoutRule.java21
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/DependencyGraph.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelineHandler.java83
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/Match.java29
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/MoveHandler.java15
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/ResizeHandler.java11
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java5
12 files changed, 165 insertions, 36 deletions
diff --git a/eclipse/dictionary.txt b/eclipse/dictionary.txt
index 853cb3c..86f5e2f 100644
--- a/eclipse/dictionary.txt
+++ b/eclipse/dictionary.txt
@@ -152,6 +152,7 @@ num
ok
os
palette
+param
params
pings
placeholder
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java
index b696332..eb3f7e7 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java
@@ -210,5 +210,18 @@ public interface IClientRulesEngine {
*/
String getAttribute(INode node, String namespace, String localName);
}
+
+ /**
+ * Given a UI root node and a potential XML node name, returns the first available id
+ * that matches the pattern "prefix%d".
+ * <p/>
+ * TabWidget is a special case and the method will always return "@android:id/tabs".
+ *
+ * @param fqcn The fully qualified class name of the view to generate a unique id for
+ * @return A suitable generated id in the attribute form needed by the XML id tag
+ * (e.g. "@+id/something")
+ */
+ public String getUniqueId(String fqcn);
+
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/Segment.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/Segment.java
index 845f82d..0fb961a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/Segment.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/Segment.java
@@ -45,7 +45,10 @@ public class Segment {
/** The node that contains this edge */
public final INode node;
- /** The id of the node */
+ /**
+ * The id of the node. May be null (in which case id should be generated when
+ * move/resize is completed
+ */
public final String id;
public Segment(int at, int from, int to, INode node, String id, SegmentType edgeType,
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/RelativeLayoutRule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/RelativeLayoutRule.java
index 5b3334e..c332649 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/RelativeLayoutRule.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/RelativeLayoutRule.java
@@ -187,6 +187,7 @@ public class RelativeLayoutRule extends BaseLayoutRule {
state.removeCycles();
// Now write the new elements.
+ INode previous = null;
for (IDragElement element : elements) {
String fqcn = element.getFqcn();
@@ -202,7 +203,25 @@ public class RelativeLayoutRule extends BaseLayoutRule {
addAttributes(newChild, element, idMap, BaseLayoutRule.DEFAULT_ATTR_FILTER);
addInnerElements(newChild, element, idMap);
- state.applyConstraints(newChild);
+ if (previous == null) {
+ state.applyConstraints(newChild);
+ previous = newChild;
+ } else {
+ // Arrange the nodes next to each other, depending on which
+ // edge we are attaching to. For example, if attaching to the
+ // top edge, arrange the subsequent nodes in a column below it.
+ //
+ // TODO: Try to do something smarter here where we detect
+ // constraints between the dragged edges, and we preserve these.
+ // We have to do this carefully though because if the
+ // constraints go through some other nodes not part of the
+ // selection, this doesn't work right, and you might be
+ // dragging several connected components, which we'd then
+ // need to stitch together such that they are all visible.
+
+ state.attachPrevious(previous, newChild);
+ previous = newChild;
+ }
}
}
});
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/DependencyGraph.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/DependencyGraph.java
index a0039fb..0b1d9e6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/DependencyGraph.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/DependencyGraph.java
@@ -21,8 +21,8 @@ import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_PREFIX;
import static com.android.ide.common.layout.LayoutConstants.VALUE_TRUE;
import com.android.ide.common.api.IDragElement;
-import com.android.ide.common.api.INode;
import com.android.ide.common.api.IDragElement.IDragAttribute;
+import com.android.ide.common.api.INode;
import com.android.ide.common.api.INode.IAttribute;
import com.android.ide.common.layout.BaseLayoutRule;
@@ -150,8 +150,8 @@ class DependencyGraph {
*
* @param nodes the set of nodes that we want to compute the transitive dependencies
* for
- * @param vertical if true, look for vertical dependencies, otherwise look for
- * horizontal dependencies
+ * @param vertical if true, look for vertical edge dependencies, otherwise look for
+ * horizontal edge dependencies
* @return the set of nodes that directly or indirectly depend on the given nodes in
* the given direction
*/
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelineHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelineHandler.java
index 8faf364..7c6e1d2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelineHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelineHandler.java
@@ -24,6 +24,7 @@ import static com.android.ide.common.api.SegmentType.RIGHT;
import static com.android.ide.common.api.SegmentType.TOP;
import static com.android.ide.common.layout.BaseLayoutRule.getMaxMatchDistance;
import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ABOVE;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_BASELINE;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_BOTTOM;
@@ -109,13 +110,15 @@ public class GuidelineHandler {
/**
* The set of nodes which depend on the currently selected nodes, including
- * transitively, through horizontal constraints.
+ * transitively, through horizontal constraints (a "horizontal constraint"
+ * is a constraint between two horizontal edges)
*/
protected Set<INode> mHorizontalDeps;
/**
* The set of nodes which depend on the currently selected nodes, including
- * transitively, through vertical constraints.
+ * transitively, through vertical constraints (a "vertical constraint"
+ * is a constraint between two vertical edges)
*/
protected Set<INode> mVerticalDeps;
@@ -468,7 +471,7 @@ public class GuidelineHandler {
continue;
}
- Match match = new Match(edge, draggedEdge, type, delta);
+ Match match = new Match(this, edge, draggedEdge, type, delta);
if (distance < closestDistance) {
closest.clear();
@@ -492,6 +495,8 @@ public class GuidelineHandler {
/**
* Given a node, apply the suggestions by expressing them as relative layout param
* values
+ *
+ * @param n the node to apply constraints to
*/
public void applyConstraints(INode n) {
// Process each edge separately
@@ -548,25 +553,25 @@ public class GuidelineHandler {
}
if (mMoveTop && mCurrentTopMatch != null) {
- applyConstraint(n, mCurrentTopMatch.getConstraint());
+ applyConstraint(n, mCurrentTopMatch.getConstraint(true /* generateId */));
if (mCurrentTopMatch.type == ALIGN_BASELINE) {
// HACK! WORKAROUND! Baseline doesn't provide a new bottom edge for attachments
- String c = mCurrentTopMatch.getConstraint();
+ String c = mCurrentTopMatch.getConstraint(true);
c = c.replace(ATTR_LAYOUT_ALIGN_BASELINE, ATTR_LAYOUT_ALIGN_BOTTOM);
applyConstraint(n, c);
}
}
if (mMoveBottom && mCurrentBottomMatch != null) {
- applyConstraint(n, mCurrentBottomMatch.getConstraint());
+ applyConstraint(n, mCurrentBottomMatch.getConstraint(true));
}
if (mMoveLeft && mCurrentLeftMatch != null) {
- applyConstraint(n, mCurrentLeftMatch.getConstraint());
+ applyConstraint(n, mCurrentLeftMatch.getConstraint(true));
}
if (mMoveRight && mCurrentRightMatch != null) {
- applyConstraint(n, mCurrentRightMatch.getConstraint());
+ applyConstraint(n, mCurrentRightMatch.getConstraint(true));
}
if (mMoveLeft) {
@@ -588,7 +593,6 @@ public class GuidelineHandler {
String name = constraint.substring(0, constraint.indexOf('='));
String value = constraint.substring(constraint.indexOf('=') + 1);
n.setAttribute(ANDROID_URI, name, value);
-
}
private void applyMargin(INode n, String marginAttribute, int margin) {
@@ -601,6 +605,58 @@ public class GuidelineHandler {
}
}
+ private void removeRelativeParams(INode node) {
+ for (ConstraintType type : ConstraintType.values()) {
+ node.setAttribute(ANDROID_URI, type.name, null);
+ }
+ node.setAttribute(ANDROID_URI,ATTR_LAYOUT_MARGIN_LEFT, null);
+ node.setAttribute(ANDROID_URI,ATTR_LAYOUT_MARGIN_RIGHT, null);
+ node.setAttribute(ANDROID_URI,ATTR_LAYOUT_MARGIN_TOP, null);
+ node.setAttribute(ANDROID_URI,ATTR_LAYOUT_MARGIN_BOTTOM, null);
+ }
+
+ /**
+ * Attach the new child to the previous node
+ * @param previous the previous child
+ * @param node the new child to attach it to
+ */
+ public void attachPrevious(INode previous, INode node) {
+ removeRelativeParams(node);
+
+ String id = previous.getStringAttr(ANDROID_URI, ATTR_ID);
+ if (id == null) {
+ return;
+ }
+
+ if (mCurrentTopMatch != null || mCurrentBottomMatch != null) {
+ // Attaching the top: arrange below, and for bottom arrange above
+ node.setAttribute(ANDROID_URI,
+ mCurrentTopMatch != null ? ATTR_LAYOUT_BELOW : ATTR_LAYOUT_ABOVE, id);
+ // Apply same left/right constraints as the parent
+ if (mCurrentLeftMatch != null) {
+ applyConstraint(node, mCurrentLeftMatch.getConstraint(true));
+ applyMargin(node, ATTR_LAYOUT_MARGIN_LEFT, mLeftMargin);
+ } else if (mCurrentRightMatch != null) {
+ applyConstraint(node, mCurrentRightMatch.getConstraint(true));
+ applyMargin(node, ATTR_LAYOUT_MARGIN_RIGHT, mRightMargin);
+ }
+ } else if (mCurrentLeftMatch != null || mCurrentRightMatch != null) {
+ node.setAttribute(ANDROID_URI,
+ mCurrentLeftMatch != null ? ATTR_LAYOUT_TO_RIGHT_OF : ATTR_LAYOUT_TO_LEFT_OF,
+ id);
+ // Apply same top/bottom constraints as the parent
+ if (mCurrentTopMatch != null) {
+ applyConstraint(node, mCurrentTopMatch.getConstraint(true));
+ applyMargin(node, ATTR_LAYOUT_MARGIN_TOP, mTopMargin);
+ } else if (mCurrentBottomMatch != null) {
+ applyConstraint(node, mCurrentBottomMatch.getConstraint(true));
+ applyMargin(node, ATTR_LAYOUT_MARGIN_BOTTOM, mBottomMargin);
+ }
+ } else {
+ return;
+ }
+ }
+
public void removeCycles() {
if (mHorizontalCycle != null) {
removeCycles(mHorizontalDeps);
@@ -762,4 +818,13 @@ public class GuidelineHandler {
return 0;
}
}
+
+ /**
+ * Returns the {@link IClientRulesEngine} IDE callback
+ *
+ * @return the {@link IClientRulesEngine} IDE callback, never null
+ */
+ public IClientRulesEngine getRulesEngine() {
+ return mRulesEngine;
+ }
} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java
index 158a792..be0fb09 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java
@@ -130,7 +130,7 @@ public final class GuidelinePainter implements IFeedbackPainter {
// Display the constraint. Remove the @id/ and @+id/ prefixes to make the text
// shorter and easier to read. This doesn't use stripPrefix() because the id is
// usually not a prefix of the value (for example, 'layout_alignBottom=@+id/foo').
- String constraint = m.getConstraint();
+ String constraint = m.getConstraint(false /* generateId */);
String description = constraint.replace(NEW_ID_PREFIX, "").replace(ID_PREFIX, "");
if (description.startsWith(ATTR_LAYOUT_PREFIX)) {
description = description.substring(ATTR_LAYOUT_PREFIX.length());
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/Match.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/Match.java
index a341113..98d02e8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/Match.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/Match.java
@@ -15,6 +15,8 @@
*/
package com.android.ide.common.layout.relative;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
import static com.android.ide.common.layout.LayoutConstants.VALUE_TRUE;
import com.android.ide.common.api.Segment;
@@ -36,15 +38,22 @@ class Match {
/** whether this {@link Match} results in a cycle */
public boolean cycle;
+ /** The associated {@link GuidelineHander} which performed the match */
+ private final GuidelineHandler mHandler;
+
/**
* Create a new match.
*
+ * @param handler the handler which performed the match
* @param edge the "other" edge that the dragged edge is matched with
* @param with the edge of the dragged node that is matched
* @param type the type of constraint this is a match for
* @param delta the signed distance between the matched edges
*/
- public Match(Segment edge, Segment with, ConstraintType type, int delta) {
+ public Match(GuidelineHandler handler, Segment edge, Segment with,
+ ConstraintType type, int delta) {
+ mHandler = handler;
+
this.edge = edge;
this.with = with;
this.type = type;
@@ -54,13 +63,29 @@ class Match {
/**
* Returns the XML constraint attribute value for this match
*
+ * @param generateId whether an id should be generated if one is missing
* @return the XML constraint attribute value for this match
*/
- public String getConstraint() {
+ public String getConstraint(boolean generateId) {
if (type.targetParent) {
return type.name + '=' + VALUE_TRUE;
} else {
String id = edge.id;
+ if (id == null || id.length() == -1) {
+ if (!generateId) {
+ // Placeholder to display for the user during dragging
+ id = "<generated>";
+ } else {
+ // Must generate an id on the fly!
+ // See if it's been set by a different constraint we've already applied
+ // to this same node
+ id = edge.node.getStringAttr(ANDROID_URI, ATTR_ID);
+ if (id == null || id.length() == 0) {
+ id = mHandler.getRulesEngine().getUniqueId(edge.node.getFqcn());
+ edge.node.setAttribute(ANDROID_URI, ATTR_ID, id);
+ }
+ }
+ }
return type.name + '=' + id;
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/MoveHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/MoveHandler.java
index c7d25b4..a2f9ac2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/MoveHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/MoveHandler.java
@@ -63,8 +63,8 @@ public class MoveHandler extends GuidelineHandler {
}
mDraggedNodes = nodes;
- mHorizontalDeps = mDependencyGraph.dependsOn(nodes, false /* vertical */);
- mVerticalDeps = mDependencyGraph.dependsOn(nodes, true /* vertical */);
+ mHorizontalDeps = mDependencyGraph.dependsOn(nodes, false /* verticalEdge */);
+ mVerticalDeps = mDependencyGraph.dependsOn(nodes, true /* verticalEdge */);
for (INode child : layout.getChildren()) {
Rect bc = child.getBounds();
@@ -81,12 +81,9 @@ public class MoveHandler extends GuidelineHandler {
}
if (!isDragged) {
- // Need an id to reference child in attachments to it, so skip
- // nodes without ids
String id = child.getStringAttr(ANDROID_URI, ATTR_ID);
- if (id == null) {
- continue;
- }
+ // It's okay for id to be null; if you apply a constraint
+ // to a node with a missing id we will generate the id
boolean addHorizontal = !mHorizontalDeps.contains(child);
boolean addVertical = !mVerticalDeps.contains(child);
@@ -233,7 +230,7 @@ public class MoveHandler extends GuidelineHandler {
Match match = pickBestMatch(mHorizontalSuggestions);
if (match != null) {
- if (mVerticalDeps.contains(match.edge.node)) {
+ if (mHorizontalDeps.contains(match.edge.node)) {
match.cycle = true;
}
@@ -259,7 +256,7 @@ public class MoveHandler extends GuidelineHandler {
match = pickBestMatch(mVerticalSuggestions);
if (match != null) {
- if (mHorizontalDeps.contains(match.edge.node)) {
+ if (mVerticalDeps.contains(match.edge.node)) {
match.cycle = true;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/ResizeHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/ResizeHandler.java
index 870798d..6cf421a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/ResizeHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/ResizeHandler.java
@@ -84,14 +84,7 @@ public class ResizeHandler extends GuidelineHandler {
for (INode child : layout.getChildren()) {
if (child != resized) {
- // Need an id to reference child in attachments to it, so skip nodes
- // without ids
- // TODO: Generate an id on the fly when needed (at commit time) instead!
String id = child.getStringAttr(ANDROID_URI, ATTR_ID);
- if (id == null) {
- continue;
- }
-
addBounds(child, id,
!mHorizontalDeps.contains(child),
!mVerticalDeps.contains(child));
@@ -208,7 +201,7 @@ public class ResizeHandler extends GuidelineHandler {
Match match = pickBestMatch(mHorizontalSuggestions);
if (match != null
&& (!mSnap || Math.abs(match.delta) < BaseLayoutRule.getMaxMatchDistance())) {
- if (mVerticalDeps.contains(match.edge.node)) {
+ if (mHorizontalDeps.contains(match.edge.node)) {
match.cycle = true;
}
@@ -232,7 +225,7 @@ public class ResizeHandler extends GuidelineHandler {
Match match = pickBestMatch(mVerticalSuggestions);
if (match != null
&& (!mSnap || Math.abs(match.delta) < BaseLayoutRule.getMaxMatchDistance())) {
- if (mHorizontalDeps.contains(match.edge.node)) {
+ if (mVerticalDeps.contains(match.edge.node)) {
match.cycle = true;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java
index 5f60911..e23f05c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/ClientRulesEngine.java
@@ -29,21 +29,23 @@ import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
+import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutCanvas;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionManager;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
+import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.resources.CyclicDependencyValidator;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.ui.MarginChooser;
-import com.android.ide.eclipse.adt.internal.ui.ResourcePreviewHelper;
import com.android.ide.eclipse.adt.internal.ui.ReferenceChooserDialog;
import com.android.ide.eclipse.adt.internal.ui.ResourceChooser;
+import com.android.ide.eclipse.adt.internal.ui.ResourcePreviewHelper;
import com.android.resources.ResourceType;
import com.android.sdklib.IAndroidTarget;
@@ -481,4 +483,10 @@ class ClientRulesEngine implements IClientRulesEngine {
}
}
+ public String getUniqueId(String fqcn) {
+ UiDocumentNode root = mRulesEngine.getEditor().getModel();
+ String prefix = fqcn.substring(fqcn.lastIndexOf('.') + 1);
+ prefix = Character.toLowerCase(prefix.charAt(0)) + prefix.substring(1);
+ return DescriptorsUtils.getFreeWidgetId(root, prefix);
+ }
} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java
index b59f2f9..b29424e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java
@@ -276,6 +276,11 @@ public class LayoutTestBase extends TestCase {
fail("Not supported in tests yet");
return px;
}
+
+ public String getUniqueId(String prefix) {
+ fail("Not supported in tests yet");
+ return null;
+ }
}
public void testDummy() {