diff options
author | Tor Norbye <tnorbye@google.com> | 2012-05-07 15:18:46 -0700 |
---|---|---|
committer | android code review <noreply-gerritcodereview@google.com> | 2012-05-07 15:18:46 -0700 |
commit | 744109a2331c46902d5c978067fbebb1855763ee (patch) | |
tree | a6b83c147b769bdd4c7fd90c27cbe66bded20df6 | |
parent | 75d10d8a01863413dbaf425eeb012408729ffbd9 (diff) | |
parent | 6c96eea7e8478c0c0708fa8f0acf897037ed125a (diff) | |
download | sdk-744109a2331c46902d5c978067fbebb1855763ee.zip sdk-744109a2331c46902d5c978067fbebb1855763ee.tar.gz sdk-744109a2331c46902d5c978067fbebb1855763ee.tar.bz2 |
Merge "Fix 30018: Flashing layout actions bar on Windows"
4 files changed, 124 insertions, 12 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java index 58e156e..3c976b0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlEditor.java @@ -246,6 +246,18 @@ public abstract class AndroidXmlEditor extends FormEditor implements IResourceCh mIgnoreXmlUpdate = ignore; } + /** + * Returns whether XML model events are ignored or not. This is the case + * when we are deliberately modifying the document in a way which does not + * change the semantics (such as formatting), or when we have already + * directly updated the model ourselves. + * + * @return true if XML events should be ignored + */ + public boolean getIgnoreXmlUpdate() { + return mIgnoreXmlUpdate; + } + // ---- Base Class Overrides, Interfaces Implemented ---- @Override diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditorDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditorDelegate.java index 325e284..4bc7641 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditorDelegate.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditorDelegate.java @@ -487,6 +487,9 @@ public class LayoutEditorDelegate extends CommonXmlDelegate public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); getEditor().getSite().getSelectionProvider().setSelection(selection); + if (getEditor().getIgnoreXmlUpdate()) { + return; + } SelectionManager manager = mGraphicalEditor.getCanvasControl().getSelectionManager(); manager.setSelection(selection); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java index 8f950b9..49157a7 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutActionBar.java @@ -18,6 +18,7 @@ package com.android.ide.eclipse.adt.internal.editors.layout.gle2; import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI; import static com.android.ide.common.layout.LayoutConstants.ATTR_ID; +import com.android.annotations.NonNull; import com.android.ide.common.api.INode; import com.android.ide.common.api.RuleAction; import com.android.ide.common.api.RuleAction.Choices; @@ -31,6 +32,7 @@ import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine; import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient; import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; import com.android.sdkuilib.internal.widgets.ResolutionChooserDialog; +import com.google.common.base.Strings; import org.eclipse.core.resources.IFile; import org.eclipse.jface.window.Window; @@ -72,6 +74,7 @@ public class LayoutActionBar extends Composite { private ToolItem mZoomInButton; private ToolItem mZoomFitButton; private ToolItem mLintButton; + private List<RuleAction> mPrevActions; /** * Creates a new {@link LayoutActionBar} and adds it to the given parent. @@ -98,14 +101,14 @@ public class LayoutActionBar extends Composite { mLintToolBar.setLayoutData(lintData); } + @Override + public void dispose() { + super.dispose(); + mPrevActions = null; + } + /** Updates the layout contents based on the current selection */ void updateSelection() { - // Get rid of any previous children - for (ToolItem c : mLayoutToolBar.getItems()) { - c.dispose(); - } - mLayoutToolBar.pack(); - NodeProxy parent = null; LayoutCanvas canvas = mEditor.getCanvasControl(); SelectionManager selectionManager = canvas.getSelectionManager(); @@ -167,12 +170,94 @@ public class LayoutActionBar extends Composite { } } - addActions(actions, index, label); + if (!updateActions(actions)) { + updateToolbar(actions, index, label); + } + mPrevActions = actions; + } + /** Update the toolbar widgets */ + private void updateToolbar(final List<RuleAction> actions, final int labelIndex, + final String label) { + if (mLayoutToolBar == null || mLayoutToolBar.isDisposed()) { + return; + } + for (ToolItem c : mLayoutToolBar.getItems()) { + c.dispose(); + } + mLayoutToolBar.pack(); + addActions(actions, labelIndex, label); mLayoutToolBar.pack(); mLayoutToolBar.layout(); } + /** + * Attempts to update the existing toolbar actions, if the action list is + * similar to the current list. Returns false if this cannot be done and the + * contents must be replaced. + */ + private boolean updateActions(@NonNull List<RuleAction> actions) { + List<RuleAction> before = mPrevActions; + List<RuleAction> after = actions; + + if (before == null) { + return false; + } + + if (!before.equals(after) || after.size() > mLayoutToolBar.getItemCount()) { + return false; + } + + int actionIndex = 0; + for (int i = 0, max = mLayoutToolBar.getItemCount(); i < max; i++) { + ToolItem item = mLayoutToolBar.getItem(i); + int style = item.getStyle(); + Object data = item.getData(); + if (data != null) { + // One action can result in multiple toolbar items (e.g. a choice action + // can result in multiple radio buttons), so we've have to replace all of + // them with the corresponding new action + RuleAction prevAction = before.get(actionIndex); + while (prevAction != data) { + actionIndex++; + if (actionIndex == before.size()) { + return false; + } + prevAction = before.get(actionIndex); + if (prevAction == data) { + break; + } else if (!(prevAction instanceof RuleAction.Separator)) { + return false; + } + } + RuleAction newAction = after.get(actionIndex); + assert newAction.equals(prevAction); // Maybe I can do this lazily instead? + + // Update action binding to the new action + item.setData(newAction); + + // Sync button states: the checked state is not considered part of + // RuleAction equality + if ((style & SWT.CHECK) != 0) { + assert newAction instanceof Toggle; + Toggle toggle = (Toggle) newAction; + item.setSelection(toggle.isChecked()); + } else if ((style & SWT.RADIO) != 0) { + assert newAction instanceof Choices; + Choices choices = (Choices) newAction; + String current = choices.getCurrent(); + String id = (String) item.getData(ATTR_ID); + boolean selected = Strings.nullToEmpty(current).equals(id); + item.setSelection(selected); + } + } else { + assert (style & SWT.SEPARATOR) != 0; + } + } + + return true; + } + private void addActions(List<RuleAction> actions, int labelIndex, String label) { if (actions.size() > 0) { // Flag used to indicate that if there are any actions -after- this, it @@ -226,7 +311,7 @@ public class LayoutActionBar extends Composite { } } - private void addToggle(final Toggle toggle) { + private void addToggle(Toggle toggle) { final ToolItem button = new ToolItem(mLayoutToolBar, SWT.CHECK); URL iconUrl = toggle.getIconUrl(); @@ -237,10 +322,12 @@ public class LayoutActionBar extends Composite { } else { button.setText(title); } + button.setData(toggle); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + Toggle toggle = (Toggle) button.getData(); toggle.getCallback().action(toggle, getSelectedNodes(), toggle.getId(), button.getSelection()); updateSelection(); @@ -263,7 +350,7 @@ public class LayoutActionBar extends Composite { } - private void addPlainAction(final RuleAction menuAction) { + private void addPlainAction(RuleAction menuAction) { final ToolItem button = new ToolItem(mLayoutToolBar, SWT.PUSH); URL iconUrl = menuAction.getIconUrl(); @@ -274,10 +361,12 @@ public class LayoutActionBar extends Composite { } else { button.setText(title); } + button.setData(menuAction); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + RuleAction menuAction = (RuleAction) button.getData(); menuAction.getCallback().action(menuAction, getSelectedNodes(), menuAction.getId(), false); updateSelection(); @@ -285,7 +374,7 @@ public class LayoutActionBar extends Composite { }); } - private void addRadio(final RuleAction.Choices choices) { + private void addRadio(RuleAction.Choices choices) { List<URL> icons = choices.getIconUrls(); List<String> titles = choices.getTitles(); List<String> ids = choices.getIds(); @@ -301,10 +390,13 @@ public class LayoutActionBar extends Composite { final ToolItem item = new ToolItem(mLayoutToolBar, SWT.RADIO); item.setToolTipText(title); item.setImage(IconFactory.getInstance().getIcon(iconUrl)); + item.setData(choices); + item.setData(ATTR_ID, id); item.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (item.getSelection()) { + RuleAction.Choices choices = (Choices) item.getData(); choices.getCallback().action(choices, getSelectedNodes(), id, null); updateSelection(); } @@ -317,7 +409,7 @@ public class LayoutActionBar extends Composite { } } - private void addDropdown(final RuleAction.Choices choices) { + private void addDropdown(RuleAction.Choices choices) { final ToolItem combo = new ToolItem(mLayoutToolBar, SWT.DROP_DOWN); URL iconUrl = choices.getIconUrl(); if (iconUrl != null) { @@ -326,6 +418,7 @@ public class LayoutActionBar extends Composite { } else { combo.setText(choices.getTitle()); } + combo.setData(choices); Listener menuListener = new Listener() { @Override @@ -335,7 +428,7 @@ public class LayoutActionBar extends Composite { point = combo.getDisplay().map(mLayoutToolBar, null, point); Menu menu = new Menu(mLayoutToolBar.getShell(), SWT.POP_UP); - + RuleAction.Choices choices = (Choices) combo.getData(); List<URL> icons = choices.getIconUrls(); List<String> titles = choices.getTitles(); List<String> ids = choices.getIds(); @@ -360,6 +453,7 @@ public class LayoutActionBar extends Composite { item.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + RuleAction.Choices choices = (Choices) combo.getData(); choices.getCallback().action(choices, getSelectedNodes(), id, null); updateSelection(); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvasViewer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvasViewer.java index bef4fba..e349a1c 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvasViewer.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvasViewer.java @@ -114,6 +114,9 @@ class LayoutCanvasViewer extends Viewer implements IPostSelectionProvider { */ @Override public void setSelection(ISelection selection, boolean reveal) { + if (mEditorDelegate.getEditor().getIgnoreXmlUpdate()) { + return; + } mCanvas.getSelectionManager().setSelection(selection); } |