| /******************************************************************************* |
| * 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; |
| } |
| |
| } |