Project: dawn-third
/*******************************************************************************
 * 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() { 
    
   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; 
 
  
}