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,
109 isTouchable = $.support.touch,
110 dragStartEvt = ( isTouchable ? "touchstart" : "mousedown" ) + ".handler",
111 dragMoveEvt = ( isTouchable ? "touchmove" : "mousemove" ) + ".handler",
112 dragStopEvt = ( isTouchable ? "touchend" : "mouseup" ) + ".handler",
113 calculateLength = function () {
114 clipLength = ( isHorizontal ? _$clip.width() : _$clip.height() );
115 viewLength = ( isHorizontal ? _$view.outerWidth( true ) : _$view.outerHeight( true ) ) - clipLength;
116 trackLength = clipLength - handlerHeight - handlerMargin * 2;
118 setHanderPostion = function ( scrollPos ) {
119 var handlerPos = Math.round( ( isHorizontal ? scrollPos.x : scrollPos.y ) / viewLength * trackLength );
120 handlerThumb.css( isHorizontal ? "left" : "top", handlerPos );
123 if ( $view.find( ".ui-handler-thumb" ).length !== 0 || typeof direction !== "string" ) {
127 $view.addClass( " ui-handler-" + theme ).append( [ prefix, direction, suffix ].join( "" ) );
128 handler = $view.find( ".ui-handler" );
129 handlerThumb = $view.find( ".ui-handler-thumb" ).hide();
130 handlerHeight = ( isHorizontal ? handlerThumb.width() : handlerThumb.height() );
131 handlerMargin = ( isHorizontal ? parseInt( handler.css( "right" ), 10 ) : parseInt( handler.css( "bottom" ), 10 ) );
138 handlerThumb.bind( dragStartEvt, {
140 }, function ( event ) {
141 scrollview._stopMScroll();
143 var target = event.data.e,
144 t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );
146 target.css( "opacity", 1.0 );
150 X : parseInt( target.css( 'left' ), 10 ) || 0,
151 Y : parseInt( target.css( 'top' ), 10 ) || 0,
157 _$view.trigger( "scrollstart" );
158 event.preventDefault();
159 event.stopPropagation();
161 $( document ).bind( dragMoveEvt, function ( event ) {
162 var moveData = $view.moveData,
165 t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );
167 handlePos = ( isHorizontal ? moveData.X + t.pageX - moveData.pX : moveData.Y + t.pageY - moveData.pY );
169 if ( handlePos < 0 ) {
173 if ( handlePos > trackLength ) {
174 handlePos = trackLength;
176 scrollPos = - Math.round( handlePos / trackLength * viewLength );
178 $view.attr( "display", "none" );
179 if ( isHorizontal ) {
180 scrollview._setScrollPosition( scrollPos, 0 );
181 moveData.target.css( {
185 scrollview._setScrollPosition( 0, scrollPos );
186 moveData.target.css( {
190 $view.attr( "display", "inline" );
192 event.preventDefault();
193 event.stopPropagation();
194 }).bind( dragStopEvt, function ( event ) {
195 $( document ).unbind( dragMoveEvt ).unbind( dragStopEvt );
197 $view.moveData = null;
198 _$view.trigger( "scrollstop" );
200 event.preventDefault();
204 $( document ).bind( dragMoveEvt, function ( event ) {
205 var isVisible = false,
206 vclass = "ui-scrollbar-visible";
208 if ( scrollview._$vScrollBar ) {
209 isVisible = scrollview._$vScrollBar.hasClass( vclass );
210 } else if ( scrollview._$hScrollBar ) {
211 isVisible = scrollview._$hScrollBar.hasClass( vclass );
214 if ( isVisible || $view.moveData !== null ) {
215 if ( handlerThumb.hasClass( "ui-handler-visible" ) ) {
216 _$view.trigger( "scrollupdate" );
218 _$view.trigger( "scrollstop" );
221 }).bind( dragStopEvt, function ( event ) {
222 if ( handlerThumb.hasClass( "ui-handler-visible" ) ) {
223 _$view.trigger( "scrollstop" );
227 $view.bind( "scrollstart", function ( event ) {
228 if ( !scrollview.enableHandler() ) {
233 if ( clipLength > viewLength || trackLength < ( handlerHeight * 4 / 3 ) ) {
237 handlerThumb.addClass( "ui-handler-visible" )
241 event.preventDefault();
242 event.stopPropagation();
243 }).bind( "scrollupdate", function ( event, data ) {
244 if ( !scrollview.enableHandler() || clipLength > viewLength || trackLength < ( handlerHeight * 4 / 3 ) ) {
248 setHanderPostion( scrollview.getScrollPosition() );
250 event.preventDefault();
251 event.stopPropagation();
252 }).bind( "scrollstop", function ( event ) {
253 if ( !scrollview.enableHandler() || clipLength > viewLength ) {
257 if ( scrollview._handlerTimer ) {
258 clearTimeout( scrollview._handlerTimer );
259 scrollview._handlerTimer = 0;
261 scrollview._handlerTimer = setTimeout( function () {
262 if ( scrollview._timerID === 0 && $view.moveData === null ) {
263 handlerThumb.removeClass( "ui-handler-visible" )
265 .css( "opacity", 1.0 )
267 scrollview._handlerTimer = 0;
271 event.preventDefault();
272 }).bind( "mousewheel", function ( event ) {
273 handlerThumb.removeClass( "ui-handler-visible" ).hide();
274 setHanderPostion( scrollview.getScrollPosition() );
278 $.extend( $.tizen.scrollview.prototype, {
279 enableHandler: function ( enabled ) {
280 if ( typeof enabled === 'undefined' ) {
281 return this.options.handler;
284 this.options.handler = !!enabled;
286 var view = this.element;
287 if ( this.options.handler ) {
288 if ( view.find( ".ui-handler" ).length === 0 ) {
289 createHandler( view );
292 view.find( ".ui-scrollbar" ).hide();
293 view.find( ".ui-handler" ).show();
295 view.find( ".ui-handler" ).hide();
296 view.find( ".ui-scrollbar" ).show();
300 _setHandlerTheme: function ( handlerTheme ) {
301 if ( !handlerTheme ) {
305 var oldClass = "ui-handler-" + this.options.handlerTheme,
306 newClass = "ui-handler-" + handlerTheme;
308 this.element.removeClass( oldClass ).addClass( newClass );
309 this.options.handlerTheme = handlerTheme;
312 _setOption: function ( key, value ) {
315 this.enableHandler( value );
318 this._setHandlerTheme( value );
321 originSetOption.call( this, key, value );
328 $( document ).delegate( ":jqmData(scroll)", "scrollviewcreate", function () {
329 var widget = $( this );
330 if ( widget.attr( "data-" + $.mobile.ns + "scroll" ) === "none"
331 || widget.jqmData( "handler" ) !== true ) {
334 widget.scrollview( "enableHandler", "true" );
336 } ( jQuery, document ) );