[TemporaryStorage] add files required for SDK build
[samples/web/TemporaryStorage.git] / tizen-web-ui-fw / latest / js / src / widgets / jquery.mobile.tizen.gallery.js
1
2 /* ***************************************************************************
3  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  * ***************************************************************************
23  *
24  *      Author: Minkyu Kang <mk7.kang@samsung.com>
25  */
26
27 /*
28  * Gallery widget
29  *
30  * HTML Attributes
31  *
32  *  data-role: set to 'gallery'
33  *  data-index: start index
34  *  data-vertical-align: set to top or middle or bottom.
35  *
36  * APIs
37  *
38  *  add(file): add the image (parameter: url of iamge)
39  *  remove(index): remove the image (parameter: index of image)
40  *  refresh(index): refresh the widget, should be called after add or remove. (parameter: start index)
41  *  empty: remove all of images from the gallery
42  *  length: get length of images
43  *  value(index): get or set current index of gallery (parameter: index of image)
44  *
45  * Events
46  *
47  *  N/A
48  *
49  * Example
50  *
51  * <div data-role="gallery" id="gallery" data-index="3" data-vertical-align="middle">
52  *      <img src="01.jpg">
53  *      <img src="02.jpg">
54  *      <img src="03.jpg">
55  *      <img src="04.jpg">
56  *      <img src="05.jpg">
57  * </div>
58  *
59  *
60  * $('#gallery-add').bind('vmouseup', function ( e ) {
61  *      $('#gallery').gallery('add', '9.jpg');
62  *      $('#gallery').gallery('add', '10.jpg');
63  *      $('#gallery').gallery('refresh');
64  * });
65  *
66  * $('#gallery-del').bind('vmouseup', function ( e ) {
67  *      $('#gallery').gallery('remove');
68  * });
69  *
70  */
71
72  /**
73         @class Gallery
74         The gallery widget shows images in a gallery on the screen. <br/><br/> To add an gallery widget to the application, use the following code:
75
76                 <div data-role="gallery" id="gallery" data-vertical-align="middle" data-index="3">
77                         <img src="01.jpg">
78                         <img src="02.jpg">
79                         <img src="03.jpg">
80                         <img src="04.jpg">
81                         <img src="05.jpg">
82                 </div>
83 */
84 /**
85         @property {Integer} data-index
86         Defines the index number of the first image in the gallery.
87         <br/>The default value is 0.
88 */
89 /**
90         @property {String} data-vertical-align
91         Defines the image alignment. The alignment options are top, middle, and bottom.
92         <br/>The default value is top.
93 */
94 /**
95         @method add
96         The add method is used to add an image to the gallery. The image_file attribute defines the image file URL.
97
98                 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
99                 $("#gallery").gallery('add', [image_file]);
100 */
101 /**
102         @method remove
103         The remove method is used to delete an image from the gallery. The image_index attribute defines the index of the image to be deleted. If not set removes current image.
104
105                 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
106                 $("#gallery").gallery('remove', [image_index]);
107 */
108 /**
109         @method refresh
110         The refresh method is used to refresh the gallery. This method must be called after adding images to the gallery.
111
112                 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
113                 $("#gallery").gallery('refresh');
114 */
115 /**
116         @method empty
117         The empty method is used to remove all of images from the gallery.
118
119                 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
120                 $("#gallery").gallery('empty');
121 */
122 /**
123         @method length
124         The length method is used to get length of images.
125
126                 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
127                 length = $("#gallery").gallery('length');
128 */
129 /**
130         @method value
131         The value method is used to get or set current index of gallery. The image_index attribute defines the index of the image to be set. If not get current index.
132
133                 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
134                 value = $("#gallery").gallery('value');
135                 $("#gallery").gallery('value', [image_index]);
136 */
137 (function ( $, window, undefined ) {
138         $.widget( "tizen.gallery", $.mobile.widget, {
139                 options: {
140                         flicking: false,
141                         duration: 500
142                 },
143
144                 dragging: false,
145                 moving: false,
146                 max_width: 0,
147                 max_height: 0,
148                 org_x: 0,
149                 org_time: null,
150                 cur_img: null,
151                 prev_img: null,
152                 next_img: null,
153                 images: [],
154                 images_hold: [],
155                 index: 0,
156                 align_type: null,
157                 direction: 1,
158                 container: null,
159                 orientationEventFire: false,
160
161                 _resize: function ( index ) {
162                         var img = this.images[index],
163                                 width = this.images[index].width(),
164                                 height = this.images[index].height(),
165                                 margin = 0,
166                                 ratio,
167                                 img_max_width = this.max_width - margin,
168                                 img_max_height = this.max_height - margin;
169
170                         ratio = height / width;
171
172                         if ( width > img_max_width ) {
173                                 img.width( img_max_width );
174                                 img.height( img_max_width * ratio );
175                         }
176
177                         height = img.height();
178
179                         if ( height > img_max_height ) {
180                                 img.height( img_max_height );
181                                 img.width( img_max_height / ratio );
182                         }
183                 },
184
185                 _align: function ( index, obj ) {
186                         var img = this.images[index],
187                                 img_top = 0;
188
189                         if ( !obj ) {
190                                 return;
191                         }
192                         if ( !obj.length ) {
193                                 return;
194                         }
195
196                         if ( this.align_type == "middle" ) {
197                                 img_top = ( this.max_height - img.height() ) / 2;
198                         } else if ( this.align_type == "bottom" ) {
199                                 img_top = this.max_height - img.height();
200                         } else {
201                                 img_top = 0;
202                         }
203
204                         obj.css( 'top', img_top + 'px' );
205                 },
206
207                 _attach: function ( index, obj ) {
208                         var self = this,
209                                 processing = function () {
210                                         self._resize( index );
211                                         self._align( index, obj );
212
213                                 },
214                                 loading = function () {
215                                         if ( self.images[index] === undefined ) {
216                                                 return;
217                                         }
218
219                                         if ( !self.images[index].height() ) {
220                                                 setTimeout( loading, 10 );
221                                                 return;
222                                         }
223
224                                         processing();
225                                 };
226
227                         if ( !obj ) {
228                                 return;
229                         }
230                         if ( !obj.length ) {
231                                 return;
232                         }
233                         if ( index < 0 ) {
234                                 return;
235                         }
236                         if ( !this.images.length ) {
237                                 return;
238                         }
239                         if ( index >= this.images.length ) {
240                                 return;
241                         }
242
243                         obj.css( "display", "block" );
244                         obj.css( "visibility", "hidden" );
245                         obj.append( this.images[index] );
246                         loading();
247                 },
248
249                 _detach: function ( index, obj ) {
250                         if ( !obj ) {
251                                 return;
252                         }
253                         if ( !obj.length ) {
254                                 return;
255                         }
256                         if ( index < 0 ) {
257                                 return;
258                         }
259                         if ( index >= this.images.length ) {
260                                 return;
261                         }
262
263                         obj.css( "display", "none" );
264                         this.images[index].removeAttr("style");
265                         this.images[index].detach();
266                 },
267
268                 _detach_all: function () {
269                         var i;
270
271                         for ( i = 0; i < this.images.length; i++ ) {
272                                 this.images[i].detach();
273                         }
274                 },
275
276                 _drag: function ( _x ) {
277                         var delta,
278                                 coord_x;
279
280                         if ( !this.dragging ) {
281                                 return;
282                         }
283
284                         if ( this.options.flicking === false ) {
285                                 delta = this.org_x - _x;
286
287                                 // first image
288                                 if ( delta < 0 && !this.prev_img.length ) {
289                                         return;
290                                 }
291                                 // last image
292                                 if ( delta > 0 && !this.next_img.length ) {
293                                         return;
294                                 }
295                         }
296
297                         coord_x = _x - this.org_x;
298
299                         this._moveLeft( this.cur_img , coord_x + 'px' );
300                         if ( this.next_img.length ) {
301                                 this._moveLeft( this.next_img ,  coord_x + this.window_width + 'px' );
302                         }
303                         if ( this.prev_img.length ) {
304                                 this._moveLeft( this.prev_img ,  coord_x - this.window_width + 'px' );
305                         }
306                 },
307
308                 _move: function ( _x ) {
309                         var delta = this.org_x - _x,
310                                 flip = 0,
311                                 drag_time,
312                                 sec,
313                                 self;
314
315                         if ( delta == 0 ) {
316                                 return;
317                         }
318
319                         if ( delta > 0 ) {
320                                 flip = delta < ( this.max_width * 0.45 ) ? 0 : 1;
321                         } else {
322                                 flip = -delta < ( this.max_width * 0.45 ) ? 0 : 1;
323                         }
324
325                         if ( !flip ) {
326                                 drag_time = Date.now() - this.org_time;
327
328                                 if ( Math.abs( delta ) / drag_time > 1 ) {
329                                         flip = 1;
330                                 }
331                         }
332
333                         if ( flip ) {
334                                 if ( delta > 0 && this.next_img.length ) {
335                                         /* next */
336                                         this._detach( this.index - 1, this.prev_img );
337
338                                         this.prev_img = this.cur_img;
339                                         this.cur_img = this.next_img;
340                                         this.next_img = this.next_img.next();
341
342                                         this.index++;
343
344                                         if ( this.next_img.length ) {
345                                                 this._moveLeft( this.next_img ,  this.window_width + 'px' );
346                                                 this._attach( this.index + 1, this.next_img );
347                                         }
348
349                                         this.direction = 1;
350
351                                 } else if ( delta < 0 && this.prev_img.length ) {
352                                         /* prev */
353                                         this._detach( this.index + 1, this.next_img );
354
355                                         this.next_img = this.cur_img;
356                                         this.cur_img = this.prev_img;
357                                         this.prev_img = this.prev_img.prev();
358
359                                         this.index--;
360
361                                         if ( this.prev_img.length ) {
362                                                 this._moveLeft( this.prev_img , -this.window_width + 'px' );
363                                                 this._attach( this.index - 1, this.prev_img );
364                                         }
365
366                                         this.direction = -1;
367                                 }
368                         }
369
370                         sec = this.options.duration;
371                         self = this;
372
373                         this.moving = true;
374
375                         setTimeout( function () {
376                                 self.moving = false;
377                         }, sec - 25 );
378
379                         this._moveLeft( this.cur_img, 0 + 'px', sec );
380                         if ( this.next_img.length ) {
381                                 this._moveLeft( this.next_img, this.window_width + 'px', sec );
382                         }
383                         if ( this.prev_img.length ) {
384                                 this._moveLeft( this.prev_img, -this.window_width + 'px', sec );
385                         }
386                 },
387
388                 _add_event: function () {
389                         var self = this,
390                                 date;
391
392                         this.container.bind( 'vmousemove', function ( e ) {
393                                 e.preventDefault();
394
395                                 if ( self.moving ) {
396                                         return;
397                                 }
398                                 if ( !self.dragging ) {
399                                         return;
400                                 }
401
402                                 self._drag( e.pageX );
403                         } );
404
405                         this.container.bind( 'vmousedown', function ( e ) {
406                                 e.preventDefault();
407
408                                 if ( self.moving ) {
409                                         return;
410                                 }
411
412                                 self.dragging = true;
413
414                                 self.org_x = e.pageX;
415
416                                 self.org_time = Date.now();
417                         } );
418
419                         this.container.bind( 'vmouseup', function ( e ) {
420                                 if ( self.moving ) {
421                                         return;
422                                 }
423
424                                 self.dragging = false;
425
426                                 self._move( e.pageX );
427                         } );
428
429                         this.container.bind( 'vmouseout', function ( e ) {
430                                 if ( self.moving ) {
431                                         return;
432                                 }
433                                 if ( !self.dragging ) {
434                                         return;
435                                 }
436
437                                 if ( ( e.pageX < 20 ) ||
438                                                 ( e.pageX > ( self.max_width - 20 ) ) ) {
439                                         self._move( e.pageX );
440                                         self.dragging = false;
441                                 }
442                         } );
443                 },
444
445                 _del_event: function () {
446                         this.container.unbind( 'vmousemove' );
447                         this.container.unbind( 'vmousedown' );
448                         this.container.unbind( 'vmouseup' );
449                         this.container.unbind( 'vmouseout' );
450                 },
451                 _setTranslateposition : function ( $ele, value ) {
452                         var translate,
453                                 cssArray = null,
454                                 self = this;
455
456                         if ( $.support.cssTransform3d ) {
457                                 translate = "translate3d(" + value + ", 0px, 0px)";
458                         } else {
459                                 translate = "translate(" + value + ", 0px)";
460                         }
461                         cssArray = {"-moz-transform": translate,
462                                         "-webkit-transform": translate,
463                                         "-ms-transform": translate,
464                                         "-o-transform": translate,
465                                         "transform": translate};
466
467                         $ele.css(cssArray);
468                         return $ele;
469                 },
470                 _hidePrevNext : function() {
471                         var self = this;
472
473                         if( self.next_img ) {
474                                 self.next_img.css( "visibility", "hidden" );
475                         }
476                         if( self.prev_img ) {
477                                 self.prev_img.css( "visibility", "hidden" );
478                         }
479
480                 },
481                 _hideCur : function() {
482                         var self = this;
483                         if( self.cur_img ) {
484                                 self.cur_img.css( "visibility", "hidden" );
485                         }
486                 },
487                 _moveLeft : function ( $ele , value , duration ) {
488                         var translate,
489                                 transition = "",
490                                 cssArray = null,
491                                 self = this;
492
493                         if ( $.support.cssTransform3d ) {
494                                 translate = "translate3d(" + value + ", 0px, 0px)";
495                         } else {
496                                 translate = "translate(" + value + ", 0px)";
497                         }
498                         if( duration !== undefined ) {
499                                 transition =  "-webkit-transform " + (duration / 1000)+ "s ease";
500                         }
501                         cssArray = {"-moz-transform": translate,
502                                         "-webkit-transform": translate,
503                                         "-ms-transform": translate,
504                                         "-o-transform": translate,
505                                         "transform": translate};
506                         if( transition !== "" ) {
507                                 cssArray["-webkit-transition"] = transition ;
508                                 if( value == "0px" ) {
509                                         $ele.one( 'webkitTransitionEnd', self._hidePrevNext );
510                                 } else {
511                                         $ele.one( 'webkitTransitionEnd', self._hideCur );
512                                 }
513                         }
514                         if( value == "0px" ) {
515                                 $ele.css( "visibility", "visible" );
516                         }
517
518                         $ele.css(cssArray);
519                         return $ele;
520                 },
521                 _show: function () {
522                         /* resizing */
523                         this.window_width = $( window ).width();
524                         this.max_width = this._get_width();
525                         this.max_height = this._get_height();
526                         this.container.css( 'height', this.max_height );
527
528                         this.cur_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + this.index + ')' );
529                         this.prev_img = this.cur_img.prev();
530                         this.next_img = this.cur_img.next();
531
532                         this._attach( this.index - 1, this.prev_img );
533                         this._attach( this.index, this.cur_img );
534                         this._attach( this.index + 1, this.next_img );
535
536                         this.cur_img.css( 'visibility', 'visible' );
537                         if ( this.prev_img.length ) {
538                                 this._setTranslateposition( this.prev_img, -this.window_width + 'px');
539                         }
540
541                         this._moveLeft( this.cur_img, '0px');
542                         if ( this.next_img.length ) {
543                                 this._setTranslateposition( this.next_img, this.window_width + 'px' );
544                         }
545                 },
546
547                 show: function () {
548                         if ( !this.images.length ) {
549                                 return;
550                         }
551
552                         this._show();
553                         this._add_event();
554                 },
555
556                 _hide: function () {
557                         this._detach( this.index - 1, this.prev_img );
558                         this._detach( this.index, this.cur_img );
559                         this._detach( this.index + 1, this.next_img );
560                 },
561
562                 hide: function () {
563                         this._hide();
564                         this._del_event();
565                 },
566
567                 _get_width: function () {
568                         return $( this.element ).width();
569                 },
570
571                 _get_height: function () {
572                         var $page = $( this.element ).parentsUntil( 'ui-page' ),
573                                 $content = $page.children( '.ui-content' ),
574                                 header_h = $page.children( '.ui-header' ).outerHeight() || 0,
575                                 footer_h = $page.children( '.ui-footer' ).outerHeight() || 0,
576                                 padding = parseFloat( $content.css( 'padding-top' ) )
577                                         + parseFloat( $content.css( 'padding-bottom' ) ),
578                                 content_h = $( window ).height() - header_h - footer_h - padding;
579
580                         return content_h;
581                 },
582
583                 _create: function () {
584                         var temp_img,
585                                 self = this,
586                                 index,
587                                 i = 0;
588
589                         $( this.element ).wrapInner( '<div class="ui-gallery"></div>' );
590                         $( this.element ).find( 'img' ).wrap( '<div class="ui-gallery-bg"></div>' );
591
592                         this.container = $( this.element ).find('.ui-gallery');
593
594                         temp_img = $( 'div' ).find( '.ui-gallery-bg:first' );
595
596                         while ( temp_img.length ) {
597                                 this.images[i] = temp_img.find( 'img' );
598                                 temp_img = temp_img.next();
599                                 i++;
600                         }
601
602                         this._detach_all();
603
604                         index = parseInt( $( this.element ).jqmData( 'index' ), 10 );
605                         if ( !index ) {
606                                 index = 0;
607                         }
608                         if ( index < 0 ) {
609                                 index = 0;
610                         }
611                         if ( index >= this.images.length ) {
612                                 index = this.images.length - 1;
613                         }
614
615                         this.index = index;
616
617                         this.align_type = $( this.element ).jqmData( 'vertical-align' );
618
619                         $.extend( this, {
620                                 _globalHandlers: [
621                                         {
622                                                 src: $( window ),
623                                                 handler: {
624                                                         orientationchange: $.proxy( this, "_orientationHandler" ),
625                                                         resize: $.proxy( this, "_resizeHandler" )
626                                                 }
627                                         }
628                                 ]
629                         });
630
631                         $.each( this._globalHandlers, function( idx, value ) {
632                                 value.src.bind( value.handler );
633                         });
634                 },
635
636                 _update: function () {
637                         var image_file,
638                                 bg_html,
639                                 temp_img;
640
641                         while ( this.images_hold.length ) {
642                                 image_file = this.images_hold.shift();
643
644                                 bg_html = $( '<div class="ui-gallery-bg"></div>' );
645                                 temp_img = $( '<img src="' + image_file + '"></div>' );
646
647                                 bg_html.append( temp_img );
648                                 this.container.append( bg_html );
649                                 this.images.push( temp_img );
650                         }
651
652                         this._detach_all();
653                 },
654                 _resizeHandler: function() {
655                         var self = this;
656                         if( self.orientationEventFire ) {
657                                 self.refresh();
658                                 self.orientationEventFire = false;
659                         }
660                 },
661                 _orientationHandler: function() {
662                         var self = this;
663                         self.refresh();
664                         self.orientationEventFire = true;
665                 },
666                 refresh: function ( start_index ) {
667                         this._update();
668
669                         this._hide();
670
671                         if ( start_index === undefined ) {
672                                 start_index = this.index;
673                         }
674                         if ( start_index < 0 ) {
675                                 start_index = 0;
676                         }
677                         if ( start_index >= this.images.length ) {
678                                 start_index = this.images.length - 1;
679                         }
680
681                         this.index = start_index;
682
683                         this._show();
684
685                         return this.index;
686                 },
687
688                 add: function ( file ) {
689                         this.images_hold.push( file );
690                 },
691
692                 remove: function ( index ) {
693                         var temp_img;
694
695                         if ( index === undefined ) {
696                                 index = this.index;
697                         }
698
699                         if ( index < 0 || index >= this.images.length ) {
700                                 return;
701                         }
702
703                         if ( index == this.index ) {
704                                 temp_img = this.cur_img;
705
706                                 if ( this.index == 0 ) {
707                                         this.direction = 1;
708                                 } else if ( this.index == this.images.length - 1 ) {
709                                         this.direction = -1;
710                                 }
711
712                                 if ( this.direction < 0 ) {
713                                         this.cur_img = this.prev_img;
714                                         this.prev_img = this.prev_img.prev();
715                                         if ( this.prev_img.length ) {
716                                                 this._moveLeft( this.prev_img, -this.window_width + 'px' );
717                                                 this._attach( index - 2, this.prev_img );
718                                         }
719                                         this.index--;
720                                 } else {
721                                         this.cur_img = this.next_img;
722                                         this.next_img = this.next_img.next();
723                                         if ( this.next_img.length ) {
724                                                 this._moveLeft( this.next_img, this.window_width + 'px' );
725                                                 this._attach( index + 2, this.next_img );
726                                         }
727                                 }
728                                 this._moveLeft( this.cur_img, '0px', this.options.duration );
729
730                         } else if ( index == this.index - 1 ) {
731                                 temp_img = this.prev_img;
732                                 this.prev_img = this.prev_img.prev();
733                                 if ( this.prev_img.length ) {
734                                         this._moveLeft( this.prev_img, -this.window_width + 'px' );
735                                         this._attach( index - 1, this.prev_img );
736                                 }
737                                 this.index--;
738
739                         } else if ( index == this.index + 1 ) {
740                                 temp_img = this.next_img;
741                                 this.next_img = this.next_img.next();
742                                 if ( this.next_img.length ) {
743                                         this._moveLeft( this.next_img, this.window_width + 'px' );
744                                         this._attach( index + 1, this.next_img );
745                                 }
746
747                         } else {
748                                 temp_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + index + ')' );
749                         }
750
751                         this.images.splice( index, 1 );
752                         temp_img.detach();
753                 },
754
755                 empty: function () {
756                         this.images.splice( 0, this.images.length );
757                         this.container.find('.ui-gallery-bg').detach();
758                 },
759
760                 length: function () {
761                         return this.images.length;
762                 },
763
764                 value: function ( index ) {
765                         if ( index === undefined ) {
766                                 return this.index;
767                         }
768
769                         this.refresh( index );
770                 },
771
772                 destory: function() {
773                         $( window ).unbind( 'resize', this._resizeHandler );
774                         $( window ).unbind( 'orientationchange' , this._orientationHandler );
775                 }
776
777         }); /* End of widget */
778
779         // auto self-init widgets
780         $( document ).bind( "pagecreate create", function ( e ) {
781                 $( e.target ).find( ":jqmData(role='gallery')" ).gallery();
782         });
783
784         $( document ).bind( "pageshow", function ( e ) {
785                 $( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'show' );
786         });
787
788         $( document ).bind( "pagebeforehide", function ( e ) {
789                 $( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'hide' );
790         } );
791
792 }( jQuery, this ) );
793