blob: 6e960dd51f9970b69c83e14d1eb62c920a42ef83 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.common.ui.util;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.util.Geometry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.common.ui.internal.CommonUIDebugOptions;
import org.eclipse.gmf.runtime.common.ui.internal.CommonUIPlugin;
import org.eclipse.gmf.runtime.common.ui.internal.CommonUIStatusCodes;
/**
* Utilities for windows.
*
* There are also several utility methods that can be used on controls in a
* window.
*
* @author wdiu, Wayne Diu
*/
public class WindowUtil {
/**
* Center the dialog relative to a parent window.
* @param dialogShell contains the dialog to center
* @param parentShell contains the window to center relative to
*/
public static void centerDialog(Shell dialogShell, Shell parentShell) {
try {
Point dialogSize = dialogShell.getSize();
//don't use Display and then get shell from there, since
//we are trying to find the shell of the whole Eclipse window
Point windowLocation = parentShell.getLocation();
Point windowSize = parentShell.getSize();
//do not take the absolute value.
dialogShell.setLocation(
((windowSize.x - dialogSize.x) / 2) + windowLocation.x,
((windowSize.y - dialogSize.y) / 2) + windowLocation.y);
} catch (Exception e) {
//any exception when centering a dialog may be ignored
Trace.catching(CommonUIPlugin.getDefault(), CommonUIDebugOptions.EXCEPTIONS_CATCHING, WindowUtil.class, "Failed to center dialog", e); //$NON-NLS-1$
Log.error(CommonUIPlugin.getDefault(), CommonUIStatusCodes.GENERAL_UI_FAILURE, "Failed to center dialog", e); //$NON-NLS-1$
}
}
/**
* Calculates the position of a window so that it does not run off the
* screen while taking given initLocation into account. Also, if lowerY is
* greater than -1 it takes that into account: if the window is moved above
* requested initLocation.y, than it has to be completely above lowerY. This
* is needed, for example, when the window is opened by clicking on the
* button and we don't wont the button to be hidden by this popup.
*
* @param shell
* Window shell
* @param initLocation
* the initial location;
* @param lowerY
* if -1, it is ignored; otherwise, if popup is moved up, it has
* to be completely above lowerY
* @return Constrained location
* @since 1.2
*/
public static Point constrainWindowLocation(Shell shell,
Point initLocation, int lowerY) {
// First, find the (closest) monitor that contains the popup
Monitor[] monitors = shell.getDisplay().getMonitors();
int closest = Integer.MAX_VALUE;
Monitor closestMonitor = monitors[0];
Rectangle windowBounds = shell.getBounds();
Point toFind = Geometry.centerPoint(windowBounds);
for (int idx = 0; idx < monitors.length; idx++) {
Monitor current = monitors[idx];
Rectangle clientArea = current.getClientArea();
if (clientArea.contains(toFind)) {
closestMonitor = current;
break;
}
int distance = Geometry.distanceSquared(Geometry
.centerPoint(clientArea), toFind);
if (distance < closest) {
closest = distance;
closestMonitor = current;
}
}
Rectangle monitorBounds = closestMonitor.getClientArea();
// Find location that ensures that popup stays within the screen.
int windowX = Math.max(monitorBounds.x, Math.min(initLocation.x,
monitorBounds.x + monitorBounds.width - windowBounds.width));
int windowY = Math.max(monitorBounds.y, Math.min(initLocation.y,
monitorBounds.y + monitorBounds.height - windowBounds.height));
if (lowerY > -1 && windowY < initLocation.y
&& windowY + windowBounds.height > lowerY) {
// popup is moved up and is hiding part or all of the button (or
// another control that launched the window);
// make sure it is completely above the button
windowY = lowerY - windowBounds.height;
}
return new Point(windowX, windowY);
}
/**
* Dispose a parent's children
*
* @param parent composite containing children to be disposed.
*/
public static void disposeChildren(Composite parent) {
Control[] children = parent.getChildren();
for (int i = 0; i < children.length; i++) {
children[i].dispose();
}
}
/**
* Returns height and width data in a GridData for the button that was
* passed in. You can call button.setLayoutData with the returned
* data.
*
* @param button which has already been made. We'll be making the
* GridData for this button, so be sure that the text has already
* been set.
* @return GridData for this button with the suggested height and width
*/
public static GridData makeButtonData(Button button) {
GC gc = new GC(button);
gc.setFont(button.getFont());
GridData data = new GridData();
data.heightHint =
Dialog.convertVerticalDLUsToPixels(
gc.getFontMetrics(),
14);
data.widthHint =
Math.max(
Dialog.convertHorizontalDLUsToPixels(
gc.getFontMetrics(),
IDialogConstants.BUTTON_WIDTH),
button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
gc.dispose();
return data;
}
/**
* Makes the GridData for a button to be a fixed size, regardless of
* the contents of the button
* @param button the button control that we'll make the GridData for.
* @return GridData the new GridData for the button control.
*/
public static GridData makeFixedButtonData(Button button) {
GC gc = new GC(button);
gc.setFont(button.getFont());
GridData gridData = new GridData();
gridData.widthHint =
Dialog.convertHorizontalDLUsToPixels(
gc.getFontMetrics(),
IDialogConstants.BUTTON_WIDTH);
gridData.heightHint =
Dialog.convertVerticalDLUsToPixels(
gc.getFontMetrics(),
14);
gc.dispose();
return gridData;
}
/**
* Display a message box
* @param message the String message for the message box
* @param title the String title for the message box
* @param swtStyle the int style for the message box
* @param shell the Shell for the message box, such as Display.getActive().getShell()
*/
public static void doMessageBox(
String message,
String title,
int swtStyle,
Shell shell) {
MessageBox messageBox = new MessageBox(shell, swtStyle);
//stuff inside
messageBox.setMessage(message);
//title
messageBox.setText(title);
messageBox.open();
}
}