Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / docs / source / lightbox.html
diff --git a/docs/source/lightbox.html b/docs/source/lightbox.html
new file mode 100644 (file)
index 0000000..c1770e4
--- /dev/null
@@ -0,0 +1,376 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
+  <title>The source code</title>
+    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+</head>
+<body  onload="prettyPrint();">
+    <pre class="prettyprint lang-js">/*!
+ * Ext JS Library 3.2.0
+ * Copyright(c) 2006-2010 Ext JS, Inc.
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+Ext.ns('Ext.ux');
+
+Ext.ux.Lightbox = (function(){
+    var els = {},
+        images = [],
+        activeImage,
+        initialized = false,
+        selectors = [];
+
+    return {
+        overlayOpacity: 0.85,
+        animate: true,
+        resizeSpeed: 8,
+        borderSize: 10,
+        labelImage: "Image",
+        labelOf: "of",
+
+        init: function() {
+            this.resizeDuration = this.animate ? ((11 - this.resizeSpeed) * 0.15) : 0;
+            this.overlayDuration = this.animate ? 0.2 : 0;
+
+            if(!initialized) {
+                Ext.apply(this, Ext.util.Observable.prototype);
+                Ext.util.Observable.constructor.call(this);
+                this.addEvents('open', 'close');
+                this.initMarkup();
+                this.initEvents();
+                initialized = true;
+            }
+        },
+
+        initMarkup: function() {
+            els.shim = Ext.DomHelper.append(document.body, {
+                tag: 'iframe',
+                id: 'ux-lightbox-shim'
+            }, true);
+            els.overlay = Ext.DomHelper.append(document.body, {
+                id: 'ux-lightbox-overlay'
+            }, true);
+            
+            var lightboxTpl = new Ext.Template(this.getTemplate());
+            els.lightbox = lightboxTpl.append(document.body, {}, true);
+
+            var ids =
+                ['outerImageContainer', 'imageContainer', 'image', 'hoverNav', 'navPrev', 'navNext', 'loading', 'loadingLink',
+                'outerDataContainer', 'dataContainer', 'data', 'details', 'caption', 'imageNumber', 'bottomNav', 'navClose'];
+
+            Ext.each(ids, function(id){
+                els[id] = Ext.get('ux-lightbox-' + id);
+            });
+
+            Ext.each([els.overlay, els.lightbox, els.shim], function(el){
+                el.setVisibilityMode(Ext.Element.DISPLAY)
+                el.hide();
+            });
+
+            var size = (this.animate ? 250 : 1) + 'px';
+            els.outerImageContainer.setStyle({
+                width: size,
+                height: size
+            });
+        },
+
+        getTemplate : function() {
+            return [
+                '<div id="ux-lightbox">',
+                    '<div id="ux-lightbox-outerImageContainer">',
+                        '<div id="ux-lightbox-imageContainer">',
+                            '<img id="ux-lightbox-image">',
+                            '<div id="ux-lightbox-hoverNav">',
+                                '<a href="#" id="ux-lightbox-navPrev"></a>',
+                                '<a href="#" id="ux-lightbox-navNext"></a>',
+                            '</div>',
+                            '<div id="ux-lightbox-loading">',
+                                '<a id="ux-lightbox-loadingLink"></a>',
+                            '</div>',
+                        '</div>',
+                    '</div>',
+                    '<div id="ux-lightbox-outerDataContainer">',
+                        '<div id="ux-lightbox-dataContainer">',
+                            '<div id="ux-lightbox-data">',
+                                '<div id="ux-lightbox-details">',
+                                    '<span id="ux-lightbox-caption"></span>',
+                                    '<span id="ux-lightbox-imageNumber"></span>',
+                                '</div>',
+                                '<div id="ux-lightbox-bottomNav">',
+                                    '<a href="#" id="ux-lightbox-navClose"></a>',
+                                '</div>',
+                            '</div>',
+                        '</div>',
+                    '</div>',
+                '</div>'
+            ];
+        },
+
+        initEvents: function() {
+            var close = function(ev) {
+                ev.preventDefault();
+                this.close();
+            };
+
+            els.overlay.on('click', close, this);
+            els.loadingLink.on('click', close, this);
+            els.navClose.on('click', close, this);
+
+            els.lightbox.on('click', function(ev) {
+                if(ev.getTarget().id == 'ux-lightbox') {
+                    this.close();
+                }
+            }, this);
+
+            els.navPrev.on('click', function(ev) {
+                ev.preventDefault();
+                this.setImage(activeImage - 1);
+            }, this);
+
+            els.navNext.on('click', function(ev) {
+                ev.preventDefault();
+                this.setImage(activeImage + 1);
+            }, this);
+        },
+
+        register: function(sel, group) {
+            if(selectors.indexOf(sel) === -1) {
+                selectors.push(sel);
+
+                Ext.fly(document).on('click', function(ev){
+                    var target = ev.getTarget(sel);
+
+                    if (target) {
+                        ev.preventDefault();
+                        this.open(target, sel, group);
+                    }
+                }, this);
+            }
+        },
+
+        open: function(image, sel, group) {
+            group = group || false;
+            this.setViewSize();
+            els.overlay.fadeIn({
+                duration: this.overlayDuration,
+                endOpacity: this.overlayOpacity,
+                callback: function() {
+                    images = [];
+
+                    var index = 0;
+                    if(!group) {
+                        images.push([image.href, image.title]);
+                    }
+                    else {
+                        var setItems = Ext.query(sel);
+                        Ext.each(setItems, function(item) {
+                            if(item.href) {
+                                images.push([item.href, item.title]);
+                            }
+                        });
+
+                        while (images[index][0] != image.href) {
+                            index++;
+                        }
+                    }
+
+                    // calculate top and left offset for the lightbox
+                    var pageScroll = Ext.fly(document).getScroll();
+
+                    var lightboxTop = pageScroll.top + (Ext.lib.Dom.getViewportHeight() / 10);
+                    var lightboxLeft = pageScroll.left;
+                    els.lightbox.setStyle({
+                        top: lightboxTop + 'px',
+                        left: lightboxLeft + 'px'
+                    }).show();
+
+                    this.setImage(index);
+                    
+                    this.fireEvent('open', images[index]);                                        
+                },
+                scope: this
+            });
+        },
+        
+        setViewSize: function(){
+            var viewSize = this.getViewSize();
+            els.overlay.setStyle({
+                width: viewSize[0] + 'px',
+                height: viewSize[1] + 'px'
+            });
+            els.shim.setStyle({
+                width: viewSize[0] + 'px',
+                height: viewSize[1] + 'px'
+            }).show();
+        },
+
+        setImage: function(index){
+            activeImage = index;
+                      
+            this.disableKeyNav();            
+            if (this.animate) {
+                els.loading.show();
+            }
+
+            els.image.hide();
+            els.hoverNav.hide();
+            els.navPrev.hide();
+            els.navNext.hide();
+            els.dataContainer.setOpacity(0.0001);
+            els.imageNumber.hide();
+
+            var preload = new Image();
+            preload.onload = (function(){
+                els.image.dom.src = images[activeImage][0];
+                this.resizeImage(preload.width, preload.height);
+            }).createDelegate(this);
+            preload.src = images[activeImage][0];
+        },
+
+        resizeImage: function(w, h){
+            var wCur = els.outerImageContainer.getWidth();
+            var hCur = els.outerImageContainer.getHeight();
+
+            var wNew = (w + this.borderSize * 2);
+            var hNew = (h + this.borderSize * 2);
+
+            var wDiff = wCur - wNew;
+            var hDiff = hCur - hNew;
+
+            var afterResize = function(){
+                els.hoverNav.setWidth(els.imageContainer.getWidth() + 'px');
+
+                els.navPrev.setHeight(h + 'px');
+                els.navNext.setHeight(h + 'px');
+
+                els.outerDataContainer.setWidth(wNew + 'px');
+
+                this.showImage();
+            };
+            
+            if (hDiff != 0 || wDiff != 0) {
+                els.outerImageContainer.shift({
+                    height: hNew,
+                    width: wNew,
+                    duration: this.resizeDuration,
+                    scope: this,
+                    callback: afterResize,
+                    delay: 50
+                });
+            }
+            else {
+                afterResize.call(this);
+            }
+        },
+
+        showImage: function(){
+            els.loading.hide();
+            els.image.fadeIn({
+                duration: this.resizeDuration,
+                scope: this,
+                callback: function(){
+                    this.updateDetails();
+                }
+            });
+            this.preloadImages();
+        },
+
+        updateDetails: function(){
+            var detailsWidth = els.data.getWidth(true) - els.navClose.getWidth() - 10;
+            els.details.setWidth((detailsWidth > 0 ? detailsWidth : 0) + 'px');
+            
+            els.caption.update(images[activeImage][1]);
+
+            els.caption.show();
+            if (images.length > 1) {
+                els.imageNumber.update(this.labelImage + ' ' + (activeImage + 1) + ' ' + this.labelOf + '  ' + images.length);
+                els.imageNumber.show();
+            }
+
+            els.dataContainer.fadeIn({
+                duration: this.resizeDuration/2,
+                scope: this,
+                callback: function() {
+                    var viewSize = this.getViewSize();
+                    els.overlay.setHeight(viewSize[1] + 'px');
+                    this.updateNav();
+                }
+            });
+        },
+
+        updateNav: function(){
+            this.enableKeyNav();
+
+            els.hoverNav.show();
+
+            // if not first image in set, display prev image button
+            if (activeImage > 0)
+                els.navPrev.show();
+
+            // if not last image in set, display next image button
+            if (activeImage < (images.length - 1))
+                els.navNext.show();
+        },
+
+        enableKeyNav: function() {
+            Ext.fly(document).on('keydown', this.keyNavAction, this);
+        },
+
+        disableKeyNav: function() {
+            Ext.fly(document).un('keydown', this.keyNavAction, this);
+        },
+
+        keyNavAction: function(ev) {
+            var keyCode = ev.getKey();
+
+            if (
+                keyCode == 88 || // x
+                keyCode == 67 || // c
+                keyCode == 27
+            ) {
+                this.close();
+            }
+            else if (keyCode == 80 || keyCode == 37){ // display previous image
+                if (activeImage != 0){
+                    this.setImage(activeImage - 1);
+                }
+            }
+            else if (keyCode == 78 || keyCode == 39){ // display next image
+                if (activeImage != (images.length - 1)){
+                    this.setImage(activeImage + 1);
+                }
+            }
+        },
+
+        preloadImages: function(){
+            var next, prev;
+            if (images.length > activeImage + 1) {
+                next = new Image();
+                next.src = images[activeImage + 1][0];
+            }
+            if (activeImage > 0) {
+                prev = new Image();
+                prev.src = images[activeImage - 1][0];
+            }
+        },
+
+        close: function(){
+            this.disableKeyNav();
+            els.lightbox.hide();
+            els.overlay.fadeOut({
+                duration: this.overlayDuration
+            });
+            els.shim.hide();
+            this.fireEvent('close', activeImage);
+        },
+
+        getViewSize: function() {
+            return [Ext.lib.Dom.getViewWidth(), Ext.lib.Dom.getViewHeight()];
+        }
+    }
+})();
+
+Ext.onReady(Ext.ux.Lightbox.init, Ext.ux.Lightbox);</pre>    
+</body>
+</html>
\ No newline at end of file