Built motion from commit bcd50b9.|0.0.29
[motion.git] / public / assets / plugins / jscripty / js / Toolbar.js
1 /**
2  * $Id: Toolbar.js,v 1.3 2013-02-20 16:21:29 gaudenz Exp $
3  * Copyright (c) 2006-2012, JGraph Ltd
4  */
5 /**
6  * Construcs a new toolbar for the given editor.
7  */
8 function Toolbar(editorUi, container)
9 {
10         this.editorUi = editorUi;
11         this.container = container;
12         this.init();
13
14         // Global handler to hide the current menu
15         mxEvent.addGestureListeners(document, mxUtils.bind(this, function(evt)
16         {
17                 this.hideMenu();
18         }));
19 };
20
21 /**
22  * Adds the toolbar elements.
23  */
24 Toolbar.prototype.init = function()
25 {
26         this.addItems(['save', 'publish', '-', 'print', 'undo', 'redo', '-', 'copy', 'cut', 'paste', 'delete', '-', 'duplicate', '-', 'actualSize', 'zoomIn', 'zoomOut', '-']);
27         var fontElt = this.addMenu('Helvetica', mxResources.get('fontFamily'), true, 'fontFamily');
28         fontElt.style.whiteSpace = 'nowrap';
29         fontElt.style.overflow = 'hidden';
30         fontElt.style.width = '70px';
31         this.addSeparator();
32         var sizeElt = this.addMenu('12', mxResources.get('fontSize'), true, 'fontSize');
33         sizeElt.style.whiteSpace = 'nowrap';
34         sizeElt.style.overflow = 'hidden';
35         sizeElt.style.width = '30px';
36
37         this.addItems(['-', 'bold', 'italic', 'underline']);
38         // Giuseppe Careri
39         // var align = this.addMenuFunction('geSprite-left', mxResources.get('align'), false, mxUtils.bind(this, function(menu)
40         // {
41         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_LEFT], 'geIcon geSprite geSprite-left', null).setAttribute('title', mxResources.get('left'));
42         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_CENTER], 'geIcon geSprite geSprite-center', null).setAttribute('title', mxResources.get('center'));
43         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_RIGHT], 'geIcon geSprite geSprite-right', null).setAttribute('title', mxResources.get('right'));
44         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_TOP], 'geIcon geSprite geSprite-top', null).setAttribute('title', mxResources.get('top'));
45         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_MIDDLE], 'geIcon geSprite geSprite-middle', null).setAttribute('title', mxResources.get('middle'));
46         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_BOTTOM], 'geIcon geSprite geSprite-bottom', null).setAttribute('title', mxResources.get('bottom'));
47         // }));
48         // this.addItems(['fontColor', '-']);
49         // var line = this.addMenuFunction('geSprite-straight', mxResources.get('line'), false, mxUtils.bind(this, function(menu)
50         // {
51         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], [null], 'geIcon geSprite geSprite-straight', null).setAttribute('title', mxResources.get('straight'));
52         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['entityRelationEdgeStyle'], 'geIcon geSprite geSprite-entity', null).setAttribute('title', mxResources.get('entityRelation'));
53         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW], ['elbowEdgeStyle', 'horizontal'], 'geIcon geSprite geSprite-helbow', null).setAttribute('title', mxResources.get('horizontal'));
54         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW], ['elbowEdgeStyle', 'vertical'], 'geIcon geSprite geSprite-velbow', null).setAttribute('title', mxResources.get('vertical'));
55         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['segmentEdgeStyle'], 'geIcon geSprite geSprite-segment', null).setAttribute('title', mxResources.get('manual'));
56         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['orthogonalEdgeStyle'], 'geIcon geSprite geSprite-orthogonal', null).setAttribute('title', mxResources.get('automatic'));
57         // }));
58         // var linestart = this.addMenuFunction('geSprite-startclassic', mxResources.get('lineend'), false, mxUtils.bind(this, function(menu)
59         // {
60         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.NONE, 0], 'geIcon geSprite geSprite-noarrow', null).setAttribute('title', mxResources.get('none'));
61         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_CLASSIC, 1], 'geIcon geSprite geSprite-startclassic', null).setAttribute('title', mxResources.get('classic'));
62         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OPEN, 1], 'geIcon geSprite geSprite-startopen', null).setAttribute('title', mxResources.get('openArrow'));
63         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_BLOCK, 1], 'geIcon geSprite geSprite-startblock', null).setAttribute('title', mxResources.get('block'));
64         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OVAL, 1], 'geIcon geSprite geSprite-startoval', null).setAttribute('title', mxResources.get('oval'));
65         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND, 1], 'geIcon geSprite geSprite-startdiamond', null).setAttribute('title', mxResources.get('diamond'));
66         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND_THIN, 1], 'geIcon geSprite geSprite-startthindiamond', null).setAttribute('title', mxResources.get('diamondThin'));
67         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_CLASSIC, 0], 'geIcon geSprite geSprite-startclassictrans', null).setAttribute('title', mxResources.get('classic'));
68         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_BLOCK, 0], 'geIcon geSprite geSprite-startblocktrans', null).setAttribute('title', mxResources.get('block'));
69         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OVAL, 0], 'geIcon geSprite geSprite-startovaltrans', null).setAttribute('title', mxResources.get('oval'));
70         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND, 0], 'geIcon geSprite geSprite-startdiamondtrans', null).setAttribute('title', mxResources.get('diamond'));
71         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND_THIN, 0], 'geIcon geSprite geSprite-startthindiamondtrans', null).setAttribute('title', mxResources.get('diamondThin'));
72         // }));
73         // var lineend = this.addMenuFunction('geSprite-endclassic', mxResources.get('lineend'), false, mxUtils.bind(this, function(menu)
74         // {
75         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.NONE, 0], 'geIcon geSprite geSprite-noarrow', null).setAttribute('title', mxResources.get('none'));
76         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_CLASSIC, 1], 'geIcon geSprite geSprite-endclassic', null).setAttribute('title', mxResources.get('classic'));
77         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OPEN, 1], 'geIcon geSprite geSprite-endopen', null).setAttribute('title', mxResources.get('openArrow'));
78         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_BLOCK, 1], 'geIcon geSprite geSprite-endblock', null).setAttribute('title', mxResources.get('block'));
79         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OVAL, 1], 'geIcon geSprite geSprite-endoval', null).setAttribute('title', mxResources.get('oval'));
80         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND, 1], 'geIcon geSprite geSprite-enddiamond', null).setAttribute('title', mxResources.get('diamond'));
81         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND_THIN, 1], 'geIcon geSprite geSprite-endthindiamond', null).setAttribute('title', mxResources.get('diamondThin'));
82         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_CLASSIC, 0], 'geIcon geSprite geSprite-endclassictrans', null).setAttribute('title', mxResources.get('classic'));
83         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_BLOCK, 0], 'geIcon geSprite geSprite-endblocktrans', null).setAttribute('title', mxResources.get('block'));
84         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OVAL, 0], 'geIcon geSprite geSprite-endovaltrans', null).setAttribute('title', mxResources.get('oval'));
85         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND, 0], 'geIcon geSprite geSprite-enddiamondtrans', null).setAttribute('title', mxResources.get('diamond'));
86         //      this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND_THIN, 0], 'geIcon geSprite geSprite-endthindiamondtrans', null).setAttribute('title', mxResources.get('diamondThin'));
87         // }));
88         // this.addItems(['-', 'strokeColor', 'image', 'fillColor']);
89         // this.addItem('geSprite-gradientcolor', 'gradientColor').setAttribute('title', mxResources.get('gradient'));
90         // this.addItems(['shadow']);
91
92         var graph = this.editorUi.editor.graph;
93
94         // Update font size and font family labels
95         var update = mxUtils.bind(this, function()
96         {
97                 var ff = 'Helvetica';
98                 var fs = '12';
99         var state = graph.getView().getState(graph.getSelectionCell());
100
101         if (state != null)
102         {
103                 ff = state.style[mxConstants.STYLE_FONTFAMILY] || ff;
104                 fs = state.style[mxConstants.STYLE_FONTSIZE] || fs;
105
106                 if (ff.length > 10)
107                 {
108                         ff = ff.substring(0, 8) + '...';
109                 }
110
111                 fontElt.innerHTML = ff;
112                 sizeElt.innerHTML = fs;
113         }
114         });
115
116     graph.getSelectionModel().addListener(mxEvent.CHANGE, update);
117     graph.getModel().addListener(mxEvent.CHANGE, update);
118
119         // Giuseppe Careri
120         // Updates button states
121   //this.addEdgeSelectionHandler([line, linestart, lineend]);
122         //this.addSelectionHandler([align]);
123 };
124
125 /**
126  * Hides the current menu.
127  */
128 Toolbar.prototype.hideMenu = function()
129 {
130         if (this.currentMenu != null)
131         {
132                 this.currentMenu.hideMenu();
133                 this.currentMenu.destroy();
134                 this.currentMenu = null;
135         }
136 };
137
138 /**
139  * Adds a label to the toolbar.
140  */
141 Toolbar.prototype.addMenu = function(label, tooltip, showLabels, name)
142 {
143         var menu = this.editorUi.menus.get(name);
144         var elt = this.addMenuFunction(label, tooltip, showLabels, menu.funct);
145
146         menu.addListener('stateChanged', function()
147         {
148                 elt.setEnabled(menu.enabled);
149         });
150
151         return elt;
152 };
153
154 /**
155  * Adds a label to the toolbar.
156  */
157 Toolbar.prototype.addMenuFunction = function(label, tooltip, showLabels, funct)
158 {
159         var elt = (showLabels) ? this.createLabel(label) : this.createButton(label);
160         this.initElement(elt, tooltip);
161         this.addMenuHandler(elt, showLabels, funct);
162         this.container.appendChild(elt);
163
164         return elt;
165 };
166
167 /**
168  * Adds a separator to the separator.
169  */
170 Toolbar.prototype.addSeparator = function()
171 {
172         var elt = document.createElement('div');
173         elt.className = 'geSeparator';
174         this.container.appendChild(elt);
175
176         return elt;
177 };
178
179 /**
180  * Adds given action item
181  */
182 Toolbar.prototype.addItems = function(keys)
183 {
184         for (var i = 0; i < keys.length; i++)
185         {
186                 var key = keys[i];
187
188                 if (key == '-')
189                 {
190                         this.addSeparator();
191                 }
192                 else
193                 {
194                         this.addItem('geSprite-' + key.toLowerCase(), key);
195                 }
196         }
197 };
198
199 /**
200  * Adds given action item
201  */
202 Toolbar.prototype.addItem = function(sprite, key)
203 {
204         var action = this.editorUi.actions.get(key);
205         var elt = null;
206
207         if (action != null)
208         {
209                 elt = this.addButton(sprite, action.label, action.funct);
210                 elt.setEnabled(action.enabled);
211
212                 action.addListener('stateChanged', function()
213                 {
214                         elt.setEnabled(action.enabled);
215                 });
216         }
217
218         return elt;
219 };
220
221 /**
222  * Adds a button to the toolbar.
223  */
224 Toolbar.prototype.addButton = function(classname, tooltip, funct)
225 {
226         var elt = this.createButton(classname);
227
228         this.initElement(elt, tooltip);
229         this.addClickHandler(elt, funct);
230         this.container.appendChild(elt);
231
232         return elt;
233 };
234
235 /**
236  * Updates the states of the given toolbar items based on the selection.
237  */
238 Toolbar.prototype.addSelectionHandler = function(items)
239 {
240         var graph = this.editorUi.editor.graph;
241
242         var selectionListener = function()
243     {
244         var selected = !graph.isSelectionEmpty();
245
246         for (var i = 0; i < items.length; i++)
247         {
248                 items[i].setEnabled(selected);
249         }
250     };
251
252     graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
253     selectionListener();
254 };
255
256 /**
257  * Updates the states of the given toolbar items based on the selection.
258  */
259 Toolbar.prototype.addEdgeSelectionHandler = function(items)
260 {
261         var graph = this.editorUi.editor.graph;
262
263         var selectionListener = function()
264     {
265                 var edgeSelected = false;
266
267                 if (!graph.isSelectionEmpty())
268                 {
269                         var cells = graph.getSelectionCells();
270
271                         for (var i = 0; i < cells.length; i++)
272                         {
273                                 if (graph.getModel().isEdge(cells[i]))
274                                 {
275                                         edgeSelected = true;
276                                         break;
277                                 }
278                         }
279                 }
280
281         for (var i = 0; i < items.length; i++)
282         {
283                 items[i].setEnabled(edgeSelected);
284         }
285     };
286
287     graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
288     selectionListener();
289 };
290
291 /**
292  * Initializes the given toolbar element.
293  */
294 Toolbar.prototype.initElement = function(elt, tooltip)
295 {
296         elt.setAttribute('tabindex', '0');
297
298         // Adds tooltip
299         if (tooltip != null)
300         {
301                 elt.setAttribute('title', tooltip);
302         }
303
304         this.addEnabledState(elt);
305 };
306
307 /**
308  * Adds enabled state with setter to DOM node (avoids JS wrapper).
309  */
310 Toolbar.prototype.addEnabledState = function(elt)
311 {
312         var classname = elt.className;
313
314         elt.setEnabled = function(value)
315         {
316                 elt.enabled = value;
317
318                 if (value)
319                 {
320                         elt.className = classname;
321                 }
322                 else
323                 {
324                         elt.className = classname + ' geDisabled';
325                 }
326         };
327
328         elt.setEnabled(true);
329 };
330
331 /**
332  * Adds enabled state with setter to DOM node (avoids JS wrapper).
333  */
334 Toolbar.prototype.addClickHandler = function(elt, funct)
335 {
336         if (funct != null)
337         {
338                 mxEvent.addListener(elt, 'click', function(evt)
339                 {
340                         if (elt.enabled)
341                         {
342                                 funct(evt);
343                         }
344
345                         mxEvent.consume(evt);
346                 });
347         }
348 };
349
350 /**
351  * Creates and returns a new button.
352  */
353 Toolbar.prototype.createButton = function(classname)
354 {
355         var elt = document.createElement('a');
356         elt.setAttribute('href', 'javascript:void(0);');
357         elt.className = 'geButton';
358
359         var inner = document.createElement('div');
360         inner.className = 'geSprite ' + classname;
361         elt.appendChild(inner);
362
363         return elt;
364 };
365
366 /**
367  * Creates and returns a new button.
368  */
369 Toolbar.prototype.createLabel = function(label, tooltip)
370 {
371         var elt = document.createElement('a');
372         elt.setAttribute('href', 'javascript:void(0);');
373         elt.className = 'geLabel';
374         mxUtils.write(elt, label);
375
376         return elt;
377 };
378
379 /**
380  * Adds a handler for showing a menu in the given element.
381  */
382 Toolbar.prototype.addMenuHandler = function(elt, showLabels, funct, showAll)
383 {
384         if (funct != null)
385         {
386                 var graph = this.editorUi.editor.graph;
387                 var menu = null;
388
389                 mxEvent.addListener(elt, 'click', mxUtils.bind(this, function(evt)
390                 {
391                         if (elt.enabled == null || elt.enabled)
392                         {
393                                 graph.panningHandler.hideMenu();
394                                 menu = new mxPopupMenu(funct);
395                                 menu.div.className += ' geToolbarMenu';
396                                 menu.showDisabled = showAll;
397                                 menu.labels = showLabels;
398                                 menu.autoExpand = true;
399
400                                 menu.popup(elt.offsetLeft, elt.offsetTop + elt.offsetHeight + 34, null, evt);
401                                 this.currentMenu = menu;
402                         }
403
404                         mxEvent.consume(evt);
405                 }));
406         }
407 };