\r
private static final String APP_NAME = "Android Virtual Device Manager";\r
private static final String APP_NAME_MAC_MENU = "AVD Manager";\r
-\r
+ private static final String SIZE_POS_PREFIX = "avdman1"; //$NON-NLS-1$\r
\r
private final Shell mParentShell;\r
private final AvdInvocationContext mContext;\r
mShell.open();\r
mShell.layout();\r
\r
- if (postCreateContent()) { //$hide$ (hide from SWT designer)\r
+ boolean ok = postCreateContent();\r
+\r
+ if (ok && mContext == AvdInvocationContext.STANDALONE) {\r
Display display = Display.getDefault();\r
while (!mShell.isDisposed()) {\r
if (!display.readAndDispatch()) {\r
display.sleep();\r
}\r
}\r
- }\r
\r
- dispose(); //$hide$\r
+ dispose(); //$hide$\r
+ }\r
}\r
\r
private void createShell() {\r
mShell = new Shell(mParentShell, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);\r
mShell.addDisposeListener(new DisposeListener() {\r
public void widgetDisposed(DisposeEvent e) {\r
- onAndroidSdkUpdaterDispose(); //$hide$ (hide from SWT designer)\r
+ ShellSizeAndPos.saveSizeAndPos(mShell, SIZE_POS_PREFIX);\r
+\r
+ if (mContext != AvdInvocationContext.SDK_MANAGER) {\r
+ // When invoked from the sdk manager, don't dispose\r
+ // resources that the sdk manager still needs.\r
+ onAndroidSdkUpdaterDispose(); //$hide$ (hide from SWT designer)\r
+ }\r
}\r
});\r
\r
mShell.setMinimumSize(new Point(500, 300));\r
mShell.setSize(700, 500);\r
mShell.setText(APP_NAME);\r
+\r
+ ShellSizeAndPos.loadSizeAndPos(mShell, SIZE_POS_PREFIX);\r
}\r
\r
private void createContents() {\r
public class SdkUpdaterWindowImpl2 implements ISdkUpdaterWindow {\r
\r
private static final String APP_NAME = "Android SDK Manager";\r
+ private static final String SIZE_POS_PREFIX = "sdkman2"; //$NON-NLS-1$\r
+\r
private final Shell mParentShell;\r
private final SdkInvocationContext mContext;\r
/** Internal data shared between the window and its pages. */\r
mShell = new Shell(mParentShell, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);\r
mShell.addDisposeListener(new DisposeListener() {\r
public void widgetDisposed(DisposeEvent e) {\r
+ ShellSizeAndPos.saveSizeAndPos(mShell, SIZE_POS_PREFIX);\r
onAndroidSdkUpdaterDispose(); //$hide$ (hide from SWT designer)\r
}\r
});\r
mShell.setMinimumSize(new Point(500, 300));\r
mShell.setSize(700, 500);\r
mShell.setText(APP_NAME);\r
+\r
+ ShellSizeAndPos.loadSizeAndPos(mShell, SIZE_POS_PREFIX);\r
}\r
\r
private void createContents() {\r
}\r
\r
getShell().setText(\r
- String.format("%1$s - %2$s", APP_NAME, content.getPageTitle())); //$NON-NLS-1$\r
+ String.format("%1$s - %2$s", APP_NAME, content.getPageTitle()));\r
\r
Label filler = new Label(shell, SWT.NONE);\r
GridDataBuilder.create(filler).hFill().hGrab();\r
--- /dev/null
+/*\r
+ * Copyright (C) 2011 The Android Open Source Project\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.android.sdkuilib.internal.repository.sdkman2;\r
+\r
+\r
+import com.android.prefs.AndroidLocation;\r
+\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Monitor;\r
+import org.eclipse.swt.widgets.Shell;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.util.Properties;\r
+\r
+/**\r
+ * Utility to save & restore the size and position on a window\r
+ * using a common config file.\r
+ */\r
+public class ShellSizeAndPos {\r
+\r
+ private static final String SETTINGS_FILENAME = "androidwin.cfg"; //$NON-NLS-1$\r
+ private static final String PX = "_px"; //$NON-NLS-1$\r
+ private static final String PY = "_py"; //$NON-NLS-1$\r
+ private static final String SX = "_sx"; //$NON-NLS-1$\r
+ private static final String SY = "_sy"; //$NON-NLS-1$\r
+\r
+ public static void loadSizeAndPos(Shell shell, String prefix) {\r
+ Properties props = loadProperties();\r
+\r
+ try {\r
+ int px = Integer.parseInt(props.getProperty(prefix + PX));\r
+ int py = Integer.parseInt(props.getProperty(prefix + PY));\r
+ int sx = Integer.parseInt(props.getProperty(prefix + SX));\r
+ int sy = Integer.parseInt(props.getProperty(prefix + SY));\r
+\r
+ Point p1 = new Point(px, py);\r
+ Point p2 = new Point(px + sx, py + sy);\r
+ Rectangle r = new Rectangle(px, py, sy, sy);\r
+\r
+ Monitor bestMatch = null;\r
+ int bestSurface = -1;\r
+ for (Monitor monitor : shell.getDisplay().getMonitors()) {\r
+ Rectangle area = monitor.getClientArea();\r
+ if (area.contains(p1) && area.contains(p2)) {\r
+ // The shell is fully visible on this monitor. Just use that.\r
+ bestMatch = monitor;\r
+ bestSurface = Integer.MAX_VALUE;\r
+ break;\r
+ } else {\r
+ // Find which monitor displays the largest surface of the window.\r
+ // We'll use this one to center the window there, to make sure we're not\r
+ // starting split between several monitors.\r
+ Rectangle i = area.intersection(r);\r
+ int surface = i.width * i.height;\r
+ if (surface > bestSurface) {\r
+ bestSurface = surface;\r
+ bestMatch = monitor;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (bestMatch != null && bestSurface != Integer.MAX_VALUE) {\r
+ // Recenter the window on this monitor and make sure it fits\r
+ Rectangle area = bestMatch.getClientArea();\r
+\r
+ sx = Math.min(sx, area.width);\r
+ sy = Math.min(sy, area.height);\r
+ px = area.x + (area.width - sx) / 2;\r
+ py = area.y + (area.height - sy) / 2;\r
+ }\r
+\r
+ shell.setLocation(px, py);\r
+ shell.setSize(sx, sy);\r
+\r
+ } catch ( Exception e) {\r
+ // Ignore exception. We could typically get NPE from the getProperty\r
+ // or NumberFormatException from parseInt calls. Either way, do\r
+ // nothing if anything goes wrong.\r
+ }\r
+ }\r
+\r
+ public static void saveSizeAndPos(Shell shell, String prefix) {\r
+ Properties props = loadProperties();\r
+\r
+ Point loc = shell.getLocation();\r
+ Point size = shell.getSize();\r
+\r
+ props.setProperty(prefix + PX, Integer.toString(loc.x));\r
+ props.setProperty(prefix + PY, Integer.toString(loc.y));\r
+ props.setProperty(prefix + SX, Integer.toString(size.x));\r
+ props.setProperty(prefix + SY, Integer.toString(size.y));\r
+\r
+ saveProperties(props);\r
+ }\r
+\r
+ /**\r
+ * Load properties saved in {@link #SETTINGS_FILENAME}.\r
+ * If the file does not exists or doesn't load properly, just return an\r
+ * empty set of properties.\r
+ */\r
+ private static Properties loadProperties() {\r
+ Properties props = new Properties();\r
+ FileInputStream fis = null;\r
+\r
+ try {\r
+ String folder = AndroidLocation.getFolder();\r
+ File f = new File(folder, SETTINGS_FILENAME);\r
+ if (f.exists()) {\r
+ fis = new FileInputStream(f);\r
+\r
+ props.load(fis);\r
+ }\r
+ } catch (Exception e) {\r
+ // Ignore\r
+ } finally {\r
+ if (fis != null) {\r
+ try {\r
+ fis.close();\r
+ } catch (IOException e) {\r
+ }\r
+ }\r
+ }\r
+\r
+ return props;\r
+ }\r
+\r
+ private static void saveProperties(Properties props) {\r
+ FileOutputStream fos = null;\r
+\r
+ try {\r
+ String folder = AndroidLocation.getFolder();\r
+ File f = new File(folder, SETTINGS_FILENAME);\r
+ fos = new FileOutputStream(f);\r
+\r
+ props.store(fos, "## Size and Pos for SDK Manager Windows"); //$NON-NLS-1$\r
+\r
+ } catch (Exception e) {\r
+ // ignore\r
+ } finally {\r
+ if (fos != null) {\r
+ try {\r
+ fos.close();\r
+ } catch (IOException e) {\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r