• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /barrelfish-2018-10-04/usr/eclipseclp/Visualisation/src/com/parctechnologies/eclipse/visualisation/
1// BEGIN LICENSE BLOCK
2// Version: CMPL 1.1
3//
4// The contents of this file are subject to the Cisco-style Mozilla Public
5// License Version 1.1 (the "License"); you may not use this file except
6// in compliance with the License.  You may obtain a copy of the License
7// at www.eclipse-clp.org/license.
8//
9// Software distributed under the License is distributed on an "AS IS"
10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11// the License for the specific language governing rights and limitations
12// under the License.
13//
14// The Original Code is  The ECLiPSe Constraint Logic Programming System.
15// The Initial Developer of the Original Code is  Cisco Systems, Inc.
16// Portions created by the Initial Developer are
17// Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18//
19// Contributor(s):
20//
21// END LICENSE BLOCK
22
23package com.parctechnologies.eclipse.visualisation;
24
25
26import java.util.*;
27import java.io.*;
28import java.awt.*;
29import java.awt.geom.*;
30import java.beans.*;
31import java.awt.event.*;
32import java.awt.print.*;
33import javax.swing.*;
34import javax.swing.event.*;
35import javax.swing.table.*;
36import javax.swing.filechooser.*;
37import com.parctechnologies.eclipse.*;
38import com.parctechnologies.eclipse.visualisation.*;
39import com.parctechnologies.eclipse.visualisation.viewers.*;
40import att.grappa.*;
41
42/**
43 * A gantt chart viewer based on GraphViewer
44 */
45public class GanttViewer
46    extends GraphViewer
47{
48  /** component representing the labelled time axis **/
49  TickBar tickBar;
50
51  /** xScale **/
52  double xScale;
53
54  /** yScale **/
55  TickBar yTickBar;
56
57
58  /** Inital value of xScale **/
59  static final double INITIAL_XSCALE = 5.0;
60
61  /** hold the store listener, so that we can trigger display updates
62      without going via the data store */
63  StoreListener storeListener;
64
65  /**
66   * Color to use for transparent task bars
67   **/
68  static final Color transparentColor = new Color(0.0f, 0.0f, 1.0f, 0.2f);
69
70  /**
71   * Color to use for solid task bars
72   **/
73  static final Color solidColor = new Color(0.0f, 0.0f, 1.0f);
74
75  public GanttViewer(ViewletType viewletType,
76                     VisClientStateModel stateModel,
77                     Viewable viewable) {
78    super(viewletType, stateModel, viewable, NETWORK_TYPE);
79    this.moveable = false;
80  }
81
82
83  /**
84   * To prepare for the creation event we initialise the viewlet array
85   */
86  protected void prepareForCreate(CreateEvent createEvent)
87  {
88    // for gantt charts, the entire viewable is queried in advance
89    viewletDataStore =
90      new ViewletArray(createEvent.getViewableSize(),
91                       ((ViewableType.ArrayType)createEvent.getViewableType()).getFixityList(),
92                       getViewable(),
93                       (ViewletFactory)viewletType);
94    viewletDataStore.setSymRef(new SymRef(viewletDataStore,
95                                          this.getSymRef(),
96                                          "store"));
97    storeListener = new StoreListener();
98    viewletDataStore.addViewletDataStoreListener(storeListener);
99  }
100
101
102  protected void initialiseMenu()
103  {
104    //super.initialiseMenu();
105    addMenuAndPopupMenuItem("View",null);
106    addMenuAndPopupMenuItem("View",new GrappaAntiAliasToggleAction());
107
108    addMenuAndPopupMenuItem("Graph", new SetBackgroundAction(this, false));
109    addMenuAndPopupMenuItem("Graph", new SetBackgroundAction(this, true));
110
111    addMenuAndPopupMenuItem("Gantt", new SetTaskFillAction(this, "Hollow", null));
112    addMenuAndPopupMenuItem("Gantt", new SetTaskFillAction(this, "Transparent", transparentColor));
113    addMenuAndPopupMenuItem("Gantt", new SetTaskFillAction(this, "Solid", solidColor));
114    //addMenuAndPopupMenuItem("Gantt",new SetXScaleAction());
115  }
116
117  /**
118   * Returns the mnemonic to use for a given menuTitle
119   */
120  protected int getMenuMnemonic(String menuTitle) {
121    if ("Gantt".equals(menuTitle)) return KeyEvent.VK_T;
122    return super.getMenuMnemonic(menuTitle);
123  }
124
125  /** Returns any actions or sub-menus that should be available via a
126      right-click popup menu */
127  public Collection getViewerPopupMenuCollection() {
128    Collection result = super.getViewerPopupMenuCollection();
129    result.add(getPopupMenu("Gantt"));
130    return result;
131  }
132
133
134  /**
135   * Construct graph structures
136   */
137  protected void initialiseGraph() {
138    graph = new SteadyGraph(getViewable().getNameString(),
139                            true,
140                            false,
141                            STEADY_GRAPH_SOFT_MARGIN);
142    // interpret the viewable as a gantt structure
143    initialiseGantt();
144  }
145
146  protected void initialiseComponent() {
147    super.initialiseComponent();
148    // add ticker bar to the top of the chart
149    GrappaSize graphMargins = (GrappaSize)(graph.getAttributeValue(GrappaConstants.MARGIN_ATTR));
150    double margin = 0;
151    if (graphMargins != null) {
152      margin = GrappaConstants.PointsPerInch * graphMargins.width;
153    }
154    tickBar = new TickBar(graphPanel,
155                          false,
156                          10,
157                          2,
158                          5.0,
159                          margin);
160    yTickBar = new TickBar(graphPanel,
161                           true,
162                           1,
163                           1,
164                           40.0,
165                           margin);
166    TickBarMouseListener tbml = new TickBarMouseListener();
167    tickBar.addMouseListener(tbml);
168    tickBar.addMouseMotionListener(tbml);
169    scrollPane.setColumnHeaderView(tickBar);
170    scrollPane.setRowHeaderView(yTickBar);
171    setXScalePrivate(new Double(INITIAL_XSCALE));
172  }
173
174  class TickBarMouseListener extends MouseAdapter implements MouseMotionListener {
175    int initialX;
176    double initialXScale;
177
178    public void mousePressed(MouseEvent e) {
179      initialX=e.getX()-(int)tickBar.displayMargin;
180      initialXScale=xScale;
181      if (DebuggingSupport.logMessages) {
182        DebuggingSupport.logMessage(this,"initialX="+initialX);
183      }
184    }
185
186    public void mouseDragged(MouseEvent e) {
187      int currentX=e.getX()-(int)tickBar.displayMargin;
188      if (DebuggingSupport.logMessages) {
189        DebuggingSupport.logMessage(this,"currentX="+currentX);
190      }
191      tickBar.setScalingRight(currentX > initialX);
192      tickBar.setScale((initialXScale * currentX)/initialX);
193    }
194
195    public void mouseReleased(MouseEvent e) {
196      int currentX=e.getX()-(int)tickBar.displayMargin;
197      if (DebuggingSupport.logMessages) {
198        DebuggingSupport.logMessage(this,"currentX="+currentX);
199      }
200      setXScale((initialXScale * currentX)/initialX);
201    }
202
203    public void mouseMoved(MouseEvent e) {
204      // do nothing
205    }
206  }
207
208
209  protected Element getElement(java.util.List index) {
210    ArrayList newIndex = new ArrayList(index);
211    newIndex.set(0,new Integer(-1));
212    Element element = graph.findNodeByName(newIndex.toString());
213    if (element == null) {
214      element = graph.findEdgeByName(newIndex.toString());
215    }
216    return element;
217  }
218
219
220
221  protected void initialiseGantt() {
222    if (DebuggingSupport.logMessages) {
223      DebuggingSupport.logMessage(this, "initialiseGantt called");
224    }
225    Map nodeNumberToNode = new HashMap();
226    int numColumns = ((Integer)(viewletDataStore.getSize().get(0))).intValue();
227    int numTasks = ((Integer)(viewletDataStore.getSize().get(1))).intValue();
228    ArrayList index = new ArrayList(2);
229    index.add(new Integer(1));
230    index.add(new Integer(1));
231    for(int i = 1; i < numTasks+1; i++) {
232      if (DebuggingSupport.logMessages) {
233        DebuggingSupport.logMessage(this, "i="+i);
234      }
235      ViewletData data;
236      Integer integerI = new Integer(i);
237      index.set(0,new Integer(-1));
238      index.set(1,integerI);
239
240      data = null;
241
242      if (DebuggingSupport.logMessages) {
243        DebuggingSupport.logMessage(this,"task="+data+" index="+index);
244      }
245      //Node node = new Node(graph, index.toString());
246      Node node;
247
248      node = insertNode(viewletDataStore, index, data, viewletType);
249      node.getGrappaNexus().boundText = false;
250      node.setAttribute("label",getLocationName(2,i));
251    }
252  }
253
254  /**
255   * configure all the viewlets prior to having the graph drawn for
256   * the first time.
257   */
258  void customizeViewlets() {
259    int numElements = ((Integer)(viewletDataStore.getSize().get(0))).intValue();
260    int numColumns = ((Integer)(viewletDataStore.getSize().get(1))).intValue();
261    ArrayList index = new ArrayList(2);
262    index.add(new Integer(1));
263    index.add(new Integer(1));
264    for(int i = 1; i < numElements+1; i++) {
265      if (DebuggingSupport.logMessages) {
266        DebuggingSupport.logMessage(this, "i="+i);
267      }
268      ViewletData data;
269      Integer integerI = new Integer(i);
270      index.set(0,integerI);
271
272      index.set(1,new Integer(1));
273      //data = viewletDataStore.getViewletDataAt(index);
274
275      Element element = getElement(index);
276
277      elementToViewletType(index).customizeElement(viewletDataStore, index, element);
278    }
279  }
280
281  public void zoomToLevel(float zoomLevel)
282  {
283    // scale the graph
284    super.zoomToLevel(zoomLevel);
285    // scale the tickbar
286    tickBar.zoomToLevel(zoomLevel);
287    yTickBar.zoomToLevel(zoomLevel);
288  }
289
290
291  /**
292   * Set the amount by which the display should be stretched in the X
293   * direction.
294   **/
295  public void setXScale(double xScale) {
296    if (DebuggingSupport.logMessages) {
297      DebuggingSupport.logMessage(this,"old xScale="+this.xScale+" new xScale="+xScale);
298    }
299    new ViewerSetXScaleCommand(this, xScale).issue();
300  }
301
302  /**
303   * Actualy set the amount by which the display should be stretched
304   * in the X direction.  This method is called from the
305   * ViewerSetXScaleCommand command.
306   **/
307  public void setXScalePrivate(Object xScale) {
308    this.xScale=((Double)xScale).doubleValue();
309    ((GanttTaskViewletType)viewletType).setXScale(this.xScale);
310    tickBar.setScale(this.xScale);
311    storeListener.rangeUpdated(viewletDataStore, viewletDataStore.getEntireViewletRange());
312    graph.resetBoundingBox();
313  }
314
315
316  public String getToolTip(java.util.List index) {
317    // return the task name
318    int row = ((Integer)index.get(1)).intValue();
319    String taskName = getLocationName(2,row);
320    return "task "+taskName;
321  }
322
323
324  /**
325   * Class to synchronize the graph elements when changes happen to
326   * the ViewletData. */
327  protected class StoreListener implements ViewletDataStoreListener {
328    public StoreListener() {
329    }
330
331    public void rangeUpdated(ViewletDataStore store,
332                             ViewletRange range) {
333      for(Iterator it = range.iterator(); it.hasNext(); ) {
334        java.util.List index = new ArrayList((java.util.List)(it.next()));
335        index.set(0,new Integer(-1));
336        Element element = getElement(index);
337        // configure the renderer
338        ViewletType type = elementToViewletType(index);
339        type.customizeElement(store, index, element);
340      }
341      graph.repaint();
342    }
343  }
344
345  class SetTaskFillAction extends AbstractAction {
346    private GanttViewer viewer;
347    private Color color;
348
349    SetTaskFillAction(GanttViewer viewer, String name, Color color) {
350      super("Set fill color to "+name);
351      this.viewer = viewer;
352      this.color = color;
353    }
354
355    public void actionPerformed(ActionEvent event) {
356      (new GanttViewerSetTaskFillCommand(viewer, color)).issue();
357    }
358  }
359
360  public void setTaskFillColorPrivate(Object color) {
361    ((GanttTaskViewletType)viewletType).setFillColor((Color)color);
362    storeListener.rangeUpdated(viewletDataStore, viewletDataStore.getEntireViewletRange());
363  }
364
365  public static class GanttViewerSetTaskFillCommand extends ViewerSetPropertyCommand {
366    Color color;
367
368    public GanttViewerSetTaskFillCommand(Viewer viewer, Color color) {
369      super(viewer, "taskFillColor");
370      this.color = color;
371    }
372
373    /**
374     * Define the 'newValue' for this property to color
375     */
376    Object getNewValue() {
377      return color;
378    }
379  }
380}
381
382