~ubuntu-branches/ubuntu/trusty/python-traitsui/trusty

« back to all changes in this revision

Viewing changes to traitsui/group.py

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2011-07-09 13:57:39 UTC
  • Revision ID: james.westby@ubuntu.com-20110709135739-x5u20q86huissmn1
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#------------------------------------------------------------------------------
 
2
#
 
3
#  Copyright (c) 2005, Enthought, Inc.
 
4
#  All rights reserved.
 
5
#
 
6
#  This software is provided without warranty under the terms of the BSD
 
7
#  license included in enthought/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:   10/07/2004
 
15
#
 
16
#------------------------------------------------------------------------------
 
17
 
 
18
""" Defines the Group class used to represent a group of items used in a
 
19
    Traits-based user interface.
 
20
"""
 
21
 
 
22
#-------------------------------------------------------------------------------
 
23
#  Imports:
 
24
#-------------------------------------------------------------------------------
 
25
 
 
26
from __future__ import absolute_import
 
27
 
 
28
from string \
 
29
    import find
 
30
 
 
31
from traits.api import (Bool, Delegate, Float, Instance, List, Property, Range,
 
32
    ReadOnly, Str, TraitError, cached_property)
 
33
 
 
34
from traits.trait_base import enumerate
 
35
 
 
36
from .view_element import ViewSubElement
 
37
 
 
38
from .item import Item
 
39
 
 
40
from .include import Include
 
41
 
 
42
from .ui_traits import SequenceTypes, ATheme, ContainerDelegate, Orientation, Layout
 
43
 
 
44
from .dock_window_theme import dock_window_theme, DockWindowTheme
 
45
 
 
46
#-------------------------------------------------------------------------------
 
47
#  Trait definitions:
 
48
#-------------------------------------------------------------------------------
 
49
 
 
50
# Delegate trait to the object being "shadowed"
 
51
ShadowDelegate = Delegate( 'shadow' )
 
52
 
 
53
# Amount of padding to add around item
 
54
Padding = Range( 0, 15, desc = 'amount of padding to add around each item' )
 
55
 
 
56
#-------------------------------------------------------------------------------
 
57
#  'Group' class:
 
58
#-------------------------------------------------------------------------------
 
59
 
 
60
class Group ( ViewSubElement ):
 
61
    """ Represents a grouping of items in a user interface view.
 
62
    """
 
63
 
 
64
    #---------------------------------------------------------------------------
 
65
    # Trait definitions:
 
66
    #---------------------------------------------------------------------------
 
67
 
 
68
    # A list of Group, Item, and Include objects in this group.
 
69
    content = List( ViewSubElement )
 
70
 
 
71
    # A unique identifier for the group.
 
72
    id = Str
 
73
 
 
74
    # User interface label for the group. How the label is displayed depends
 
75
    # on the **show_border** attribute, and on the **layout** attribute of
 
76
    # the group's parent group or view.
 
77
    label = Str
 
78
 
 
79
    # Default context object for group items.
 
80
    object = ContainerDelegate
 
81
 
 
82
    # Default editor style of items in the group.
 
83
    style = ContainerDelegate
 
84
 
 
85
    # Default docking style of items in group.
 
86
    dock = ContainerDelegate
 
87
 
 
88
    # Default image to display on notebook tabs.
 
89
    image = ContainerDelegate
 
90
 
 
91
    # The theme to use for a DockWindow:
 
92
    dock_theme = Instance( DockWindowTheme, allow_none = False )
 
93
 
 
94
    # The theme to use for the group itself:
 
95
    group_theme = ATheme
 
96
 
 
97
    # The theme to use for items contained in the group:
 
98
    item_theme = ContainerDelegate
 
99
 
 
100
    # The theme to use for the labels of items contained in the group:
 
101
    label_theme = ContainerDelegate
 
102
 
 
103
    # Category of elements dragged from view.
 
104
    export = ContainerDelegate
 
105
 
 
106
    # Spatial orientation of the group's elements. Can be 'vertical' (default)
 
