Dotclear

source: admin/js/tool-man/drag.js @ 0:54703be25dd6

Revision 0:54703be25dd6, 7.4 KB checked in by Dsls <dsls@…>, 14 years ago (diff)

2.3 branch (trunk) first checkin

Line 
1/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
2
3ToolMan._dragFactory = {
4     createSimpleGroup : function(element, handle) {
5          handle = handle ? handle : element
6          var group = this.createGroup(element)
7          group.setHandle(handle)
8          //group.transparentDrag()
9          group.onTopWhileDragging()
10          return group
11     },
12     
13     createGroup : function(element) {
14          var group = new _ToolManDragGroup(this, element)
15         
16          var position = ToolMan.css().readStyle(element, 'position')
17          if (position == 'static') {
18               element.style["position"] = 'relative'
19          } else if (position == 'absolute') {
20               /* for Safari 1.2 */
21               ToolMan.coordinates().topLeftOffset(element).reposition(element)
22          }
23         
24          // TODO: only if ToolMan.isDebugging()
25          group.register('draginit', this._showDragEventStatus)
26          group.register('dragmove', this._showDragEventStatus)
27          group.register('dragend', this._showDragEventStatus)
28         
29          return group
30     },
31     
32     _showDragEventStatus : function(dragEvent) {
33          window.status = dragEvent.toString()
34     },
35     
36     constraints : function() {
37          return this._constraintFactory
38     },
39     
40     _createEvent : function(type, event, group) {
41          return new _ToolManDragEvent(type, event, group)
42     }
43}
44
45function _ToolManDragGroup(factory, element) {
46     this.factory = factory
47     this.element = element
48     this._handle = null
49     this._thresholdDistance = 0
50     this._transforms = new Array()
51     // TODO: refactor into a helper object, move into events.js
52     this._listeners = new Array()
53     this._listeners['draginit'] = new Array()
54     this._listeners['dragstart'] = new Array()
55     this._listeners['dragmove'] = new Array()
56     this._listeners['dragend'] = new Array()
57}
58
59_ToolManDragGroup.prototype = {
60     /*
61      * TODO:
62      *   - unregister(type, func)
63      *   - move custom event listener stuff into Event library
64      *   - keyboard nudging of "selected" group
65      */
66     
67     setHandle : function(handle) {
68          var events = ToolMan.events()
69         
70          handle.toolManDragGroup = this
71          events.register(handle, 'mousedown', this._dragInit)
72          //handle.onmousedown = function() { return false }
73         
74          if (this.element != handle)
75               events.unregister(this.element, 'mousedown', this._dragInit)
76     },
77     
78     register : function(type, func) {
79          this._listeners[type].push(func)
80     },
81     
82     addTransform : function(transformFunc) {
83          this._transforms.push(transformFunc)
84     },
85     
86     verticalOnly : function() {
87          this.addTransform(this.factory.constraints().vertical())
88     },
89     
90     horizontalOnly : function() {
91          this.addTransform(this.factory.constraints().horizontal())
92     },
93     
94     setThreshold : function(thresholdDistance) {
95          this._thresholdDistance = thresholdDistance
96     },
97     
98     transparentDrag : function(opacity) {
99          if (typeof(opacity) == "undefined") {
100               opacity = 0.75;
101          }
102          var originalOpacity = ToolMan.css().readStyle(this.element, "opacity")
103         
104          this.register('dragstart', function(dragEvent) {
105               var element = dragEvent.group.element
106               element.style.opacity = opacity
107               element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')'
108          })
109          this.register('dragend', function(dragEvent) {
110               var element = dragEvent.group.element
111               element.style.opacity = originalOpacity
112               element.style.filter = 'alpha(opacity=100)'
113          })
114     },
115     
116     onTopWhileDragging : function(zIndex) {
117          if (typeof(zIndex) == "undefined") {
118               zIndex = 100000;
119          }
120         
121          var originalZIndex = ToolMan.css().readStyle(this.element, "z-index")
122         
123          this.register('dragstart', function(dragEvent) {
124               dragEvent.group.element.style.zIndex = zIndex
125          })
126          this.register('dragend', function(dragEvent) {
127               if (typeof(originalZIndex) != "undefined") {
128                    dragEvent.group.element.style.zIndex = originalZIndex
129               }
130               //dragEvent.group.element.style.backgroundColor = '#f00';
131          })
132     },
133     
134     _dragInit : function(event) {
135          event = ToolMan.events().fix(event)
136          var group = document.toolManDragGroup = this.toolManDragGroup
137          var dragEvent = group.factory._createEvent('draginit', event, group)
138         
139          group._isThresholdExceeded = false
140          group._initialMouseOffset = dragEvent.mouseOffset
141          group._grabOffset = dragEvent.mouseOffset.minus(dragEvent.topLeftOffset)
142          ToolMan.events().register(document, 'mousemove', group._drag)
143          document.onmousemove = function() { return false }
144          ToolMan.events().register(document, 'mouseup', group._dragEnd)
145         
146          ToolMan.events().register(document, 'mousedown',group._drag);
147          document.onmousedown = function() { return false; };
148         
149          group._notifyListeners(dragEvent)
150     },
151     
152     _drag : function(event) {
153          event = ToolMan.events().fix(event)
154          var coordinates = ToolMan.coordinates()
155          var group = this.toolManDragGroup
156          if (!group) return
157          var dragEvent = group.factory._createEvent('dragmove', event, group)
158         
159          var newTopLeftOffset = dragEvent.mouseOffset.minus(group._grabOffset)
160         
161          // TODO: replace with DragThreshold object
162          if (!group._isThresholdExceeded) {
163               var distance = 
164                         dragEvent.mouseOffset.distance(group._initialMouseOffset)
165               if (distance < group._thresholdDistance) return
166               group._isThresholdExceeded = true
167               group._notifyListeners(
168                         group.factory._createEvent('dragstart', event, group))
169          }
170         
171          for (i in group._transforms) {
172               var transform = group._transforms[i]
173               newTopLeftOffset = transform(newTopLeftOffset, dragEvent)
174          }
175         
176          var dragDelta = newTopLeftOffset.minus(dragEvent.topLeftOffset)
177          var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta)
178          newTopLeftPosition.reposition(group.element)
179          dragEvent.transformedMouseOffset = newTopLeftOffset.plus(group._grabOffset)
180         
181          group._notifyListeners(dragEvent)
182         
183          var errorDelta = newTopLeftOffset.minus(coordinates.topLeftOffset(group.element))
184          if (errorDelta.x != 0 || errorDelta.y != 0) {
185               coordinates.topLeftPosition(group.element).plus(errorDelta).reposition(group.element)
186          }
187     },
188     
189     _dragEnd : function(event) {
190          event = ToolMan.events().fix(event)
191          var group = this.toolManDragGroup
192          var dragEvent = group.factory._createEvent('dragend', event, group)
193         
194          group._notifyListeners(dragEvent)
195         
196          this.toolManDragGroup = null
197          ToolMan.events().unregister(document, 'mousemove', group._drag)
198          document.onmousemove = null
199          ToolMan.events().unregister(document, 'mouseup', group._dragEnd)
200         
201          ToolMan.events().register(document, 'mousedown', group._drag);
202          document.onmousedown = function() { return true };
203     },
204     
205     _notifyListeners : function(dragEvent) {
206          var listeners = this._listeners[dragEvent.type]
207          for (i in listeners) {
208               listeners[i](dragEvent)
209          }
210     }
211}
212
213function _ToolManDragEvent(type, event, group) {
214     this.type = type
215     this.group = group
216     this.mousePosition = ToolMan.coordinates().mousePosition(event)
217     this.mouseOffset = ToolMan.coordinates().mouseOffset(event)
218     this.transformedMouseOffset = this.mouseOffset
219     this.topLeftPosition = ToolMan.coordinates().topLeftPosition(group.element)
220     this.topLeftOffset = ToolMan.coordinates().topLeftOffset(group.element)
221}
222
223_ToolManDragEvent.prototype = {
224     toString : function() {
225          return "mouse: " + this.mousePosition + this.mouseOffset + "    " +
226                    "xmouse: " + this.transformedMouseOffset + "    " +
227                    "left,top: " + this.topLeftPosition + this.topLeftOffset
228     }
229}
230
231ToolMan._dragFactory._constraintFactory = {
232     vertical : function() {
233          return function(coordinate, dragEvent) {
234               var x = dragEvent.topLeftOffset.x
235               return coordinate.x != x
236                         ? coordinate.factory.create(x, coordinate.y) 
237                         : coordinate
238          }
239     },
240     
241     horizontal : function() {
242          return function(coordinate, dragEvent) {
243               var y = dragEvent.topLeftOffset.y
244               return coordinate.y != y
245                         ? coordinate.factory.create(coordinate.x, y) 
246                         : coordinate
247          }
248     }
249}
Note: See TracBrowser for help on using the repository browser.

Sites map