/*******************************************************************************
* Copyright (c) 2010 Oak Ridge National Laboratory.
* 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
******************************************************************************/
package org.csstudio.swt.xygraph.figures;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import org.csstudio.swt.xygraph.preference.XYPreferences;
import org.csstudio.swt.xygraph.util.XYGraphMediaFactory;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
/**The legend to indicate the style and size of the trace line and point.
* The border color of the legend is same as the traces' Y-Axis color.
* @author Xihui Chen
*
*/
public class Legend extends RectangleFigure {
private final static int ICON_WIDTH = 25;
private final static int INNER_GAP = 2;
private final static int OUT_GAP = 5;
// private final static Font LEGEND_FONT = XYGraphMediaFactory.getInstance().getFont(
// XYGraphMediaFactory.FONT_ARIAL);
//
// private final Color WHITE_COLOR = XYGraphMediaFactory.getInstance().getColor(
// XYGraphMediaFactory.COLOR_WHITE);
private final Color BLACK_COLOR = XYGraphMediaFactory.getInstance().getColor(
XYGraphMediaFactory.COLOR_BLACK);
private final List<Trace> traceList = new ArrayList<Trace>();
public Legend(XYGraph xyGraph) {
// setFont(LEGEND_FONT);
xyGraph.getPlotArea().addPropertyChangeListener(PlotArea.BACKGROUND_COLOR, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
setBackgroundColor((Color) evt.getNewValue());
}
});
setBackgroundColor(xyGraph.getPlotArea().getBackgroundColor());
setForegroundColor(BLACK_COLOR);
setOpaque(false);
setOutline(true);
}
/**Add a trace to the axis.
* @param trace the trace to be added.
*/
public void addTrace(Trace trace){
traceList.add(trace);
}
/**Remove a trace from the axis.
* @param trace
* @return true if this axis contained the specified trace
*/
public boolean removeTrace(Trace trace){
return traceList.remove(trace);
}
@Override
protected void outlineShape(Graphics graphics) {
if (!traceList.isEmpty()) {
graphics.setForegroundColor(traceList.get(0).getYAxis().getForegroundColor());
}
super.outlineShape(graphics);
}
@Override
protected void fillShape(Graphics graphics) {
if(!((XYGraph)getParent()).isTransparent())
super.fillShape(graphics);
int hPos = bounds.x + INNER_GAP;
int vPos = bounds.y + INNER_GAP;
int i=0;
for(Trace trace : traceList){
int hwidth = OUT_GAP + ICON_WIDTH + INNER_GAP +
+ FigureUtilities.getTextExtents(trace.getName(), getFont()).width;
int hEnd = hPos + hwidth;
if(hEnd > (bounds.x + bounds.width) && i>0){
hPos= bounds.x + INNER_GAP;
vPos += ICON_WIDTH + INNER_GAP;
hEnd = hPos + hwidth;
}
// graphics.setForegroundColor(trace.getYAxis().getForegroundColor());
// Rectangle rect = new Rectangle(hPos, vPos-INNER_GAP/2, hwidth - OUT_GAP,ICON_WIDTH-INNER_GAP);
// graphics.fillRectangle(rect);
// graphics.drawRectangle(rect);
drawTraceLegend(trace, graphics, hPos, vPos);
hPos = hEnd;
i++;
}
}
private void drawTraceLegend(Trace trace, Graphics graphics, int hPos, int vPos){
graphics.pushState();
if (XYPreferences.useAdvancedGraphics())
graphics.setAntialias(SWT.ON);
graphics.setForegroundColor(trace.getTraceColor());
//draw symbol
switch (trace.getTraceType()) {
case BAR:
trace.drawLine(graphics, new Point(hPos + ICON_WIDTH/2, vPos + trace.getPointSize()/2),
new Point(hPos + ICON_WIDTH/2, vPos + ICON_WIDTH));
trace.drawPoint(graphics, new Point(hPos + ICON_WIDTH/2, vPos+ trace.getPointSize()/2));
break;
case AREA:
graphics.setBackgroundColor(trace.getTraceColor());
if (XYPreferences.useAdvancedGraphics())
graphics.setAlpha(trace.getAreaAlpha());
graphics.fillPolygon(new int[]{hPos, vPos + ICON_WIDTH/2,
hPos + ICON_WIDTH/2, vPos + trace.getPointSize()/2,
hPos + ICON_WIDTH, vPos + ICON_WIDTH/2,
hPos + ICON_WIDTH, vPos + ICON_WIDTH,
hPos, vPos + ICON_WIDTH});
if (XYPreferences.useAdvancedGraphics())
graphics.setAlpha(255);
trace.drawPoint(graphics, new Point(hPos + ICON_WIDTH/2, vPos+ trace.getPointSize()/2));
break;
default:
trace.drawLine(graphics, new Point(hPos, vPos + ICON_WIDTH/2),
new Point(hPos + ICON_WIDTH, vPos + ICON_WIDTH/2));
trace.drawPoint(graphics, new Point(hPos + ICON_WIDTH/2, vPos+ICON_WIDTH/2));
break;
}
//draw text
graphics.drawText(trace.getName(), hPos+ICON_WIDTH + INNER_GAP,
vPos + ICON_WIDTH/2 -
FigureUtilities.getTextExtents(trace.getName(), getFont()).height/2);
graphics.popState();
}
@Override
public Dimension getPreferredSize(int wHint, int hHint) {
int maxWidth =0;
int hEnd = INNER_GAP;
int height = ICON_WIDTH + INNER_GAP;
// int i=0;
for(Trace trace : traceList){
hEnd = hEnd + OUT_GAP + ICON_WIDTH + INNER_GAP +
+ FigureUtilities.getTextExtents(trace.getName(), getFont()).width;
if(hEnd > wHint){
hEnd= INNER_GAP + OUT_GAP + ICON_WIDTH + INNER_GAP +
+ FigureUtilities.getTextExtents(trace.getName(), getFont()).width;
height += ICON_WIDTH + INNER_GAP;
}
if(maxWidth < hEnd)
maxWidth = hEnd;
// i++;
}
return new Dimension(maxWidth, height);
}
/**
* @return the traceList
*/
public List<Trace> getTraceList() {
return traceList;
}
}