107
    # or 'horizontal'.
 
108
    orientation = Orientation
 
109
 
 
110
    # Layout style of the group, which can be one of the following:
 
111
    #
 
112
    # * 'normal' (default): Sub-groups are displayed sequentially in a single
 
113
    #   panel.
 
114
    # * 'flow': Sub-groups are displayed sequentially, and then "wrap" when
 
115
    #   they exceed the available space in the **orientation** direction.
 
116
    # * 'split': Sub-groups are displayed in a single panel, separated by
 
117
    #   "splitter bars", which the user can drag to adjust the amount of space
 
118
    #   for each sub-group.
 
119
    # * 'tabbed': Each sub-group appears on a separate tab, labeled with the
 
120
    #   sub-group's *label* text, if any.
 
121
    #
 
122
    # This attribute is ignored for groups that contain only items, or contain
 
123
    # only one sub-group.
 
124
    layout = Layout
 
125
 
 
126
    # Should the group be scrollable along the direction of orientation?
 
127
    scrollable = Bool( False )
 
128
 
 
129
    # The number of columns in the group
 
130
    columns = Range( 1, 50 )
 
131
 
 
132
    # Should a border be drawn around group? If set to True, the **label** text
 
133
    # is embedded in the border. If set to False, the label appears as a banner
 
134
    # above the elements of the group.
 
135
    show_border = Bool( False )
 
136
 
 
137
    # Should labels be added to items in group? Only items that are directly
 
138
    # contained in the group are affected. That is, if the group contains
 
139
    # a sub-group, the display of labels in the sub-group is not affected by
 
140
    # the attribute on this group.
 
141
    show_labels = Bool( True )
 
142
 
 
143
    # Should labels be shown to the left of items (True) or the right (False)?
 
144
    # Only items that are directly contained in the group are affected. That is,
 
145
    # if the group contains a sub-group, the display of labels in the sub-group
 
146
    # is not affected by the attribute in this group. If **show_labels** is
 
147
    # False, this attribute is irrelevant.
 
148
    show_left = Bool( True )
 
149
 
 
150
    # Is this group the tab that is initially selected? If True, the group's
 
151
    # tab is displayed when the view is opened. If the **layout** of the group's
 
152
    # parent is not 'tabbed', this attribute is ignored.
 
153
    selected = Bool( False )
 
154
 
 
155
    # Should the group use extra space along its parent group's layout
 
156
    # orientation?
 
157
    springy = Bool( False )
 
158
 
 
159
    # Optional help text (for top-level group). This help text appears in the
 
160
    # View-level help window (created by the default help handler), for any
 
161
    # View that contains *only* this group. Group-level help is ignored for
 
162
    # nested groups and multiple top-level groups
 
163
    help = Str
 
164
 
 
165
    # Pre-condition for including the group in the display. If the expression
 
166
    # evaluates to False, the group is not defined in the display. Conditions
 
167
    # for **defined_when** are evaluated only once, when the display is first
 
168
    # constructed. Use this attribute for conditions based on attributes that
 
169
    # vary from object to object, but that do not change over time.
 
170
    defined_when = Str
 
171
 
 
172
    # Pre-condition for showing the group. If the expression evaluates to False,
 
173
    # the group and its items are not visible (and they disappear if they were
 
174
    # previously visible). If the value evaluates to True, the group and items
 
175
    # become visible. All **visible_when** conditions are checked each time
 
176
    # that any trait value is edited in the display. Therefore, you can use
 
177
    # **visible_when** conditions to hide or show groups in response to user
 
178
    # input.
 
179
    visible_when = Str
 
180
 
 
181
    # Pre-condition for enabling the group. If the expression evaluates to False,
 
182
    # the group is disabled, that is, none of the widgets accept input. All
 
183
    # **enabled_when** conditions are checked each time that any trait value
 
184
    # is edited in the display. Therefore, you can use **enabled_when**
 
