blob: a5979aa9a95c6fbf6002e7f8e446d06935a61013 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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
* Tasktop Technologies - generalized ProgressInfoItem for reuse
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.discovery.util;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
/**
* Based on {@link org.eclipse.ui.internal.progress.ProgressInfoItem}.
*
* @author Steffen Pingel
*/
public abstract class ControlListItem<T> extends Composite {
static String DARK_COLOR_KEY = "org.eclipse.mylyn.commons.ui.ControlListItem.DARK_COLOR"; //$NON-NLS-1$
interface IndexListener {
/**
* Select the item previous to the receiver.
*/
public void selectPrevious();
/**
* Select the next previous to the receiver.
*/
public void selectNext();
/**
* Select the receiver.
*/
public void select();
public void open();
}
IndexListener indexListener;
private int currentIndex;
private boolean selected;
private final MouseAdapter mouseListener;
private boolean isShowing = true;
private final MouseTrackAdapter mouseTrackListener;
private boolean hot;
static {
// Mac has different Gamma value
int shift = "carbon".equals(SWT.getPlatform()) ? -25 : -10;//$NON-NLS-1$
Color lightColor = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
// Determine a dark color by shifting the list color
RGB darkRGB = new RGB(Math.max(0, lightColor.getRed() + shift), Math.max(0, lightColor.getGreen() + shift), Math.max(0, lightColor.getBlue() + shift));
JFaceResources.getColorRegistry().put(DARK_COLOR_KEY, darkRGB);
}
/**
* Create a new instance of the receiver with the specified parent, style and info object/
*
* @param parent
* @param style
* @param progressInfo
*/
public ControlListItem(Composite parent, int style, T element) {
super(parent, style | SWT.NO_FOCUS);
Assert.isNotNull(element);
super.setData(element);
setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
mouseListener = doCreateMouseListener();
mouseTrackListener = doCreateMouseTrackListener();
registerChild(this);
// Control[] children = getChildren();
// for (Control child : children) {
// registerChild(child);
// }
setHot(false);
}
@SuppressWarnings("unchecked")
@Override
public T getData() {
return (T) super.getData();
}
@Override
public void setData(Object data) {
throw new IllegalArgumentException();
}
private MouseTrackAdapter doCreateMouseTrackListener() {
return new MouseTrackAdapter() {
private int enterCount;
@Override
public void mouseEnter(MouseEvent e) {
enterCount++;
updateHotState();
}
@Override
public void mouseExit(MouseEvent e) {
enterCount--;
getDisplay().asyncExec(new Runnable() {
public void run() {
if (!isDisposed()) {
updateHotState();
}
}
});
}
private void updateHotState() {
if (enterCount == 0) {
if (isHot()) {
setHot(false);
}
} else {
if (!isHot()) {
setHot(true);
}
}
}
};
}
private MouseAdapter doCreateMouseListener() {
return new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (indexListener != null) {
if (e.count == 2) {
indexListener.open();
} else {
indexListener.select();
}
}
}
};
}
public boolean isHot() {
return hot;
}
public void setHot(boolean hot) {
this.hot = hot;
}
protected void registerChild(Control child) {
child.addMouseListener(mouseListener);
child.addMouseTrackListener(mouseTrackListener);
}
/**
* Refresh the contents of the receiver.
*/
protected abstract void refresh();
/**
* Set the color base on the index
*
* @param index
*/
public void updateColors(int index) {
currentIndex = index;
if (selected) {
setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION));
setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
} else {
if (index % 2 == 0) {
setBackground(JFaceResources.getColorRegistry().get(DARK_COLOR_KEY));
} else {
setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
}
setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
}
}
@Override
public void setForeground(Color color) {
super.setForeground(color);
Control[] children = getChildren();
for (Control child : children) {
child.setForeground(color);
}
}
@Override
public void setBackground(Color color) {
super.setBackground(color);
Control[] children = getChildren();
for (Control child : children) {
child.setBackground(color);
}
}
/**
* Set the selection colors.
*
* @param select
* boolean that indicates whether or not to show selection.
*/
public void setSelected(boolean select) {
selected = select;
updateColors(currentIndex);
}
/**
* Set the listener for index changes.
*
* @param indexListener
*/
void setIndexListener(IndexListener indexListener) {
this.indexListener = indexListener;
}
/**
* Return whether or not the receiver is selected.
*
* @return boolean
*/
public boolean isSelected() {
return selected;
}
/**
* Set whether or not the receiver is being displayed based on the top and bottom of the currently visible area.
*
* @param top
* @param bottom
*/
void setDisplayed(int top, int bottom) {
int itemTop = getLocation().y;
int itemBottom = itemTop + getBounds().height;
setDisplayed(itemTop <= bottom && itemBottom > top);
}
/**
* Set whether or not the receiver is being displayed
*
* @param displayed
*/
private void setDisplayed(boolean displayed) {
// See if this element has been turned off
boolean refresh = !isShowing && displayed;
isShowing = displayed;
if (refresh) {
refresh();
}
}
}