author | rgbecker |
Wed, 03 Sep 2008 16:10:51 +0000 | |
changeset 2964 | 32352db0d71e |
parent 2776 | reportlab/graphics/widgetbase.py@6e7adab745fe |
child 3032 | 22224b1b4d24 |
permissions | -rw-r--r-- |
2332 | 1 |
#Copyright ReportLab Europe Ltd. 2000-2004 |
817 | 2 |
#see license.txt for license details |
2332 | 3 |
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/widgetbase.py |
4 |
__version__=''' $Id$ ''' |
|
568 | 5 |
import string |
6 |
||
7 |
from reportlab.graphics import shapes |
|
724 | 8 |
from reportlab import rl_config |
568 | 9 |
from reportlab.lib import colors |
927 | 10 |
from reportlab.lib.validators import * |
948 | 11 |
from reportlab.lib.attrmap import * |
568 | 12 |
|
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
13 |
class PropHolder: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
14 |
'''Base for property holders''' |
568 | 15 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
16 |
_attrMap = None |
925 | 17 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
18 |
def verify(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
19 |
"""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
|
20 |
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
|
21 |
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
|
22 |
checking function is found) checks each |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
23 |
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
|
24 |
or raises an informative exception. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
25 |
""" |
948 | 26 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
27 |
if self._attrMap is not None: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
28 |
for key in self.__dict__.keys(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
29 |
if key[0] <> '_': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
30 |
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
|
31 |
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
|
32 |
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
|
33 |
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
|
34 |
assert hasattr(self, attr), msg |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
35 |
value = getattr(self, attr) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
36 |
args = (value, attr, self.__class__.__name__) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
37 |
assert metavalue.validate(value), "Invalid value %s for attribute %s in class %s" % args |
925 | 38 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
39 |
if rl_config.shapeChecking: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
40 |
"""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
|
41 |
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
|
42 |
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
|
43 |
""" |
925 | 44 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
45 |
def __setattr__(self, name, value): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
46 |
"""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
|
47 |
in some parallel base classes.""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
48 |
validateSetattr(self,name,value) |
568 | 49 |
|
925 | 50 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
51 |
def getProperties(self,recur=1): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
52 |
"""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
|
53 |
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
|
54 |
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
|
55 |
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
|
56 |
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
|
57 |
""" |
925 | 58 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
59 |
from reportlab.lib.validators import isValidChild |
931 | 60 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
61 |
# 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
|
62 |
# expose sequence contents? |
931 | 63 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
64 |
props = {} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
65 |
for name in self.__dict__.keys(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
66 |
if name[0:1] <> '_': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
67 |
component = getattr(self, name) |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
68 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
69 |
if recur and isValidChild(component): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
70 |
# child object, get its properties too |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
71 |
childProps = component.getProperties(recur=recur) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
72 |
for (childKey, childValue) in childProps.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
73 |
#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
|
74 |
#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
|
75 |
#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
|
76 |
if childKey[0] == '[': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
77 |
props['%s%s' % (name, childKey)] = childValue |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
78 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
79 |
props['%s.%s' % (name, childKey)] = childValue |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
80 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
81 |
props[name] = component |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
82 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
83 |
return props |
568 | 84 |
|
925 | 85 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
86 |
def setProperties(self, propDict): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
87 |
"""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
|
88 |
child objects e.g. "chart.legend.width = 200". |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
89 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
90 |
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
|
91 |
were set individually in python code. |
568 | 92 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
93 |
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
|
94 |
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
|
95 |
widget designers. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
96 |
""" |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
97 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
98 |
childPropDicts = {} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
99 |
for (name, value) in propDict.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
100 |
parts = string.split(name, '.', 1) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
101 |
if len(parts) == 1: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
102 |
#simple attribute, set it now |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
103 |
setattr(self, name, value) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
104 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
105 |
(childName, remains) = parts |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
106 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
107 |
childPropDicts[childName][remains] = value |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
108 |
except KeyError: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
109 |
childPropDicts[childName] = {remains: value} |
925 | 110 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
111 |
# now assign to children |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
112 |
for (childName, childPropDict) in childPropDicts.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
113 |
child = getattr(self, childName) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
114 |
child.setProperties(childPropDict) |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
115 |
|
925 | 116 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
117 |
def dumpProperties(self, prefix=""): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
118 |
"""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
|
119 |
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
|
120 |
samples for documentation. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
121 |
""" |
925 | 122 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
123 |
propList = self.getProperties().items() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
124 |
propList.sort() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
125 |
if prefix: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
126 |
prefix = prefix + '.' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
127 |
for (name, value) in propList: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
128 |
print '%s%s = %s' % (prefix, name, value) |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
129 |
|
925 | 130 |
|
927 | 131 |
class Widget(PropHolder, shapes.UserNode): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
132 |
"""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
|
133 |
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
|
134 |
widgets and vice versa.""" |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
135 |
|
2363 | 136 |
def _setKeywords(self,**kw): |
137 |
for k,v in kw.items(): |
|
138 |
if not self.__dict__.has_key(k): |
|
139 |
setattr(self,k,v) |
|
140 |
||
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
141 |
def draw(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
142 |
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
|
143 |
raise shapes.NotImplementedError, msg |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
144 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
145 |
def demo(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
146 |
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
|
147 |
raise shapes.NotImplementedError, msg |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
148 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
149 |
def provideNode(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
150 |
return self.draw() |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
151 |
|
2004
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
152 |
def getBounds(self): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
153 |
"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
|
154 |
return self.draw().getBounds() |
1683 | 155 |
|
2776 | 156 |
class ScaleWidget(Widget): |
157 |
'''Contents with a scale and offset''' |
|
158 |
_attrMap = AttrMap( |
|
159 |
x = AttrMapValue(isNumber,desc="x offset"), |
|
160 |
y = AttrMapValue(isNumber,desc="y offset"), |
|
161 |
scale = AttrMapValue(isNumber,desc="scale"), |
|
162 |
contents = AttrMapValue(None,desc="Contained drawable elements"), |
|
163 |
) |
|
164 |
def __init__(self,x=0,y=0,scale=1.0,contents=None): |
|
165 |
self.x = x |
|
166 |
self.y = y |
|
167 |
if not contents: contents=[] |
|
168 |
elif not isinstance(contents,(tuple,list)): |
|
169 |
contents = (contents,) |
|
170 |
self.contents = list(contents) |
|
171 |
self.scale = scale |
|
172 |
||
173 |
def draw(self): |
|
174 |
return shapes.Group(transform=(self.scale,0,0,self.scale,self.x,self.y),*self.contents) |
|
175 |
||
971 | 176 |
_ItemWrapper={} |
914
d4a08fcf249a
Added a __len__ method to TypedPropertyCOllection.
dinu_gherman
parents:
848
diff
changeset
|
177 |
|
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
178 |
class TypedPropertyCollection(PropHolder): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
179 |
"""A container with properties for objects of the same kind. |
925 | 180 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
181 |
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
|
182 |
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
|
183 |
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
|
184 |
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
|
185 |
a new child object to hold that data. |
925 | 186 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
187 |
So: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
188 |
wedges = TypedPropertyCollection(WedgeProperties) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
189 |
wedges.strokeWidth = 2 # applies to all |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
190 |
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
|
191 |
wedges[3].strokeColor = colors.blue # only to one |
925 | 192 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
193 |
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
|
194 |
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
|
195 |
there are only two data points. |
2519
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
196 |
|
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
197 |
We try and make sensible use of tuple indeces. |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
198 |
line[(3,x)] is backed by line[(3,)], line[3] & line |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
199 |
""" |
914
d4a08fcf249a
Added a __len__ method to TypedPropertyCOllection.
dinu_gherman
parents:
848
diff
changeset
|
200 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
201 |
def __init__(self, exampleClass): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
202 |
#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
|
203 |
self.__dict__['_value'] = exampleClass() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
204 |
self.__dict__['_children'] = {} |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
205 |
|
2420 | 206 |
def wKlassFactory(self,Klass): |
207 |
class WKlass(Klass): |
|
208 |
def __getattr__(self,name): |
|
209 |
try: |
|
210 |
return self.__class__.__bases__[0].__getattr__(self,name) |
|
211 |
except: |
|
2519
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
212 |
i = self._index |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
213 |
if i: |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
214 |
c = self._parent._children |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
215 |
if c.has_key(i) and c[i].__dict__.has_key(name): |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
216 |
return getattr(c[i],name) |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
217 |
elif len(i)==1: |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
218 |
i = i[0] |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
219 |
if c.has_key(i) and c[i].__dict__.has_key(name): |
2b98e73f9718
merge utf8 2666:2667 widgetbase: make line[3] back up for line[(3,x)]
rgbecker
parents:
2420
diff
changeset
|
220 |
return getattr(c[i],name) |
2420 | 221 |
return getattr(self._parent,name) |
222 |
return WKlass |
|
223 |
||
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
224 |
def __getitem__(self, index): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
225 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
226 |
return self._children[index] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
227 |
except KeyError: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
228 |
Klass = self._value.__class__ |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
229 |
if _ItemWrapper.has_key(Klass): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
230 |
WKlass = _ItemWrapper[Klass] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
231 |
else: |
2420 | 232 |
_ItemWrapper[Klass] = WKlass = self.wKlassFactory(Klass) |
970 | 233 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
234 |
child = WKlass() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
235 |
child._parent = self |
1687 | 236 |
if type(index) in (type(()),type([])): |
237 |
index = tuple(index) |
|
238 |
if len(index)>1: |
|
239 |
child._index = tuple(index[:-1]) |
|
240 |
else: |
|
241 |
child._index = None |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
242 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
243 |
child._index = None |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
244 |
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
|
245 |
del child.__dict__[i] |
970 | 246 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
247 |
self._children[index] = child |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
248 |
return child |
584 | 249 |
|
1687 | 250 |
def has_key(self,key): |
251 |
if type(key) in (type(()),type([])): key = tuple(key) |
|
252 |
return self._children.has_key(key) |
|
253 |
||
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
254 |
def __setitem__(self, key, value): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
255 |
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
|
256 |
assert isinstance(value, self._value.__class__), msg |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
257 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
258 |
def __len__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
259 |
return len(self._children.keys()) |
1683 | 260 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
261 |
def getProperties(self,recur=1): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
262 |
# 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
|
263 |
# differs from the parent |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
264 |
props = {} |
584 | 265 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
266 |
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
|
267 |
props['%s' % key] = value |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
268 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
269 |
for idx in self._children.keys(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
270 |
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
|
271 |
for (key, value) in childProps.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
272 |
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
|
273 |
newKey = '[%s].%s' % (idx, key) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
274 |
props[newKey] = value |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
275 |
return props |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
276 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
277 |
def setVector(self,**kw): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
278 |
for name, value in kw.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
279 |
for i in xrange(len(value)): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
280 |
setattr(self[i],name,value[i]) |
914
d4a08fcf249a
Added a __len__ method to TypedPropertyCOllection.
dinu_gherman
parents:
848
diff
changeset
|
281 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
282 |
def __getattr__(self,name): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
283 |
return getattr(self._value,name) |
997
e0888bb81f13
Allow TypedPropertyCollection exemplar class to have getattr etc
rgbecker
parents:
996
diff
changeset
|
284 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
285 |
def __setattr__(self,name,value): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
286 |
return setattr(self._value,name,value) |
997
e0888bb81f13
Allow TypedPropertyCollection exemplar class to have getattr etc
rgbecker
parents:
996
diff
changeset
|
287 |
|
925 | 288 |
## No longer needed! |
848 | 289 |
class StyleProperties(PropHolder): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
290 |
"""A container class for attributes used in charts and legends. |
848 | 291 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
292 |
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
|
293 |
(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
|
294 |
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
|
295 |
and/or the individual appearance of data series in charts. |
848 | 296 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
297 |
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
|
298 |
properties, where the 'desc' attribute contains a descriptive |
1683 | 299 |
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
|
300 |
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
|
301 |
the legend would be its own business, though. |
848 | 302 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
303 |
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
|
304 |
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
|
305 |
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
|
306 |
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
|
307 |
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
|
308 |
ones like strokeWidth. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
309 |
""" |
1683 | 310 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
311 |
_attrMap = AttrMap( |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
312 |
strokeWidth = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
313 |
strokeLineCap = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
314 |
strokeLineJoin = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
315 |
strokeMiterLimit = AttrMapValue(None), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
316 |
strokeDashArray = AttrMapValue(isListOfNumbersOrNone), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
317 |
strokeOpacity = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
318 |
strokeColor = AttrMapValue(isColorOrNone), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
319 |
fillColor = AttrMapValue(isColorOrNone), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
320 |
desc = AttrMapValue(isString), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
321 |
) |
848 | 322 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
323 |
def __init__(self, **kwargs): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
324 |
"Initialize with attributes if any." |
848 | 325 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
326 |
for k, v in kwargs.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
327 |
setattr(self, k, v) |
1683 | 328 |
|
848 | 329 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
330 |
def __setattr__(self, name, value): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
331 |
"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
|
332 |
validateSetattr(self,name,value) |
848 | 333 |
|
925 | 334 |
|
568 | 335 |
class TwoCircles(Widget): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
336 |
def __init__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
337 |
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
|
338 |
self.rightCircle = shapes.Circle(300,100,20, fillColor=colors.red) |
568 | 339 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
340 |
def draw(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
341 |
return shapes.Group(self.leftCircle, self.rightCircle) |
568 | 342 |
|
925 | 343 |
|
568 | 344 |
class Face(Widget): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
345 |
"""This draws a face with two eyes. |
925 | 346 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
347 |
It exposes a couple of properties |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
348 |
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
|
349 |
""" |
925 | 350 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
351 |
_attrMap = AttrMap( |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
352 |
x = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
353 |
y = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
354 |
size = AttrMapValue(isNumber), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
355 |
skinColor = AttrMapValue(isColorOrNone), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
356 |
eyeColor = AttrMapValue(isColorOrNone), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
357 |
mood = AttrMapValue(OneOf('happy','sad','ok')), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
358 |
) |
568 | 359 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
360 |
def __init__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
361 |
self.x = 10 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
362 |
self.y = 10 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
363 |
self.size = 80 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
364 |
self.skinColor = None |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
365 |
self.eyeColor = colors.blue |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
366 |
self.mood = 'happy' |
568 | 367 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
368 |
def demo(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
369 |
pass |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
370 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
371 |
def draw(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
372 |
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
|
373 |
g = shapes.Group() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
374 |
g.transform = [1,0,0,1,self.x, self.y] |
925 | 375 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
376 |
# background |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
377 |
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
|
378 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
379 |
# left eye |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
380 |
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
|
381 |
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
|
382 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
383 |
# right eye |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
384 |
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
|
385 |
g.add(shapes.Circle(s * 0.65, s * 0.65, s * 0.05, fillColor=self.eyeColor)) |
568 | 386 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
387 |
# nose |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
388 |
g.add(shapes.Polygon( |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
389 |
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
|
390 |
fillColor=None)) |
568 | 391 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
392 |
# mouth |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
393 |
if self.mood == 'happy': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
394 |
offset = -0.05 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
395 |
elif self.mood == 'sad': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
396 |
offset = +0.05 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
397 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
398 |
offset = 0 |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
399 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
400 |
g.add(shapes.Polygon( |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
401 |
points = [ |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
402 |
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
|
403 |
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
|
404 |
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
|
405 |
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
|
406 |
], |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
407 |
fillColor = colors.pink, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
408 |
strokeColor = colors.red, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
409 |
strokeWidth = s * 0.03 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
410 |
)) |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
411 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
412 |
return g |
568 | 413 |
|
925 | 414 |
|
568 | 415 |
class TwoFaces(Widget): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
416 |
def __init__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
417 |
self.faceOne = Face() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
418 |
self.faceOne.mood = "happy" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
419 |
self.faceTwo = Face() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
420 |
self.faceTwo.x = 100 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
421 |
self.faceTwo.mood = "sad" |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
422 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
423 |
def draw(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
424 |
"""Just return a group""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
425 |
return shapes.Group(self.faceOne, self.faceTwo) |
568 | 426 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
427 |
def demo(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
428 |
"""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
|
429 |
no implementation needed here""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
430 |
pass |
847
c1b686db033c
Robin's refactoring to separate propholder and Widget
andy_robinson
parents:
817
diff
changeset
|
431 |
|
2004
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
432 |
class Sizer(Widget): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
433 |
"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
|
434 |
|
2004
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
435 |
_attrMap = AttrMap(BASE=shapes.SolidShape, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
436 |
contents = AttrMapValue(isListOfShapes,desc="Contained drawable elements"), |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
437 |
) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
438 |
def __init__(self, *elements): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
439 |
self.contents = [] |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
440 |
self.fillColor = colors.cyan |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
441 |
self.strokeColor = colors.magenta |
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2004
diff
changeset
|
442 |
|
2004
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
443 |
for elem in elements: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
444 |
self.add(elem) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
445 |
|
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
446 |
def _addNamedNode(self,name,node): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
447 |
'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
|
448 |
if name: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
449 |
if name not in self._attrMap.keys(): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
450 |
self._attrMap[name] = AttrMapValue(isValidChild) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
451 |
setattr(self, name, node) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
452 |
|
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
453 |
def add(self, node, name=None): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
454 |
"""Appends non-None child node to the 'contents' attribute. In addition, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
455 |
if a name is provided, it is subsequently accessible by name |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
456 |
""" |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
457 |
# propagates properties down |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
458 |
if node is not None: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
459 |
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
|
460 |
self.contents.append(node) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
461 |
self._addNamedNode(name,node) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
462 |
|
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
463 |
def getBounds(self): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
464 |
# get bounds of each object |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
465 |
if self.contents: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
466 |
b = [] |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
467 |
for elem in self.contents: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
468 |
b.append(elem.getBounds()) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
469 |
return shapes.getRectsBounds(b) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
470 |
else: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
471 |
return (0,0,0,0) |
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2004
diff
changeset
|
472 |
|
2004
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
473 |
def draw(self): |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
474 |
g = shapes.Group() |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
475 |
(x1, y1, x2, y2) = self.getBounds() |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
476 |
r = shapes.Rect( |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
477 |
x = x1, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
478 |
y = y1, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
479 |
width = x2-x1, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
480 |
height = y2-y1, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
481 |
fillColor = self.fillColor, |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
482 |
strokeColor = self.strokeColor |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
483 |
) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
484 |
g.add(r) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
485 |
for elem in self.contents: |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
486 |
g.add(elem) |
14a180d2691f
Added getBounds() logic throughout graphics hierarchy
andy_robinson
parents:
1687
diff
changeset
|
487 |
return g |
925 | 488 |
|
568 | 489 |
def test(): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
490 |
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
|
491 |
wedges = TypedPropertyCollection(WedgeProperties) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
492 |
wedges.fillColor = colors.red |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
493 |
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
|
494 |
print len(_ItemWrapper) |
951 | 495 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
496 |
d = shapes.Drawing(400, 200) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
497 |
tc = TwoCircles() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
498 |
d.add(tc) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
499 |
import renderPDF |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
500 |
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
|
501 |
print 'saved sample_widget.pdf' |
568 | 502 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
503 |
d = shapes.Drawing(400, 200) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
504 |
f = Face() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
505 |
f.skinColor = colors.yellow |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
506 |
f.mood = "sad" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
507 |
d.add(f, name='theFace') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
508 |
print 'drawing 1 properties:' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
509 |
d.dumpProperties() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
510 |
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
|
511 |
print 'saved face.pdf' |
568 | 512 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
513 |
d2 = d.expandUserNodes() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
514 |
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
|
515 |
print 'saved face_copy.pdf' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
516 |
print 'drawing 2 properties:' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1558
diff
changeset
|
517 |
d2.dumpProperties() |
568 | 518 |
|
925 | 519 |
|
568 | 520 |
if __name__=='__main__': |
1687 | 521 |
test() |