1 | define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/fx", |
---|
2 | "dijit/_Templated","dijit/layout/ContentPane","dojo/dom-class", |
---|
3 | "dojo/text!./resources/ScrollPane.html"], |
---|
4 | function(kernel,declare,html,baseFx,Templated,ContentPane,domClass,template){ |
---|
5 | |
---|
6 | kernel.experimental("dojox.layout.ScrollPane"); |
---|
7 | |
---|
8 | // FIXME: need to adust the _line somehow, it stops scrolling |
---|
9 | |
---|
10 | /*===== |
---|
11 | var ContentPane = dijit.layout.ContentPane, |
---|
12 | Templated = dijit._Templated; |
---|
13 | =====*/ |
---|
14 | |
---|
15 | declare("dojox.layout.ScrollPane",[ContentPane, Templated],{ |
---|
16 | // summary: A pane that "scrolls" its content based on the mouse poisition inside |
---|
17 | // |
---|
18 | // description: |
---|
19 | // A sizable container that takes it's content's natural size and creates |
---|
20 | // a scroll effect based on the relative mouse position. It is an interesting |
---|
21 | // way to display lists of data, or blocks of content, within a confined |
---|
22 | // space. |
---|
23 | // |
---|
24 | // Horizontal scrolling is supported. Combination scrolling is not. |
---|
25 | // |
---|
26 | // example: |
---|
27 | // | <div dojoType="dojox.layout.ScrollPane" style="width:150px height:300px;"> |
---|
28 | // | <!-- any height content --> |
---|
29 | // | </div> |
---|
30 | // |
---|
31 | // _line: dojo._Line |
---|
32 | // storage for our top and bottom most scrollpoints |
---|
33 | _line: null, |
---|
34 | |
---|
35 | // _lo: the height of the visible pane |
---|
36 | _lo: null, |
---|
37 | |
---|
38 | _offset: 15, |
---|
39 | |
---|
40 | // orientation: String |
---|
41 | // either "horizontal" or "vertical" for scroll orientation. |
---|
42 | orientation: "vertical", |
---|
43 | |
---|
44 | // alwaysShow: Boolean |
---|
45 | // whether the scroll helper should hide when mouseleave |
---|
46 | autoHide: true, |
---|
47 | templateString: template, |
---|
48 | |
---|
49 | resize: function(size){ |
---|
50 | // summary: calculates required sizes. Call this if you add/remove content manually, or reload the content. |
---|
51 | |
---|
52 | // if size is passed, it means we need to take care of sizing ourself (this is for IE<8) |
---|
53 | if(size){ |
---|
54 | if(size.h){ |
---|
55 | html.style(this.domNode,'height',size.h+'px'); |
---|
56 | } |
---|
57 | if(size.w){ |
---|
58 | html.style(this.domNode,'width',size.w+'px'); |
---|
59 | } |
---|
60 | } |
---|
61 | var dir = this._dir, |
---|
62 | vert = this._vertical, |
---|
63 | val = this.containerNode[(vert ? "scrollHeight" : "scrollWidth")]; |
---|
64 | |
---|
65 | html.style(this.wrapper, this._dir, this.domNode.style[this._dir]); |
---|
66 | this._lo = html.coords(this.wrapper, true); |
---|
67 | |
---|
68 | this._size = Math.max(0, val - this._lo[(vert ? "h" : "w")]); |
---|
69 | if(!this._size){ |
---|
70 | this.helper.style.display="none"; |
---|
71 | //make sure we reset scroll position, otherwise the content may be hidden |
---|
72 | this.wrapper[this._scroll]=0; |
---|
73 | return; |
---|
74 | }else{ |
---|
75 | this.helper.style.display=""; |
---|
76 | } |
---|
77 | this._line = new baseFx._Line(0 - this._offset, this._size + (this._offset * 2)); |
---|
78 | |
---|
79 | // share a relative position w the scroll offset via a line |
---|
80 | var u = this._lo[(vert ? "h" : "w")], |
---|
81 | r = Math.min(1, u / val), // ratio |
---|
82 | s = u * r, // size |
---|
83 | c = Math.floor(u - (u * r)); // center |
---|
84 | |
---|
85 | this._helpLine = new baseFx._Line(0, c); |
---|
86 | |
---|
87 | // size the helper |
---|
88 | html.style(this.helper, dir, Math.floor(s) + "px"); |
---|
89 | |
---|
90 | }, |
---|
91 | |
---|
92 | postCreate: function(){ |
---|
93 | this.inherited(arguments); |
---|
94 | // for the helper |
---|
95 | if(this.autoHide){ |
---|
96 | this._showAnim = baseFx._fade({ node:this.helper, end:0.5, duration:350 }); |
---|
97 | this._hideAnim = baseFx.fadeOut({ node:this.helper, duration: 750 }); |
---|
98 | } |
---|
99 | |
---|
100 | // orientation helper |
---|
101 | this._vertical = (this.orientation == "vertical"); |
---|
102 | if(!this._vertical){ |
---|
103 | domClass.add(this.containerNode,"dijitInline"); |
---|
104 | this._dir = "width"; |
---|
105 | this._edge = "left"; |
---|
106 | this._scroll = "scrollLeft"; |
---|
107 | }else{ |
---|
108 | this._dir = "height"; |
---|
109 | this._edge = "top"; |
---|
110 | this._scroll = "scrollTop"; |
---|
111 | } |
---|
112 | |
---|
113 | if(this._hideAnim){ |
---|
114 | this._hideAnim.play(); |
---|
115 | } |
---|
116 | html.style(this.wrapper,"overflow","hidden"); |
---|
117 | |
---|
118 | }, |
---|
119 | |
---|
120 | _set: function(/* Float */n){ |
---|
121 | if(!this._size){ return; } |
---|
122 | // summary: set the pane's scroll offset, and position the virtual scroll helper |
---|
123 | this.wrapper[this._scroll] = Math.floor(this._line.getValue(n)); |
---|
124 | html.style(this.helper, this._edge, Math.floor(this._helpLine.getValue(n)) + "px"); |
---|
125 | }, |
---|
126 | |
---|
127 | _calc: function(/* Event */e){ |
---|
128 | // summary: calculate the relative offset of the cursor over the node, and call _set |
---|
129 | if(!this._lo){ this.resize(); } |
---|
130 | this._set(this._vertical ? |
---|
131 | ((e.pageY - this._lo.y) / this._lo.h) : |
---|
132 | ((e.pageX - this._lo.x) / this._lo.w) |
---|
133 | ); |
---|
134 | }, |
---|
135 | |
---|
136 | _enter: function(e){ |
---|
137 | if(this._hideAnim){ |
---|
138 | if(this._hideAnim.status() == "playing"){ |
---|
139 | this._hideAnim.stop(); |
---|
140 | } |
---|
141 | this._showAnim.play(); |
---|
142 | } |
---|
143 | }, |
---|
144 | |
---|
145 | _leave: function(e){ |
---|
146 | if(this._hideAnim){ |
---|
147 | this._hideAnim.play(); |
---|
148 | } |
---|
149 | } |
---|
150 | }); |
---|
151 | }); |
---|