185
    # conditions to enable or disable groups in response to user input.
 
186
    enabled_when = Str
 
187
 
 
188
    # Amount of padding (in pixels) to add around each item in the group. The
 
189
    # value must be an integer between 0 and 15. (Unlike the Item class, the
 
190
    # Group class does not support negative padding.) The padding for any
 
191
    # individual widget is the sum of the padding for its Group, the padding
 
192
    # for its Item, and the default spacing determined by the toolkit.
 
193
    padding = Padding
 
194
 
 
195
    # Requested width of the group (calculated from widths of contents)
 
196
    width = Property( Float, depends_on='content' )
 
197
 
 
198
    # Requested height of the group (calculated from heights of contents)
 
199
    height = Property( Float, depends_on='content' )
 
200
 
 
201
    #---------------------------------------------------------------------------
 
202
    #  Initializes the object:
 
203
    #---------------------------------------------------------------------------
 
204
 
 
205
    def __init__ ( self, *values, **traits ):
 
206
        """ Initializes the group object.
 
207
        """
 
208
        super( ViewSubElement, self ).__init__( **traits )
 
209
 
 
210
        content = self.content
 
211
 
 
212
        # Process any embedded Group options first:
 
213
        for value in values:
 
214
            if (isinstance(value, basestring)) and (value[0:1] in '-|'):
 
215
                # Parse Group trait options if specified as a string:
 
216
                self._parse( value )
 
217
 
 
218
        # Process all of the data passed to the constructor:
 
219
        for value in values:
 
220
            if isinstance( value, ViewSubElement ):
 
221
                content.append( value )
 
222
            elif type( value ) in SequenceTypes:
 
223
                # Map (...) or [...] to a Group():
 
224
                content.append( Group( *value ) )
 
225
            elif isinstance( value, basestring ):
 
226
                if value[0:1] in '-|':
 
227
                    # We've already parsed Group trait options above:
 
228
                    pass
 
229
                elif (value[:1] == '<') and (value[-1:] == '>'):
 
230
                    # Convert string to an Include value:
 
231
                    content.append( Include( value[1:-1].strip() ) )
 
232
                else:
 
233
                    # Else let the Item class try to make sense of it:
 
234
                    content.append( Item( value ) )
 
235
            else:
 
236
                raise TypeError, "Unrecognized argument type: %s" % value
 
237
 
 
238
        # Make sure this Group is the container for all its children:
 
239
        self.set_container()
 
240
 
 
241
    #-- Default Trait Values ---------------------------------------------------
 
242
 
 
243
    def _dock_theme_default ( self ):
 
244
        return dock_window_theme()
 
245
 
 
246
    #---------------------------------------------------------------------------
 
247
    #  Gets the label to use for a specified Group in a specified UI:
 
248
    #---------------------------------------------------------------------------
 
249
 
 
250
    def get_label ( self, ui ):
 
251
        """ Gets the label to use this group.
 
252
        """
 
253
        if self.label != '':
 
254
            return self.label
 
255
 
 
256
        return 'Group'
 
257
 
 
258
    #---------------------------------------------------------------------------
 
259
    #  Returns whether or not the object is replacable by an Include object:
 
260
    #---------------------------------------------------------------------------
 
261
 
 
262
    def is_includable ( self ):
 
263
        """ Returns a Boolean value indicating whether the object is replacable
 
264
        by an Include object.
 
265
        """
 
266
        return (self.id != '')
 
267
 
 
268
    #---------------------------------------------------------------------------
 
269
    #  Replaces any items which have an 'id' with an Include object with the
 
270
    #  same 'id', and puts the object with the 'id' into the specified
 
271
    #  ViewElements object:
 
272
    #---------------------------------------------------------------------------
 
273
 
 
274
    def replace_include ( self, view_elements ):
 
275
        """ Replaces any items that have an **id** attribute with an Include
 
276
        object with the same ID value, and puts the object with the ID
 
277
        into the specified ViewElements object.
 
278
 
 
279
        Parameters
 
280
        ----------
 
281
        view_elements : ViewElements object
 
282
            A set of Group, Item, and Include objects
 
283
        """
 
