aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2011-05-12 22:49:07 -0700
committerRaphael Moll <ralf@android.com>2011-05-13 00:04:49 -0700
commitb1900cb3916414a7c95c5c3bb2c4a457efab4dee (patch)
treece7887222ce1230e269512dfb813eafaa041f313
parentb001f6889ef4c41a9d07678b4f15c3aee6321a22 (diff)
downloadsdk-b1900cb3916414a7c95c5c3bb2c4a457efab4dee.zip
sdk-b1900cb3916414a7c95c5c3bb2c4a457efab4dee.tar.gz
sdk-b1900cb3916414a7c95c5c3bb2c4a457efab4dee.tar.bz2
Refactor some common Dialog methods in a base class.
Change-Id: I4a81badcfeeca70fde747590daee9ae91c17795f
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AddonSitesDialog.java120
-rw-r--r--sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java81
-rw-r--r--sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java9
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java214
4 files changed, 261 insertions, 163 deletions
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AddonSitesDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AddonSitesDialog.java
index 9502099..d9d4111 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AddonSitesDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AddonSitesDialog.java
@@ -16,11 +16,11 @@
package com.android.sdkuilib.internal.repository;
-import com.android.sdklib.SdkConstants;
import com.android.sdklib.internal.repository.SdkAddonSource;
import com.android.sdklib.internal.repository.SdkSource;
import com.android.sdklib.internal.repository.SdkSourceCategory;
import com.android.sdklib.internal.repository.SdkSources;
+import com.android.sdkuilib.ui.SwtBaseDialog;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
@@ -47,8 +47,6 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
@@ -57,22 +55,10 @@ import org.eclipse.swt.widgets.TableColumn;
import java.util.Arrays;
-public class AddonSitesDialog extends Dialog {
-
- /**
- * Min Y location for dialog. Need to deal with the menu bar on mac os.
- */
- private final static int MIN_Y = SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN ?
- 20 : 0;
-
-
- /** Last dialog size for this session. */
- private static Point sLastSize;
+public class AddonSitesDialog extends SwtBaseDialog {
private final UpdaterData mUpdaterData;
- private boolean mChanged;
- private Shell mShell;
private Table mTable;
private TableViewer mTableViewer;
private Button mButtonNew;
@@ -88,45 +74,24 @@ public class AddonSitesDialog extends Dialog {
* @param parent The parent's shell
*/
public AddonSitesDialog(Shell parent, UpdaterData updaterData) {
- super(parent, SWT.NONE);
+ super(parent, SWT.APPLICATION_MODAL, "Add-on Sites");
mUpdaterData = updaterData;
- setText("Add-on Sites");
- }
-
- /**
- * Open the dialog.
- *
- * @return True if anything was changed.
- */
- public boolean open() {
- createContents();
- positionShell();
- postCreate();
- mShell.open();
- mShell.layout();
- Display display = getParent().getDisplay();
- while (!mShell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
-
- return mChanged;
}
/**
* Create contents of the dialog.
*/
- private void createContents() {
- mShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
- mShell.setMinimumSize(new Point(450, 300));
- mShell.setSize(450, 300);
- mShell.setText(getText());
+ @Override
+ protected void createContents() {
+ Shell shell = getShell();
+ shell.setMinimumSize(new Point(450, 300));
+ shell.setSize(450, 300);
+
GridLayout gl_shell = new GridLayout();
gl_shell.numColumns = 2;
- mShell.setLayout(gl_shell);
+ shell.setLayout(gl_shell);
- mlabel = new Label(mShell, SWT.NONE);
+ mlabel = new Label(shell, SWT.NONE);
mlabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
mlabel.setText(
"This dialog lets you manage the URLs of external add-on sites to be used.\n" +
@@ -136,7 +101,7 @@ public class AddonSitesDialog extends Dialog {
"Adding a URL here will not allow you to clone an official Android repository."
);
- mTableViewer = new TableViewer(mShell, SWT.BORDER | SWT.FULL_SELECTION);
+ mTableViewer = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION);
mTableViewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
on_TableViewer_selectionChanged(event);
@@ -157,7 +122,7 @@ public class AddonSitesDialog extends Dialog {
mColumnUrl.setWidth(100);
mColumnUrl.setText("New Column");
- mButtonNew = new Button(mShell, SWT.NONE);
+ mButtonNew = new Button(shell, SWT.NONE);
mButtonNew.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -167,7 +132,7 @@ public class AddonSitesDialog extends Dialog {
mButtonNew.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
mButtonNew.setText("New...");
- mButtonEdit = new Button(mShell, SWT.NONE);
+ mButtonEdit = new Button(shell, SWT.NONE);
mButtonEdit.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -177,7 +142,7 @@ public class AddonSitesDialog extends Dialog {
mButtonEdit.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
mButtonEdit.setText("Edit...");
- mButtonDelete = new Button(mShell, SWT.NONE);
+ mButtonDelete = new Button(shell, SWT.NONE);
mButtonDelete.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -186,9 +151,9 @@ public class AddonSitesDialog extends Dialog {
});
mButtonDelete.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
mButtonDelete.setText("Delete...");
- new Label(mShell, SWT.NONE);
+ new Label(shell, SWT.NONE);
- mButtonClose = new Button(mShell, SWT.NONE);
+ mButtonClose = new Button(shell, SWT.NONE);
mButtonClose.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -215,39 +180,6 @@ public class AddonSitesDialog extends Dialog {
});
}
- /**
- * Centers the dialog in its parent shell.
- */
- private void positionShell() {
- // Centers the dialog in its parent shell
- Shell child = mShell;
- Shell parent = getParent();
- if (child != null && parent != null) {
-
- // get the parent client area with a location relative to the display
- Rectangle parentArea = parent.getClientArea();
- Point parentLoc = parent.getLocation();
- int px = parentLoc.x;
- int py = parentLoc.y;
- int pw = parentArea.width;
- int ph = parentArea.height;
-
- // Reuse the last size if there's one, otherwise use the default
- Point childSize = sLastSize != null ? sLastSize : child.getSize();
- int cw = childSize.x;
- int ch = childSize.y;
-
- int x = px + (pw - cw) / 2;
- if (x < 0) x = 0;
-
- int y = py + (ph - ch) / 2;
- if (y < MIN_Y) y = MIN_Y;
-
- child.setLocation(x, y);
- child.setSize(cw, ch);
- }
- }
-
private void newOrEdit(final boolean isEdit) {
SdkSources sources = mUpdaterData.getSources();
final SdkSource[] knownSources = sources.getAllSources();
@@ -262,7 +194,12 @@ public class AddonSitesDialog extends Dialog {
return;
}
- InputDialog dlg = new InputDialog(mShell, title, msg, initialValue, new IInputValidator() {
+ InputDialog dlg = new InputDialog(
+ getShell(),
+ title,
+ msg,
+ initialValue,
+ new IInputValidator() {
public String isValid(String newText) {
newText = newText == null ? null : newText.trim();
@@ -318,7 +255,7 @@ public class AddonSitesDialog extends Dialog {
sources.add(
SdkSourceCategory.USER_ADDONS,
newSource);
- mChanged = true;
+ setReturnValue(true);
loadList();
// select the new source
@@ -336,7 +273,7 @@ public class AddonSitesDialog extends Dialog {
return;
}
- MessageBox mb = new MessageBox(mShell,
+ MessageBox mb = new MessageBox(getShell(),
SWT.YES | SWT.NO | SWT.ICON_QUESTION | SWT.APPLICATION_MODAL);
mb.setText("Delete add-on site");
mb.setMessage(String.format("Do you want to delete the URL %1$s?", selectedUrl));
@@ -345,7 +282,7 @@ public class AddonSitesDialog extends Dialog {
for (SdkSource source : sources.getSources(SdkSourceCategory.USER_ADDONS)) {
if (selectedUrl.equals(source.getUrl())) {
sources.remove(source);
- mChanged = true;
+ setReturnValue(true);
loadList();
}
}
@@ -353,7 +290,7 @@ public class AddonSitesDialog extends Dialog {
}
private void on_ButtonClose_widgetSelected(SelectionEvent e) {
- mShell.close();
+ close();
}
private void on_Table_mouseUp(MouseEvent e) {
@@ -370,7 +307,8 @@ public class AddonSitesDialog extends Dialog {
mButtonEdit.setEnabled(!sel.isEmpty());
}
- private void postCreate() {
+ @Override
+ protected void postCreate() {
// initialize the list
mTableViewer.setLabelProvider(new LabelProvider());
mTableViewer.setContentProvider(new SourcesContentProvider());
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java
index 6a85c14..4c0ea8c 100644
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java
@@ -21,15 +21,12 @@ import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.avd.AvdInfo.AvdStatus;
+import com.android.sdkuilib.ui.SwtBaseDialog;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
@@ -40,55 +37,22 @@ import java.util.Set;
/**
* Dialog displaying the details of an AVD.
*/
-final class AvdDetailsDialog extends Dialog {
+final class AvdDetailsDialog extends SwtBaseDialog {
- /** Last dialog size for this session. */
- private static Point sLastSize;
-
- private Shell mDialogShell;
private final AvdInfo mAvdInfo;
-
private Composite mRootComposite;
public AvdDetailsDialog(Shell shell, AvdInfo avdInfo) {
- super(shell, SWT.APPLICATION_MODAL);
+ super(shell, SWT.APPLICATION_MODAL, "AVD details");
mAvdInfo = avdInfo;
-
- setText("AVD details");
- }
-
- /**
- * Open the dialog and blocks till it gets closed
- */
- public void open() {
- createContents();
- positionShell(); //$hide$ (hide from SWT designer)
- mDialogShell.open();
- mDialogShell.layout();
-
- Display display = getParent().getDisplay();
- while (!mDialogShell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
-
- if (!mDialogShell.isDisposed()) {
- sLastSize = mDialogShell.getSize();
- mDialogShell.close();
- }
}
/**
* Create contents of the dialog.
*/
- private void createContents() {
- mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
- mDialogShell.setLayout(new GridLayout(1, false));
- mDialogShell.setSize(450, 300);
- mDialogShell.setText(getText());
-
- mRootComposite = new Composite(mDialogShell, SWT.NONE);
+ @Override
+ protected void createContents() {
+ mRootComposite = new Composite(getShell(), SWT.NONE);
mRootComposite.setLayout(new GridLayout(2, false));
mRootComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
@@ -169,6 +133,12 @@ final class AvdDetailsDialog extends Dialog {
// Hide everything down-below from SWT designer
//$hide>>$
+
+ @Override
+ protected void postCreate() {
+ // pass
+ }
+
/**
* Displays a value with a label.
*
@@ -187,33 +157,6 @@ final class AvdDetailsDialog extends Dialog {
l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
}
- /**
- * Centers the dialog in its parent shell.
- */
- private void positionShell() {
- // Centers the dialog in its parent shell
- Shell child = mDialogShell;
- Shell parent = getParent();
- if (child != null && parent != null) {
-
- // get the parent client area with a location relative to the display
- Rectangle parentArea = parent.getClientArea();
- Point parentLoc = parent.getLocation();
- int px = parentLoc.x;
- int py = parentLoc.y;
- int pw = parentArea.width;
- int ph = parentArea.height;
-
- // Reuse the last size if there's one, otherwise use the default
- Point childSize = sLastSize != null ? sLastSize : child.getSize();
- int cw = childSize.x;
- int ch = childSize.y;
-
- child.setLocation(px + (pw - cw) / 2, py + (ph - ch) / 2);
- child.setSize(cw, ch);
- }
- }
-
// End of hiding from SWT Designer
//$hide<<$
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java
index 8329fd6..9bf9c29 100644
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java
@@ -26,12 +26,15 @@ import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
/**
- * jface-based dialog that properly sets up a {@link GridLayout} top composite with the proper
+ * JFace-based dialog that properly sets up a {@link GridLayout} top composite with the proper
* margin.
- *
+ * <p/>
* Implementing dialog must create the content of the dialog in
* {@link #createDialogContent(Composite)}.
- *
+ * <p/>
+ * A JFace dialog is perfect if you want a typical "OK | cancel" workflow, with the OK and
+ * cancel things all handled for you using a predefined layout. If you want a different set
+ * of buttons or a different layout, consider {@link SwtBaseDialog} instead.
*/
public abstract class GridDialog extends Dialog {
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java
new file mode 100755
index 0000000..524c7b5
--- /dev/null
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkuilib.ui;
+
+import com.android.sdklib.SdkConstants;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A base class for an SWT Dialog.
+ * <p/>
+ * The base class offers the following goodies: <br/>
+ * - Dialog is automatically centered on its parent. <br/>
+ * - Dialog size is reused during the session. <br/>
+ * - A simple API with an {@link #open()} method that returns a boolean. <br/>
+ * <p/>
+ * A typical usage is:
+ * <pre>
+ * MyDialog extends SwtBaseDialog { ... }
+ * MyDialog d = new MyDialog(parentShell, "My Dialog Title");
+ * if (d.open()) {
+ * ...do something like refresh parent list view
+ * }
+ * </pre>
+ * We also have a JFace-base {@link GridDialog}.
+ * The JFace dialog is good when you just want a typical OK/Cancel layout with the
+ * buttons all managed for you.
+ * This SWT base dialog has little decoration.
+ * It's up to you to manage whatever buttons you want, if any.
+ */
+public abstract class SwtBaseDialog extends Dialog {
+
+ /**
+ * Min Y location for dialog. Need to deal with the menu bar on mac os.
+ */
+ private final static int MIN_Y =
+ SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN ? 20 : 0;
+
+ /** Last dialog size for this session, different for each dialog class. */
+ private static Map<Class<?>, Point> sLastSizeMap = new HashMap<Class<?>, Point>();
+
+ private boolean mReturnValue;
+ private Shell mShell;
+
+ /**
+ * Create the dialog.
+ *
+ * @param parent The parent's shell
+ * @param title The dialog title. Must not be null.
+ */
+ public SwtBaseDialog(Shell parent, int swtStyle, String title) {
+ super(parent, swtStyle);
+ setText(title);
+ }
+
+ /**
+ * Open the dialog.
+ *
+ * @return The last value set using {@link #setReturnValue(boolean)} or false by default.
+ */
+ public boolean open() {
+ createShell();
+ createContents();
+ positionShell();
+ postCreate();
+ mShell.open();
+ mShell.layout();
+ Display display = getParent().getDisplay();
+ while (!mShell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ return mReturnValue;
+ }
+
+ /**
+ * Creates the shell for this dialog.
+ * The default shell has a size of 450x300, which is also its minimum size.
+ * You might want to override these values.
+ * <p/>
+ * Called before {@link #createContents()}.
+ */
+ protected void createShell() {
+ mShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
+ mShell.setMinimumSize(new Point(450, 300));
+ mShell.setSize(450, 300);
+ mShell.setText(getText());
+ mShell.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ saveSize();
+ }
+ });
+ }
+
+ /**
+ * Creates the content and attaches it to the current shell (cf. {@link #getShell()}).
+ * <p/>
+ * Derived classes should consider creating the UI here and initializing their
+ * state in {@link #postCreate()}.
+ */
+ protected abstract void createContents();
+
+ /**
+ * Called after {@link #createContents()} and after {@link #positionShell()}
+ * just before the dialog is actually shown on screen.
+ * <p/>
+ * Derived classes should consider creating the UI in {@link #createContents()} and
+ * initialize it here.
+ */
+ protected abstract void postCreate();
+
+ /**
+ * Returns the current value that {@link #open()} will return to the caller.
+ * Default is false.
+ */
+ protected boolean getReturnValue() {
+ return mReturnValue;
+ }
+
+ /**
+ * Sets the value that {@link #open()} will return to the caller.
+ * @param returnValue The new value to be returned by {@link #open()}.
+ */
+ protected void setReturnValue(boolean returnValue) {
+ mReturnValue = returnValue;
+ }
+
+ /**
+ * Returns the shell created by {@link #createShell()}.
+ * @return The current {@link Shell}.
+ */
+ protected Shell getShell() {
+ return mShell;
+ }
+
+ /**
+ * Saves the dialog size and close the dialog.
+ * The {@link #open()} method will given return value (see {@link #setReturnValue(boolean)}.
+ */
+ protected void close() {
+ saveSize();
+ getShell().close();
+ }
+
+ //-------
+
+ /**
+ * Centers the dialog in its parent shell.
+ */
+ private void positionShell() {
+ // Centers the dialog in its parent shell
+ Shell child = mShell;
+ Shell parent = getParent();
+ if (child != null && parent != null) {
+ // get the parent client area with a location relative to the display
+ Rectangle parentArea = parent.getClientArea();
+ Point parentLoc = parent.getLocation();
+ int px = parentLoc.x;
+ int py = parentLoc.y;
+ int pw = parentArea.width;
+ int ph = parentArea.height;
+
+ // Reuse the last size if there's one, otherwise use the default
+ Point childSize = sLastSizeMap.get(this.getClass());
+ if (childSize == null) {
+ childSize = child.getSize();
+ }
+ int cw = childSize.x;
+ int ch = childSize.y;
+
+ int x = px + (pw - cw) / 2;
+ if (x < 0) x = 0;
+
+ int y = py + (ph - ch) / 2;
+ if (y < MIN_Y) y = MIN_Y;
+
+ child.setLocation(x, y);
+ child.setSize(cw, ch);
+ }
+ }
+
+ private void saveSize() {
+ if (mShell != null && !mShell.isDisposed()) {
+ sLastSizeMap.put(this.getClass(), mShell.getSize());
+ }
+ }
+
+}