/*
* Copyright 2010 The Rabbit Eclipse Plug-in Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package rabbit.ui.internal.viewers;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newLinkedList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.TreeItem;
import java.util.List;
/**
* A label provider for a tree viewer column that paints horizontal bars in the
* cells.
*/
public class TreeViewerCellPainter extends StyledCellLabelProvider {
private Color customBackground;
private Color systemForeground;
private final IValueProvider valueProvider;
private final boolean isLinux;
/**
* @param valueProvider the provider for getting the values of each tree path.
* @throws NullPointerException if argument is null.
*/
public TreeViewerCellPainter(IValueProvider valueProvider) {
this.valueProvider = checkNotNull(valueProvider, "valueProvider");
this.isLinux = Platform.getOS().equals(Platform.OS_LINUX);
}
@Override
public void dispose() {
super.dispose();
customBackground.dispose();
}
/**
* Gets the value provider of this painter.
*
* @return The value provider.
*/
public IValueProvider getValueProvider() {
return valueProvider;
}
@Override
public void initialize(ColumnViewer viewer, ViewerColumn column) {
super.initialize(viewer, column);
Display display = viewer.getControl().getDisplay();
systemForeground = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
customBackground = createColor(display);
}
@Override
public void paint(Event event, Object element) {
if (!valueProvider.shouldPaint(element)) {
return;
}
TreePath path = getTreePath((TreeItem) event.item);
int columnWidth = event.gc.getClipping().width;
int width = getWidth(columnWidth, path);
if (width == 0) {
return;
}
int x = event.x;
int y = event.y;
int height = event.height - 1;
GC gc = event.gc;
Color oldBackground = gc.getBackground();
Color oldForeground = gc.getForeground();
int oldAnti = gc.getAntialias();
int oldAlpha = gc.getAlpha();
/*
* On Linux, enabling GC's antialias or changing the alpha will sometimes
* cause the color bar to be half drawn.
*/
if (!isLinux) {
int alpha = (int) (width / (float) columnWidth * 255);
if (alpha < 100) {
alpha = 100;
}
gc.setAlpha(alpha);
gc.setAntialias(SWT.ON);
}
gc.setBackground(customBackground);
gc.fillRectangle(x, y, 2, height);
gc.fillRoundRectangle(x, y, width, height, 4, 4);
gc.setAlpha(oldAlpha);
gc.setAntialias(oldAnti);
gc.setForeground(systemForeground);
gc.drawLine(x, y, x, y + height - 1);
gc.drawLine(x + width, y, x + width, y + height - 1);
gc.setBackground(oldBackground);
gc.setForeground(oldForeground);
}
/**
* Creates the desired color for painting the cells. Callers of this method
* must dispose the returned color themselves.
*
* @param display the display to create the color for.
* @return a new color.
*/
protected Color createColor(Display display) {
return new Color(display, 84, 141, 212);
}
private TreePath getTreePath(TreeItem item) {
List<Object> segments = newLinkedList();
while (item != null) {
segments.add(0, item.getData());
item = item.getParentItem();
}
return new TreePath(segments.toArray());
}
/**
* Gets the width in pixels for the paint.
*/
private int getWidth(int columnWidth, TreePath path) {
long maxValue = valueProvider.getMaxValue();
if (maxValue == 0) {
return 0;
}
long value = valueProvider.getValue(path);
int width = (int) (value * columnWidth / (double) valueProvider
.getMaxValue());
width = ((value != 0) && (width == 0)) ? 2 : width;
if (value != 0 && width < 2) {
width = 2;
}
return width;
}
}