<s> import time <EOL> from __pyjamas__ import wnd , doc <EOL> from pyjamas import DOM <EOL> from pyjamas import Window <EOL> from pyjamas . ui import GlassWidget <EOL> from pyjamas . ui . RootPanel import RootPanel <EOL> from pyjamas . ui import Event <EOL> from pyjamas . Timer import Timer <EOL> from pyjamas . dnd . utils import DraggingWidget , isCanceled , findDraggable , eventCoordinates , getElementUnderMouse <EOL> from pyjamas . dnd . DataTransfer import DataTransfer , DragDataStore <EOL> from pyjamas . dnd . DragEvent import DragEvent <EOL> from pyjamas . dnd import READ_ONLY , READ_WRITE , PROTECTED <EOL> ACTIVELY_DRAGGING = <NUM_LIT:3> <EOL> DRAGGING_NO_MOVEMENT_YET = <NUM_LIT:2> <EOL> NOT_DRAGGING = <NUM_LIT:1> <EOL> class DNDHelper ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . dropTargets = [ ] <EOL> self . dragging = NOT_DRAGGING <EOL> self . dragBusy = False <EOL> self . _currentTargetElement = None <EOL> self . previousDropTarget = None <EOL> self . draggingImage = None <EOL> self . origMouseX = <NUM_LIT:0> <EOL> self . origMouseY = <NUM_LIT:0> <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> self . data = None <EOL> self . returnTimer = Timer ( notify = self . onReturningWidget ) <EOL> self . mouseEvent = None <EOL> self . dragDataStore = None <EOL> def setCurrentTargetElement ( self , element ) : <EOL> if self . _currentTargetElement is not None : <EOL> if not DOM . compare ( self . _currentTargetElement , element ) : <EOL> self . fireDNDEvent ( '<STR_LIT>' , self . currentTargetElement , <EOL> self . currentDropWidget ) <EOL> self . _currentTargetElement = element <EOL> def getCurrentTargetElement ( self ) : <EOL> return self . _currentTargetElement <EOL> currentTargetElement = property ( getCurrentTargetElement , <EOL> setCurrentTargetElement ) <EOL> def getElement ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . dragWidget . getElement ( ) <EOL> def updateDropEffect ( self , dataTransfer , event_type ) : <EOL> """<STR_LIT>""" <EOL> dropEffect = '<STR_LIT:none>' <EOL> if event_type in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> ea = dataTransfer . getEffectAllowed ( ) <EOL> if ea == '<STR_LIT:none>' : <EOL> dropEffect = '<STR_LIT:none>' <EOL> elif ea . startswith ( '<STR_LIT>' ) or ea == '<STR_LIT:all>' : <EOL> dropEffect = '<STR_LIT>' <EOL> elif ea . startswith ( '<STR_LIT>' ) : <EOL> dropEffect = '<STR_LIT>' <EOL> elif ea == '<STR_LIT>' : <EOL> dropEffect = '<STR_LIT>' <EOL> else : <EOL> dropEffect = '<STR_LIT>' <EOL> elif event_type in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> dropEffect = self . currentDragOperation <EOL> dataTransfer . dropEffect = dropEffect <EOL> def updateDragOperation ( self , event ) : <EOL> """<STR_LIT>""" <EOL> dataTransfer = event . dataTransfer <EOL> ea = dataTransfer . effectAllowed <EOL> de = dataTransfer . dropEffect <EOL> if ( de == '<STR_LIT>' and ea in <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:all>' ] ) : <EOL> self . currentDragOperation = '<STR_LIT>' <EOL> elif ( de == '<STR_LIT>' and ea in <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:all>' ] ) : <EOL> self . currentDragOperation = '<STR_LIT>' <EOL> elif ( de == '<STR_LIT>' and ea in <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:all>' ] ) : <EOL> self . currentDragOperation = '<STR_LIT>' <EOL> else : <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> def updateAllowedEffects ( self , drag_event ) : <EOL> dt = drag_event . dataTransfer <EOL> self . dragDataStore . allowed_effects_state = dt . effectAllowed <EOL> def registerTarget ( self , target ) : <EOL> """<STR_LIT>""" <EOL> if not target in self . dropTargets : <EOL> self . dropTargets . append ( target ) <EOL> def unregisterTarget ( self , target ) : <EOL> """<STR_LIT>""" <EOL> while target in self . dropTargets : <EOL> self . dropTargets . remove ( target ) <EOL> def setDragImage ( self , element , x , y ) : <EOL> position_absolute = DOM . getStyleAttribute ( element , <EOL> '<STR_LIT>' ) == '<STR_LIT>' <EOL> if position_absolute : <EOL> self . dragLeftOffset = x + DOM . getAbsoluteLeft ( <EOL> element . offsetParent ) <EOL> self . dragTopOffset = y + DOM . getAbsoluteTop ( <EOL> element . offsetParent ) <EOL> else : <EOL> self . dragLeftOffset = x <EOL> self . dragTopOffset = y <EOL> if element . tagName . lower ( ) . endswith ( '<STR_LIT>' ) : <EOL> src = DOM . getAttribute ( element , '<STR_LIT:src>' ) <EOL> element = DOM . createElement ( '<STR_LIT>' ) <EOL> DOM . setAttribute ( element , '<STR_LIT:src>' , src ) <EOL> if not self . draggingImage : <EOL> self . createDraggingImage ( element ) <EOL> else : <EOL> self . draggingImage . setImage ( element ) <EOL> def addFeedbackElement ( self , element ) : <EOL> """<STR_LIT>""" <EOL> if self . draggingImage : <EOL> self . draggingImage . addElement ( element ) <EOL> else : <EOL> self . createDraggingImage ( element ) <EOL> def createDraggingImage ( self , element ) : <EOL> self . draggingImage = DraggingWidget ( element ) <EOL> return self . draggingImage <EOL> def setDragImageLocation ( self , x , y ) : <EOL> """<STR_LIT>""" <EOL> elt_top = y - self . dragTopOffset <EOL> elt_left = x - self . dragLeftOffset <EOL> self . draggingImage . setStyleAttribute ( '<STR_LIT>' , elt_top ) <EOL> self . draggingImage . setStyleAttribute ( '<STR_LIT:left>' , elt_left ) <EOL> def getAbsoluteLeft ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . dragWidget . getAbsoluteLeft ( ) <EOL> def getAbsoluteTop ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . dragWidget . getAbsoluteTop ( ) <EOL> def makeDragEvent ( self , event , type , target = None ) : <EOL> dt = DataTransfer ( self . dragDataStore ) <EOL> self . updateDropEffect ( dt , type ) <EOL> drag_event = DragEvent ( event , type , dt , target ) <EOL> return drag_event <EOL> def finalize ( self , event ) : <EOL> self . dragDataStore . allowed_effects_state = event . dataTransfer . effectAllowed <EOL> if event . type in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> self . dragDataStore . setMode ( PROTECTED ) <EOL> event . dataTransfer . dataStore = None <EOL> def fireDNDEvent ( self , name , target , widget ) : <EOL> if name == '<STR_LIT>' : <EOL> self . dragDataStore . setMode ( READ_WRITE ) <EOL> elif name == '<STR_LIT>' : <EOL> self . dragDataStore . setMode ( READ_ONLY ) <EOL> event = self . makeDragEvent ( self . mouseEvent , name , target ) <EOL> widget . onBrowserEvent ( event ) <EOL> self . finalize ( event ) <EOL> return event <EOL> def initFeedbackImage ( self ) : <EOL> ds = self . dragDataStore <EOL> x = <NUM_LIT:0> <EOL> y = <NUM_LIT:0> <EOL> if ds . bitmap is not None : <EOL> if ds . hotspot_coordinate is not None : <EOL> offset = ds . hotspot_coordinate <EOL> x = offset [ <NUM_LIT:0> ] <EOL> y = offset [ <NUM_LIT:1> ] <EOL> self . setDragImage ( ds . bitmap , x , y ) <EOL> return <EOL> if self . dragDataStore . elements : <EOL> for element in self . dragDataStore . elements : <EOL> self . addFeedbackElement ( element ) <EOL> def onMouseMove ( self , sender , x , y ) : <EOL> event = DOM . eventGetCurrentEvent ( ) <EOL> self . mouseEvent = event <EOL> button = DOM . eventGetButton ( event ) <EOL> if not button == Event . BUTTON_LEFT : <EOL> return <EOL> x , y = eventCoordinates ( event ) <EOL> if self . dragging == DRAGGING_NO_MOVEMENT_YET : <EOL> self . origMouseX = x <EOL> self . origMouseY = y <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> fromElement = self . dragWidget . getElement ( ) <EOL> try : <EOL> draggable = fromElement . draggable <EOL> except : <EOL> draggable = False <EOL> if not draggable : <EOL> fromElement = findDraggable ( sender . getElement ( ) , <EOL> self . origMouseX , self . origMouseY ) <EOL> if fromElement is None : <EOL> self . dragging = NOT_DRAGGING <EOL> return <EOL> self . origTop = DOM . getAbsoluteTop ( fromElement ) <EOL> self . origLeft = DOM . getAbsoluteLeft ( fromElement ) <EOL> position_absolute = DOM . getStyleAttribute ( fromElement , <EOL> '<STR_LIT>' ) == '<STR_LIT>' <EOL> if position_absolute : <EOL> self . dragLeftOffset = ( self . origMouseX - <EOL> DOM . getAbsoluteLeft ( fromElement . offsetParent ) ) <EOL> self . dragTopOffset = ( self . origMouseY - <EOL> DOM . getAbsoluteTop ( fromElement . offsetParent ) ) <EOL> else : <EOL> self . dragLeftOffset = self . origMouseX - self . origLeft <EOL> self . dragTopOffset = self . origMouseY - self . origTop <EOL> self . dragDataStore . elements = [ fromElement ] <EOL> dragStartEvent = self . fireDNDEvent ( '<STR_LIT>' , None , <EOL> self . dragWidget ) <EOL> if not isCanceled ( dragStartEvent ) : <EOL> self . initFeedbackImage ( ) <EOL> RootPanel ( ) . add ( self . draggingImage ) <EOL> self . setDragImageLocation ( x , y ) <EOL> self . dragging = ACTIVELY_DRAGGING <EOL> GlassWidget . show ( self ) <EOL> elif self . dragging == ACTIVELY_DRAGGING : <EOL> try : <EOL> doc ( ) . selection . empty ( ) <EOL> except : <EOL> wnd ( ) . getSelection ( ) . removeAllRanges ( ) <EOL> self . setDragImageLocation ( x , y ) <EOL> if self . dragBusy or time . time ( ) - self . drag_time < <NUM_LIT> : <EOL> return <EOL> self . doDrag ( event , x , y ) <EOL> self . drag_time = time . time ( ) <EOL> def doDrag ( self , event , x , y ) : <EOL> self . dragBusy = True <EOL> drag_event = self . fireDNDEvent ( '<STR_LIT>' , None , self . dragWidget ) <EOL> if not isCanceled ( drag_event ) : <EOL> target = None <EOL> widget = None <EOL> for widget in self . dropTargets : <EOL> target = getElementUnderMouse ( widget , x , y ) <EOL> if target is not None : <EOL> break <EOL> if target : <EOL> drop_widget = widget <EOL> drop_element = target <EOL> if ( not self . currentTargetElement or <EOL> not DOM . compare ( drop_element , self . currentTargetElement ) ) : <EOL> enter_event = self . fireDNDEvent ( '<STR_LIT>' , drop_element , <EOL> drop_widget ) <EOL> if isCanceled ( enter_event ) : <EOL> self . currentTargetElement = drop_element <EOL> self . currentDropWidget = drop_widget <EOL> if self . currentTargetElement is not None : <EOL> over_event = self . fireDNDEvent ( '<STR_LIT>' , drop_element , <EOL> self . currentDropWidget ) <EOL> if isCanceled ( over_event ) : <EOL> self . updateDragOperation ( over_event ) <EOL> else : <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> self . draggingImage . updateCursor ( self . currentDragOperation ) <EOL> else : <EOL> self . currentTargetElement = None <EOL> else : <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> self . dragBusy = False <EOL> def onMouseDown ( self , sender , x , y ) : <EOL> self . dragWidget = sender <EOL> event = DOM . eventGetCurrentEvent ( ) <EOL> self . mouseEvent = event <EOL> button = DOM . eventGetButton ( event ) <EOL> if button != Event . BUTTON_LEFT : <EOL> return <EOL> self . dragging = DRAGGING_NO_MOVEMENT_YET <EOL> self . drag_time = time . time ( ) <EOL> self . dragDataStore = DragDataStore ( ) <EOL> def onMouseUp ( self , sender , x , y ) : <EOL> self . dragging = NOT_DRAGGING <EOL> if self . draggingImage : <EOL> GlassWidget . hide ( ) <EOL> if ( self . currentDragOperation == '<STR_LIT:none>' <EOL> or not self . currentTargetElement ) : <EOL> if self . currentTargetElement : <EOL> self . fireDNDEvent ( '<STR_LIT>' , self . currentTargetElement , <EOL> self . currentDropWidget ) <EOL> else : <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> self . returnDrag ( ) <EOL> else : <EOL> drop_event = self . fireDNDEvent ( '<STR_LIT>' , self . currentTargetElement , <EOL> self . currentDropWidget ) <EOL> if isCanceled ( drop_event ) : <EOL> self . currentDragOperation = drop_event . dataTransfer . dropEffect <EOL> else : <EOL> self . currentDragOperation = '<STR_LIT:none>' <EOL> self . zapDragImage ( ) <EOL> self . fireDNDEvent ( '<STR_LIT>' , None , self . dragWidget ) <EOL> def zapDragImage ( self ) : <EOL> RootPanel ( ) . remove ( self . draggingImage ) <EOL> self . draggingImage = None <EOL> def returnDrag ( self ) : <EOL> self . moveItemTo ( self . draggingImage , self . origLeft , self . origTop ) <EOL> def returnXY ( self , start , destination , count ) : <EOL> start_x , start_y = start <EOL> destination_x , destination_y = destination <EOL> diff_x = ( start_x - destination_x ) / count <EOL> diff_y = ( start_y - destination_y ) / count <EOL> while ( abs ( start_x - destination_x ) > <NUM_LIT:10> <EOL> or abs ( start_y - destination_y ) > <NUM_LIT:10> ) : <EOL> start_x -= diff_x <EOL> start_y -= diff_y <EOL> yield start_x , start_y <EOL> raise StopIteration <EOL> def onReturningWidget ( self , timer ) : <EOL> try : <EOL> next_loc = self . return_iterator . next ( ) <EOL> except StopIteration : <EOL> self . zapDragImage ( ) <EOL> return <EOL> x , y = next_loc <EOL> self . draggingImage . setStyleAttribute ( '<STR_LIT>' , str ( y ) ) <EOL> self . draggingImage . setStyleAttribute ( '<STR_LIT:left>' , str ( x ) ) <EOL> self . returnTimer . schedule ( <NUM_LIT:50> ) <EOL> def moveItemTo ( self , widget , x , y ) : <EOL> self . returnWidget = widget <EOL> returnWidgetDestination = x , y <EOL> widgetStart = widget . getAbsoluteLeft ( ) , widget . getAbsoluteTop ( ) <EOL> self . return_iterator = self . returnXY ( widgetStart , <EOL> returnWidgetDestination , <NUM_LIT:10> ) <EOL> self . returnTimer . schedule ( <NUM_LIT:50> ) <EOL> def onMouseEnter ( self , sender ) : <EOL> pass <EOL> def onMouseLeave ( self , sender ) : <EOL> if self . dragging == DRAGGING_NO_MOVEMENT_YET : <EOL> self . dragging = NOT_DRAGGING <EOL> def onMouseGlassEnter ( self , sender ) : <EOL> pass <EOL> def onMouseGlassLeave ( self , sender ) : <EOL> pass <EOL> dndHelper = None <EOL> def initDNDHelper ( ) : <EOL> global dndHelper <EOL> if dndHelper is None : <EOL> dndHelper = DNDHelper ( ) <EOL> initDNDHelper ( ) </s>
