ADT: GLE toggle buttons in configuration composite.
New GLE2 toggles:
- explode view
- show borders
Change-Id: I638b1d4591bee4729be7b4dff753cb166b3eaa61
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
index 1178449..f2f4ce5 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationComposite.java
@@ -41,6 +41,7 @@
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
@@ -83,12 +84,13 @@
private final ArrayList<ResourceQualifier[] > mLocaleList =
new ArrayList<ResourceQualifier[]>();
- private final IConfigListener mListener;
-
private boolean mClipping = true;
private LayoutDevice mCurrentDevice;
+ /** The config listener given to the constructor. Never null. */
+ private final IConfigListener mListener;
+
/**
* Interface implemented by the part which owns a {@link ConfigurationComposite}.
* This notifies the owners when the configuration change.
@@ -99,7 +101,7 @@
void onConfigurationChange();
void onThemeChange();
void onCreate();
- void OnClippingChange();
+ void onClippingChange();
ProjectResources getProjectResources();
ProjectResources getFrameworkResources();
@@ -107,17 +109,91 @@
Map<String, Map<String, IResourceValue>> getConfiguredFrameworkResources();
}
- public ConfigurationComposite(IConfigListener listener, Composite parent, int style) {
+ /**
+ * Interface implemented by the part which owns a {@link ConfigurationComposite}
+ * to define and handle custom toggle buttons in the button bar. Each toggle is
+ * implemented using a button, with a callback when the button is selected.
+ */
+ public static abstract class CustomToggle {
+
+ /** The UI label of the toggle. Can be null if the image exists. */
+ private final String mUiLabel;
+
+ /** The image to use for this toggle. Can be null if the label exists. */
+ private final Image mImage;
+
+ /** The tooltip for the toggle. Can be null. */
+ private final String mUiTooltip;
+
+ /**
+ * Initializes a new {@link CustomToggle}. The values set here will be used
+ * later to create the actual toggle.
+ *
+ * @param uiLabel The UI label of the toggle. Can be null if the image exists.
+ * @param image The image to use for this toggle. Can be null if the label exists.
+ * @param uiTooltip The tooltip for the toggle. Can be null.
+ */
+ public CustomToggle(
+ String uiLabel,
+ Image image,
+ String uiTooltip) {
+ mUiLabel = uiLabel;
+ mImage = image;
+ mUiTooltip = uiTooltip;
+ }
+
+ /** Called by the {@link ConfigurationComposite} when the button is selected. */
+ public abstract void onSelected(boolean newState);
+
+ private void createToggle(Composite parent) {
+ final Button b = new Button(parent, SWT.TOGGLE | SWT.FLAT);
+
+ if (mUiTooltip != null) {
+ b.setToolTipText(mUiTooltip);
+ }
+ if (mImage != null) {
+ b.setImage(mImage);
+ }
+ if (mUiLabel != null) {
+ b.setText(mUiLabel);
+ }
+
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ onSelected(b.getSelection());
+ }
+ });
+ }
+ }
+
+ /**
+ * Creates a new {@link ConfigurationComposite} and adds it to the parent.
+ *
+ * @param listener An {@link IConfigListener} that gets and sets configuration properties.
+ * Mandatory, cannot be null.
+ * @param customToggles An array of {@link CustomToggle} to define extra toggles button
+ * to display at the top of the composite. Can be empty or null.
+ * @param parent The parent composite.
+ * @param style The style of this composite.
+ */
+ public ConfigurationComposite(IConfigListener listener,
+ CustomToggle[] customToggles,
+ Composite parent, int style) {
super(parent, style);
mListener = listener;
+ if (customToggles == null) {
+ customToggles = new CustomToggle[0];
+ }
+
GridLayout gl;
GridData gd;
- int cols = 10; // device*2+config*2+locale*2+separator*2+theme+createBtn
+ int cols = 10; // device*2+config*2+locale*2+separator*2+theme+createBtn
- // ---- First line: collapse button, clipping button, editing config display.
+ // ---- First line: custom buttons, clipping button, editing config display.
Composite labelParent = new Composite(this, SWT.NONE);
- labelParent.setLayout(gl = new GridLayout(3, false));
+ labelParent.setLayout(gl = new GridLayout(3 + customToggles.length, false));
gl.marginWidth = gl.marginHeight = 0;
labelParent.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
gd.horizontalSpan = cols;
@@ -127,6 +203,10 @@
mCurrentLayoutLabel.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
gd.widthHint = 50;
+ for (CustomToggle toggle : customToggles) {
+ toggle.createToggle(labelParent);
+ }
+
mClippingButton = new Button(labelParent, SWT.TOGGLE | SWT.FLAT);
mClippingButton.setSelection(mClipping);
mClippingButton.setToolTipText("Toggles screen clipping on/off");
@@ -134,7 +214,7 @@
mClippingButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- OnClippingChange();
+ onClippingChange();
}
});
@@ -675,10 +755,10 @@
}
}
- protected void OnClippingChange() {
+ protected void onClippingChange() {
mClipping = mClippingButton.getSelection();
if (mListener != null) {
- mListener.OnClippingChange();
+ mListener.onClippingChange();
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java
index 25b67df..2280b30 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle1/GraphicalLayoutEditor.java
@@ -29,6 +29,7 @@
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.LayoutCreatorDialog;
+import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.CustomToggle;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
@@ -147,6 +148,8 @@
private ProjectCallback mProjectCallback;
private ILayoutLog mLogger;
+ private boolean mUseExplodeMode;
+ private boolean mUseOutlineMode;
private boolean mNeedsXmlReload = false;
private boolean mNeedsRecompute = false;
@@ -195,8 +198,6 @@
}
};
- private boolean mExplodedView;
-
public GraphicalLayoutEditor(LayoutEditor layoutEditor) {
mLayoutEditor = layoutEditor;
setEditDomain(new DefaultEditDomain(this));
@@ -220,7 +221,33 @@
gl.marginHeight = gl.marginWidth = 0;
// create the top part for the configuration control
- mConfigComposite = new ConfigurationComposite(this, parent, SWT.NONE);
+
+ CustomToggle[] toggles = new CustomToggle[] {
+ new CustomToggle(
+ "Explode",
+ null, //image
+ "Displays extra margins in the layout."
+ ) {
+ @Override
+ public void onSelected(boolean newState) {
+ mUseExplodeMode = newState;
+ recomputeLayout();
+ }
+ },
+ new CustomToggle(
+ "Outline",
+ null, //image
+ "Shows the outline of all views in the layout."
+ ) {
+ @Override
+ public void onSelected(boolean newState) {
+ mUseOutlineMode = newState;
+ recomputeLayout();
+ }
+ }
+ };
+
+ mConfigComposite = new ConfigurationComposite(this, toggles, parent, SWT.NONE);
// create a new composite that will contain the standard editor controls.
Composite editorParent = new Composite(parent, SWT.NONE);
@@ -822,7 +849,7 @@
recomputeLayout();
}
- public void OnClippingChange() {
+ public void onClippingChange() {
recomputeLayout();
}
@@ -955,10 +982,9 @@
// Compute the layout
Rectangle rect = getBounds();
- mExplodedView = !mConfigComposite.getClipping(); //FIXME: need new toggle
int width = rect.width;
int height = rect.height;
- if (mExplodedView) {
+ if (mUseExplodeMode) {
// compute how many padding in x and y will bump the screen size
ExplodedRenderingHelper helper = new ExplodedRenderingHelper(
getModel(), iProject);
@@ -977,7 +1003,7 @@
boolean isProjectTheme = mConfigComposite.isProjectTheme();
UiElementPullParser parser = new UiElementPullParser(getModel(),
- mExplodedView, density, xdpi, iProject);
+ mUseExplodeMode, density, xdpi, iProject);
ILayoutResult result = computeLayout(bridge, parser,
iProject /* projectKey */,
@@ -1378,6 +1404,6 @@
}
public boolean hasOutline() {
- return mExplodedView;
+ return mUseOutlineMode;
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java
index 796bce1..a8c6386 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java
@@ -26,6 +26,7 @@
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.LayoutCreatorDialog;
+import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.CustomToggle;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationComposite.IConfigListener;
import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
@@ -147,6 +148,8 @@
private ReloadListener mReloadListener;
+ protected boolean mUseExplodeMode;
+
public GraphicalEditorPart(LayoutEditor layoutEditor) {
mLayoutEditor = layoutEditor;
@@ -215,8 +218,33 @@
gl.marginHeight = gl.marginWidth = 0;
// create the top part for the configuration control
+
+ CustomToggle[] toggles = new CustomToggle[] {
+ new CustomToggle(
+ "Explode",
+ null, //image
+ "Displays extra margins in the layout."
+ ) {
+ @Override
+ public void onSelected(boolean newState) {
+ mUseExplodeMode = newState;
+ recomputeLayout();
+ }
+ },
+ new CustomToggle(
+ "Outline",
+ null, //image
+ "Shows the of all views in the layout."
+ ) {
+ @Override
+ public void onSelected(boolean newState) {
+ mLayoutCanvas.setShowOutline(newState);
+ }
+ }
+ };
+
mConfigListener = new ConfigListener();
- mConfigComposite = new ConfigurationComposite(mConfigListener, parent, SWT.BORDER);
+ mConfigComposite = new ConfigurationComposite(mConfigListener, toggles, parent, SWT.BORDER);
mConfigComposite.updateUIFromResources();
mSashPalette = new SashForm(parent, SWT.HORIZONTAL);
@@ -390,7 +418,7 @@
recomputeLayout();
}
- public void OnClippingChange() {
+ public void onClippingChange() {
recomputeLayout();
}
@@ -891,10 +919,9 @@
// Compute the layout
Rectangle rect = getBounds();
- boolean explodedView = !mConfigComposite.getClipping(); //FIXME: need new toggle
int width = rect.width;
int height = rect.height;
- if (explodedView) {
+ if (mUseExplodeMode) {
// compute how many padding in x and y will bump the screen size
ExplodedRenderingHelper helper = new ExplodedRenderingHelper(
getModel(), iProject);
@@ -913,7 +940,7 @@
boolean isProjectTheme = mConfigComposite.isProjectTheme();
UiElementPullParser parser = new UiElementPullParser(getModel(),
- explodedView, density, xdpi, iProject);
+ mUseExplodeMode, density, xdpi, iProject);
ILayoutResult result = computeLayout(bridge, parser,
iProject /* projectKey */,
@@ -962,7 +989,7 @@
* the implementation API level.
*
* Implementation detail: the bridge's computeLayout() method already returns a newly
- * allocated ILayourResult.
+ * allocated ILayoutResult.
*/
@SuppressWarnings("deprecation")
private static ILayoutResult computeLayout(LayoutBridge bridge,
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 d0e810c..1f7658f 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
@@ -123,12 +123,18 @@
/** Hover border color. Must be disposed, it's NOT a system color. */
private Color mHoverFgColor;
+ /** Outline color. Do not dispose, it's a system color. */
+ private Color mOutlineColor;
+
/**
* The <em>current</em> alternate selection, if any, which changes when the Alt key is
* used during a selection. Can be null.
*/
private AlternateSelection mAltSelection;
+ /** When true, always display the outline of all views. */
+ private boolean mShowOutline;
+
public LayoutCanvas(Composite parent, int style) {
super(parent, style | SWT.DOUBLE_BUFFERED);
@@ -136,6 +142,7 @@
Display d = getDisplay();
mSelectionFgColor = d.getSystemColor(SWT.COLOR_RED);
mHoverFgColor = new Color(d, 0xFF, 0x99, 0x00); // orange
+ mOutlineColor = d.getSystemColor(SWT.COLOR_GREEN);
mSelectionFont = d.getSystemFont();
addPaintListener(new PaintListener() {
@@ -217,6 +224,11 @@
redraw();
}
+ public void setShowOutline(boolean newState) {
+ mShowOutline = newState;
+ redraw();
+ }
+
/**
* Called by the {@link GraphicalEditorPart} when the Copy action is requested.
*
@@ -307,6 +319,12 @@
}
}
+ if (mShowOutline) {
+ gc.setForeground(mOutlineColor);
+ gc.setLineStyle(SWT.LINE_DOT);
+ drawOutline(gc, mLastValidViewInfoRoot);
+ }
+
if (mHoverRect != null) {
gc.setForeground(mHoverFgColor);
gc.setLineStyle(SWT.LINE_DOT);
@@ -325,6 +343,16 @@
}
}
+ private void drawOutline(GC gc, ViewInfo info) {
+
+ Rectangle r = info.getAbsRect();
+ gc.drawRectangle(r.x + IMAGE_MARGIN, r.y + IMAGE_MARGIN, r.width, r.height);
+
+ for (ViewInfo vi : info.getChildren()) {
+ drawOutline(gc, vi);
+ }
+ }
+
private void drawSelection(GC gc, Selection s) {
Rectangle r = s.getRect();
@@ -611,7 +639,7 @@
* have a fixed API.
*/
private static class ViewInfo {
- private final Rectangle mRealRect;
+ private final Rectangle mAbsRect;
private final Rectangle mSelectionRect;
private final String mName;
private final Object mKey;
@@ -638,13 +666,13 @@
int w = viewInfo.getRight() - x;
int h = viewInfo.getBottom() - y;
- mRealRect = new Rectangle(x, y, w, h);
-
if (parent != null) {
x += parentX;
y += parentY;
}
+ mAbsRect = new Rectangle(x, y, w - 1, h - 1);
+
if (viewInfo.getChildren() != null) {
for (ILayoutViewInfo child : viewInfo.getChildren()) {
mChildren.add(new ViewInfo(child, this, x, y));
@@ -669,12 +697,11 @@
}
/**
- * Returns the original {@link ILayoutResult} bounds, relative to the parent.
- * @deprecated TODO Remove if it's not going to be used
+ * Returns the original {@link ILayoutResult} bounds in absolute coordinates
+ * over the whole graphic.
*/
- @SuppressWarnings("unused")
- public Rectangle getRealRect() {
- return mRealRect;
+ public Rectangle getAbsRect() {
+ return mAbsRect;
}
/*
@@ -860,5 +887,4 @@
}
}
-
}