enthought / traitsui
1
# -------------------------------------------------------------------------
2
#
3
#  Copyright (c) 2008, Enthought, Inc.
4
#  All rights reserved.
5
#
6
#  This software is provided without warranty under the terms of the BSD
7
#  license included in LICENSE.txt and may be redistributed only
8
#  under the conditions described in the aforementioned license.  The license
9
#  is also available online at http://www.enthought.com/licenses/BSD.txt
10
#
11
#  Thanks for using Enthought open source!
12
#
13
#  Author: David C. Morrill
14
#  Date:   02/29/2008
15
#
16
# -------------------------------------------------------------------------
17

18 4
"""  Defines adapter interfaces for use with the ListStrEditor.
19
"""
20

21 4
from traits.api import (
22
    Any,
23
    Bool,
24
    Enum,
25
    Event,
26
    HasPrivateTraits,
27
    Int,
28
    Interface,
29
    List,
30
    Str,
31
    on_trait_change,
32
    provides,
33
)
34 4
from .toolkit_traits import Color
35

36

37
# -------------------------------------------------------------------------
38
#  'IListStrAdapter' interface:
39
# -------------------------------------------------------------------------
40

41

42 4
class IListStrAdapter(Interface):
43

44
    #: The index of the current item being adapted.
45 4
    index = Int()
46

47
    #: Current item being adapted.
48 4
    item = Any()
49

50
    #: The current value (if any).
51 4
    value = Any()
52

53
    #: Does the adapter know how to handle the current *item* or not?
54 4
    accepts = Bool()
55

56
    #: Does the value of *accepts* depend only upon the type of *item*?
57 4
    is_cacheable = Bool()
58

59

60
# -------------------------------------------------------------------------
61
#  'AnIListStrAdapter' class:
62
# -------------------------------------------------------------------------
63

64

65 4
@provides(IListStrAdapter)
66 4
class AnIListStrAdapter(HasPrivateTraits):
67

68
    # Implementation of the IListStrAdapter Interface ------------------------
69

70
    #: The index of the current item being adapted.
71 4
    index = Int()
72

73
    #: Current item being adapted.
74 4
    item = Any()
75

76
    #: The current value (if any).
77 4
    value = Any()
78

79
    #: Does the adapter know how to handle the current *item* or not?
80 4
    accepts = Bool(True)
81

82
    #: Does the value of *accepts* depend only upon the type of *item*?
83 4
    is_cacheable = Bool(True)
84

85

86
# -------------------------------------------------------------------------
87
#  'ListStrAdapter' class:
88
# -------------------------------------------------------------------------
89

90

91 4
class ListStrAdapter(HasPrivateTraits):
92
    """ The base class for adapting list items to values that can be edited
93
        by a ListStrEditor.
94
    """
95

96
    # Trait Definitions ------------------------------------------------------
97

98
    #: Specifies the default value for a new list item.
99 4
    default_value = Any("")
100

101
    #: Specifies the default text for a new list item.
102 4
    default_text = Str()
103

104
    #: The default text color for even list items.
105 4
    even_text_color = Color(None, update=True)
106

107
    #: The default text color for odd list items.
108 4
    odd_text_color = Color(None, update=True)
109

110
    #: The default text color for list items.
111 4
    text_color = Color(None, update=True)
112

113
    #: The default background color for even list items.
114 4
    even_bg_color = Color(None, update=True)
115

116
    #: The default background color for odd list items.
117 4
    odd_bg_color = Color(None, update=True)
118

119
    #: The default background color for list items.
120 4
    bg_color = Color(None, update=True)
121

122
    #: The name of the default image to use for list items.
123 4
    image = Str(None, update=True)
124

125
    #: Can the text value of each list item be edited.
126 4
    can_edit = Bool(True)
127

128
    #: Specifies where a dropped item should be placed in the list relative to
129
    #: the item it is dropped on.
130 4
    dropped = Enum("after", "before")
131

132
    #: The index of the current item being adapter.
133 4
    index = Int()
134

