| /* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */ |
| |
| ToolMan._dragFactory = { |
| createSimpleGroup : function(element, handle) { |
| handle = handle ? handle : element |
| var group = this.createGroup(element) |
| group.setHandle(handle) |
| group.transparentDrag() |
| group.onTopWhileDragging() |
| return group |
| }, |
| |
| createGroup : function(element) { |
| var group = new _ToolManDragGroup(this, element) |
| |
| var position = ToolMan.css().readStyle(element, 'position') |
| if (position == 'static') { |
| element.style["position"] = 'relative' |
| } else if (position == 'absolute') { |
| /* for Safari 1.2 */ |
| ToolMan.coordinates().topLeftOffset(element).reposition(element) |
| } |
| |
| // TODO: only if ToolMan.isDebugging() |
| group.register('draginit', this._showDragEventStatus) |
| group.register('dragmove', this._showDragEventStatus) |
| group.register('dragend', this._showDragEventStatus) |
| |
| return group |
| }, |
| |
| _showDragEventStatus : function(dragEvent) { |
| window.status = dragEvent.toString() |
| }, |
| |
| constraints : function() { |
| return this._constraintFactory |
| }, |
| |
| _createEvent : function(type, event, group) { |
| return new _ToolManDragEvent(type, event, group) |
| } |
| } |
| |
| function _ToolManDragGroup(factory, element) { |
| this.factory = factory |
| this.element = element |
| this._handle = null |
| this._thresholdDistance = 0 |
| this._transforms = new Array() |
| // TODO: refactor into a helper object, move into events.js |
| this._listeners = new Array() |
| this._listeners['draginit'] = new Array() |
| this._listeners['dragstart'] = new Array() |
| this._listeners['dragmove'] = new Array() |
| this._listeners['dragend'] = new Array() |
| } |
| |
| _ToolManDragGroup.prototype = { |
| /* |
| * TODO: |
| * - unregister(type, func) |
| * - move custom event listener stuff into Event library |
| * - keyboard nudging of "selected" group |
| */ |
| |
| setHandle : function(handle) { |
| var events = ToolMan.events() |
| |
| handle.toolManDragGroup = this |
| events.register(handle, 'mousedown', this._dragInit) |
| handle.onmousedown = function() { return false } |
| |
| if (this.element != handle) |
| events.unregister(this.element, 'mousedown', this._dragInit) |
| }, |
| |
| register : function(type, func) { |
| this._listeners[type].push(func) |
| }, |
| |
| addTransform : function(transformFunc) { |
| this._transforms.push(transformFunc) |
| }, |
| |
| verticalOnly : function() { |
| this.addTransform(this.factory.constraints().vertical()) |
| }, |
| |
| horizontalOnly : function() { |
| this.addTransform(this.factory.constraints().horizontal()) |
| }, |
| |
| setThreshold : function(thresholdDistance) { |
| this._thresholdDistance = thresholdDistance |
| }, |
| |
| transparentDrag : function(opacity) { |
| var opacity = typeof(opacity) != "undefined" ? opacity : 0.75; |
| var originalOpacity = ToolMan.css().readStyle(this.element, "opacity") |
| |
| this.register('dragstart', function(dragEvent) { |
| var element = dragEvent.group.element |
| element.style.opacity = opacity |
| element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')' |
| }) |
| this.register('dragend', function(dragEvent) { |
| var element = dragEvent.group.element |
| element.style.opacity = originalOpacity |
| element.style.filter = 'alpha(opacity=100)' |
| }) |
| }, |
| |
| onTopWhileDragging : function(zIndex) { |
| var zIndex = typeof(zIndex) != "undefined" ? zIndex : 100000; |
| var originalZIndex = ToolMan.css().readStyle(this.element, "z-index") |
| |
| this.register('dragstart', function(dragEvent) { |
| dragEvent.group.element.style.zIndex = zIndex |
| }) |
| this.register('dragend', function(dragEvent) { |
| dragEvent.group.element.style.zIndex = originalZIndex |
| }) |
| }, |
| |
| _dragInit : function(event) { |
| event = ToolMan.events().fix(event) |
| var group = document.toolManDragGroup = this.toolManDragGroup |
| var dragEvent = group.factory._createEvent('draginit', event, group) |
| |
| group._isThresholdExceeded = false |
| group._initialMouseOffset = dragEvent.mouseOffset |
| group._grabOffset = dragEvent.mouseOffset.minus(dragEvent.topLeftOffset) |
| ToolMan.events().register(document, 'mousemove', group._drag) |
| document.onmousemove = function() { return false } |
| ToolMan.events().register(document, 'mouseup', group._dragEnd) |
| |
| group._notifyListeners(dragEvent) |
| }, |
| |
| _drag : function(event) { |
| event = ToolMan.events().fix(event) |
| var coordinates = ToolMan.coordinates() |
| var group = this.toolManDragGroup |
| if (!group) return |
| var dragEvent = group.factory._createEvent('dragmove', event, group) |
| |
| var newTopLeftOffset = dragEvent.mouseOffset.minus(group._grabOffset) |
| |
| // TODO: replace with DragThreshold object |
| if (!group._isThresholdExceeded) { |
| var distance = |
| dragEvent.mouseOffset.distance(group._initialMouseOffset) |
| if (distance < group._thresholdDistance) return |
| group._isThresholdExceeded = true |
| group._notifyListeners( |
| group.factory._createEvent('dragstart', event, group)) |
| } |
| |
| for (i in group._transforms) { |
| var transform = group._transforms[i] |
| newTopLeftOffset = transform(newTopLeftOffset, dragEvent) |
| } |
| |
| var dragDelta = newTopLeftOffset.minus(dragEvent.topLeftOffset) |
| var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta) |
| newTopLeftPosition.reposition(group.element) |
| dragEvent.transformedMouseOffset = newTopLeftOffset.plus(group._grabOffset) |
| |
| group._notifyListeners(dragEvent) |
| |
| var errorDelta = newTopLeftOffset.minus(coordinates.topLeftOffset(group.element)) |
| if (errorDelta.x != 0 || errorDelta.y != 0) { |
| coordinates.topLeftPosition(group.element).plus(errorDelta).reposition(group.element) |
| } |
| }, |
| |
| _dragEnd : function(event) { |
| event = ToolMan.events().fix(event) |
| var group = this.toolManDragGroup |
| var dragEvent = group.factory._createEvent('dragend', event, group) |
| |
| group._notifyListeners(dragEvent) |
| |
| this.toolManDragGroup = null |
| ToolMan.events().unregister(document, 'mousemove', group._drag) |
| document.onmousemove = null |
| ToolMan.events().unregister(document, 'mouseup', group._dragEnd) |
| }, |
| |
| _notifyListeners : function(dragEvent) { |
| var listeners = this._listeners[dragEvent.type] |
| for (i in listeners) { |
| listeners[i](dragEvent) |
| } |
| } |
| } |
| |
| function _ToolManDragEvent(type, event, group) { |
| this.type = type |
| this.group = group |
| this.mousePosition = ToolMan.coordinates().mousePosition(event) |
| this.mouseOffset = ToolMan.coordinates().mouseOffset(event) |
| this.transformedMouseOffset = this.mouseOffset |
| this.topLeftPosition = ToolMan.coordinates().topLeftPosition(group.element) |
| this.topLeftOffset = ToolMan.coordinates().topLeftOffset(group.element) |
| } |
| |
| _ToolManDragEvent.prototype = { |
| toString : function() { |
| return "mouse: " + this.mousePosition + this.mouseOffset + " " + |
| "xmouse: " + this.transformedMouseOffset + " " + |
| "left,top: " + this.topLeftPosition + this.topLeftOffset |
| } |
| } |
| |
| ToolMan._dragFactory._constraintFactory = { |
| vertical : function() { |
| return function(coordinate, dragEvent) { |
| var x = dragEvent.topLeftOffset.x |
| return coordinate.x != x |
| ? coordinate.factory.create(x, coordinate.y) |
| : coordinate |
| } |
| }, |
| |
| horizontal : function() { |
| return function(coordinate, dragEvent) { |
| var y = dragEvent.topLeftOffset.y |
| return coordinate.y != y |
| ? coordinate.factory.create(coordinate.x, y) |
| : coordinate |
| } |
| } |
| } |