284
        for i, item in enumerate( self.content ):
 
285
            if item.is_includable():
 
286
                id = item.id
 
287
                if id in view_elements.content:
 
288
                    raise TraitError, \
 
289
                          "Duplicate definition for view element '%s'" % id
 
290
                self.content[ i ] = Include( id )
 
291
                view_elements.content[ id ] = item
 
292
            item.replace_include( view_elements )
 
293
 
 
294
    #---------------------------------------------------------------------------
 
295
    #  Returns a ShadowGroup for the Group which recursively resolves all
 
296
    #  imbedded Include objects and which replaces all imbedded Group objects
 
297
    #  with a corresponding ShadowGroup:
 
298
    #---------------------------------------------------------------------------
 
299
 
 
300
    def get_shadow ( self, ui ):
 
301
        """ Returns a ShadowGroup object for the current Group object, which
 
302
        recursively resolves all embedded Include objects and which replaces
 
303
        each embedded Group object with a corresponding ShadowGroup.
 
304
        """
 
305
        content = []
 
306
        groups  = 0
 
307
        level   = ui.push_level()
 
308
        for value in self.content:
 
309
            # Recursively replace Include objects:
 
310
            while isinstance( value, Include ):
 
311
                value = ui.find( value )
 
312
 
 
313
            # Convert Group objects to ShadowGroup objects, but include Item
 
314
            # objects as is (ignore any 'None' values caused by a failed
 
315
            # Include):
 
316
            if isinstance( value, Group ):
 
317
                if self._defined_when( ui, value ):
 
318
                    content.append( value.get_shadow( ui ) )
 
319
                    groups += 1
 
320
            elif isinstance( value, Item ):
 
321
                if self._defined_when( ui, value ):
 
322
                    content.append( value )
 
323
 
 
324
            ui.pop_level( level )
 
325
 
 
326
        # Return the ShadowGroup:
 
327
        return ShadowGroup( shadow = self, content = content, groups = groups )
 
328
 
 
329
    #---------------------------------------------------------------------------
 
330
    #  Sets the correct container for the content:
 
331
    #---------------------------------------------------------------------------
 
332
 
 
333
    def set_container ( self ):
 
334
        """ Sets the correct container for the content.
 
335
        """
 
336
        for item in self.content:
 
337
            item.container = self
 
338
 
 
339
    #---------------------------------------------------------------------------
 
340
    #  Returns whether the object should be defined in the user interface:
 
341
    #---------------------------------------------------------------------------
 
342
 
 
343
    def _defined_when ( self, ui, value ):
 
344
        """ Should the object be defined in the user interface?
 
345
        """
 
346
        if value.defined_when == '':
 
347
            return True
 
348
        return ui.eval_when( value.defined_when )
 
349
 
 
350
    #---------------------------------------------------------------------------
 
351
    #  Parses Group options specified as a string:
 
352
    #---------------------------------------------------------------------------
 
353
 
 
354
    def _parse ( self, value ):
 
355
        """ Parses Group options specified as a string.
 
356
        """
 
357
        # Override the defaults, since we only allow 'True' values to be
 
358
        # specified:
 
359
        self.show_border = self.show_labels = self.show_left = False
 
360
 
 
361
        # Parse all of the single or multi-character options:
 
362
        value, empty = self._parse_label( value )
 
363
        value = self._parse_style( value )
 
364
        value = self._option( value, '-', 'orientation', 'horizontal' )
 
365
        value = self._option( value, '|', 'orientation', 'vertical' )
 
366
        value = self._option( value, '=', 'layout',      'split' )
 
367
        value = self._option( value, '^', 'layout',      'tabbed' )
 
368
        value = self._option( value, '>', 'show_labels',  True )
 
369
        value = self._option( value, '<', 'show_left',    True )
 
370
        value = self._option( value, '!', 'selected',     True )
 
