File: drag_drop_feature.py

package info (click to toggle)
enthought-traits-ui 2.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 15,204 kB
  • ctags: 9,623
  • sloc: python: 45,547; sh: 32; makefile: 19
file content (217 lines) | stat: -rw-r--r-- 8,602 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#-------------------------------------------------------------------------------
#  
#  Adds a 'drag and drop' feature to DockWindow which exposes traits on the 
#  object associated with a DockControl as draggable or droppable items. If the
#  object contains one or more traits with 'draggable' metadata, then the value
#  of those traits will be draggable. If the object contains one or more traits
#  with 'droppable' metadata, then each trait that will accept a specified item
#  will receive that item when it is dropped on the feature.
#  
#  Written by: David C. Morrill
#  
#  Date: 07/04/2006
#  
#  (c) Copyright 2006 by David C. Morrill
#  
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#  Imports:
#-------------------------------------------------------------------------------

from enthought.traits.api \
    import HasStrictTraits, HasTraits, List, Str
    
from enthought.pyface.dock.api \
    import DockWindowFeature
    
from enthought.pyface.image_resource \
    import ImageResource
    
#-------------------------------------------------------------------------------
#  Constants:
#-------------------------------------------------------------------------------

# Feature settings:
settings = (
    ImageResource( 'drag_feature' ),
    ImageResource( 'drop_feature' ),
    ImageResource( 'dragdrop_feature' )
)
    
#-------------------------------------------------------------------------------
#  'MultiDragDrop' class:
#-------------------------------------------------------------------------------

class MultiDragDrop ( HasStrictTraits ):
    
    #---------------------------------------------------------------------------
    #  Trait definitions:  
    #---------------------------------------------------------------------------

    # LIst of object being dragged:
    objects = List

#-------------------------------------------------------------------------------
#  'DragDropFeature' class:
#-------------------------------------------------------------------------------

class DragDropFeature ( DockWindowFeature ):
    
    #---------------------------------------------------------------------------
    #  Class variables:  
    #---------------------------------------------------------------------------

    # The user interface name of the feature:
    feature_name = 'Drag and Drop'
    
    #---------------------------------------------------------------------------
    #  Trait definitions:  
    #---------------------------------------------------------------------------

    # The names of the object traits to drag from:
    drag_traits = List( Str )
    
    # The names of the object traits that can be dropped on:
    drop_traits = List( Str )
    
    #---------------------------------------------------------------------------
    #  Returns the object to be dragged when the user drags feature image:
    #---------------------------------------------------------------------------
    
    def drag ( self ):
        """ Returns the object to be dragged when the user drags feature image.
        """
        item = self.dock_control.object
        n    = len( self.drag_traits )
        
        if n == 1:
            return getattr( item, self.drag_traits[0], None )
            
        if n > 1:
            objects = []
            for trait in self.drag_traits:
                object = getattr( item, trait, None )
                if object is not None:
                    objects.append( object )
            if len( objects ) == 1:
                return objects[0]
            if len( objects ) > 1:
                return MultiDragDrop( objects = objects )
            
        return None
        
    #---------------------------------------------------------------------------
    #  Handles the user dropping a specified object on the feature image:  
    #---------------------------------------------------------------------------

    def drop ( self, object ):
        """ Handles the user dropping a specified object on the feature image.
        """
        item        = self.dock_control.object
        drop_traits = self.drop_traits
            
        if isinstance( object, MultiDragDrop ):
            for drag in object.objects:
                 for drop_trait in drop_traits:
                     try:
                         setattr( item, drop_trait, drag )
                     except:
                         pass
        else:
             for drop_trait in drop_traits:
                 try:
                     setattr( item, drop_trait, object )
                 except:
                     pass
        
    #---------------------------------------------------------------------------
    #  Returns whether a specified object can be dropped on the feature image:  
    #---------------------------------------------------------------------------
 
    def can_drop ( self, object ):
        """ Returns whether a specified object can be dropped on the feature 
            image.
        """
        item        = self.dock_control.object
        drop_traits = self.drop_traits
        
        if isinstance( object, MultiDragDrop ):
            for drag in object.objects:
                for drop_trait in drop_traits:
                    try:
                        item.base_trait( drop_trait ).validate( item,
                                                              drop_trait, drag )
                        return True
                    except:
                        pass
        else:
            for drop_trait in drop_traits:
                try:
                    item.base_trait( drop_trait ).validate( item, drop_trait, 
                                                            object )
                    return True
                except:
                    pass
            
        return False

#-- Overidable Class Methods ---------------------------------------------------

    #---------------------------------------------------------------------------
    #  Returns a feature object for use with the specified DockControl (or None 
    #  if the feature does not apply to the DockControl object):   
    #---------------------------------------------------------------------------

    def feature_for ( cls, dock_control ):
        """ Returns a feature object for use with the specified DockControl (or
            None if the feature does not apply to the DockControl object).
        """
        from enthought.pyface.dock.features.api import is_not_none
        
        object = dock_control.object
        if isinstance( object, HasTraits ):
            drag_tooltip = drop_tooltip = ''
            drag_traits  = []
            drop_traits  = []
            
            traits = object.traits( draggable = is_not_none )
            if len( traits ) >= 1:
                drag_traits = traits.keys()
                drag_traits.sort()
                drag_tooltips = [ trait.draggable for trait in traits.values()
                                  if isinstance( trait.draggable, str ) ]
                if len( drag_tooltips ) > 0:
                    drag_tooltip = '\n'.join( drag_tooltips )
                if drag_tooltip == '':
                    drag_tooltip = 'Drag this item.'
                drag_tooltip += '\n'
                
            traits = object.traits( droppable = is_not_none )
            if len( traits ) >= 1:
                drop_traits = traits.keys()
                drop_traits.sort()
                drop_tooltips = [ trait.droppable for trait in traits.values()
                                  if isinstance( trait.droppable, str ) ]
                if len( drop_tooltips ) > 0:
                    drop_tooltip = '\n'.join( drop_tooltips )
                if drop_tooltip == '':
                    drop_tooltip = 'Drop an item here.'
                
            if (drag_tooltip != '') or (drop_tooltip != ''):
                i = 1
                if drag_tooltip != '':
                    i = 0
                    if drop_tooltip != '':
                        i = 2
            
                return cls( dock_control = dock_control,
                            image        = settings[i],
                            tooltip      = (drag_tooltip+drop_tooltip).strip(),
                            drag_traits  = drag_traits,
                            drop_traits  = drop_traits )
            
        return None
        
    feature_for = classmethod( feature_for )