reportlab/graphics/widgetbase.py
author rgbecker
Fri, 17 Dec 2004 16:58:32 +0000
changeset 2420 8c40b77b4862
parent 2363 d541aeb182a1
child 2519 2b98e73f9718
permissions -rw-r--r--
graphics: changes for SmartLegend
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 2200
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2004
817
8c3a399effda License text changes
rgbecker
parents: 724
diff changeset
     2
#see license.txt for license details
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 2200
diff changeset
     3
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/widgetbase.py
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 2200
diff changeset
     4
__version__=''' $Id$ '''
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
     5
import string
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
     6
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
     7
from reportlab.graphics import shapes
724
0b10945bd324 Renamed config.py to rl_config.py
rgbecker
parents: 621
diff changeset
     8
from reportlab import rl_config
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
     9
from reportlab.lib import colors
927
ad7eb78babb4 Switched to using lib.validators module.
dinu_gherman
parents: 925
diff changeset
    10
from reportlab.lib.validators import *
948
2531b35adf85 New AttrMap emplacement
rgbecker
parents: 940
diff changeset
    11
from reportlab.lib.attrmap import *
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
    12
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    13
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
    14
class PropHolder:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    15
    '''Base for property holders'''
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
    16
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    17
    _attrMap = None
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    18
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    19
    def verify(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    20
        """If the _attrMap attribute is not None, this
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    21
        checks all expected attributes are present; no
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    22
        unwanted attributes are present; and (if a
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    23
        checking function is found) checks each
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    24
        attribute has a valid value.  Either succeeds
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    25
        or raises an informative exception.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    26
        """
948
2531b35adf85 New AttrMap emplacement
rgbecker
parents: 940
diff changeset
    27
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    28
        if self._attrMap is not None:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    29
            for key in self.__dict__.keys():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    30
                if key[0] <> '_':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    31
                    msg = "Unexpected attribute %s found in %s" % (key, self)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    32
                    assert self._attrMap.has_key(key), msg
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    33
            for (attr, metavalue) in self._attrMap.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    34
                msg = "Missing attribute %s from %s" % (attr, self)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    35
                assert hasattr(self, attr), msg
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    36
                value = getattr(self, attr)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    37
                args = (value, attr, self.__class__.__name__)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    38
                assert metavalue.validate(value), "Invalid value %s for attribute %s in class %s" % args
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    39
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    40
    if rl_config.shapeChecking:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    41
        """This adds the ability to check every attribute assignment
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    42
        as it is made. It slows down shapes but is a big help when
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    43
        developing. It does not get defined if rl_config.shapeChecking = 0.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    44
        """
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    45
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    46
        def __setattr__(self, name, value):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    47
            """By default we verify.  This could be off
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    48
            in some parallel base classes."""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    49
            validateSetattr(self,name,value)
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
    50
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    51
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    52
    def getProperties(self,recur=1):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    53
        """Returns a list of all properties which can be edited and
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    54
        which are not marked as private. This may include 'child
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    55
        widgets' or 'primitive shapes'.  You are free to override
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    56
        this and provide alternative implementations; the default
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    57
        one simply returns everything without a leading underscore.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    58
        """
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    59
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    60
        from reportlab.lib.validators import isValidChild
931
07db840b3db6 Changed validator functions into classes.
dinu_gherman
parents: 927
diff changeset
    61
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    62
        # TODO when we need it, but not before -
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    63
        # expose sequence contents?
931
07db840b3db6 Changed validator functions into classes.
dinu_gherman
parents: 927
diff changeset
    64
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    65
        props = {}
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    66
        for name in self.__dict__.keys():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    67
            if name[0:1] <> '_':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    68
                component = getattr(self, name)
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
    69
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    70
                if recur and isValidChild(component):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    71
                    # child object, get its properties too
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    72
                    childProps = component.getProperties(recur=recur)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    73
                    for (childKey, childValue) in childProps.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    74
                        #key might be something indexed like '[2].fillColor'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    75
                        #or simple like 'fillColor'; in the former case we
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    76
                        #don't need a '.' between me and my child.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    77
                        if childKey[0] == '[':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    78
                            props['%s%s' % (name, childKey)] = childValue
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    79
                        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    80
                            props['%s.%s' % (name, childKey)] = childValue
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    81
                else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    82
                    props[name] = component
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
    83
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    84
        return props
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
    85
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
    86
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    87
    def setProperties(self, propDict):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    88
        """Permits bulk setting of properties.  These may include
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    89
        child objects e.g. "chart.legend.width = 200".
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
    90
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    91
        All assignments will be validated by the object as if they
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    92
        were set individually in python code.
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
    93
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    94
        All properties of a top-level object are guaranteed to be
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    95
        set before any of the children, which may be helpful to
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    96
        widget designers.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    97
        """
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
    98
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
    99
        childPropDicts = {}
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   100
        for (name, value) in propDict.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   101
            parts = string.split(name, '.', 1)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   102
            if len(parts) == 1:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   103
                #simple attribute, set it now
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   104
                setattr(self, name, value)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   105
            else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   106
                (childName, remains) = parts
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   107
                try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   108
                    childPropDicts[childName][remains] = value
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   109
                except KeyError:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   110
                    childPropDicts[childName] = {remains: value}
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   111
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   112
        # now assign to children
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   113
        for (childName, childPropDict) in childPropDicts.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   114
            child = getattr(self, childName)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   115
            child.setProperties(childPropDict)
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   116
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   117
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   118
    def dumpProperties(self, prefix=""):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   119
        """Convenience. Lists them on standard output.  You
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   120
        may provide a prefix - mostly helps to generate code
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   121
        samples for documentation.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   122
        """
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   123
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   124
        propList = self.getProperties().items()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   125
        propList.sort()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   126
        if prefix:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   127
            prefix = prefix + '.'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   128
        for (name, value) in propList:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   129
            print '%s%s = %s' % (prefix, name, value)
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   130
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   131
927
ad7eb78babb4 Switched to using lib.validators module.
dinu_gherman
parents: 925
diff changeset
   132
class Widget(PropHolder, shapes.UserNode):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   133
    """Base for all user-defined widgets.  Keep as simple as possible. Does
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   134
    not inherit from Shape so that we can rewrite shapes without breaking
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   135
    widgets and vice versa."""
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   136
2363
d541aeb182a1 remove 2.2 isms
rgbecker
parents: 2332
diff changeset
   137
    def _setKeywords(self,**kw):
d541aeb182a1 remove 2.2 isms
rgbecker
parents: 2332
diff changeset
   138
        for k,v in kw.items():
d541aeb182a1 remove 2.2 isms
rgbecker
parents: 2332
diff changeset
   139
            if not self.__dict__.has_key(k):
d541aeb182a1 remove 2.2 isms
rgbecker
parents: 2332
diff changeset
   140
                setattr(self,k,v)
d541aeb182a1 remove 2.2 isms
rgbecker
parents: 2332
diff changeset
   141
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   142
    def draw(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   143
        msg = "draw() must be implemented for each Widget!"
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   144
        raise shapes.NotImplementedError, msg
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   145
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   146
    def demo(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   147
        msg = "demo() must be implemented for each Widget!"
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   148
        raise shapes.NotImplementedError, msg
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   149
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   150
    def provideNode(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   151
        return self.draw()
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   152
2004
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   153
    def getBounds(self):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   154
        "Return outer boundary as x1,y1,x2,y2.  Can be overridden for efficiency"
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   155
        return self.draw().getBounds()
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   156
971
9ca160e4f41a Fixed _ItemWrapper name and made it really cache
rgbecker
parents: 970
diff changeset
   157
_ItemWrapper={}
914
d4a08fcf249a Added a __len__ method to TypedPropertyCOllection.
dinu_gherman
parents: 848
diff changeset
   158
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   159
class TypedPropertyCollection(PropHolder):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   160
    """A container with properties for objects of the same kind.
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   161
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   162
    This makes it easy to create lists of objects. You initialize
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   163
    it with a class of what it is to contain, and that is all you
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   164
    can add to it.  You can assign properties to the collection
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   165
    as a whole, or to a numeric index within it; if so it creates
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   166
    a new child object to hold that data.
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   167
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   168
    So:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   169
        wedges = TypedPropertyCollection(WedgeProperties)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   170
        wedges.strokeWidth = 2                # applies to all
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   171
        wedges.strokeColor = colors.red       # applies to all
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   172
        wedges[3].strokeColor = colors.blue   # only to one
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   173
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   174
    The last line should be taken as a prescription of how to
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   175
    create wedge no. 3 if one is needed; no error is raised if
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   176
    there are only two data points.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   177
    """
914
d4a08fcf249a Added a __len__ method to TypedPropertyCOllection.
dinu_gherman
parents: 848
diff changeset
   178
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   179
    def __init__(self, exampleClass):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   180
        #give it same validation rules as what it holds
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   181
        self.__dict__['_value'] = exampleClass()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   182
        self.__dict__['_children'] = {}
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   183
2420
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   184
    def wKlassFactory(self,Klass):
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   185
        class WKlass(Klass):
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   186
            def __getattr__(self,name):
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   187
                try:
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   188
                    return self.__class__.__bases__[0].__getattr__(self,name)
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   189
                except:
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   190
                    if self._index and self._parent._children.has_key(self._index) \
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   191
                        and self._parent._children[self._index].__dict__.has_key(name):
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   192
                        return getattr(self._parent._children[self._index],name)
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   193
                    return getattr(self._parent,name)
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   194
        return WKlass
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   195
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   196
    def __getitem__(self, index):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   197
        try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   198
            return self._children[index]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   199
        except KeyError:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   200
            Klass = self._value.__class__
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   201
            if _ItemWrapper.has_key(Klass):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   202
                WKlass = _ItemWrapper[Klass]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   203
            else:
2420
8c40b77b4862 graphics: changes for SmartLegend
rgbecker
parents: 2363
diff changeset
   204
                _ItemWrapper[Klass] = WKlass = self.wKlassFactory(Klass)
970
87d965592699 Improved element wrapping seems to work
rgbecker
parents: 968
diff changeset
   205
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   206
            child = WKlass()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   207
            child._parent = self
1687
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   208
            if type(index) in (type(()),type([])):
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   209
                index = tuple(index)
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   210
                if len(index)>1:
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   211
                    child._index = tuple(index[:-1])
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   212
                else:
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   213
                    child._index = None
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   214
            else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   215
                child._index = None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   216
            for i in filter(lambda x,K=child.__dict__.keys(): x in K,child._attrMap.keys()):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   217
                del child.__dict__[i]
970
87d965592699 Improved element wrapping seems to work
rgbecker
parents: 968
diff changeset
   218
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   219
            self._children[index] = child
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   220
            return child
584
94214696e4b9 Added barchart compatibility
andy_robinson
parents: 574
diff changeset
   221
1687
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   222
    def has_key(self,key):
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   223
        if type(key) in (type(()),type([])): key = tuple(key)
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   224
        return self._children.has_key(key)
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   225
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   226
    def __setitem__(self, key, value):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   227
        msg = "This collection can only hold objects of type %s" % self._value.__class__.__name__
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   228
        assert isinstance(value, self._value.__class__), msg
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   229
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   230
    def __len__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   231
        return len(self._children.keys())
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   232
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   233
    def getProperties(self,recur=1):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   234
        # return any children which are defined and whatever
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   235
        # differs from the parent
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   236
        props = {}
584
94214696e4b9 Added barchart compatibility
andy_robinson
parents: 574
diff changeset
   237
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   238
        for (key, value) in self._value.getProperties(recur=recur).items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   239
            props['%s' % key] = value
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   240
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   241
        for idx in self._children.keys():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   242
            childProps = self._children[idx].getProperties(recur=recur)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   243
            for (key, value) in childProps.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   244
                if not hasattr(self,key) or getattr(self, key)<>value:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   245
                    newKey = '[%s].%s' % (idx, key)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   246
                    props[newKey] = value
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   247
        return props
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   248
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   249
    def setVector(self,**kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   250
        for name, value in kw.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   251
            for i in xrange(len(value)):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   252
                setattr(self[i],name,value[i])
914
d4a08fcf249a Added a __len__ method to TypedPropertyCOllection.
dinu_gherman
parents: 848
diff changeset
   253
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   254
    def __getattr__(self,name):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   255
        return getattr(self._value,name)
997
e0888bb81f13 Allow TypedPropertyCollection exemplar class to have getattr etc
rgbecker
parents: 996
diff changeset
   256
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   257
    def __setattr__(self,name,value):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   258
        return setattr(self._value,name,value)
997
e0888bb81f13 Allow TypedPropertyCollection exemplar class to have getattr etc
rgbecker
parents: 996
diff changeset
   259
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   260
## No longer needed!
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   261
class StyleProperties(PropHolder):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   262
    """A container class for attributes used in charts and legends.
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   263
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   264
    Attributes contained can be those for any graphical element
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   265
    (shape?) in the ReportLab graphics package. The idea for this
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   266
    container class is to be useful in combination with legends
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   267
    and/or the individual appearance of data series in charts.
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   268
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   269
    A legend could be as simple as a wrapper around a list of style
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   270
    properties, where the 'desc' attribute contains a descriptive
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   271
    string and the rest could be used by the legend e.g. to draw
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   272
    something like a color swatch. The graphical presentation of
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   273
    the legend would be its own business, though.
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   274
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   275
    A chart could be inspecting a legend or, more directly, a list
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   276
    of style properties to pick individual attributes that it knows
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   277
    about in order to render a particular row of the data. A bar
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   278
    chart e.g. could simply use 'strokeColor' and 'fillColor' for
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   279
    drawing the bars while a line chart could also use additional
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   280
    ones like strokeWidth.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   281
    """
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   282
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   283
    _attrMap = AttrMap(
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   284
        strokeWidth = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   285
        strokeLineCap = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   286
        strokeLineJoin = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   287
        strokeMiterLimit = AttrMapValue(None),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   288
        strokeDashArray = AttrMapValue(isListOfNumbersOrNone),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   289
        strokeOpacity = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   290
        strokeColor = AttrMapValue(isColorOrNone),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   291
        fillColor = AttrMapValue(isColorOrNone),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   292
        desc = AttrMapValue(isString),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   293
        )
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   294
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   295
    def __init__(self, **kwargs):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   296
        "Initialize with attributes if any."
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   297
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   298
        for k, v in kwargs.items():
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   299
            setattr(self, k, v)
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   300
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   301
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   302
    def __setattr__(self, name, value):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   303
        "Verify attribute name and value, before setting it."
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   304
        validateSetattr(self,name,value)
848
0b9f07f0a2ed Added StyleProeprties class
rgbecker
parents: 847
diff changeset
   305
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   306
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   307
class TwoCircles(Widget):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   308
    def __init__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   309
        self.leftCircle = shapes.Circle(100,100,20, fillColor=colors.red)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   310
        self.rightCircle = shapes.Circle(300,100,20, fillColor=colors.red)
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   311
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   312
    def draw(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   313
        return shapes.Group(self.leftCircle, self.rightCircle)
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   314
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   315
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   316
class Face(Widget):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   317
    """This draws a face with two eyes.
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   318
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   319
    It exposes a couple of properties
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   320
    to configure itself and hides all other details.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   321
    """
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   322
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   323
    _attrMap = AttrMap(
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   324
        x = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   325
        y = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   326
        size = AttrMapValue(isNumber),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   327
        skinColor = AttrMapValue(isColorOrNone),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   328
        eyeColor = AttrMapValue(isColorOrNone),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   329
        mood = AttrMapValue(OneOf('happy','sad','ok')),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   330
        )
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   331
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   332
    def __init__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   333
        self.x = 10
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   334
        self.y = 10
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   335
        self.size = 80
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   336
        self.skinColor = None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   337
        self.eyeColor = colors.blue
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   338
        self.mood = 'happy'
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   339
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   340
    def demo(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   341
        pass
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   342
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   343
    def draw(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   344
        s = self.size  # abbreviate as we will use this a lot
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   345
        g = shapes.Group()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   346
        g.transform = [1,0,0,1,self.x, self.y]
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   347
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   348
        # background
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   349
        g.add(shapes.Circle(s * 0.5, s * 0.5, s * 0.5, fillColor=self.skinColor))
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   350
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   351
        # left eye
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   352
        g.add(shapes.Circle(s * 0.35, s * 0.65, s * 0.1, fillColor=colors.white))
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   353
        g.add(shapes.Circle(s * 0.35, s * 0.65, s * 0.05, fillColor=self.eyeColor))
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   354
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   355
        # right eye
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   356
        g.add(shapes.Circle(s * 0.65, s * 0.65, s * 0.1, fillColor=colors.white))
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   357
        g.add(shapes.Circle(s * 0.65, s * 0.65, s * 0.05, fillColor=self.eyeColor))
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   358
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   359
        # nose
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   360
        g.add(shapes.Polygon(
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   361
            points=[s * 0.5, s * 0.6, s * 0.4, s * 0.3, s * 0.6, s * 0.3],
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   362
            fillColor=None))
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   363
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   364
        # mouth
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   365
        if self.mood == 'happy':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   366
            offset = -0.05
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   367
        elif self.mood == 'sad':
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   368
            offset = +0.05
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   369
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   370
            offset = 0
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   371
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   372
        g.add(shapes.Polygon(
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   373
            points = [
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   374
                s * 0.3, s * 0.2, #left of mouth
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   375
                s * 0.7, s * 0.2, #right of mouth
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   376
                s * 0.6, s * (0.2 + offset), # the bit going up or down
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   377
                s * 0.4, s * (0.2 + offset) # the bit going up or down
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   378
                ],
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   379
            fillColor = colors.pink,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   380
            strokeColor = colors.red,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   381
            strokeWidth = s * 0.03
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   382
            ))
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   383
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   384
        return g
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   385
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   386
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   387
class TwoFaces(Widget):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   388
    def __init__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   389
        self.faceOne = Face()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   390
        self.faceOne.mood = "happy"
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   391
        self.faceTwo = Face()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   392
        self.faceTwo.x = 100
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   393
        self.faceTwo.mood = "sad"
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   394
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   395
    def draw(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   396
        """Just return a group"""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   397
        return shapes.Group(self.faceOne, self.faceTwo)
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   398
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   399
    def demo(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   400
        """The default case already looks good enough,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   401
        no implementation needed here"""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   402
        pass
847
c1b686db033c Robin's refactoring to separate propholder and Widget
andy_robinson
parents: 817
diff changeset
   403
2004
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   404
class Sizer(Widget):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   405
    "Container to show size of all enclosed objects"
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2004
diff changeset
   406
2004
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   407
    _attrMap = AttrMap(BASE=shapes.SolidShape,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   408
        contents = AttrMapValue(isListOfShapes,desc="Contained drawable elements"),
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   409
        )
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   410
    def __init__(self, *elements):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   411
        self.contents = []
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   412
        self.fillColor = colors.cyan
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   413
        self.strokeColor = colors.magenta
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2004
diff changeset
   414
2004
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   415
        for elem in elements:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   416
            self.add(elem)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   417
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   418
    def _addNamedNode(self,name,node):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   419
        'if name is not None add an attribute pointing to node and add to the attrMap'
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   420
        if name:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   421
            if name not in self._attrMap.keys():
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   422
                self._attrMap[name] = AttrMapValue(isValidChild)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   423
            setattr(self, name, node)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   424
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   425
    def add(self, node, name=None):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   426
        """Appends non-None child node to the 'contents' attribute. In addition,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   427
        if a name is provided, it is subsequently accessible by name
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   428
        """
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   429
        # propagates properties down
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   430
        if node is not None:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   431
            assert isValidChild(node), "Can only add Shape or UserNode objects to a Group"
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   432
            self.contents.append(node)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   433
            self._addNamedNode(name,node)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   434
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   435
    def getBounds(self):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   436
        # get bounds of each object
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   437
        if self.contents:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   438
            b = []
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   439
            for elem in self.contents:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   440
                b.append(elem.getBounds())
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   441
            return shapes.getRectsBounds(b)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   442
        else:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   443
            return (0,0,0,0)
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2004
diff changeset
   444
2004
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   445
    def draw(self):
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   446
        g = shapes.Group()
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   447
        (x1, y1, x2, y2) = self.getBounds()
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   448
        r = shapes.Rect(
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   449
            x = x1,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   450
            y = y1,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   451
            width = x2-x1,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   452
            height = y2-y1,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   453
            fillColor = self.fillColor,
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   454
            strokeColor = self.strokeColor
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   455
            )
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   456
        g.add(r)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   457
        for elem in self.contents:
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   458
            g.add(elem)
14a180d2691f Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents: 1687
diff changeset
   459
        return g
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   460
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   461
def test():
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   462
    from reportlab.graphics.charts.piecharts import WedgeProperties
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   463
    wedges = TypedPropertyCollection(WedgeProperties)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   464
    wedges.fillColor = colors.red
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   465
    wedges.setVector(fillColor=(colors.blue,colors.green,colors.white))
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   466
    print len(_ItemWrapper)
951
d810699237a0 Added TypedPropertyCollection.setVector
rgbecker
parents: 948
diff changeset
   467
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   468
    d = shapes.Drawing(400, 200)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   469
    tc = TwoCircles()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   470
    d.add(tc)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   471
    import renderPDF
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   472
    renderPDF.drawToFile(d, 'sample_widget.pdf', 'A Sample Widget')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   473
    print 'saved sample_widget.pdf'
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   474
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   475
    d = shapes.Drawing(400, 200)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   476
    f = Face()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   477
    f.skinColor = colors.yellow
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   478
    f.mood = "sad"
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   479
    d.add(f, name='theFace')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   480
    print 'drawing 1 properties:'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   481
    d.dumpProperties()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   482
    renderPDF.drawToFile(d, 'face.pdf', 'A Sample Widget')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   483
    print 'saved face.pdf'
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   484
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   485
    d2 = d.expandUserNodes()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   486
    renderPDF.drawToFile(d2, 'face_copy.pdf', 'An expanded drawing')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   487
    print 'saved face_copy.pdf'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   488
    print 'drawing 2 properties:'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1558
diff changeset
   489
    d2.dumpProperties()
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   490
925
0436c4cb1d71 Code and docstring enhancements.
dinu_gherman
parents: 914
diff changeset
   491
568
9cadc5ef53db Added graphics module
andy_robinson
parents:
diff changeset
   492
if __name__=='__main__':
1687
3a572e14ec3e Allow for multicolour single data barcharts
rgbecker
parents: 1683
diff changeset
   493
    test()