371
 
 
372
        show_labels      = not (self.show_labels and self.show_left)
 
373
        self.show_left   = not self.show_labels
 
374
        self.show_labels = show_labels
 
375
 
 
376
        # Parse all of the punctuation based sub-string options:
 
377
        value = self._split( 'id', value, ':', find,  0, 1 )
 
378
        if value != '':
 
379
            self.object = value
 
380
 
 
381
    #---------------------------------------------------------------------------
 
382
    #  Handles a label being found in the string definition:
 
383
    #---------------------------------------------------------------------------
 
384
 
 
385
    def _parsed_label ( self ):
 
386
        """ Handles a label being found in the string definition.
 
387
        """
 
388
        self.show_border = True
 
389
 
 
390
    #---------------------------------------------------------------------------
 
391
    #  Returns a 'pretty print' version of the Group:
 
392
    #---------------------------------------------------------------------------
 
393
 
 
394
    def __repr__ ( self ):
 
395
        """ Returns a "pretty print" version of the Group.
 
396
        """
 
397
        result  = []
 
398
        items   = ',\n'.join( [ item.__repr__() for item in self.content ] )
 
399
        if len( items ) > 0:
 
400
            result.append( items )
 
401
 
 
402
        options = self._repr_options( 'orientation', 'show_border',
 
403
                      'show_labels', 'show_left', 'selected', 'id', 'object',
 
404
                      'label', 'style', 'layout' )
 
405
        if options is not None:
 
406
            result.append( options )
 
407
 
 
408
        content = ',\n'.join( result )
 
409
        if len( content ) == 0:
 
410
            return self.__class__.__name__ + '()'
 
411
 
 
412
        return '%s(\n%s\n)' % (
 
413
               self.__class__.__name__, self._indent( content ) )
 
414
 
 
415
    #---------------------------------------------------------------------------
 
416
    #  Property getters/setters for width/height attributes
 
417
    #---------------------------------------------------------------------------
 
418
 
 
419
    @cached_property
 
420
    def _get_width ( self ):
 
421
        """ Returns the requested width of the Group.
 
422
        """
 
423
        width = 0.0
 
424
        for item in self.content:
 
425
            if item.width >= 1:
 
426
                if self.orientation == 'horizontal':
 
427
                    width += item.width
 
428
                elif self.orientation == 'vertical':
 
429
                    width = max( width, item.width )
 
430
 
 
431
        if width == 0:
 
432
            width = -1.0
 
433
 
 
434
        return width
 
435
 
 
436
    @cached_property
 
437
    def _get_height ( self ):
 
438
        """ Returns the requested height of the Group.
 
439
        """
 
440
        height = 0.0
 
441
        for item in self.content:
 
442
            if item.height >= 1:
 
443
                if self.orientation == 'horizontal':
 
444
                    height = max( height, item.height )
 
445
                elif self.orientation == 'vertical':
 
446
                    height += item.height
 
447
 
 
448
        if height == 0:
 
449
            height = -1.0
 
450
 
 
451
        return height
 
452
 
 
453
#-------------------------------------------------------------------------------
 
454
#  'HGroup' class:
 
455
#-------------------------------------------------------------------------------
 
456
 
 
457
class HGroup ( Group ):
 
458
    """ A group whose items are laid out horizontally.
 
459
    """
 
460
 
 
461
    #---------------------------------------------------------------------------
 
462
    #  Trait definitions:
 
463
    #---------------------------------------------------------------------------
 
464
 
 
465
    # Override standard Group trait defaults to give it horizontal group
 
466
    # behavior:
 
467
    orientation = 'horizontal'
 
468
 
 
469
#-------------------------------------------------------------------------------
 
470
#  'VGroup' class:
 
471
#-------------------------------------------------------------------------------
 
472
 
 
473
class VGroup ( Group ):
 
474
    """ A group whose items are laid out vertically.
 
475
    """
 
476
 
 
477
    #---------------------------------------------------------------------------
 
