• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /barrelfish-2018-10-04/usr/eclipseclp/Visualisation/src/com/parctechnologies/eclipse/visualisation/viewers/
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.viewers;
24
25import com.parctechnologies.eclipse.*;
26import com.parctechnologies.eclipse.visualisation.*;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import java.awt.geom.*;
31import java.awt.Color;
32import java.awt.Component;
33import java.awt.Dimension;
34import java.awt.Graphics;
35import java.awt.Graphics2D;
36import java.util.*;
37import java.awt.event.ActionEvent;
38import javax.swing.*;
39import javax.swing.table.*;
40import att.grappa.*;
41
42
43/**
44 * Display a task in a gantt viewer
45 **/
46public class GanttTaskViewletType extends BoundsViewletType {
47
48  /** The factor by which to stretch the displayy in the x direction **/
49  double xScale = 1.0;
50
51  /** defualt line color **/
52  final Color DEFAULT_COLOR = Color.blue;
53
54  /** The color to use when drawing tasks **/
55  Color color;
56
57  public GanttTaskViewletType(String changeable) {
58    super(changeable);
59  }
60
61  public ViewletData build()
62  {
63    return new Data();
64  }
65
66  public String getDescription()
67  {
68    return("GanttTask viewlet");
69  }
70
71  public Class getCustomRendererClass() {
72    return Renderer.class;
73  }
74
75  public void setXScale(double xScale) {
76    this.xScale = xScale;
77  }
78
79  public void setFillColor(Color color) {
80    this.color = color;
81  }
82
83  public void customizeElement(ViewletDataStore store,
84                               java.util.List index,
85                               Element element) {
86    if (((Integer)(index.get(0))).intValue() == -1) {
87      if (DebuggingSupport.logMessages) {
88        DebuggingSupport.logMessage(this,"GanttTask Viewlet customize");
89      }
90      final double YSCALE=40;
91      // when the first index is given as -1, this will force
92      // the whole 'row' to be intepreted as a task in a gannt
93      // chart.
94      ArrayList index2 = new ArrayList(index);
95      Data data;
96      double taskData[] = new double[6];
97      index2.set(0, new Integer(1));
98      // start
99      data = (Data)store.getViewletDataAt(index2);
100      taskData[0] = data.min;
101      taskData[1] = data.max;
102      // end=start+duration
103      index2.set(0, new Integer(2));
104      data = (Data)store.getViewletDataAt(index2);
105      taskData[2] = taskData[0] + data.min;
106      taskData[3] = taskData[1] + data.max;
107      // resource
108      index2.set(0, new Integer(3));
109      data = (Data)store.getViewletDataAt(index2);
110      taskData[4] = data.min;
111      taskData[5] = data.max+0.9;
112
113      // set the custom renderer
114      double width=(taskData[3]-taskData[0])*xScale / GrappaConstants.PointsPerInch;
115      double height=(taskData[5]-taskData[4])*YSCALE / GrappaConstants.PointsPerInch;
116
117      double x = ((taskData[3] + taskData[0])*xScale / 2);
118      double y = ((taskData[5] + taskData[4])*YSCALE / 2);
119      element.setAttribute("pos",x+",-"+y);
120      element.setAttribute("width",""+width);
121      element.setAttribute("height",""+height);
122      element.getGrappaNexus().updateShape();
123      if (DebuggingSupport.logMessages) {
124        DebuggingSupport.logMessage(this,"taskData="+taskData+" pos="+x+",-"+y+" width="+width+" height="+height);
125        DebuggingSupport.logMessage(this,"element.getAttribute(width)="+element.getAttribute("width"));
126        DebuggingSupport.logMessage(this,"element.getAttribute(height)="+element.getAttribute("height"));
127      }
128      element.setAttribute("shape",new Integer(Grappa.CUSTOM_SHAPE));
129      element.setAttribute(Grappa.CUSTOM_ATTR,getCustomRendererClass().getName());
130
131      // set background color
132      Color backColor = (color==null?DEFAULT_COLOR:color);
133      // set filled, if a color has been specified
134      if (color != null) {
135        element.setAttribute("style", "filled");
136        if (data.getHoldsOnUpdates()) {
137          element.setAttribute("color", backColor.darker());
138        } else {
139          element.setAttribute("color", backColor);
140        }
141      } else {
142        element.setAttribute("color", backColor);
143        if (data.getHoldsOnUpdates()) {
144          element.setAttribute("style", "dotted");
145        } else {
146          element.setAttribute("style", "solid");
147        }
148      }
149      //Color color = new Color(0.0f, 0.0f, 1.0f, 0.2f);
150      //Color color = new Color(0.0f, 0.0f, 1.0f);
151      // force shape update
152      element.object = taskData;
153      element.getGrappaNexus().updateText();
154      element.getGrappaNexus().updateShape();
155    } else {
156      super.customizeElement(store, index, element);
157    }
158  }
159
160  /**
161   * Return a collection of actions which can be applied to viewlets
162   * in this table
163   */
164  public Collection getActions(ViewletDataStore store,
165                               ViewletRange range) {
166    Collection ll = new LinkedList();
167    if ((range != null) & (!range.isEmpty())) {
168      // Add new actions here
169      ll.add((new ToggleHoldAction()).createCompoundAction(store, range));
170    }
171    if ((range != null) & (range.size()==1)) {
172      java.util.List index = (java.util.List)(range.iterator().next());
173      // Add new actions here which apply only to single viewlets
174    }
175    if ((range != null) & (range.size()==3)) {
176      java.util.List index = (java.util.List)(range.iterator().next());
177      // Add new actions here which apply to a single task
178      ll.add(new DisplayTaskInDetailAction(store,index));
179    }
180    return ll;
181  }
182
183
184  /**
185   * Action class to display the bounds in detail in a popup window
186   **/
187  private class DisplayTaskInDetailAction extends ViewletAction {
188    List index;
189    ViewletDataStore store;
190
191    DisplayTaskInDetailAction(ViewletDataStore store,
192                              java.util.List index) {
193      super("Display task bounds");
194      putValue(Action.NAME, "Display task bounds");
195      putValue(Action.LONG_DESCRIPTION,
196               "Popup window displaying the task in detail");
197      putValue(Action.SHORT_DESCRIPTION,
198               "Popup window displaying the task in detail");
199      //putValue(Action.SMALL_ICON, new FadeIcon(20, 20));
200      this.store = store;
201      this.index = index;
202    }
203
204    public void actionPerformed(ActionEvent e) {
205      ArrayList index2 = new ArrayList(index);
206      Data data;
207
208      Double taskData[][] = new Double[4][4]; // start, duration, end, resource
209
210      // start
211      index2.set(0, new Integer(1));
212      data = (Data)store.getViewletDataAt(index2);
213      taskData[0][0] = new Double(data.initialMin);
214      taskData[0][1] = new Double(data.min);
215      taskData[0][2] = new Double(data.max);
216      taskData[0][3] = new Double(data.initialMax);
217
218      // duration
219      index2.set(0, new Integer(2));
220      data = (Data)store.getViewletDataAt(index2);
221      // end = duration
222      taskData[1][0] = new Double(data.initialMin);
223      taskData[1][1] = new Double(data.max);
224      taskData[1][2] = new Double(data.min);
225      taskData[1][3] = new Double(data.initialMax);
226      // end=start+duration
227      taskData[2][0] = new Double(taskData[0][0].doubleValue() + taskData[1][0].doubleValue());
228      taskData[2][1] = new Double(taskData[0][1].doubleValue() + taskData[1][1].doubleValue());
229      taskData[2][2] = new Double(taskData[0][2].doubleValue() + taskData[1][2].doubleValue());
230      taskData[2][3] = new Double(taskData[0][3].doubleValue() + taskData[1][3].doubleValue());
231
232      // resource
233      index2.set(0, new Integer(3));
234      data = (Data)store.getViewletDataAt(index2);
235      taskData[3][0] = new Double(data.initialMin);
236      taskData[3][1] = new Double(data.max);
237      taskData[3][2] = new Double(data.min);
238      taskData[3][3] = new Double(data.initialMax);
239
240      String columnNames[] = {"Initial Min", "Min", "Max", "Initial Max"};
241      String rowNames[][] = {{"Start"}, {"Duration"}, {"End"}, {"Resource"}};
242
243      JTable table = new JTable(taskData,columnNames);
244      table.setEnabled(false);
245      table.setColumnSelectionAllowed(false);
246      table.setRowSelectionAllowed(false);
247      table.setCellSelectionEnabled(false);
248      JScrollPane message = new JScrollPane(table);
249      String rowName[] = {""};
250      JTable rowNameTable = new JTable(rowNames,rowName);
251      message.setRowHeaderView(rowNameTable);
252      message.getRowHeader().setPreferredSize(rowNameTable.getPreferredSize());
253      message.getViewport().setPreferredSize(table.getPreferredSize());
254
255      JOptionPane.
256        showConfirmDialog(null,
257                          message,
258                          "Task bounds in detail",
259                          JOptionPane.DEFAULT_OPTION);
260    }
261  }
262
263
264
265  public static class Renderer extends CustRenderer {
266    public Renderer(Element element,
267                    double x, double y, double w, double h) {
268      super(element, x, y, w, h);
269      if (DebuggingSupport.logMessages) {
270        DebuggingSupport.logMessage(this,"GanttTask Renderer constructed for element "+element);
271      }
272      double[] data = (double[])(element.object);
273      if (data != null) {
274        configure(new Rectangle2D.Double(x,y,w,h),
275                  data);
276      }
277    }
278
279    public void configure(Rectangle2D bounds,
280                          double[] data) {
281      // data[0]=start min, data[1]=start max,
282      // data[2]=end min, data[3]=end max,
283      // data[4]=resource min, data[5]=resource max
284
285      // draw a "box and stick" diagram within the specified bounds
286      //
287      // E  +------+    +----------------+
288      //    |      |    |                |
289      //    |      |    |                |
290      //    |      |    |                |
291      // F  +------+----+----------------+
292      //    A      B    C                D
293      //
294      //Rectangle2D bounds = getBounds2D();
295      float A,B,C,D,E,F;
296      //A = (float)data[0];
297      //D = (float)data[3];
298      A = (float)bounds.getMinX();
299      if (DebuggingSupport.logMessages) {
300        DebuggingSupport.logMessage(this,"A="+A+" bounds.getMinX()"+bounds.getMinX());
301      }
302      D = (float)bounds.getMaxX();
303      if (DebuggingSupport.logMessages) {
304        DebuggingSupport.logMessage(this,"D="+D);
305      }
306      //E = (float)(data[4]);
307      //F = (float)((data[5]));
308      E = (float)bounds.getMinY();
309      F = (float)bounds.getMaxY();
310
311      // remove potential for divide by zero
312      if (data[0] == data[3]) {
313        data[3]+=0.001;
314      }
315      // calculate scale for drawing
316      double rangeX=data[3]-data[0];
317      double rangeY=data[5]-data[4];
318
319      B = A + (float)(((data[2]-data[0]) * bounds.getWidth()) / rangeX);
320      C = A + (float)(((data[1]-data[0]) * bounds.getWidth()) / rangeX);
321
322      // draw outline
323      float vertices[][] = {{A,F},{A,E},{B,E},{B,F},
324                            {C,F},{C,E},{D,E},{D,F}};
325      path.moveTo(vertices[0][0], vertices[0][1]);
326      for(int i = 1; i < vertices.length; i++) {
327        if (DebuggingSupport.logMessages) {
328          DebuggingSupport.logMessage(this,"GanttTask point "+i+
329                                      " x="+vertices[i][0]+
330                                      " y="+vertices[i][1]);
331        }
332        path.lineTo(vertices[i][0], vertices[i][1]);
333      }
334      path.closePath();
335    }
336  }
337
338
339
340}
341
342