package jqian.slicer.view.global;
import java.util.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Tree;
/**
* @author bruteforce
* A bar located on a tree item to display the distribution of sth.
*/
public abstract class DistributionDisplayBar {
protected int _barLocatingColumn; //The column where the bar locates
protected Tree _tree;
protected Listener _paintListener;
protected int _columnWidth;
protected Display _display;
protected Color _distributionColor;
/**
*
* @param tree
* @param barLocatingColumn
*/
protected DistributionDisplayBar(Tree tree,int barLocatingColumn,Color distributionColor){
this._tree = tree;
this._barLocatingColumn = barLocatingColumn;
this._paintListener = new PaintListener();
this._columnWidth = tree.getColumn(barLocatingColumn).getWidth();
this._display = tree.getShell().getDisplay();
this._distributionColor = distributionColor;
}
public void enable(){
/*
* NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
* Therefore, it is critical for performance that these methods be
* as efficient as possible.
*/
_tree.addListener(SWT.PaintItem,_paintListener);
}
public void disable(){
_tree.removeListener(SWT.PaintItem,_paintListener);
}
/**
* Determine the length of the colored bar
* @param itemdata The itemdata corresponds to a tree/table item
*/
protected abstract int getBarWidth(Object itemdata);
/**
* Determine the text displayed in colored bar
* @param itemdata The itemdata corresponds to a tree/table item
*/
protected abstract String getBarText(Object itemdata);
/**
* The distributions are represented as a couple of relevant positions in percentage
* @param itemdata The itemdata corresponds to a tree/table item
*/
protected abstract Collection<Float> getDistributions(Object itemdata);
protected void drawDistribution(GC gc,Object itemdata,int barLeft,int barTop,int barHeight){
int barWidth = getBarWidth(itemdata);
Color original = gc.getForeground();
gc.setForeground(_distributionColor);
Collection<Float> distibutes = getDistributions(itemdata);
for(Iterator<Float> it=distibutes.iterator();it.hasNext();){
Float pos = it.next();
drawDistributionLine(gc,barLeft,barTop,barWidth,barHeight,pos);
}
gc.setForeground(original);
}
protected static void drawDistributionLine(GC gc,int barLeft,int barTop,int barWidth, int barHeight, float relevantPos){
int position = (int)(barWidth * relevantPos);
gc.drawLine(barLeft+position, barTop, barLeft+position, barTop+barHeight);
}
private class PaintListener implements Listener{
public void handleEvent(Event event) {
if (event.index == _barLocatingColumn) {
TreeItem item = (TreeItem)event.item;
Object data = item.getData();
int width = getBarWidth(data);
//float percent = getSlicePercentage(data);
GC gc = event.gc;
Color foreground = gc.getForeground();
Color background = gc.getBackground();
gc.setForeground(_display.getSystemColor(SWT.COLOR_RED));
gc.setBackground(_display.getSystemColor(SWT.COLOR_YELLOW));
//draw a file size diaplay bar
gc.fillGradientRectangle(event.x, event.y, width, event.height,true);
Rectangle rect2 = new Rectangle(event.x,event.y,width-1,event.height-1);
gc.drawRectangle(rect2);
gc.setForeground(_display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
//draw slices on the file size display bar
drawDistribution(gc, data, event.x, event.y, event.height);
//display the percentage text
String text = getBarText(data);
Point size = event.gc.textExtent(text);
int offset = Math.max(0, (event.height - size.y) / 2);
gc.drawText(text, event.x + 2, event.y + offset, true);
gc.setForeground(background);
gc.setBackground(foreground);
}
}
}
public static String percentToString(float percent){
int high = (int)(percent*100);
int low = (int)(percent*10000)%100;
String text = ""+high+"."+low+"%";
return text;
}
}