478
    #  Trait definitions:
 
479
    #---------------------------------------------------------------------------
 
480
 
 
481
    # Override standard Group trait defaults to give it vertical group behavior:
 
482
    orientation = 'vertical'
 
483
 
 
484
#-------------------------------------------------------------------------------
 
485
#  'VGrid' class:
 
486
#-------------------------------------------------------------------------------
 
487
 
 
488
class VGrid ( VGroup ):
 
489
    """ A group whose items are laid out in 2 columns.
 
490
    """
 
491
 
 
492
    #---------------------------------------------------------------------------
 
493
    #  Trait definitions:
 
494
    #---------------------------------------------------------------------------
 
495
 
 
496
    # Override standard Group trait defaults to give it grid behavior:
 
497
    columns = 2
 
498
 
 
499
#-------------------------------------------------------------------------------
 
500
#  'HFlow' class:
 
501
#-------------------------------------------------------------------------------
 
502
 
 
503
class HFlow ( HGroup ):
 
504
    """ A group in which items are laid out horizontally, and "wrap" when
 
505
    they exceed the available horizontal space..
 
506
    """
 
507
 
 
508
    #---------------------------------------------------------------------------
 
509
    #  Trait definitions:
 
510
    #---------------------------------------------------------------------------
 
511
 
 
512
    # Override standard Group trait defaults to give it horizontal flow
 
513
    # behavior:
 
514
    layout      = 'flow'
 
515
    show_labels = False
 
516
 
 
517
#-------------------------------------------------------------------------------
 
518
#  'VFlow' class:
 
519
#-------------------------------------------------------------------------------
 
520
 
 
521
class VFlow ( VGroup ):
 
522
    """ A group in which items are laid out vertically, and "wrap" when they
 
523
    exceed the available vertical space.
 
524
    """
 
525
 
 
526
    #---------------------------------------------------------------------------
 
527
    #  Trait definitions:
 
528
    #---------------------------------------------------------------------------
 
529
 
 
530
    # Override standard Group trait defaults to give it vertical flow behavior:
 
531
    layout      = 'flow'
 
532
    show_labels = False
 
533
 
 
534
#-------------------------------------------------------------------------------
 
535
#  'VFold' class:
 
536
#-------------------------------------------------------------------------------
 
537
 
 
538
class VFold ( VGroup ):
 
539
    """ A group in which items are laid out vertically and can be collapsed
 
540
        (i.e. 'folded') by clicking their title.
 
541
    """
 
542
 
 
543
    #---------------------------------------------------------------------------
 
544
    #  Trait definitions:
 
545
    #---------------------------------------------------------------------------
 
546
 
 
547
    # Override standard Group trait defaults to give it vertical folding group
 
548
    # behavior:
 
549
    layout      = 'fold'
 
550
    show_labels = False
 
551
 
 
552
#-------------------------------------------------------------------------------
 
553
#  'HSplit' class:
 
554
#-------------------------------------------------------------------------------
 
555
 
 
556
class HSplit ( Group ):
 
557
    """ A horizontal group with splitter bars to separate it from other groups.
 
558
    """
 
559
 
 
560
    #---------------------------------------------------------------------------
 
561
    #  Trait definitions:
 
562
    #---------------------------------------------------------------------------
 
563
 
 
564
    # Override standard Group trait defaults to give it horizontal splitter
 
565
    # behavior:
 
566
    layout      = 'split'
 
567
    orientation = 'horizontal'
 
568
 
 
569
#-------------------------------------------------------------------------------
 
570
#  'VSplit' class:
 
571
#-------------------------------------------------------------------------------
 
572
 
 
573
class VSplit ( Group ):
 
574
    """ A vertical group with splitter bars to separate it from other groups.
 
575
    """
 
576
 
 
577
    #---------------------------------------------------------------------------
 
578
    #  Trait definitions:
 
579
    #---------------------------------------------------------------------------
 
580
 
 
581
    # Override standard Group trait defaults to give it vertical splitter
 