135
    #: The current item being adapted.
136 4
    item = Any()
137

138
    #: The current value (if any).
139 4
    value = Any()
140

141
    #: List of optional delegated adapters.
142 4
    adapters = List(IListStrAdapter, update=True)
143

144
    # -- Private Trait Definitions --------------------------------------------
145

146
    #: Cache of attribute handlers.
147 4
    cache = Any({})
148

149
    #: Event fired when the cache is flushed.
150 4
    cache_flushed = Event(update=True)
151

152
    # -- Adapter methods that are sensitive to item type ----------------------
153

154 4
    def get_can_edit(self, object, trait, index):
155
        """ Returns whether the user can edit a specified *object.trait[index]*
156
            list item. A True result indicates the value can be edited, while
157
            a False result indicates that it cannot be edited.
158
        """
159 4
        return self._result_for("get_can_edit", object, trait, index)
160

161 4
    def get_drag(self, object, trait, index):
162
        """ Returns the 'drag' value for a specified *object.trait[index]*
163
            list item. A result of *None* means that the item cannot be
164
            dragged.
165
        """
166 4
        return self._result_for("get_drag", object, trait, index)
167

168 4
    def get_can_drop(self, object, trait, index, value):
169
        """ Returns whether the specified *value* can be dropped on the
170
            specified *object.trait[index]* list item. A value of **True**
171
            means the *value* can be dropped; and a value of **False**
172
            indicates that it cannot be dropped.
173
        """
174 0
        return self._result_for("get_can_drop", object, trait, index, value)
175

176 4
    def get_dropped(self, object, trait, index, value):
177
        """ Returns how to handle a specified *value* being dropped on a
178
            specified *object.trait[index]* list item. The possible return
179
            values are:
180

181
            'before'
182
                Insert the specified *value* before the dropped on item.
183
            'after'
184
                Insert the specified *value* after the dropped on item.
185
        """
186 0
        return self._result_for("get_dropped", object, trait, index, value)
187

188 4
    def get_text_color(self, object, trait, index):
189
        """ Returns the text color for a specified *object.trait[index]* list
190
            item. A result of None means use the default list item text color.
191
        """
192 4
        return self._result_for("get_text_color", object, trait, index)
193

194 4
    def get_bg_color(self, object, trait, index):
195
        """ Returns the background color for a specified *object.trait[index]*
196
            list item. A result of None means use the default list item
197
            background color.
198
        """
199 4
        return self._result_for("get_bg_color", object, trait, index)
200

201 4
    def get_image(self, object, trait, index):
202
        """ Returns the name of the image to use for a specified
203
            *object.trait[index]* list item. A result of None means no image
204
            should be used. Otherwise, the result should either be the name of
205
            the image, or an ImageResource item specifying the image to use.
206
        """
207 4
        return self._result_for("get_image", object, trait, index)
208

209 4
    def get_item(self, object, trait, index):
210
        """ Returns the value of the *object.trait[index]* list item.
211
        """
212 4
        return self._result_for("get_item", object, trait, index)
213

214 4
    def get_text(self, object, trait, index):
215
        """ Returns the text to display for a specified *object.trait[index]*
216
            list item.
217
        """
218 4
        return self._result_for("get_text", object, trait, index)
219

220
    # -- Adapter methods that are not sensitive to item type ------------------
221

222 4
    def len(self, object, trait):
223
        """ Returns the number of items in the specified *object.trait* list.
224
        """
225
        # Sometimes, during shutdown, the object has been set to None.
226 4
        if object is None:
227 4
            return 0
228
        else:
229 4
            return len(getattr(object, trait))
230

231 4
    def get_default_value(self, object, trait):
232
        """ Returns a new default value for the specified *object.trait* list.
233
        """
234 0
        return self.default_value
235

236 4
    def get_default_text(self, object, trait):
237
        """ Returns the default text for the specified *object.trait* list.
238
        """
239 4
        return self.default_text
240

241 4
    def get_default_image(self, object, trait):
242
        """ Returns the default image for the specified *object.trait* list.
243
        """
