pathaxis direction added
[PyX/mjg.git] / design / attributes
blob80708e8e3239a127f22d6e188a124f2ee902e2f5
1 Attributes. Design summary.
2 ===========================
5 What are attributes?
6 --------------------
8 Attributes define properties of a given object when it is being used.
9 They are instances derived from the class attr.attr. Typically, there
10 are different kind of attributes which are usually orthogonal to each
11 other, while for one attribute kind, several choices are possible.
13     Example:
15     When stroking a path, the linewidth and the linestyle are
16     different kind of attributes. The linewidth might be normal, thin,
17     thick, or whatever else. The linestyle might be solid, dashed etc.
20 Where are attributes used?
21 --------------------------
23 Typically, attributes occur in lists passed as an optional keyword
24 argument to a method or a function. The object the attributes refer to
25 might be the first argument (not taking into account the self
26 argument) of the method, like in
28     canvas.stroke(path, [attr1, attr2, attr3])
31 Attribute categories
32 --------------------
34 There are different categories of attributes. We give a (not yet?)
35 complete list here:
37     - stroke attributes, aka strokestyles (style module)
38       inherited from style.strokestyle
39     - fill attributes, aka fillstyles
40       inherited from style.fillstyle
41     - text attributes, aka textattrs (text module)
42       inherited from style.textattr
43     - decorators (deco module)
44       inherited from deco.deco
45     - transformations (trafo module)
46     - clippings?
47       (AW: might go away; boxes could do that)
49 Operations usually allow for certain attibute categories only. For
50 example when stroking a path, text attributes are not allowed, while
51 stroke attributes and decoraters are. Some attributes might belong to
52 several attribute categories like colors, which are both, stroke and
53 fill attributes. This is described by multiple inheritance and the
54 attribute categories can be fetched by the buildin isinstance method.
57 Attribute instances as member variables
58 ---------------------------------------
60 Usable attributes are always instances. For simple mind attributes, we
61 have the following technology:
63     class linewidth(strokestyle):
65         def __init__(...):
66         etc.
68     linewidth.normal = linewidth("0.2 mm")
69     linewidth.thick = linewidth("0.2828 mm")
70     etc.
72 Thus there are different possibilities to get a linewidth: by
73 linewidth("0.25 mm") and by linewidth.normal (and the like).
76 Specializing attribute instances
77 --------------------------------
79 There might be more complicated attributes, where it is more
80 questionable, how attribute instances should be used. An easy, yet not
81 striking, example would be changes in some color parameters of a color
82 attribute. Consider a CMYK color, where only the blackness should be
83 changed. Thus we need to have a syntax for further specializing an
84 already existing attribute instance. This could be done by __call__
85 (or some arbitrary other named method --- the later would not really
86 be helpfull in the authors eyes). The code would look like:
88     some_cmyk_color = color.cmyk(0.1, 0.2, 0.3, 0.4)
89     darker_version = some_cmyk_color(b=1)
91 Both, some_cmyk_color and darker_version are instances of color.cmyk.
92 Since usually some parameters are to be changed only, the parameters
93 should be accessable by keyword arguments. Attribute lists in keyword
94 arguments could gain from the attribute replacement and clearing
95 functionality described below. Basically, the specialization (__call__
96 method) should take exactly the same arguments like the constructor
97 (__init__ method). It might be consistent to provide the
98 specialization possibility for all attribute instances.
101 Merging attribute lists
102 -----------------------
104 Attributes allow for exclusion, overwriting each other and ordering.
105 This process is called merging of attributes and it is performed by
106 the function merge from attr.py.
108 The merging process might take into account some default attributes.
109 They are passed in a special keyword argument.
111     Example:
113     use_attr_list = attr.merge(original_attr_list, defaults=default_attr_list)
115 When original_attr_list or a member of original_attr_list is None, the
116 result use_attr_list is None.
118 There are special clearing attributes, which overwrite other
119 attributes and do not add themself when merging an attribute list.
120 By that it is possible to certain or all default attributes. There are
121 prototypes for clearing attributes defined in attr.py.
123 XXX We might be more explicit about clearing attributes.
126 Changeable attributes
127 ---------------------
129 Changeable attributes are instances derived from attr.changeattr. They
130 provide a select method with the following prototype:
132     select(self, index, total)
134 The index is an unsigned integer and the total is a positive integer.
135 The select method might raise an ValueError, when the select method is
136 called for parameters, it doesn't allow for. An example would be a
137 color change from a starting color to an end color. Such a changeable
138 attribute would not allow for a total equals to 1.
140 The select function from attr.py returns a list of attributes out of a
141 list of attributes and changeable attributes. The prototype uses the
142 same index and total arguments, as described above:
144     select(attr_list, index, total)
146 When changeable attributes are used, the select process must be
147 performed previous to the merging.