1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Shows images one by one, and moves them by flicking
4 //>>group: Tizen:Widgets
6 define( [ ], function ( ) {
7 //>>excludeEnd("jqmBuildExclude");
9 /* ***************************************************************************
10 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 * ***************************************************************************
31 * Author: Minkyu Kang <mk7.kang@samsung.com>
39 * data-role: set to 'gallery'
40 * data-index: start index
41 * data-vertical-align: set to top or middle or bottom.
45 * add(file): add the image (parameter: url of iamge)
46 * remove(index): remove the image (parameter: index of image)
47 * refresh(index): refresh the widget, should be called after add or remove. (parameter: start index)
48 * empty: remove all of images from the gallery
49 * length: get length of images
50 * value(index): get or set current index of gallery (parameter: index of image)
58 * <div data-role="gallery" id="gallery" data-index="3" data-vertical-align="middle">
67 * $('#gallery-add').bind('vmouseup', function ( e ) {
68 * $('#gallery').gallery('add', '9.jpg');
69 * $('#gallery').gallery('add', '10.jpg');
70 * $('#gallery').gallery('refresh');
73 * $('#gallery-del').bind('vmouseup', function ( e ) {
74 * $('#gallery').gallery('remove');
81 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:
83 <div data-role="gallery" id="gallery" data-vertical-align="middle" data-index="3">
92 @property {Integer} data-index
93 Defines the index number of the first image in the gallery.
94 <br/>The default value is 0.
97 @property {String} data-vertical-align
98 Defines the image alignment. The alignment options are top, middle, and bottom.
99 <br/>The default value is top.
103 The add method is used to add an image to the gallery. The image_file attribute defines the image file URL.
105 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
106 $("#gallery").gallery('add', [image_file]);
110 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.
112 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
113 $("#gallery").gallery('remove', [image_index]);
117 The refresh method is used to refresh the gallery. This method must be called after adding images to the gallery.
119 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
120 $("#gallery").gallery('refresh');
124 The empty method is used to remove all of images from the gallery.
126 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
127 $("#gallery").gallery('empty');
131 The length method is used to get length of images.
133 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
134 length = $("#gallery").gallery('length');
138 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.
140 <div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
141 value = $("#gallery").gallery('value');
142 $("#gallery").gallery('value', [image_index]);
144 (function ( $, window, undefined ) {
145 $.widget( "tizen.gallery", $.mobile.widget, {
166 orientationEventFire: false,
168 _resize: function ( index ) {
169 var img = this.images[index],
170 width = this.images[index].width(),
171 height = this.images[index].height(),
174 img_max_width = this.max_width - margin,
175 img_max_height = this.max_height - margin;
177 ratio = height / width;
179 if ( width > img_max_width ) {
180 img.width( img_max_width );
181 img.height( img_max_width * ratio );
184 height = img.height();
186 if ( height > img_max_height ) {
187 img.height( img_max_height );
188 img.width( img_max_height / ratio );
192 _align: function ( index, obj ) {
193 var img = this.images[index],
203 if ( this.align_type == "middle" ) {
204 img_top = ( this.max_height - img.height() ) / 2;
205 } else if ( this.align_type == "bottom" ) {
206 img_top = this.max_height - img.height();
211 obj.css( 'top', img_top + 'px' );
214 _attach: function ( index, obj ) {
216 processing = function () {
217 self._resize( index );
218 self._align( index, obj );
220 loading = function () {
221 if ( self.images[index] === undefined ) {
225 if ( !self.images[index].height() ) {
226 setTimeout( loading, 10 );
242 if ( !this.images.length ) {
245 if ( index >= this.images.length ) {
249 obj.css( "display", "block" );
250 obj.append( this.images[index] );
254 _detach: function ( index, obj ) {
264 if ( index >= this.images.length ) {
268 obj.css( "display", "none" );
269 this.images[index].removeAttr("style");
270 this.images[index].detach();
273 _detach_all: function () {
276 for ( i = 0; i < this.images.length; i++ ) {
277 this.images[i].detach();
281 _drag: function ( _x ) {
285 if ( !this.dragging ) {
289 if ( this.options.flicking === false ) {
290 delta = this.org_x - _x;
293 if ( delta < 0 && !this.prev_img.length ) {
297 if ( delta > 0 && !this.next_img.length ) {
302 coord_x = _x - this.org_x;
304 this._moveLeft( this.cur_img , coord_x + 'px');
305 if ( this.next_img.length ) {
306 this._moveLeft( this.next_img , coord_x + this.window_width + 'px' );
308 if ( this.prev_img.length ) {
309 this._moveLeft( this.prev_img , coord_x - this.window_width + 'px' );
313 _move: function ( _x ) {
314 var delta = this.org_x - _x,
325 flip = delta < ( this.max_width * 0.45 ) ? 0 : 1;
327 flip = -delta < ( this.max_width * 0.45 ) ? 0 : 1;
331 drag_time = Date.now() - this.org_time;
333 if ( Math.abs( delta ) / drag_time > 1 ) {
339 if ( delta > 0 && this.next_img.length ) {
341 this._detach( this.index - 1, this.prev_img );
343 this.prev_img = this.cur_img;
344 this.cur_img = this.next_img;
345 this.next_img = this.next_img.next();
349 if ( this.next_img.length ) {
350 this._moveLeft( this.next_img , this.window_width + 'px' );
351 this._attach( this.index + 1, this.next_img );
356 } else if ( delta < 0 && this.prev_img.length ) {
358 this._detach( this.index + 1, this.next_img );
360 this.next_img = this.cur_img;
361 this.cur_img = this.prev_img;
362 this.prev_img = this.prev_img.prev();
366 if ( this.prev_img.length ) {
367 this._moveLeft( this.prev_img , -this.window_width + 'px' );
368 this._attach( this.index - 1, this.prev_img );
375 sec = this.options.duration;
380 setTimeout( function () {
384 this._moveLeft( this.cur_img, 0 + 'px', sec );
385 if ( this.next_img.length ) {
386 this._moveLeft( this.next_img, this.window_width + 'px', sec );
388 if ( this.prev_img.length ) {
389 this._moveLeft( this.prev_img, -this.window_width + 'px', sec );
393 _add_event: function () {
397 this.container.bind( 'vmousemove', function ( e ) {
403 if ( !self.dragging ) {
407 self._drag( e.pageX );
410 this.container.bind( 'vmousedown', function ( e ) {
417 self.dragging = true;
419 self.org_x = e.pageX;
421 self.org_time = Date.now();
424 this.container.bind( 'vmouseup', function ( e ) {
429 self.dragging = false;
431 self._move( e.pageX );
434 this.container.bind( 'vmouseout', function ( e ) {
438 if ( !self.dragging ) {
442 if ( ( e.pageX < 20 ) ||
443 ( e.pageX > ( self.max_width - 20 ) ) ) {
444 self._move( e.pageX );
445 self.dragging = false;
450 _del_event: function () {
451 this.container.unbind( 'vmousemove' );
452 this.container.unbind( 'vmousedown' );
453 this.container.unbind( 'vmouseup' );
454 this.container.unbind( 'vmouseout' );
456 _setTranslateposition : function ( $ele, value ) {
460 if ( $.support.cssTransform3d ) {
461 translate = "translate3d(" + value + ", 0px, 0px)";
463 translate = "translate(" + value + ", 0px)";
465 cssArray = {"-moz-transform": translate,
466 "-webkit-transform": translate,
467 "-ms-transform": translate,
468 "-o-transform": translate,
469 "transform": translate};
474 _moveLeft : function ( $ele , value , duration) {
479 if ( $.support.cssTransform3d ) {
480 translate = "translate3d(" + value + ", 0px, 0px)";
482 translate = "translate(" + value + ", 0px)";
484 if( duration !== undefined ) {
485 transition = "-webkit-transform " + (duration / 1000)+ "s ease";
487 cssArray = {"-moz-transform": translate,
488 "-webkit-transform": translate,
489 "-ms-transform": translate,
490 "-o-transform": translate,
491 "transform": translate};
492 if( transition !== "" ) {
493 cssArray["-webkit-transition"] = transition ;
501 this.window_width = $( window ).width();
502 this.max_width = this._get_width();
503 this.max_height = this._get_height();
504 this.container.css( 'height', this.max_height );
506 this.cur_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + this.index + ')' );
507 this.prev_img = this.cur_img.prev();
508 this.next_img = this.cur_img.next();
510 this._attach( this.index - 1, this.prev_img );
511 this._attach( this.index, this.cur_img );
512 this._attach( this.index + 1, this.next_img );
514 if ( this.prev_img.length ) {
515 this._setTranslateposition( this.prev_img, -this.window_width + 'px');
518 this._moveLeft( this.cur_img, '0px');
519 if ( this.next_img.length ) {
520 this._setTranslateposition( this.next_img, this.window_width + 'px' );
525 if ( !this.images.length ) {
534 this._detach( this.index - 1, this.prev_img );
535 this._detach( this.index, this.cur_img );
536 this._detach( this.index + 1, this.next_img );
544 _get_width: function () {
545 return $( this.element ).width();
548 _get_height: function () {
549 var $page = $( this.element ).parentsUntil( 'ui-page' ),
550 $content = $page.children( '.ui-content' ),
551 header_h = $page.children( '.ui-header' ).outerHeight() || 0,
552 footer_h = $page.children( '.ui-footer' ).outerHeight() || 0,
553 padding = parseFloat( $content.css( 'padding-top' ) )
554 + parseFloat( $content.css( 'padding-bottom' ) ),
555 content_h = $( window ).height() - header_h - footer_h - padding;
560 _create: function () {
566 $( this.element ).wrapInner( '<div class="ui-gallery"></div>' );
567 $( this.element ).find( 'img' ).wrap( '<div class="ui-gallery-bg"></div>' );
569 this.container = $( this.element ).find('.ui-gallery');
571 temp_img = $( 'div' ).find( '.ui-gallery-bg:first' );
573 while ( temp_img.length ) {
574 this.images[i] = temp_img.find( 'img' );
575 temp_img = temp_img.next();
581 index = parseInt( $( this.element ).jqmData( 'index' ), 10 );
588 if ( index >= this.images.length ) {
589 index = this.images.length - 1;
594 this.align_type = $( this.element ).jqmData( 'vertical-align' );
601 orientationchange: $.proxy( this, "_orientationHandler" ),
602 resize: $.proxy( this, "_resizeHandler" )
608 $.each( this._globalHandlers, function( idx, value ) {
609 value.src.bind( value.handler );
613 _update: function () {
618 while ( this.images_hold.length ) {
619 image_file = this.images_hold.shift();
621 bg_html = $( '<div class="ui-gallery-bg"></div>' );
622 temp_img = $( '<img src="' + image_file + '"></div>' );
624 bg_html.append( temp_img );
625 this.container.append( bg_html );
626 this.images.push( temp_img );
631 _resizeHandler: function() {
633 if( self.orientationEventFire ) {
635 self.orientationEventFire = false;
638 _orientationHandler: function() {
641 self.orientationEventFire = true;
643 refresh: function ( start_index ) {
648 if ( start_index === undefined ) {
649 start_index = this.index;
651 if ( start_index < 0 ) {
654 if ( start_index >= this.images.length ) {
655 start_index = this.images.length - 1;
658 this.index = start_index;
665 add: function ( file ) {
666 this.images_hold.push( file );
669 remove: function ( index ) {
672 if ( index === undefined ) {
676 if ( index < 0 || index >= this.images.length ) {
680 if ( index == this.index ) {
681 temp_img = this.cur_img;
683 if ( this.index == 0 ) {
685 } else if ( this.index == this.images.length - 1 ) {
689 if ( this.direction < 0 ) {
690 this.cur_img = this.prev_img;
691 this.prev_img = this.prev_img.prev();
692 if ( this.prev_img.length ) {
693 this._moveLeft( this.prev_img, -this.window_width + 'px' );
694 this._attach( index - 2, this.prev_img );
698 this.cur_img = this.next_img;
699 this.next_img = this.next_img.next();
700 if ( this.next_img.length ) {
701 this._moveLeft( this.next_img, this.window_width + 'px' );
702 this._attach( index + 2, this.next_img );
705 this._moveLeft( this.cur_img, '0px', this.options.duration );
707 } else if ( index == this.index - 1 ) {
708 temp_img = this.prev_img;
709 this.prev_img = this.prev_img.prev();
710 if ( this.prev_img.length ) {
711 this._moveLeft( this.prev_img, -this.window_width + 'px' );
712 this._attach( index - 1, this.prev_img );
716 } else if ( index == this.index + 1 ) {
717 temp_img = this.next_img;
718 this.next_img = this.next_img.next();
719 if ( this.next_img.length ) {
720 this._moveLeft( this.next_img, this.window_width + 'px' );
721 this._attach( index + 1, this.next_img );
725 temp_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + index + ')' );
728 this.images.splice( index, 1 );
733 this.images.splice( 0, this.images.length );
734 this.container.find('.ui-gallery-bg').detach();
737 length: function () {
738 return this.images.length;
741 value: function ( index ) {
742 if ( index === undefined ) {
746 this.refresh( index );
749 destory: function() {
750 $( window ).unbind( 'resize', this._resizeHandler );
751 $( window ).unbind( 'orientationchange' , this._orientationHandler );
754 }); /* End of widget */
756 // auto self-init widgets
757 $( document ).bind( "pagecreate create", function ( e ) {
758 $( e.target ).find( ":jqmData(role='gallery')" ).gallery();
761 $( document ).bind( "pageshow", function ( e ) {
762 $( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'show' );
765 $( document ).bind( "pagebeforehide", function ( e ) {
766 $( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'hide' );
771 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
773 //>>excludeEnd("jqmBuildExclude");