1765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/*******************************************************************************
2765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Copyright (c) 2011 Google, Inc.
3765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * All rights reserved. This program and the accompanying materials
4765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * are made available under the terms of the Eclipse Public License v1.0
5765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * which accompanies this distribution, and is available at
6765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * http://www.eclipse.org/legal/epl-v10.html
7765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *
8765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Contributors:
9765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *    Google, Inc. - initial API and implementation
10765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *******************************************************************************/
11765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepackage org.eclipse.wb.internal.core.utils.ui.dialogs;
12765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
13765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.dialogs.Dialog;
14765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.dialogs.IDialogSettings;
15765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.SWT;
16765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.ControlEvent;
17765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.ControlListener;
18765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Point;
19765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Rectangle;
20765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Shell;
21765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.ui.plugin.AbstractUIPlugin;
22765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
23765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/**
24765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * {@link Dialog} that remembers location/size between usage sessions.
25765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *
26765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @author scheglov_ke
27765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @coverage core.ui
28765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */
29765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic abstract class ResizableDialog extends Dialog {
30765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  /**
31765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   * Key for accessing {@link Dialog} from its {@link Shell}.
32765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   */
33765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  public static final String KEY_DIALOG = "KEY_DIALOG";
34765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
35765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
36765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Internal constants
37765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
38765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
39765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private static final String X = "x";
40765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private static final String Y = "y";
41765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private static final String WIDTH = "width";
42765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private static final String HEIGHT = "height";
43765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
44765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
45765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Instance fields
46765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
47765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
48765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private final AbstractUIPlugin m_plugin;
49765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
50765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
51765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
52765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Constructor
53765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
54765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
55765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  public ResizableDialog(Shell parentShell, AbstractUIPlugin plugin) {
56765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    super(parentShell);
57765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    m_plugin = plugin;
58765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
59765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
60765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
61765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
62765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
63765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Size
64765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
65765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
66765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  @Override
67765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected Point getInitialSize() {
68765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    // track the current dialog bounds
69765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    installDialogBoundsTracker();
70765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    // answer the size from the previous incarnation
71765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    Point defaultSize = getDefaultSize();
72765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    if ((getShellStyle() & SWT.RESIZE) != 0) {
73765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      Rectangle oldBounds = loadBounds();
74765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      if (oldBounds != null) {
75765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        Rectangle displayBounds = getShell().getDisplay().getBounds();
76765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        int width = Math.min(displayBounds.width, Math.max(oldBounds.width, defaultSize.x));
77765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        int height = Math.min(displayBounds.height, Math.max(oldBounds.height, defaultSize.y));
78765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        return new Point(width, height);
79765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
80765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    }
81765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    // use default size
82765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    return defaultSize;
83765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
84765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
85765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  /**
86765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   * @return the default size of dialog.
87765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   */
88765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected Point getDefaultSize() {
89765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    return super.getInitialSize();
90765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
91765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
92765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
93765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
94765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Location
95765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
96765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
97765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  @Override
98765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected Point getInitialLocation(Point initialSize) {
99765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    Rectangle windowBounds;
100765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    {
101765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      Shell windowShell = m_plugin.getWorkbench().getActiveWorkbenchWindow().getShell();
102765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      windowBounds = windowShell.getBounds();
103765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    }
104765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    // answer the location from the previous incarnation
105765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    Rectangle bounds = loadBounds();
106765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    if (bounds != null) {
107765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      int x = bounds.x;
108765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      int y = bounds.y;
109765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      int maxX = windowBounds.x + windowBounds.width - initialSize.x;
110765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      int maxY = windowBounds.y + windowBounds.height - initialSize.y;
111765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      if (x > maxX) {
112765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        x = maxX;
113765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
114765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      if (y > maxY) {
115765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        y = maxY;
116765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
117765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      if (x < windowBounds.x) {
118765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        x = windowBounds.x;
119765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
120765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      if (y < windowBounds.y) {
121765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        y = windowBounds.y;
122765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
123765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      return new Point(x, y);
124765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    }
125765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    // default location - centered on workbench window
126765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    int x = windowBounds.x + (windowBounds.width - initialSize.x) / 2;
127765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    int y = windowBounds.y + (windowBounds.height - initialSize.y) / 2;
128765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    return new Point(x, y);
129765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
130765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
131765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
132765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
133765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Bounds
134765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
135765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
136765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  /**
137765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   * Loads bounds from {@link IDialogSettings}.
138765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   */
139765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private Rectangle loadBounds() {
140765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    IDialogSettings settings = getDialogSettings();
141765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    try {
142765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      return new Rectangle(settings.getInt(X),
143765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye          settings.getInt(Y),
144765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye          settings.getInt(WIDTH),
145765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye          settings.getInt(HEIGHT));
146765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    } catch (NumberFormatException e) {
147765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      return null;
148765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    }
149765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
150765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
151765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  /**
152765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   * Saves bounds to {@link IDialogSettings}.
153765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   */
154765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private void saveBounds(Rectangle bounds) {
155765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    IDialogSettings settings = getDialogSettings();
156765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    settings.put(X, bounds.x);
157765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    settings.put(Y, bounds.y);
158765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    settings.put(WIDTH, bounds.width);
159765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    settings.put(HEIGHT, bounds.height);
160765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
161765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
162765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  /**
163765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   * @return the {@link IDialogSettings} for this dialog with this type.
164765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   */
165765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected IDialogSettings getDialogSettings() {
166765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    IDialogSettings settings = m_plugin.getDialogSettings();
167765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    String sectionName = getDialogSettingsSectionName();
168765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    if (settings.getSection(sectionName) == null) {
169765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      return settings.addNewSection(sectionName);
170765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    }
171765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    return settings.getSection(sectionName);
172765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
173765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
174765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  /**
175765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   * @return the name of section for dialog specific bounds. By default uses name of {@link Class},
176765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   *         but if same dialog is used for displaying different content, then may be overridden.
177765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye   */
178765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected String getDialogSettingsSectionName() {
179765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    return getClass().getName();
180765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
181765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
182765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
183765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
184765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Size tracking
185765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
186765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
187765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected Rectangle cachedBounds;
188765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
189765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  private void installDialogBoundsTracker() {
190765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    getShell().addControlListener(new ControlListener() {
191765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      public void controlMoved(ControlEvent e) {
192765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        cachedBounds = getShell().getBounds();
193765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
194765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
195765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      public void controlResized(ControlEvent e) {
196765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye        cachedBounds = getShell().getBounds();
197765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      }
198765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    });
199765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
200765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
201765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  @Override
202765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  public boolean close() {
203765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    boolean shellMaximized = getShell().getMaximized();
204765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    boolean closed = super.close();
205765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    if (closed && !shellMaximized && cachedBounds != null) {
206765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye      saveBounds(cachedBounds);
207765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    }
208765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    return closed;
209765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
210765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye
211765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
212765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
213765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  // Shell
214765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  //
215765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  ////////////////////////////////////////////////////////////////////////////
216765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  @Override
217765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  protected void configureShell(Shell newShell) {
218765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    super.configureShell(newShell);
219765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye    newShell.setData(KEY_DIALOG, this);
220765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye  }
221765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye}
222