1 /* ***************************************************************************
2 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 * ***************************************************************************
23 * Authors: Wonseop Kim ( wonseop.kim@samsung.com )
27 * "Handler" is a widget helping a user to scroll a window or panel.
28 * It is different from the scrollview feature in that the handler has a fixed size
29 * and disappears when a scroll size is smaller than a parent window's size.
30 * If the handler widget is activated, a scroll bar on the screen will be deactivated.
31 * The handler widget supports scrolling up and down and indicates the position of the scrolled window.
35 * data-handler : This attribute is indicating that whether enable.
36 * If you want to use, you will set 'true'.
37 * data-handler-theme : Set the widget theme ( optional )
41 * enableHandler ( boolean )
42 * : Get or set the use of handler widget.
43 * If the value is "true", it will be run handler widget.
44 * If the value is "false", it will be not run handler widget.
45 * If no value is specified, will act as a getter.
51 * <div data-role="content" data-scroll="y" data-handler="true">
52 * <ul data-role="listview">
53 * <li data-role="list-divider">A</li>
54 * <li><a href="#">Adam Kinkaid</a></li>
62 The handler widget enables the user to vertically scroll through a page or panel using a fixed-size handle. The widget indicates the position of the scrolled window, and only appears on the screen if the parent page or panel's scroll size is larger than the screen size. <br/> To add a handler widget to the application, use the following code:
64 <div data-role="content" data-scroll="y" data-handler="true">
65 <ul data-role="listview">
66 <li data-role="list-divider">A</li>
67 <li><a href="#">Adam Kinkaid</a></li>
72 You can use the enableHandler method with the handler widget to get (if no value is defined) or set the handler usage status. If the [enable] value is true, the handler is enabled; otherwise the handler is not used.
74 $("#.selector").scrollview("enableHandler", [enable]);
77 @property {Boolean} data-handler
78 Enables the handler widget. The value must be set to true.
81 @property {String} data-handler-theme
82 Sets the handler widget theme.
84 ( function ( $, document, undefined ) {
85 // The options of handler in scrollview
86 $.tizen.scrollview.prototype.options.handler = false;
87 $.tizen.scrollview.prototype.options.handlerTheme = "s";
89 var originSetOption = $.tizen.scrollview.prototype._setOption,
90 createHandler = function ( target ) {
92 prefix = "<div class=\"ui-handler ui-handler-direction-",
93 suffix = "\"><div class=\"ui-handler-track\"><div class=\"ui-handler-thumb\"></div></div></div>",
94 scrollview = $view.data( "scrollview" ),
95 options = scrollview.options,
96 direction = options.direction,
97 parentTheme = $.mobile.getInheritedTheme( scrollview, "s" ),
98 theme = options.theme || parentTheme,
99 isHorizontal = ( scrollview.options.direction === "x" ),
100 _$view = scrollview._$view,
101 _$clip = scrollview._$clip,
110 isTouchable = $.support.touch,
111 dragStartEvt = ( isTouchable ? "touchstart" : "mousedown" ) + ".handler",
112 dragMoveEvt = ( isTouchable ? "touchmove" : "mousemove" ) + ".handler",
113 dragStopEvt = ( isTouchable ? "touchend" : "mouseup" ) + ".handler",
114 dragLeaveEvt = ( isTouchable ? " touchleave" : " mouseleave" ) + ".handler",
115 calculateLength = function () {
116 clipLength = ( isHorizontal ? _$clip.width() : _$clip.height() );
117 viewLength = ( isHorizontal ? _$view.width() : _$view.height() ) - clipLength;
118 trackLength = clipLength - handlerHeight - handlerMargin * 2;
120 setHanderPostion = function ( scrollPos ) {
121 var handlerPos = Math.round( ( isHorizontal ? scrollPos.x : scrollPos.y ) / viewLength * trackLength );
122 handlerThumb[0].style[ ( isHorizontal ? "left" : "top" ) ] = handlerPos + "px";
124 stopHandlerScroll = function () {
125 $( document ).unbind( ".handler" );
126 $view.moveData = null;
127 _$view.trigger( "scrollstop" );
130 if ( $view.find( ".ui-handler-thumb" ).length !== 0 || typeof direction !== "string" ) {
134 $view.addClass( " ui-handler-" + theme ).append( [ prefix, direction, suffix ].join( "" ) );
135 handler = $view.find( ".ui-handler" );
136 handlerThumb = $view.find( ".ui-handler-thumb" ).hide();
137 handlerHeight = ( isHorizontal ? handlerThumb.width() : handlerThumb.height() );
138 handlerMargin = ( isHorizontal ? parseInt( handler.css( "right" ), 10 ) : parseInt( handler.css( "bottom" ), 10 ) );
145 handlerThumb.bind( dragStartEvt, {
147 }, function ( event ) {
148 scrollview._stopMScroll();
150 var target = event.data.e,
151 t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );
153 target.style.opacity = 1.0;
157 X : parseInt( target.style.left, 10 ) || 0,
158 Y : parseInt( target.style.top, 10 ) || 0,
164 _$view.trigger( "scrollstart" );
166 if ( !isTouchable ) {
167 event.preventDefault();
170 $( document ).bind( dragMoveEvt, function ( event ) {
171 var moveData = $view.moveData,
172 target = moveData.target,
175 t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );
177 handlePos = ( isHorizontal ? moveData.X + t.pageX - moveData.pX : moveData.Y + t.pageY - moveData.pY );
179 if ( handlePos < 0 ) {
183 if ( handlePos > trackLength ) {
184 handlePos = trackLength;
186 scrollPos = - Math.round( handlePos / trackLength * viewLength );
188 if ( isHorizontal ) {
189 scrollview._setScrollPosition( scrollPos, 0 );
190 target.style.left = handlePos + "px";
192 scrollview._setScrollPosition( 0, scrollPos );
193 target.style.top = handlePos + "px";
196 event.preventDefault();
197 }).bind( dragStopEvt + dragLeaveEvt, function ( event ) {
202 _$view.bind( dragStopEvt, function ( event ) {
206 $view.bind( "scrollstart", function ( event ) {
207 if ( !scrollview.enableHandler() ) {
213 clearInterval( moveTimer );
214 moveTimer = undefined;
217 if ( viewLength < 0 || clipLength < handlerHeight ) {
221 handlerThumb.addClass( "ui-handler-visible" )
224 }).bind( "scrollupdate", function ( event, data ) {
225 if ( !scrollview.enableHandler() || viewLength < 0 || clipLength < handlerHeight ) {
229 setHanderPostion( scrollview.getScrollPosition() );
230 }).bind( "scrollstop", function ( event ) {
231 if ( !scrollview.enableHandler() || viewLength < 0 ) {
235 moveTimer = setInterval( function () {
236 setHanderPostion( scrollview.getScrollPosition() );
237 if ( !scrollview._gesture_timer ) {
238 clearInterval( moveTimer );
239 moveTimer = undefined;
243 if ( scrollview._handlerTimer ) {
244 clearTimeout( scrollview._handlerTimer );
245 scrollview._handlerTimer = 0;
247 scrollview._handlerTimer = setTimeout( function () {
248 if ( scrollview._timerID === 0 && $view.moveData === null ) {
249 handlerThumb.removeClass( "ui-handler-visible" )
251 .css( "opacity", 1.0 )
253 scrollview._handlerTimer = 0;
256 }).bind( "mousewheel", function ( event ) {
257 handlerThumb.removeClass( "ui-handler-visible" ).hide();
258 setHanderPostion( scrollview.getScrollPosition() );
262 $.extend( $.tizen.scrollview.prototype, {
263 enableHandler: function ( enabled ) {
264 if ( typeof enabled === 'undefined' ) {
265 return this.options.handler;
268 this.options.handler = !!enabled;
270 var $view = this.element;
271 if ( this.options.handler ) {
272 if ( $view.find( ".ui-handler" ).length === 0 ) {
273 createHandler( $view );
276 $view.find( ".ui-scrollbar" ).hide();
277 $view.find( ".ui-handler" ).show();
279 $view.find( ".ui-handler" ).hide();
280 $view.find( ".ui-scrollbar" ).show();
284 _setHandlerTheme: function ( handlerTheme ) {
285 if ( !handlerTheme ) {
289 var oldClass = "ui-handler-" + this.options.handlerTheme,
290 newClass = "ui-handler-" + handlerTheme;
292 this.element.removeClass( oldClass ).addClass( newClass );
293 this.options.handlerTheme = handlerTheme;
296 _setOption: function ( key, value ) {
299 this.enableHandler( value );
302 this._setHandlerTheme( value );
305 originSetOption.call( this, key, value );
312 $( document ).delegate( ":jqmData(scroll)", "scrollviewcreate", function () {
313 var widget = $( this );
314 if ( widget.attr( "data-" + $.mobile.ns + "scroll" ) === "none"
315 || widget.attr( "data-" + $.mobile.ns + "handler" ) !== "true" ) {
318 widget.scrollview( "enableHandler", "true" );
320 } ( jQuery, document ) );