244 4
        return self.image
245

246 4
    def get_default_bg_color(self, object, trait):
247
        """ Returns the default background color for the specified
248
            *object.trait* list.
249
        """
250 4
        return self._get_bg_color()
251

252 4
    def get_default_text_color(self, object, trait):
253
        """ Returns the default text color for the specified *object.trait*
254
            list.
255
        """
256 4
        return self._get_text_color()
257

258 4
    def set_text(self, object, trait, index, text):
259
        """ Sets the text for a specified *object.trait[index]* list item to
260
            *text*.
261
        """
262 0
        getattr(object, trait)[index] = text
263

264 4
    def delete(self, object, trait, index):
265
        """ Deletes the specified *object.trait[index]* list item.
266
        """
267 0
        del getattr(object, trait)[index]
268

269 4
    def insert(self, object, trait, index, value):
270
        """ Inserts a new value at the specified *object.trait[index]* list
271
            index.
272
        """
273 0
        getattr(object, trait)[index:index] = [value]
274

275
    # -- Private Adapter Implementation Methods -------------------------------
276

277 4
    def _get_can_edit(self):
278 4
        return self.can_edit
279

280 4
    def _get_drag(self):
281 4
        return str(self.item)
282

283 4
    def _get_can_drop(self):
284 0
        return isinstance(self.value, str)
285

286 4
    def _get_dropped(self):
287 0
        return self.dropped
288

289 4
    def _get_text_color(self):
290 4
        if (self.index % 2) == 0:
291 4
            return self.even_text_color_ or self.text_color_
292

293 4
        return self.odd_text_color or self.text_color_
294

295 4
    def _get_bg_color(self):
296 4
        if (self.index % 2) == 0:
297 4
            return self.even_bg_color_ or self.bg_color_
298

299 4
        return self.odd_bg_color or self.bg_color_
300

301 4
    def _get_image(self):
302 4
        return self.image
303

304 4
    def _get_item(self):
305 4
        return self.item
306

307 4
    def _get_text(self):
308 4
        return str(self.item)
309

310
    # -- Private Methods ------------------------------------------------------
311

312 4
    def _result_for(self, name, object, trait, index, value=None):
313
        """ Returns/Sets the value of the specified *name* attribute for the
314
            specified *object.trait[index]* list item.
315
        """
316 4
        self.index = index
317 4
        self.value = value
318 4
        items = getattr(object, trait)
319 4
        if index >= len(items):
320 4
            self.item = item = None
321
        else:
322 4
            self.item = item = items[index]
323

324 4
        item_class = item.__class__
325 4
        key = "%s:%s" % (item_class.__name__, name)
326 4
        handler = self.cache.get(key)
327 4
        if handler is not None:
328 4
            return handler()
329

330 4
        trait_name = name[4:]
331

332 4
        for adapter in self.adapters:
333 0
            adapter.index = index
334 0
            adapter.item = item
335 0
            adapter.value = value
336 4
            if adapter.accepts and (adapter.trait(trait_name) is not None):
337 4
                handler = lambda: getattr(
338
                    adapter.trait_set(
339
                        index=self.index, item=self.item, value=self.value
340
                    ),
341
                    trait_name,
342
                )
343

344 4
                if adapter.is_cacheable:
345 0
                    break
346

347 0
                return handler()
348
        else:
349 4
            for klass in item_class.__mro__:
350 4
                cname = "%s_%s" % (klass.__name__, trait_name)
351 4
                if self.trait(cname) is not None:
352 4
                    handler = lambda: getattr(self, cname)
353 0
                    break
354
            else:
355 4
                handler = getattr(self, "_" + name)
356

357 4
        self.cache[key] = handler
358 4
        return handler()
359

360 4
    @on_trait_change("adapters.+update")
361
    def _flush_cache(self):
362
        """ Flushes the cache when any trait on any adapter changes.
363
        """
364 0
        self.cache = {}
365 0
        self.cache_flushed = True

Read our documentation on viewing source code .

Loading