/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.eclipse.ui.dialogs;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
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.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import com.windowtester.eclipse.ui.image.DialogImage;
/**
* A dialog with a details button.
*/
public abstract class AbstractDetailsDialog extends Dialog {
/**
* The title of the dialog
*/
private final String title;
/**
* The message to display
*/
private final String message;
/**
* The image to dsplay
*/
private final Image image;
/**
* The details button
*/
private Button detailsButton;
/**
* The details area
*/
private Control detailsArea;
/**
* The window size for the alternate state
*/
private Point cachedWindowSize;
////////////////////////////////////////////////////////////////////////////
//
// Constructors
//
////////////////////////////////////////////////////////////////////////////
/**
* Creates a dialog showing the specified message.
* Note that the dialog will have no visual representation (no widgets)
* until it is told to open.
*
* @param parentShell the shell under which to create this dialog
* @param title the title to use for this dialog,
* or <code>null</code> to indicate that the default title should be used
* @param image the image to appear to the left of the dialog
* or <code>null</code> for no image
* @param message the dialog message
*/
public AbstractDetailsDialog(Shell parentShell, String title, DialogImage image, String message) {
this(parentShell, title, image.getImage(), message);
}
/**
* Creates a dialog showing the specified message.
* Note that the dialog will have no visual representation (no widgets)
* until it is told to open.
*
* @param parentShell the shell under which to create this dialog
* @param title the title to use for this dialog,
* or <code>null</code> to indicate that the default title should be used
* @param image the image to appear to the left of the dialog
* or <code>null</code> for no image
* @param message the dialog message
*/
public AbstractDetailsDialog(Shell parentShell, String title, Image image, String message) {
super(parentShell);
this.title = title;
this.image = image;
this.message = message;
setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
}
////////////////////////////////////////////////////////////////////////////
//
// UI creation and event handling
//
////////////////////////////////////////////////////////////////////////////
/**
* Override superclass implementation to handle details button.
*
* @param id the id of the button that was pressed
*/
protected void buttonPressed(int id) {
if (id == IDialogConstants.DETAILS_ID) { // was the details button pressed?
toggleDetailsArea();
}
else {
super.buttonPressed(id);
}
}
/**
* Override the superclass implementation to set the dialog's title
*
* @param shell the dialog's shell
*/
protected void configureShell(Shell shell) {
super.configureShell(shell);
if (title != null)
shell.setText(title);
}
/**
* Override superclass implementation to create OK and Details buttons
* but no cancel button.
*
* @param parent the button bar
*/
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, false);
detailsButton = createButton(parent, IDialogConstants.DETAILS_ID, IDialogConstants.SHOW_DETAILS_LABEL, false);
}
/**
* Creates and returns the contents of the upper part
* of the dialog (above the button bar).
*
* @param parent the parent of the dialog area
* @return the dialog area (above the button bar)
*/
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if (image != null) {
((GridLayout) composite.getLayout()).numColumns = 2;
Label label = new Label(composite, 0);
image.setBackground(label.getBackground());
label.setImage(image);
label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_BEGINNING));
}
// create message
Label label = new Label(composite, SWT.WRAP);
if (message != null)
label.setText(message);
GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
label.setLayoutData(data);
label.setFont(parent.getFont());
return composite;
}
/**
* Toggles the unfolding of the details area. This is triggered by
* the user pressing the details button.
*/
protected void toggleDetailsArea() {
Point oldWindowSize = getShell().getSize();
Point newWindowSize = cachedWindowSize;
cachedWindowSize = oldWindowSize;
// show the details area
if (detailsArea == null) {
detailsArea = createDetailsArea((Composite) getContents());
detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
}
// hide the details area
else {
detailsArea.dispose();
detailsArea = null;
detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL);
}
/*
* Must be sure to call getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT)
* before calling getShell().setSize(newWindowSize);
* since controls have been added or removed
*/
// compute the new window size
Point oldSize = getContents().getSize();
Point newSize = getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT);
if (newWindowSize == null)
newWindowSize = new Point(oldWindowSize.x, oldWindowSize.y + (newSize.y - oldSize.y));
// crop new window size to screen
Point windowLoc = getShell().getLocation();
Rectangle screenArea = getContents().getDisplay().getClientArea();
if (newWindowSize.y > screenArea.height - (windowLoc.y - screenArea.y))
newWindowSize.y = screenArea.height - (windowLoc.y - screenArea.y);
getShell().setSize(newWindowSize);
((Composite) getContents()).layout();
}
/**
* Create the details area with content.
*
* @param parent the parent of the details area
* @return the details area
*/
protected abstract Control createDetailsArea(Composite parent);
}