source: Dev/branches/jQueryUI/client/RGraph/libraries/RGraph.common.context.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

File size: 23.5 KB
Line 
1    /**
2    * o------------------------------------------------------------------------------o
3    * | This file is part of the RGraph package - you can learn more at:             |
4    * |                                                                              |
5    * |                          http://www.rgraph.net                               |
6    * |                                                                              |
7    * | This package is licensed under the RGraph license. For all kinds of business |
8    * | purposes there is a small one-time licensing fee to pay and for non          |
9    * | commercial  purposes it is free to use. You can read the full license here:  |
10    * |                                                                              |
11    * |                      http://www.rgraph.net/LICENSE.txt                       |
12    * o------------------------------------------------------------------------------o
13    */
14
15    if (typeof(RGraph) == 'undefined') RGraph = {isRGraph:true,type:'common'};
16
17
18    /**
19    * This gunction shows a context menu containing the parameters
20    * provided to it
21    *
22    * @param object canvas    The canvas object
23    * @param array  menuitems The context menu menuitems
24    * @param object e         The event object
25    */
26    RGraph.Contextmenu = function (canvas, menuitems, e)
27    {
28        e = RGraph.FixEventObject(e);
29
30        /**
31        * Fire the custom RGraph event onbeforecontextmenu
32        */
33        RGraph.FireCustomEvent(canvas.__object__, 'onbeforecontextmenu');
34
35        /**
36        * Hide any existing menu
37        */
38        if (RGraph.Registry.Get('chart.contextmenu')) {
39            RGraph.HideContext();
40        }
41       
42        // Hide any zoomed canvas
43        RGraph.HideZoomedCanvas();
44
45        /**
46        * Hide the palette if necessary
47        */
48        RGraph.HidePalette();
49       
50        /**
51        * This is here to ensure annotating is OFF
52        */
53        canvas.__object__.Set('chart.mousedown', false);
54
55        var x      = e.pageX;
56        var y      = e.pageY;
57        var div    = document.createElement('div');
58        var bg     = document.createElement('div');
59
60        div.className             = 'RGraph_contextmenu';
61        div.__canvas__            = canvas; /* Store a reference to the canvas on the contextmenu object */
62        div.style.position        = 'absolute';
63        div.style.left            = 0;
64        div.style.top             = 0;
65        div.style.border          = '1px solid black';
66        div.style.backgroundColor = 'white';
67        div.style.boxShadow       = '3px 3px 3px rgba(96,96,96,0.5)';
68        div.style.MozBoxShadow    = '3px 3px 3px rgba(96,96,96,0.5)';
69        div.style.WebkitBoxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
70        div.style.filter          = 'progid:DXImageTransform.Microsoft.Shadow(color=#aaaaaa,direction=135)';
71        div.style.opacity         = 0;
72
73        bg.className             = 'RGraph_contextmenu_background';
74        bg.style.position        = 'absolute';
75        bg.style.backgroundColor = '#ccc';
76        bg.style.borderRight     = '1px solid #aaa';
77        bg.style.top             = 0;
78        bg.style.left            = 0;
79        bg.style.width           = '18px';
80        bg.style.height          = '100%';
81        bg.style.opacity         = 0;
82
83
84        div = document.body.appendChild(div);
85        bg  = div.appendChild(bg);
86
87
88        /**
89        * Now add the context menu items
90        */
91        for (i=0; i<menuitems.length; ++i) {
92           
93            var menuitem = document.createElement('div');
94           
95            menuitem.__canvas__      = canvas;
96            menuitem.__contextmenu__ = div;
97            menuitem.className       = 'RGraph_contextmenu_item';
98           
99            if (menuitems[i]) {
100                menuitem.style.padding = '2px 5px 2px 23px';
101                menuitem.style.fontFamily = 'Arial';
102                menuitem.style.fontSize = '10pt';
103                menuitem.style.fontWeight = 'normal';
104                menuitem.innerHTML = menuitems[i][0];
105
106                if (RGraph.is_array(menuitems[i][1])) {
107                    menuitem.style.backgroundImage = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAQUlEQVQImY3NoQ2AMABE0ZewABMyGQ6mqWODzlAclBSFO8HZl8uf0FFxCHtwYkt4Y6ChYE44cGH9/fyae2p2LAleW9oVTQuVf6gAAAAASUVORK5CYII=)';
108                    menuitem.style.backgroundRepeat = 'no-repeat';
109                    menuitem.style.backgroundPosition = '97% center';
110                }
111
112                // Add the mouseover event
113                if (menuitems[i][1]) {
114                    if (menuitem.addEventListener) {
115                        menuitem.addEventListener("mouseover", function (e) {RGraph.HideContextSubmenu(); e.target.style.backgroundColor = 'rgba(0,0,0,0.2)'; e.target.style.cursor = 'pointer';}, false);
116                        menuitem.addEventListener("mouseout", function (e) {e.target.style.backgroundColor = 'inherit'; e.target.style.cursor = 'default';}, false);
117                    } else  {
118                        menuitem.attachEvent("onmouseover", function () {RGraph.HideContextSubmenu();event.srcElement.style.backgroundColor = '#eee';event.srcElement.style.cursor = 'pointer';}
119                    , false);
120                        menuitem.attachEvent("onmouseout", function () {event.srcElement.style.backgroundColor = 'inherit'; event.srcElement.style.cursor = 'default';}, false);
121                    }
122                } else {
123                    if (menuitem.addEventListener) {
124                        menuitem.addEventListener("mouseover", function (e) {e.target.style.cursor = 'default';}, false);
125                        menuitem.addEventListener("mouseout", function (e) {e.target.style.cursor = 'default';}, false);
126                    } else  {
127                        menuitem.attachEvent("onmouseover", function () {event.srcElement.style.cursor = 'default'}, false);
128                        menuitem.attachEvent("onmouseout", function () {event.srcElement.style.cursor = 'default';}, false);
129                    }
130                }
131
132            } else {
133                menuitem.style.borderBottom = '1px solid #ddd';
134                menuitem.style.marginLeft = '25px';
135            }
136
137            div.appendChild(menuitem);
138
139            /**
140            * Install the event handler that calls the menuitem
141            */
142            if (menuitems[i] && menuitems[i][1] && typeof(menuitems[i][1]) == 'function') {
143                if (document.all  && 0) { // MSIE bit no longer necessary
144                    menuitem.attachEvent('onclick', menuitems[i][1]);
145                    menuitem.attachEvent('onclick', function () {RGraph.HideContext();});
146                } else {
147                    menuitem.addEventListener('click', menuitems[i][1], false);
148                }
149           
150            // Submenu
151            } else if (menuitems[i] && menuitems[i][1] && RGraph.is_array(menuitems[i][1])) {
152                (function ()
153                {
154                    var tmp = menuitems[i][1]; // This is here because of "references vs primitives" and how they're passed around in Javascript
155                    menuitem.addEventListener('mouseover', function (e) {RGraph.Contextmenu_submenu(canvas.__object__, tmp, e.target);}, false);
156                })();
157            }
158        }
159
160        /**
161        * Now all the menu items have been added, set the shadow width
162        * Shadow now handled by CSS3?
163        */
164        div.style.width = (div.offsetWidth + 10) + 'px';
165        div.style.height = (div.offsetHeight - 2) + 'px';
166
167        /**
168        * Set the background (the left bar) width if it's MSIE
169        */
170        //if (document.all) {
171        //    bg.style.height = (div.offsetHeight - 2) + 'px';
172        //}
173
174        // Show the menu to the left or the right (normal) of the cursor?
175        if (x + div.offsetWidth > document.body.offsetWidth) {
176            x -= div.offsetWidth;
177        }
178       
179        // Reposition the menu (now we have the real offsetWidth)
180        div.style.left = x + 'px';
181        div.style.top = y + 'px';
182
183        /**
184        * Do a little fade in effect
185        */
186        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.2", 50);
187        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.4", 100);
188        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.6", 150);
189        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.8", 200);
190        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 1", 250);
191
192        // The fade in effect on the left gray bar
193        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.2", 50);
194        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.4", 100);
195        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.6", 150);
196        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.8", 200);
197        setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 1", 250);
198
199        // Store the context menu in the registry
200        RGraph.Registry.Set('chart.contextmenu', div);
201        RGraph.Registry.Set('chart.contextmenu.bg', bg);
202        RGraph.Registry.Get('chart.contextmenu').oncontextmenu = function () {return false;};
203        RGraph.Registry.Get('chart.contextmenu.bg').oncontextmenu = function () {return false;};
204
205        /**
206        * Install the event handlers that hide the context menu
207        */
208        canvas.addEventListener('click', function () {RGraph.HideContext();}, false);
209
210        window.onclick = function (e)
211        {
212            RGraph.HideContext();
213           
214            // Removed on 3/7/10 - stops a bug in conjunction with annotating which presents itself on the Rscatter
215            //RGraph.Redraw();
216           
217            // Fire the onclick event again
218            if (e.target.onclick && e.button == 0) {
219                e.target.onclick(e);
220            }
221        }
222
223        window.onresize = function () {RGraph.HideContext();}
224       
225        /**
226        * Add the __shape__ object to the context menu
227        */
228       
229        /**
230        * Set the shape coords from the .getShape()  method
231        */
232        if (typeof(canvas.__object__.getShape) == 'function') {
233            RGraph.Registry.Get('chart.contextmenu').__shape__ = canvas.__object__.getShape(e);
234        }
235
236
237        e.stopPropagation();
238
239        /**
240        * Fire the (RGraph) oncontextmenu event
241        */
242        RGraph.FireCustomEvent(canvas.__object__, 'oncontextmenu');
243
244        return false;
245    }
246
247
248    /**
249    * Hides the context menu if it's currently visible
250    */
251    RGraph.HideContext = function ()
252    {
253        var cm   = RGraph.Registry.Get('chart.contextmenu');
254        var cmbg = RGraph.Registry.Get('chart.contextmenu.bg');
255       
256        //Hide any submenu currently being displayed
257        RGraph.HideContextSubmenu();
258
259        if (cm) {
260            cm.parentNode.removeChild(cm);
261            cmbg.parentNode.removeChild(cmbg);
262
263            cm.style.visibility = 'hidden';
264            cm.style.display = 'none';
265            RGraph.Registry.Set('chart.contextmenu', null);
266           
267            cmbg.style.visibility = 'hidden';
268            cmbg.style.display = 'none';
269            RGraph.Registry.Set('chart.contextmenu.bg', null);
270        }
271    }
272
273
274    /**
275    * Hides the context menus SUBMENU if it's currently visible
276    */
277    RGraph.HideContextSubmenu = function ()
278    {
279        var sub  = RGraph.Registry.Get('chart.contextmenu.submenu');
280
281        if (sub) {
282            sub.style.visibility = 'none';
283            sub.style.display    = 'none';
284            RGraph.Registry.Set('chart.contextmenu.submenu', null);
285        }
286    }
287
288
289    /**
290    * Shows the context menu after making a few checks - not opera (doesn't support oncontextmenu,
291    * not safari (tempermentality), not chrome (hmmm)
292    */
293    RGraph.ShowContext = function (obj)
294    {
295        RGraph.HidePalette();
296
297        if (obj.Get('chart.contextmenu') && obj.Get('chart.contextmenu').length) {
298
299            var isOpera      = navigator.userAgent.indexOf('Opera') >= 0;
300            var isSafari     = navigator.userAgent.indexOf('Safari') >= 0;
301            var isChrome     = navigator.userAgent.indexOf('Chrome') >= 0;
302            var isMacFirefox = navigator.userAgent.indexOf('Firefox') > 0 && navigator.userAgent.indexOf('Mac') > 0;
303            var isIE9        = navigator.userAgent.indexOf('MSIE 9') >= 0;
304
305            if (((!isOpera && !isSafari) || isChrome) && !isMacFirefox) {
306
307                obj.canvas.oncontextmenu = function (e)
308                {
309                     e = RGraph.FixEventObject(e);
310
311                    if (e.ctrlKey) return true;
312
313                    RGraph.Contextmenu(obj.canvas, obj.Get('chart.contextmenu'), e);
314
315                    return false;
316                }
317
318            // Accomodate Opera and Safari - use double click event
319            } else {
320
321                obj.canvas.addEventListener('dblclick', function (e)
322                {
323                    if (e.ctrlKey) return true;
324
325                    if (!RGraph.Registry.Get('chart.contextmenu')) {
326                        RGraph.Contextmenu(obj.canvas, obj.Get('chart.contextmenu'), e);
327                    }
328                }, false);
329            }
330        }
331    }
332
333
334    /**
335    * This draws a submenu should it be necessary
336    *
337    * @param object obj  The graph object
338    * @param object menu The context menu
339    */
340    RGraph.Contextmenu_submenu = function (obj, menuitems, parentMenuItem)
341    {
342        RGraph.HideContextSubmenu();
343
344        var canvas  = obj.canvas;
345        var context = obj.context;
346        var menu    = parentMenuItem.parentNode;
347
348        var subMenu = document.createElement('DIV');
349        subMenu.style.position = 'absolute';
350        subMenu.style.width = '100px';
351        subMenu.style.top = menu.offsetTop + parentMenuItem.offsetTop + 'px';
352        subMenu.style.left            = (menu.offsetLeft + menu.offsetWidth - (RGraph.isIE8() ? 9 : 0)) + 'px';
353        subMenu.style.backgroundColor = 'white';
354        subMenu.style.border          = '1px solid black';
355        subMenu.className             = 'RGraph_contextmenu';
356        subMenu.__contextmenu__       = menu;
357        subMenu.style.boxShadow       = '3px 3px 3px rgba(96,96,96,0.5)';
358        subMenu.style.MozBoxShadow    = '3px 3px 3px rgba(96,96,96,0.5)';
359        subMenu.style.WebkitBoxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
360        subMenu.style.filter          = 'progid:DXImageTransform.Microsoft.Shadow(color=#aaaaaa,direction=135)';
361        document.body.appendChild(subMenu);
362       
363        for (var i=0; i<menuitems.length; ++i) {
364                   
365            var menuitem = document.createElement('DIV');
366           
367            menuitem.__canvas__      = canvas;
368            menuitem.__contextmenu__ = menu;
369            menuitem.className       = 'RGraph_contextmenu_item';
370           
371            if (menuitems[i]) {
372                menuitem.style.padding = '2px 5px 2px 23px';
373                menuitem.style.fontFamily = 'Arial';
374                menuitem.style.fontSize = '10pt';
375                menuitem.style.fontWeight = 'normal';
376                menuitem.innerHTML = menuitems[i][0];
377       
378                if (menuitems[i][1]) {
379                    if (menuitem.addEventListener) {
380                        menuitem.addEventListener("mouseover", function (e) {e.target.style.backgroundColor = 'rgba(0,0,0,0.2)'; e.target.style.cursor = 'pointer';}, false);
381                        menuitem.addEventListener("mouseout", function (e) {e.target.style.backgroundColor = 'inherit'; e.target.style.cursor = 'default';}, false);
382                    } else  {
383                        menuitem.attachEvent("onmouseover", function () {event.srcElement.style.backgroundColor = 'rgba(0,0,0,0.2)'; event.srcElement.style.cursor = 'pointer'}, false);
384                        menuitem.attachEvent("onmouseout", function () {event.srcElement.style.backgroundColor = 'inherit'; event.srcElement.style.cursor = 'default';}, false);
385                    }
386                } else {
387                    if (menuitem.addEventListener) {
388                        menuitem.addEventListener("mouseover", function (e) {e.target.style.cursor = 'default';}, false);
389                        menuitem.addEventListener("mouseout", function (e) {e.target.style.cursor = 'default';}, false);
390                    } else  {
391                        menuitem.attachEvent("onmouseover", function () {event.srcElement.style.cursor = 'default'}, false);
392                        menuitem.attachEvent("onmouseout", function () {event.srcElement.style.cursor = 'default';}, false);
393                    }
394                }
395            } else {
396                menuitem.style.borderBottom = '1px solid #ddd';
397                menuitem.style.marginLeft = '25px';
398            }
399           
400            subMenu.appendChild(menuitem);
401       
402            if (menuitems[i] && menuitems[i][1]) {
403                if (document.all) {
404                    menuitem.attachEvent('onclick', menuitems[i][1]);
405                } else {
406                    menuitem.addEventListener('click', menuitems[i][1], false);
407                }
408            }
409        }
410
411
412        var bg                   = document.createElement('DIV');
413        bg.className             = 'RGraph_contextmenu_background';
414        bg.style.position        = 'absolute';
415        bg.style.backgroundColor = '#ccc';
416        bg.style.borderRight     = '1px solid #aaa';
417        bg.style.top             = 0;
418        bg.style.left            = 0;
419        bg.style.width           = '18px';
420        bg.style.height          = '100%';
421
422        bg  = subMenu.appendChild(bg);
423
424        RGraph.Registry.Set('chart.contextmenu.submenu', subMenu);
425    }
426
427
428    /**
429    * A function designed to be used in conjunction with thed context menu
430    * to allow people to get image versions of canvases.
431    *
432    * @param      canvas Optionally you can pass in the canvas, which will be used
433    */
434    RGraph.showPNG = function ()
435    {
436        if (RGraph.isIE8()) {
437            alert('[RGRAPH PNG] Sorry, showing a PNG is not supported on MSIE8.');
438            return;
439        }
440
441        if (arguments[0] && arguments[0].id) {
442            var canvas = arguments[0];
443            var event  = arguments[1];
444       
445        } else if (RGraph.Registry.Get('chart.contextmenu')) {
446            var canvas = RGraph.Registry.Get('chart.contextmenu').__canvas__;
447       
448        } else {
449            alert('[RGRAPH SHOWPNG] Could not find canvas!');
450        }
451
452        var obj = canvas.__object__;
453
454        /**
455        * Create the gray background DIV to cover the page
456        */
457        var bg = document.createElement('DIV');
458            bg.id = '__rgraph_image_bg__';
459            bg.style.position = 'fixed';
460            bg.style.top = '-10px';
461            bg.style.left = '-10px';
462            bg.style.width = '5000px';
463            bg.style.height = '5000px';
464            bg.style.backgroundColor = 'rgb(204,204,204)';
465            bg.style.opacity = 0;
466        document.body.appendChild(bg);
467       
468       
469        /**
470        * Create the div that the graph sits in
471        */
472        var div = document.createElement('DIV');
473            div.style.backgroundColor = 'white';
474            div.style.opacity = 0;
475            div.style.border = '1px solid black';
476            div.style.position = 'fixed';
477            div.style.top = '20%';
478            div.style.width = canvas.width + 'px';
479            div.style.height = canvas.height + 35 + 'px';
480            div.style.left = (document.body.clientWidth / 2) - (canvas.width / 2) + 'px';
481            div.style.padding = '5px';
482
483            div.style.borderRadius = '10px';
484            div.style.MozBorderRadius = '10px';
485            div.style.WebkitBorderRadius = '10px';
486
487            div.style.boxShadow    = '0 0 15px rgba(96,96,96,0.5)';
488            div.style.MozBoxShadow = '0 0 15px rgba(96,96,96,0.5)';
489            div.style.WebkitBoxShadow = 'rgba(96,96,96,0.5) 0 0 15px';
490
491            div.__canvas__ = canvas;
492            div.__object__ = obj;
493            div.id = '__rgraph_image_div__';
494        document.body.appendChild(div);
495
496       
497        /**
498        * Add the HTML text inputs
499        */
500        div.innerHTML += '<div style="position: absolute; margin-left: 10px; top: ' + canvas.height + 'px; width: ' + (canvas.width - 50) + 'px; height: 25px"><span style="display: inline; display: inline-block; width: 65px; text-align: right">URL:</span><textarea style="float: right; overflow: hidden; height: 15px; width: ' + (canvas.width - obj.gutterLeft - obj.gutterRight - 80) + 'px" onclick="this.select()" readonly="readonly" id="__rgraph_dataurl__">' + canvas.toDataURL() + '</textarea></div>';
501        div.innerHTML += '<div style="position: absolute; top: ' + (canvas.height + 25) + 'px; left: ' + (obj.gutterLeft - 65 + (canvas.width / 2)) + 'px; width: ' + (canvas.width - obj.gutterRight) + 'px; font-size: 65%">A link using the URL: <a href="' + canvas.toDataURL() + '">View</a></div>'
502
503       
504       
505        /**
506        * Create the image rendition of the graph
507        */
508        var img = document.createElement('IMG');
509        RGraph.Registry.Set('chart.png', img);
510        img.__canvas__ = canvas;
511        img.__object__ = obj;
512        img.id = '__rgraph_image_img__';
513        img.className = 'RGraph_png';
514
515        img.src = canvas.toDataURL();
516
517        div.appendChild(img);
518       
519        setTimeout(function () {document.getElementById("__rgraph_dataurl__").select();}, 50);
520       
521        window.addEventListener('resize', function (e){var img = RGraph.Registry.Get('chart.png');img.style.left = (document.body.clientWidth / 2) - (img.width / 2) + 'px';}, false);
522       
523        bg.onclick = function (e)
524        {
525            var div = document.getElementById("__rgraph_image_div__");
526            var bg = document.getElementById("__rgraph_image_bg__");
527
528            if (div) {
529                div.style.opacity = 0;
530
531                div.parentNode.removeChild(div);
532
533                div.id = '';
534                div.style.display = 'none';
535                div = null;
536            }
537
538            if (bg) {
539                bg.style.opacity = 0;
540
541                bg.id = '';
542                bg.style.display = 'none';
543                bg = null;
544            }
545        }
546       
547        window.addEventListener('resize', function (e) {bg.onclick(e);}, false)
548       
549        /**
550        * This sets the image as a global variable, circumventing repeated calls to document.getElementById()
551        */
552        __rgraph_image_bg__  = bg;
553        __rgraph_image_div__ = div;
554
555
556        setTimeout('__rgraph_image_div__.style.opacity = 0.2', 50);
557        setTimeout('__rgraph_image_div__.style.opacity = 0.4', 100);
558        setTimeout('__rgraph_image_div__.style.opacity = 0.6', 150);
559        setTimeout('__rgraph_image_div__.style.opacity = 0.8', 200);
560        setTimeout('__rgraph_image_div__.style.opacity = 1', 250);
561
562        setTimeout('__rgraph_image_bg__.style.opacity = 0.1', 50);
563        setTimeout('__rgraph_image_bg__.style.opacity = 0.2', 100);
564        setTimeout('__rgraph_image_bg__.style.opacity = 0.3', 150);
565        setTimeout('__rgraph_image_bg__.style.opacity = 0.4', 200);
566        setTimeout('__rgraph_image_bg__.style.opacity = 0.5', 250);
567
568
569       
570        img.onclick = function (e)
571        {
572            if (e.stopPropagation) e.stopPropagation();
573            else event.cancelBubble = true;
574        }
575       
576        if (event && event.stopPropagation) {
577            event.stopPropagation();
578        }
579    }
Note: See TracBrowser for help on using the repository browser.