582
    # behavior:
 
583
    layout      = 'split'
 
584
    orientation = 'vertical'
 
585
 
 
586
#-------------------------------------------------------------------------------
 
587
#  'Tabbed' class:
 
588
#-------------------------------------------------------------------------------
 
589
 
 
590
class Tabbed ( Group ):
 
591
    """ A group that is shown as a tabbed notebook.
 
592
    """
 
593
 
 
594
    #---------------------------------------------------------------------------
 
595
    #  Trait definitions:
 
596
    #---------------------------------------------------------------------------
 
597
 
 
598
    # Override standard Group trait defaults to give it tabbed notebook
 
599
    # behavior:
 
600
    layout  = 'tabbed'
 
601
    springy = True
 
602
 
 
603
#-------------------------------------------------------------------------------
 
604
#  'ShadowGroup' class:
 
605
#-------------------------------------------------------------------------------
 
606
 
 
607
class ShadowGroup ( Group ):
 
608
    """ Corresponds to a Group object, but with all embedded Include
 
609
        objects resolved, and with all embedded Group objects replaced by
 
610
        corresponding ShadowGroup objects.
 
611
    """
 
612
 
 
613
    #---------------------------------------------------------------------------
 
614
    # Trait definitions:
 
615
    #---------------------------------------------------------------------------
 
616
 
 
617
    # Group object this is a "shadow" for
 
618
    shadow = ReadOnly
 
619
 
 
620
    # Number of ShadowGroups in **content**
 
621
    groups = ReadOnly
 
622
 
 
623
    # Name of the group
 
624
    id = ShadowDelegate
 
625
 
 
626
    # User interface label for the group
 
627
    label = ShadowDelegate
 
628
 
 
629
    # Default context object for group items
 
630
    object = ShadowDelegate
 
631
 
 
632
    # Default style of items in the group
 
633
    style = ShadowDelegate
 
634
 
 
635
    # Default docking style of items in the group
 
636
    dock = ShadowDelegate
 
637
 
 
638
    # Default image to display on notebook tabs
 
639
    image = ShadowDelegate
 
640
 
 
641
    # The theme to use for a DockWindow:
 
642
    dock_theme = ShadowDelegate
 
643
 
 
644
    # The theme to use for the group itself:
 
645
    group_theme = ShadowDelegate
 
646
 
 
647
    # The theme to use for item's contained in the group:
 
648
    item_theme = ShadowDelegate
 
649
 
 
650
    # The theme to use for the labels of items contained in the group:
 
651
    label_theme = ShadowDelegate
 
652
 
 
653
    # Category of elements dragged from the view
 
654
    export = ShadowDelegate
 
655
 
 
656
    # Spatial orientation of the group
 
657
    orientation = ShadowDelegate
 
658
 
 
659
    # Layout style of the group
 
660
    layout = ShadowDelegate
 
661
 
 
662
    # Should the group be scrollable along the direction of orientation?
 
663
    scrollable = ShadowDelegate
 
664
 
 
665
    # The number of columns in the group
 
666
    columns = ShadowDelegate
 
667
 
 
668
    # Should a border be drawn around group?
 
669
    show_border = ShadowDelegate
 
670
 
 
671
    # Should labels be added to items in group?
 
672
    show_labels = ShadowDelegate
 
673
 
 
674
    # Should labels be shown to the left of items (vs. the right)?
 
675
    show_left = ShadowDelegate
 
676
 
 
677
    # Is group the initially selected page?
 
678
    selected = ShadowDelegate
 
679
 
 
680
    # Should the group use extra space along its parent group's layout
 
681
    # orientation?
 
682
    springy = ShadowDelegate
 
683
 
 
684
    # Optional help text (for top-level group)
 
685
    help = ShadowDelegate
 
686
 
 
687
    # Pre-condition for defining the group
 
688
    defined_when = ShadowDelegate
 
689
 
 
690
    # Pre-condition for showing the group
 
