blob: 7c325c0590636dbdda46b56dbb4c7b28d2972c03 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 Tasktop Technologies 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:
* Tasktop Technologies - initial API and implementation
* Frank Becker - improvements
*******************************************************************************/
package org.eclipse.mylyn.commons.workbench;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.mylyn.commons.ui.compatibility.CommonThemes;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.themes.IThemeManager;
/**
* @author Mik Kersten
* @author Frank Becker
* @since 3.7
*/
public abstract class GradientDrawer {
private final Listener CATEGORY_GRADIENT_DRAWER = new Listener() {
public void handleEvent(Event event) {
GC gc = event.gc;
if (shouldApplyGradient(event) && gc != null) {
Scrollable scrollable = (Scrollable) event.widget;
Rectangle area = scrollable.getClientArea();
Rectangle rect = event.getBounds();
/* Paint the selection beyond the end of last column */
expandRegion(event, scrollable, gc, area);
/* Draw Gradient Rectangle */
Color oldForeground = gc.getForeground();
Color oldBackground = gc.getBackground();
gc.setForeground(categoryGradientEnd);
gc.drawLine(0, rect.y, area.width, rect.y);
gc.setForeground(categoryGradientStart);
gc.setBackground(categoryGradientEnd);
// gc.setForeground(categoryGradientStart);
// gc.setBackground(categoryGradientEnd);
// gc.setForeground(new Clr(Display.getCurrent(), 255, 0, 0));
gc.fillGradientRectangle(0, rect.y + 1, area.width, rect.height, true);
/* Bottom Line */
// gc.setForeground();
gc.setForeground(categoryGradientEnd);
gc.drawLine(0, rect.y + rect.height - 1, area.width, rect.y + rect.height - 1);
gc.setForeground(oldForeground);
gc.setBackground(oldBackground);
/* Mark as Background being handled */
event.detail &= ~SWT.BACKGROUND;
}
}
private void expandRegion(Event event, Scrollable scrollable, GC gc, Rectangle area) {
int columnCount;
if (scrollable instanceof Table) {
columnCount = ((Table) scrollable).getColumnCount();
} else {
columnCount = ((Tree) scrollable).getColumnCount();
}
if (event.index == columnCount - 1 || columnCount == 0) {
int width = area.x + area.width - event.x;
if (width > 0) {
Region region = new Region();
gc.getClipping(region);
region.add(event.x, event.y, width, event.height);
gc.setClipping(region);
region.dispose();
}
}
}
};
protected abstract boolean shouldApplyGradient(Event event);
private final IPropertyChangeListener THEME_CHANGE_LISTENER = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(IThemeManager.CHANGE_CURRENT_THEME)
|| event.getProperty().equals(CommonThemes.COLOR_SCHEDULED_PAST)
|| event.getProperty().equals(CommonThemes.COLOR_COMPLETED_TODAY)
|| event.getProperty().equals(CommonThemes.COLOR_COMPLETED)
|| event.getProperty().equals(CommonThemes.COLOR_OVERDUE)
|| event.getProperty().equals(CommonThemes.COLOR_SCHEDULED_TODAY)
|| event.getProperty().equals(CommonThemes.COLOR_SCHEDULED_PAST)
|| event.getProperty().equals(CommonThemes.COLOR_SCHEDULED_TODAY)
|| event.getProperty().equals(CommonThemes.COLOR_SCHEDULED_THIS_WEEK)
|| event.getProperty().equals(CommonThemes.COLOR_TASK_ACTIVE)
|| CommonThemes.isCommonTheme(event.getProperty())) {
configureGradientColors();
}
}
};
private boolean gradientListenerAdded = false;
private final IThemeManager themeManager;
private Color categoryGradientStart;
private Color categoryGradientEnd;
private final TreeViewer treeViewer;
public GradientDrawer(IThemeManager theThemeManager, TreeViewer treeViewer) {
this.themeManager = theThemeManager;
this.treeViewer = treeViewer;
treeViewer.getControl().addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (themeManager != null) {
themeManager.removePropertyChangeListener(THEME_CHANGE_LISTENER);
}
}
});
configureGradientColors();
themeManager.addPropertyChangeListener(THEME_CHANGE_LISTENER);
}
private void configureGradientColors() {
categoryGradientStart = themeManager.getCurrentTheme()
.getColorRegistry()
.get(CommonThemes.COLOR_CATEGORY_GRADIENT_START);
categoryGradientEnd = themeManager.getCurrentTheme()
.getColorRegistry()
.get(CommonThemes.COLOR_CATEGORY_GRADIENT_END);
boolean customized = true;
if (categoryGradientStart != null && categoryGradientStart.getRed() == 240
&& categoryGradientStart.getGreen() == 240 && categoryGradientStart.getBlue() == 240
&& categoryGradientEnd != null && categoryGradientEnd.getRed() == 220
&& categoryGradientEnd.getGreen() == 220 && categoryGradientEnd.getBlue() == 220) {
customized = false;
}
if (gradientListenerAdded == false && categoryGradientStart != null
&& !categoryGradientStart.equals(categoryGradientEnd)) {
getViewer().getTree().addListener(SWT.EraseItem, CATEGORY_GRADIENT_DRAWER);
gradientListenerAdded = true;
if (!customized) {
// Set parent-based colors
Color parentBackground = getViewer().getTree().getParent().getBackground();
double GRADIENT_TOP;// = 1.05;// 1.02;
double GRADIENT_BOTTOM;// = .995;// 1.035;
// Constants to darken or lighten the default gradients
if ("Windows 7".equals(System.getProperty("os.name"))) { //$NON-NLS-1$//$NON-NLS-2$
GRADIENT_TOP = 1.05;
GRADIENT_BOTTOM = 1.09;
} else {
GRADIENT_TOP = 1.05;
GRADIENT_BOTTOM = .995;
}
int red = Math.max(0, Math.min(255, (int) (parentBackground.getRed() * GRADIENT_TOP)));
int green = Math.max(0, Math.min(255, (int) (parentBackground.getGreen() * GRADIENT_TOP)));
int blue = Math.max(0, Math.min(255, (int) (parentBackground.getBlue() * GRADIENT_TOP)));
try {
categoryGradientStart = new Color(Display.getDefault(), red, green, blue);
} catch (Exception e) {
categoryGradientStart = getViewer().getTree().getParent().getBackground();
// StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not set color: " + red //$NON-NLS-1$
// + ", " + green + ", " + blue, e)); //$NON-NLS-1$ //$NON-NLS-2$
}
red = Math.min(255, Math.max(0, (int) (parentBackground.getRed() / GRADIENT_BOTTOM)));
green = Math.min(255, Math.max(0, (int) (parentBackground.getGreen() / GRADIENT_BOTTOM)));
blue = Math.min(255, Math.max(0, (int) (parentBackground.getBlue() / GRADIENT_BOTTOM)));
try {
categoryGradientEnd = new Color(Display.getDefault(), red, green, blue);
} catch (Exception e) {
categoryGradientStart = getViewer().getTree().getParent().getBackground();
// StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not set color: " + red //$NON-NLS-1$
// + ", " + green + ", " + blue, e)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
} else if (categoryGradientStart != null && categoryGradientStart.equals(categoryGradientEnd)) {
getViewer().getTree().removeListener(SWT.EraseItem, CATEGORY_GRADIENT_DRAWER);
gradientListenerAdded = false;
}
}
public TreeViewer getViewer() {
return treeViewer;
}
}