blob: 7415cc95474bcbaf06d7ae7dde99a1230ad79047 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 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.ui.internal.progress;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.internal.TrimUtil;
/**
* The ProgressCanvasViewer is the viewer used by progress windows. It displays text
* on the canvas.
*/
public class ProgressCanvasViewer extends AbstractProgressViewer {
Canvas canvas;
Object[] displayedItems = new Object[0];
private final static List EMPTY_LIST = new ArrayList();
/**
* Font metrics to use for determining pixel sizes.
*/
private FontMetrics fontMetrics;
private int numShowItems = 1;
private int maxCharacterWidth;
private int orientation = SWT.HORIZONTAL;
/**
* Create a new instance of the receiver with the supplied
* parent and style bits.
* @param parent The composite the Canvas is created in
* @param style style bits for the canvas
* @param itemsToShow the number of items this will show
* @param numChars The number of characters for the width hint.
* @param side the side to display text, this helps determine horizontal vs vertical
*/
ProgressCanvasViewer(Composite parent, int style, int itemsToShow, int numChars, int orientation) {
super();
this.orientation = orientation;
numShowItems = itemsToShow;
maxCharacterWidth = numChars;
canvas = new Canvas(parent, style);
hookControl(canvas);
// Compute and store a font metric
GC gc = new GC(canvas);
gc.setFont(JFaceResources.getDefaultFont());
fontMetrics = gc.getFontMetrics();
gc.dispose();
initializeListeners();
}
/**
* NE: Copied from ContentViewer. We don't want the OpenStrategy hooked
* in StructuredViewer.hookControl otherwise the canvas will take focus
* since it has a key listener. We don't want this included in the window's
* tab traversal order. Defeating it here is more self-contained then
* setting the tab list on the shell or other parent composite.
*/
protected void hookControl(Control control) {
control.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
handleDispose(event);
}
});
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#doFindInputItem(java.lang.Object)
*/
protected Widget doFindInputItem(Object element) {
return null; // No widgets associated with items
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#doFindItem(java.lang.Object)
*/
protected Widget doFindItem(Object element) {
return null; // No widgets associated with items
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#doUpdateItem(org.eclipse.swt.widgets.Widget,
* java.lang.Object, boolean)
*/
protected void doUpdateItem(Widget item, Object element, boolean fullMap) {
canvas.redraw();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#getSelectionFromWidget()
*/
protected List getSelectionFromWidget() {
//No selection on a Canvas
return EMPTY_LIST;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object)
*/
protected void internalRefresh(Object element) {
displayedItems = getSortedChildren(getRoot());
canvas.redraw();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#reveal(java.lang.Object)
*/
public void reveal(Object element) {
//Nothing to do here as we do not scroll
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(java.util.List,
* boolean)
*/
protected void setSelectionToWidget(List l, boolean reveal) {
//Do nothing as there is no selection
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.Viewer#getControl()
*/
public Control getControl() {
return canvas;
}
private void initializeListeners() {
canvas.addPaintListener(new PaintListener() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
*/
public void paintControl(PaintEvent event) {
GC gc = event.gc;
Transform transform = null;
if (orientation == SWT.VERTICAL) {
transform = new Transform(event.display);
transform.translate(TrimUtil.TRIM_DEFAULT_HEIGHT, 0);
transform.rotate(90);
}
ILabelProvider labelProvider = (ILabelProvider) getLabelProvider();
int itemCount = Math.min(displayedItems.length, numShowItems);
int yOffset = 0;
int xOffset = 0;
if (numShowItems == 1) {//If there is a single item try to center it
Rectangle clientArea = canvas.getParent().getClientArea();
if (orientation == SWT.HORIZONTAL) {
int size = clientArea.height;
yOffset = size - (fontMetrics.getHeight());
yOffset = yOffset / 2;
} else {
int size = clientArea.width;
xOffset = size - (fontMetrics.getHeight());
xOffset = xOffset / 2;
}
}
for (int i = 0; i < itemCount; i++) {
String string = labelProvider.getText(displayedItems[i]);
if(string == null) {
string = "";//$NON-NLS-1$
}
if (orientation == SWT.HORIZONTAL) {
gc.drawString(string, 2, yOffset + (i * fontMetrics.getHeight()), true);
} else {
gc.setTransform(transform);
gc.drawString(string, xOffset + (i * fontMetrics.getHeight()), 2, true);
}
}
if (transform != null)
transform.dispose();
}
});
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ContentViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)
*/
public void setLabelProvider(IBaseLabelProvider labelProvider) {
Assert.isTrue(labelProvider instanceof ILabelProvider);
super.setLabelProvider(labelProvider);
}
/**
* Get the size hints for the receiver. These are used for
* layout data.
* @return Point - the preferred x and y coordinates
*/
public Point getSizeHints() {
Display display = canvas.getDisplay();
GC gc = new GC(canvas);
FontMetrics fm = gc.getFontMetrics();
int charWidth = fm.getAverageCharWidth();
int charHeight = fm.getHeight();
int maxWidth = display.getBounds().width / 2;
int maxHeight = display.getBounds().height / 6;
int fontWidth = charWidth * maxCharacterWidth;
int fontHeight = charHeight * numShowItems;
if (maxWidth < fontWidth) {
fontWidth = maxWidth;
}
if (maxHeight < fontHeight) {
fontHeight = maxHeight;
}
gc.dispose();
return new Point(fontWidth, fontHeight);
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.progress.AbstractProgressViewer#add(java.lang.Object[])
*/
public void add(Object[] elements) {
refresh(true);
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.progress.AbstractProgressViewer#remove(java.lang.Object[])
*/
public void remove(Object[] elements) {
refresh(true);
}
}