8f4021ee7f664a5fce60a771ab91827d829279cf
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / palette / XcosPalette.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4  * 
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at    
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.palette;
14
15 import java.awt.Color;
16 import java.awt.Dimension;
17 import java.awt.FlowLayout;
18 import java.awt.GradientPaint;
19 import java.awt.Graphics;
20 import java.awt.Graphics2D;
21 import java.awt.Point;
22 import java.awt.Rectangle;
23 import java.awt.datatransfer.DataFlavor;
24 import java.awt.dnd.DnDConstants;
25 import java.awt.dnd.DragGestureEvent;
26 import java.awt.dnd.DragGestureListener;
27 import java.awt.dnd.DragSource;
28 import java.awt.event.ComponentEvent;
29 import java.awt.event.ComponentListener;
30 import java.awt.event.MouseEvent;
31 import java.awt.event.MouseListener;
32
33 import javax.swing.ImageIcon;
34 import javax.swing.JComponent;
35 import javax.swing.JPanel;
36 import javax.swing.JScrollPane;
37 import javax.swing.TransferHandler;
38
39 import org.flexdock.plaf.common.border.ShadowBorder;
40
41 import com.mxgraph.swing.util.mxGraphTransferable;
42 import com.mxgraph.util.mxConstants;
43 import com.mxgraph.util.mxEvent;
44 import com.mxgraph.util.mxEventObject;
45 import com.mxgraph.util.mxEventSource;
46 import com.mxgraph.util.mxEventSource.mxIEventListener;
47
48 public class XcosPalette extends JScrollPane implements ComponentListener {
49     private static final long serialVersionUID = 1L;
50     private static final int HMARGIN = 5;
51     private static final int VMARGIN = 5;
52     private static final int DEFAULT_NB_COLS = 1; /* Updated dynamically at creation */
53
54     private JPanel panel = null;
55     private String name;
56
57     protected BlockPalette selectedEntry;
58
59     protected mxEventSource eventSource = new mxEventSource(this);
60
61     protected Color gradientColor = Color.LIGHT_GRAY;
62
63     public XcosPalette(String name) {
64         super(new JPanel());
65         panel = (JPanel) getViewport().getComponent(0);
66         this.name = name;
67         setBackground(Color.WHITE);
68
69         panel.setBackground(Color.WHITE);
70         panel.setLayout(new FlowLayout(FlowLayout.LEADING, HMARGIN, VMARGIN));
71         panel.setPreferredSize(new Dimension(DEFAULT_NB_COLS * (BlockPalette.BLOCK_WIDTH + HMARGIN), 0));
72
73         getVerticalScrollBar().setBlockIncrement(BlockPalette.BLOCK_HEIGHT + VMARGIN);
74         getVerticalScrollBar().setUnitIncrement(BlockPalette.BLOCK_HEIGHT + VMARGIN);
75
76         //getHorizontalScrollBar().setVisible(false);
77         getHorizontalScrollBar().setBlockIncrement(BlockPalette.BLOCK_WIDTH + HMARGIN);
78         getHorizontalScrollBar().setUnitIncrement(BlockPalette.BLOCK_WIDTH + HMARGIN);
79
80         addComponentListener(this);
81         // Clears the current selection when the background is clicked
82         addMouseListener(new MouseListener()
83         {
84
85             /*
86              * (non-Javadoc)
87              * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
88              */
89             public void mousePressed(MouseEvent e) {
90                 clearSelection();
91             }
92
93             /*
94              * (non-Javadoc)
95              * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
96              */
97             public void mouseClicked(MouseEvent e) {
98             }
99
100             /*
101              * (non-Javadoc)
102              * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
103              */
104             public void mouseEntered(MouseEvent e) {
105             }
106
107             /*
108              * (non-Javadoc)
109              * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
110              */
111             public void mouseExited(MouseEvent e) {
112             }
113
114             /*
115              * (non-Javadoc)
116              * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
117              */
118             public void mouseReleased(MouseEvent e) {
119             }
120
121         });
122
123         // Shows a nice icon for drag and drop but doesn't import anything
124         setTransferHandler(new TransferHandler() {
125             private static final long serialVersionUID = 1L;
126
127             public boolean canImport(JComponent comp, DataFlavor[] flavors) {
128                 return true;
129             }
130         });
131     }
132
133     /**
134      * 
135      */
136     public void setGradientColor(Color c) {
137         gradientColor = c;
138     }
139
140     /**
141      * 
142      */
143     public Color getGradientColor() {
144         return gradientColor;
145     }
146
147     /**
148      * 
149      */
150     public void paintComponent(Graphics g) {
151         if (gradientColor == null) {
152             super.paintComponent(g);
153         } else {
154             Rectangle rect = getVisibleRect();
155
156             if (g.getClipBounds() != null) {
157                 rect = rect.intersection(g.getClipBounds());
158             }
159
160             Graphics2D g2 = (Graphics2D) g;
161
162             g2.setPaint(new GradientPaint(0, 0, getBackground(), getWidth(), 0,
163                     gradientColor));
164             g2.fill(rect);
165         }
166     }
167
168     /**
169      * 
170      */
171     public void clearSelection() {
172         setSelectionEntry(null, null);
173     }
174
175     /**
176      * 
177      */
178     public void setSelectionEntry(BlockPalette entry, mxGraphTransferable t) {
179         BlockPalette last = selectedEntry;
180         selectedEntry = entry;
181
182         if (last != null) {
183             last.setBorder(null);
184             last.setOpaque(false);
185         }
186
187         if (selectedEntry != null) {
188             selectedEntry.setBorder(new ShadowBorder());
189             selectedEntry.setOpaque(true);
190         }
191
192         eventSource.fireEvent(mxEvent.SELECT, new mxEventObject(new Object[] {
193                 selectedEntry, t, last }));
194     }
195
196
197
198     /**
199      * 
200      * @param name
201      * @param icon
202      * @param style
203      * @param width
204      * @param height
205      * @param value
206      */
207     public void addTemplate(final String name, ImageIcon icon) {
208
209         final BlockPalette entry = new BlockPalette(icon);
210
211         entry.setPalette(this);
212         entry.setToolTipText(name);
213         entry.setText(name);
214
215         // Install the handler for dragging nodes into a graph
216         DragGestureListener dragGestureListener = new DragGestureListener()
217         {
218             /**
219              * 
220              */
221             public void dragGestureRecognized(DragGestureEvent e) {
222                 e.startDrag(null, mxConstants.EMPTY_IMAGE, new Point(), entry.getTransferable(), null);
223             }
224
225         };
226
227         DragSource dragSource = new DragSource();
228         dragSource.createDefaultDragGestureRecognizer(entry,
229                 DnDConstants.ACTION_COPY, dragGestureListener);
230
231         panel.add(entry);
232     }
233
234     /**
235      * @param eventName
236      * @param listener
237      * @see com.mxgraph.util.mxEventSource#addListener(java.lang.String, com.mxgraph.util.mxEventSource.mxIEventListener)
238      */
239     public void addListener(String eventName, mxIEventListener listener) {
240         eventSource.addListener(eventName, listener);
241     }
242
243     /**
244      * @return
245      * @see com.mxgraph.util.mxEventSource#isEventsEnabled()
246      */
247     public boolean isEventsEnabled() {
248         return eventSource.isEventsEnabled();
249     }
250
251     /**
252      * @param listener
253      * @see com.mxgraph.util.mxEventSource#removeListener(com.mxgraph.util.mxEventSource.mxIEventListener)
254      */
255     public void removeListener(mxIEventListener listener) {
256         eventSource.removeListener(listener);
257     }
258
259     /**
260      * @param eventName
261      * @param listener
262      * @see com.mxgraph.util.mxEventSource#removeListener(java.lang.String, com.mxgraph.util.mxEventSource.mxIEventListener)
263      */
264     public void removeListener(mxIEventListener listener, String eventName) {
265         eventSource.removeListener(listener, eventName);
266     }
267
268     /**
269      * @param eventsEnabled
270      * @see com.mxgraph.util.mxEventSource#setEventsEnabled(boolean)
271      */
272     public void setEventsEnabled(boolean eventsEnabled) {
273         eventSource.setEventsEnabled(eventsEnabled);
274     }
275
276     public void componentHidden(ComponentEvent arg0) {
277     }
278
279     public void componentMoved(ComponentEvent arg0) {
280     }
281
282     public void componentResized(ComponentEvent arg0) {
283         if (arg0.getSource() instanceof XcosPalette) {
284             XcosPalette palette = ((XcosPalette) arg0.getSource());
285             int panelWidth = (int) palette.getSize().getWidth() - 3;
286
287             //take care if VerticalScrollBar is visible to compute visible area
288             if (getVerticalScrollBar().isVisible()) {
289                 panelWidth -=  getVerticalScrollBar().getWidth();
290             }
291
292             int numberOfCols = panelWidth / (BlockPalette.BLOCK_WIDTH + HMARGIN);
293             double numberOfRows = (double) panel.getComponentCount() / (double) numberOfCols;
294             int preferedHeight = (int) ((BlockPalette.BLOCK_HEIGHT + VMARGIN) * Math.ceil(numberOfRows));
295
296             panel.setPreferredSize(new Dimension(panelWidth, preferedHeight));
297         }
298     }
299
300     public void componentShown(ComponentEvent arg0) {
301     }
302
303     public String toString() {
304         return this.name;
305     }
306
307     public BlockPalette getSelectedEntry() {
308         return selectedEntry;
309     }
310
311     public void setSelectedEntry(BlockPalette selectedEntry) {
312         this.selectedEntry = selectedEntry;
313     }
314
315 }