691
    visible_when = ShadowDelegate
 
692
 
 
693
    # Pre-condition for enabling the group
 
694
    enabled_when = ShadowDelegate
 
695
 
 
696
    # Amount of padding to add around each item
 
697
    padding = ShadowDelegate
 
698
 
 
699
    #---------------------------------------------------------------------------
 
700
    #  Returns the contents of the ShadowGroup within a specified user interface
 
701
    #  building context. This makes sure that all Group types are of the same
 
702
    #  type (i.e. Group or Item) and that all Include objects have been replaced
 
703
    #  by their substituted values:
 
704
    #---------------------------------------------------------------------------
 
705
 
 
706
    def get_content ( self, allow_groups = True ):
 
707
        """ Returns the contents of the Group within a specified context for
 
708
        building a user interface.
 
709
 
 
710
        This method makes sure that all Group types are of the same type (i.e.,
 
711
        Group or Item) and that all Include objects have been replaced by their
 
712
        substituted values.
 
713
        """
 
714
        # Make a copy of the content:
 
715
        result = self.content[:]
 
716
 
 
717
        # If result includes any ShadowGroups and they are not allowed,
 
718
        # replace them:
 
719
        if self.groups != 0:
 
720
            if not allow_groups:
 
721
                i = 0
 
722
                while i < len( result ):
 
723
                    value = result[i]
 
724
                    if isinstance( value, ShadowGroup ):
 
725
                        items         = value.get_content( False )
 
726
                        result[i:i+1] = items
 
727
                        i += len( items )
 
728
                    else:
 
729
                        i += 1
 
730
            elif (self.groups != len( result )) and (self.layout == 'normal'):
 
731
                items   = []
 
732
                content = []
 
733
                for item in result:
 
734
                    if isinstance( item, ShadowGroup ):
 
735
                        self._flush_items( content, items )
 
736
                        content.append( item )
 
737
                    else:
 
738
                        items.append( item )
 
739
                self._flush_items( content, items )
 
740
                result = content
 
741
 
 
742
        # Return the resulting list of objects:
 
743
        return result
 
744
 
 
745
    #---------------------------------------------------------------------------
 
746
    #  Returns an id used to identify the group:
 
747
    #---------------------------------------------------------------------------
 
748
 
 
749
    def get_id ( self ):
 
750
        """ Returns an ID for the group.
 
751
        """
 
752
        if self.id != '':
 
753
            return self.id
 
754
 
 
755
        return ':'.join( [ item.get_id() for item in self.get_content() ] )
 
756
 
 
757
    #---------------------------------------------------------------------------
 
758
    #  Sets the correct container for the content:
 
759
    #---------------------------------------------------------------------------
 
760
 
 
761
    def set_container ( self ):
 
762
        """ Sets the correct container for the content.
 
763
        """
 
764
        pass
 
765
 
 
766
    #---------------------------------------------------------------------------
 
767
    #  Creates a sub-Group for any items contained in a specified list:
 
768
    #---------------------------------------------------------------------------
 
769
 
 
770
    def _flush_items ( self, content, items ):
 
771
        """ Creates a sub-group for any items contained in a specified list.
 
772
        """
 
773
        if len( items ) > 0:
 
774
            content.append( ShadowGroup( shadow      = self.shadow,
 
775
                                         groups      = 0,
 
776
                                         label       = '',
 
777
                                         show_border = False,
 
778
                                         content     = items ).set(
 
779
                                         show_labels = self.show_labels,
 
780
                                         show_left   = self.show_left,
 
781
                                         springy     = self.springy,
 
782
                                         orientation = self.orientation ) )
 
783
            del items[:]
 
784
 
 
785
    #---------------------------------------------------------------------------
 
786
    #  Returns a 'pretty print' version of the Group:
 
787
    #---------------------------------------------------------------------------
 
788
 
 
789
    def __repr__ ( self ):
 
790
        """ Returns a "pretty print" version of the Group.
 
791
        """
 
792
        return repr( self.shadow )