• 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.util.*;
34import java.awt.event.ActionEvent;
35import javax.swing.*;
36import javax.swing.table.*;
37import att.grappa.*;
38
39
40/**
41 * Displays a fading square, color changes on forward/backward updates
42 * and then fades slowly to white.  */
43public class FadeViewletType extends AbstractViewletType {
44
45    private TableCellRenderer tableCellRenderer;
46
47    public static final int MAX_FADE = 10;
48
49    /** Holds four colours per fade level*/
50    FadeColorSupport fadeColorSupport;
51
52    public FadeViewletType(String changeable) {
53        super(changeable);
54        fadeColorSupport = new FadeColorSupport(MAX_FADE, new Color(0,255,0), new Color(255,0,0));
55    }
56
57
58    /* ViewletFactory methods */
59    public boolean canBuildFrom(ElementType elementType)
60    {
61	return(true);
62    }
63
64    public ViewletData build()
65    {
66	return new Data();
67    }
68
69    public String getDescription()
70    {
71	return("Fade viewlet");
72    }
73
74    /* ViewletType methods */
75    public synchronized TableCellRenderer getTableCellRenderer() {
76	if (tableCellRenderer == null) {
77	    tableCellRenderer = new CellRenderer();
78	}
79	return tableCellRenderer;
80    }
81
82    synchronized Class getCustomRendererClass() {
83      return CustRenderer.class;
84    }
85
86    protected Color getColor(Data data, boolean isSelected) {
87        int greyness = 0;
88        if (data.getHoldsOnUpdates()) {
89            greyness++;
90        }
91        if (isSelected) {
92            greyness+=2;
93        }
94        Color col;
95        int val = data.getFadeCount();
96        if (val > 0) {
97            col = fadeColorSupport.forwardColor[val][greyness];
98        } else {
99            col = fadeColorSupport.backwardColor[-val][greyness];
100        }
101        return col;
102    }
103
104    public void customizeElement(ViewletDataStore store,
105                                 java.util.List index,
106                                 Element element) {
107        Data data = (Data)(store.getViewletDataAt(index));
108        if (element instanceof Node) {
109            // set the custom renderer
110            element.setAttribute("shape","box");
111            // set the custom renderer
112            element.setAttribute("style","filled");
113            // set the node label
114            element.setAttribute("label","");
115            // set background color
116            element.setAttribute("color",getColor(data, false));
117        } else {
118            // instance of edge
119        }
120    }
121
122
123    public BatchGoal collectPreBuildGoal(Viewer viewer,
124                                         ViewletDataStore store,
125                                         ViewletRange range)
126    {
127	BatchGoal result = new BatchGoal();
128	return(result);
129    }
130
131    public void startBuild(Viewer viewer,
132                           ViewletDataStore store,
133                           ViewletRange range,
134                           List results) {
135    }
136
137    public BatchGoal collectPreUpdateGoal(Viewer viewer,
138                                          ViewletDataStore store,
139					  ViewletRange range,
140					  UpdateEvent updateEvent)
141    {
142	BatchGoal result = new BatchGoal();
143	return(result);
144    }
145
146    protected void setUpdating(Viewer viewer,
147                               ViewletDataStore store,
148			       ViewletRange range,
149			       int fadeCount) {
150	Iterator indexListIterator = range.iterator();
151	List currentIndex;
152	while(indexListIterator.hasNext()) {
153	    currentIndex = (List) indexListIterator.next();
154	    if (DebuggingSupport.logMessages) {
155		DebuggingSupport.logMessage(this, "currentIndex="+currentIndex);
156	    }
157	    Data viewletData =
158		(Data)(store.getViewletDataAt(currentIndex));
159	    if (DebuggingSupport.logMessages) {
160		DebuggingSupport.logMessage(this, "viewletData="+viewletData);
161	    }
162	    // Set the updating flag and store the new data
163	    if (viewletData == null) {
164		viewletData = (Data)build();
165	    }
166	    viewletData.setFadeCount(fadeCount);
167	    store.setViewletDataAt(currentIndex, viewletData);
168	}
169    }
170
171    public void startUpdate(Viewer viewer,
172                            ViewletDataStore store,
173			    ViewletRange range,
174			    List results,
175			    UpdateEvent updateEvent)
176    {
177        // set the fade counter
178        setUpdating(viewer, store, range,((updateEvent instanceof ForwardUpdateEvent)?MAX_FADE:-MAX_FADE));
179
180        ViewletRange faded = new ViewletRangeCollection();
181        ViewletRange all = store.getEntireViewletRange() ;
182        for(Iterator it = all.iterator(); it.hasNext(); ) {
183            List index = (List)it.next();
184            Data data = (Data)(store.getViewletDataAt(index));
185            if (data.fade()) {
186                faded.add(index);
187            }
188        }
189        // Indicate that these cells were updated
190        store.fireViewletRangeUpdated(faded);
191    }
192
193    /*
194     * Data is a viewlet which can monitor elements of any type. It is
195     * responsible for:
196     * <ul>
197     * <li> Maintaining a record of the text representation of the term.
198     * </ul>
199     */
200    public static class Data extends ViewletDataImpl
201    {
202	int updating;
203        protected int fadeCount;
204
205	public Data()
206	{
207	    super();
208            fadeCount = 0;
209	}
210
211	public String toString() {
212	    return "";
213	}
214
215
216        public int getFadeCount() {
217            return fadeCount;
218        }
219
220        public void setFadeCount(int count) {
221            fadeCount = count;
222        }
223
224
225        /**
226         * Move the fade counter toward zero
227         * @return true iff the fadeCount changed
228         */
229        public boolean fade() {
230            if (fadeCount == 0) {
231                return false;
232            }
233            if (fadeCount > 0) {
234                fadeCount--;
235            } else {
236                /* fadeCount < 0 */
237                fadeCount++;
238            }
239            return true;
240        }
241
242    }
243
244
245    /**
246     * Return a collection of actions which can be applied to viewlets
247     * in this table
248     */
249    public Collection getActions(ViewletDataStore store,
250                                 ViewletRange range) {
251        Collection ll = super.getActions(store, range);
252        if ((range != null) & (!range.isEmpty())) {
253            // Add type specific actions here
254        }
255        return ll;
256    }
257
258    /**
259     * The default text cell render
260     */
261    private class CellRenderer extends DefaultTableCellRenderer {
262
263	public CellRenderer() {
264	    super();
265	    setHorizontalAlignment(SwingConstants.CENTER);
266	}
267
268	public Component getTableCellRendererComponent(JTable table,
269						       Object value,
270						       boolean isSelected,
271						       boolean hasFocus,
272						       int row,
273						       int column) {
274
275            JLabel result ;
276            if (table == null) {
277                result = new JLabel();
278            } else {
279                result =
280                    (JLabel)(super.getTableCellRendererComponent(table,
281                                                                 value,
282                                                                 isSelected,
283                                                                 hasFocus,
284                                                                 row,
285                                                                 column));
286            }
287	    Data data = (Data)value;
288
289            result.setBackground(getColor(data, isSelected));
290	    return result;
291	}
292    }
293
294    /**
295     * Specialised ViewletDataStore for dealing with FadeViewlet's.
296     *
297     * <p>Stores the data in an expanding 1D array of ints.
298     */
299    public static class Store extends AbstractViewletDataStore {
300        /** number of elements between rows.  Not the same as width,
301            which is the number of elements in a row.  This difference
302            allows the 2D array to expand a few times without having
303            to copy large amounts of data */
304        protected int pitch[];
305
306        /** number of elements in a 'row' for a given dimension */
307        protected int width[];
308
309        /** Holds 'fixity' for each dimension */
310        protected boolean fixed[];
311
312        /** Holds the ints */
313        protected int[] array;
314
315        public Store(List size, List fixity, Viewable viewable) {
316            super(size, fixity, viewable, null);
317            width = new int[size.size()];
318            fixed = new boolean[fixity.size()];
319            // copy size to width
320            for(int i = 0; i < width.length; i++) {
321                width[i] = ((Integer)(size.get(i))).intValue();
322                fixed[i] = "fixed".equals(fixity.get(i));
323            }
324            int arraySize = setPitch();
325            // allocate initial array
326            array = new int[arraySize];
327        }
328
329        protected synchronized int setPitch() {
330            int arraySize = 1;
331            pitch = new int[fixed.length];
332            /* Set pitch based on fixity and width */
333            for(int i = pitch.length-1; i >= 0; i++) {
334                // on entry to the loop, arraySize holds the number of
335                // elements taken up by sub-arrays of the previous
336                // number of dimensions
337                if (fixed[i]) {
338                    pitch[i] = width[i] * arraySize;
339                } else {
340                    pitch[i] = (width[i] + 4) * arraySize;
341                }
342                // on exit from the loop, arraySize holds the number
343                // of elements taken up by a sub-array of the current
344                // number of elements
345                arraySize *= arraySize * pitch[i];
346            }
347            return arraySize;
348        }
349
350        /**
351         * Expand dimension nested at level <code>dimension</code> by one.
352         * records the pre-expansion size in the variable oldSize.
353         */
354        public void startExpandDimension(int dimension)
355        {
356            super.startExpandDimension(dimension);
357            if (width[dimension] < pitch[dimension]) {
358                // no need to do much since we have enough space to
359                // expand into
360                width[dimension]++;
361            } else {
362                // need to allocate a new array and copy the data across
363                int oldWidth[] = width;
364                int oldPitch[] = pitch;
365                int oldArray[] = array;
366                // increase size
367                width[dimension]++;
368                // re-calculate pitch info
369                int arraySize = setPitch();
370                // allocate new array
371                array = new int[arraySize];
372                // copy data, this should be optimised to use
373                // System.arrayCopy
374                switch(pitch.length) {
375                case 1: {
376                    // optimise 1D array
377                    System.arraycopy(oldArray, 0, array, 0, oldWidth[0]);
378                    break;
379                }
380                case 2: {
381                    // optimise 2D array
382                    int srcI = 0;
383                    int dstI = 0;
384                    for(int i=0; i < width[0]; i++) {
385                        // for each row
386                        System.arraycopy(oldArray, srcI,
387                                         array, dstI,
388                                         oldWidth[1]);
389                        srcI += oldPitch[1];
390                        dstI += pitch[1];
391                    }
392                    break;
393                }
394                default: {
395                    // generic
396                }
397                }
398            }
399        }
400
401        protected int calcIndex(List index) {
402            int i = 0;
403            for(int dim=0; dim < index.size() ; dim++ ) {
404                i += ((Integer)(index.get(dim))).intValue() * pitch[dim];
405            }
406            return i;
407        }
408
409        /**
410         * This method must be overridden in sub-classes
411         */
412        public ViewletData getViewletDataAt(List index) {
413            int value = array[calcIndex(index)];
414            // construct Data object from value
415            Data data = new Data();
416            data.setFadeCount(value);
417            return data;
418        }
419
420        /**
421         * This method must be overridden in sub-classes
422         */
423        public void setViewletDataAt(List index, ViewletData data) {
424            //  deconstruct Data object info value
425            int value = ((Data)data).getFadeCount();
426            // construct Data object from value
427            array[calcIndex(index)] = value;
428        }
429
430    }
431
432}
433
434