]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/layoutf.py
removed second parameter from GetFirstChild calls
[wxWidgets.git] / wxPython / wx / lib / layoutf.py
1 from wxPython.wx import wxLayoutConstraints,\
2 wxTop, wxLeft, wxBottom, wxRight, \
3 wxHeight, wxWidth, wxCentreX, wxCentreY
4 import re
5
6 class Layoutf(wxLayoutConstraints):
7 """
8 The class Layoutf(wxLayoutConstraints) presents a simplification
9 of the wxLayoutConstraints syntax. The name Layoutf is choosen
10 because of the similarity with C's printf function.
11
12 Quick Example:
13
14 lc = Layoutf('t=t#1;l=r10#2;r!100;h%h50#1', (self, self.panel))
15
16 is equivalent to
17
18 lc = wxLayoutContraints()
19 lc.top.SameAs(self, wxTop)
20 lc.left.SameAs(self.panel, wxRight, 10)
21 lc.right.Absolute(100)
22 lc.height.PercentOf(self, wxHeight, 50)
23
24 Usage:
25
26 You can give a constraint string to the Layoutf constructor,
27 or use the 'pack' method. The following are equivalent:
28
29 lc = Layoutf('t=t#1;l=r#2;r!100;h%h50#1', (self, self.panel))
30
31 and
32
33 lc = Layoutf()
34 lc.pack('t=t#1;l=r#2;r!100;h%h50#1', (self, self.panel))
35
36 Besides 'pack' there's also 'debug_pack' which does not set
37 constraints, but prints traditional wxLayoutConstraint calls to
38 stdout.
39
40 The calls to the Layoutf constructor and pack methods have
41 the following argument list:
42
43 (constraint_string, objects_tuple)
44
45 Constraint String syntax:
46
47 Constraint directives are separated by semi-colons. You
48 generally (always?) need four directives to completely describe a
49 subwindow's location.
50
51 A single directive has either of the following forms:
52
53 1. <own attribute><compare operation>[numerical argument]
54 for example r!100 -> lc.right.Absolute(100) )
55 and w* -> lc.width.AsIs()
56
57 2. <own attribute><compare operation>[numerical argument]
58 #<compare object nr.>
59 for example t_10#2 (lc.top.Below(<second obj>, 10)
60
61 3. <own attribute><compare operation><compare attribute>
62 [numerical argument]#<compare object nr.>
63 for example w%h50#2 ( lc.width.PercentOf(<second obj>,
64 wxHeight, 50) and t=b#1 ( lc.top.SameAs(<first obj>,
65 wxBottom) )
66
67 Which one you need is defined by the <compare operation>
68 type. The following take type 1 (no object to compare with):
69
70 '!': 'Absolute', '?': 'Unconstrained', '*': 'AsIs'
71
72 These take type 2 (need to be compared with another object)
73
74 '<': 'LeftOf', '>': 'RightOf', '^': 'Above', '_': 'Below'
75
76 These take type 3 (need to be compared to another object
77 attribute)
78
79 '=': 'SameAs', '%': 'PercentOf'
80
81 For all types, the <own attribute> letter can be any of
82
83 't': 'top', 'l': 'left', 'b': 'bottom',
84 'r': 'right', 'h': 'height', 'w': 'width',
85 'x': 'centreX', 'y': 'centreY'
86
87 If the operation takes an (optional) numerical argument, place it
88 in [numerical argument]. For type 3 directives, the <compare
89 attribute> letter can be any of
90
91 't': 'wxTop', 'l': 'wxLeft', 'b': 'wxBottom'
92 'r': 'wxRight', 'h': 'wxHeight', 'w': 'wxWidth',
93 'x': 'wxCentreX', 'y': 'wxCentreY'
94
95 Note that these are the same letters as used for <own attribute>,
96 so you'll only need to remember one set. Finally, the object
97 whose attribute is refered to, is specified by #<compare object
98 nr>, where <compare object nr> is the 1-based (stupid, I know,
99 but I've gotten used to it) index of the object in the
100 objects_tuple argument.
101
102 Bugs:
103
104 Not entirely happy about the logic in the order of arguments
105 after the <compare operation> character.
106
107 Not all wxLayoutConstraint methods are included in the
108 syntax. However, the type 3 directives are generally the most
109 used. Further excuse: wxWindows layout constraints are at the
110 time of this writing not documented.
111
112 """
113
114 attr_d = { 't': 'top', 'l': 'left', 'b': 'bottom',
115 'r': 'right', 'h': 'height', 'w': 'width',
116 'x': 'centreX', 'y': 'centreY' }
117 op_d = { '=': 'SameAs', '%': 'PercentOf', '<': 'LeftOf',
118 '>': 'RightOf', '^': 'Above', '_': 'Below',
119 '!': 'Absolute', '?': 'Unconstrained', '*': 'AsIs' }
120 cmp_d = { 't': 'wxTop', 'l': 'wxLeft', 'b': 'wxBottom',
121 'r': 'wxRight', 'h': 'wxHeight', 'w': 'wxWidth',
122 'x': 'wxCentreX', 'y': 'wxCentreY' }
123
124 rexp1 = re.compile('^\s*([tlrbhwxy])\s*([!\?\*])\s*(\d*)\s*$')
125 rexp2 = re.compile('^\s*([tlrbhwxy])\s*([=%<>^_])\s*([tlrbhwxy]?)\s*(\d*)\s*#(\d+)\s*$')
126
127 def __init__(self,pstr=None,winlist=None):
128 wxLayoutConstraints.__init__(self)
129 if pstr:
130 self.pack(pstr,winlist)
131
132 def pack(self, pstr, winlist):
133 pstr = pstr.lower()
134 for item in pstr.split(';'):
135 m = self.rexp1.match(item)
136 if m:
137 g = list(m.groups())
138 attr = getattr(self, self.attr_d[g[0]])
139 func = getattr(attr, self.op_d[g[1]])
140 if g[1] == '!':
141 func(int(g[2]))
142 else:
143 func()
144 continue
145 m = self.rexp2.match(item)
146 if not m: raise ValueError
147 g = list(m.groups())
148 attr = getattr(self, self.attr_d[g[0]])
149 func = getattr(attr, self.op_d[g[1]])
150 if g[3]: g[3] = int(g[3])
151 else: g[3] = None;
152 g[4] = int(g[4]) - 1
153 if g[1] in '<>^_':
154 if g[3]: func(winlist[g[4]], g[3])
155 else: func(winlist[g[4]])
156 else:
157 cmp = eval(self.cmp_d[g[2]])
158 if g[3]: func(winlist[g[4]], cmp, g[3])
159 else: func(winlist[g[4]], cmp)
160
161 def debug_pack(self, pstr, winlist):
162 pstr = pstr.lower()
163 for item in pstr.split(';'):
164 m = self.rexp1.match(item)
165 if m:
166 g = list(m.groups())
167 attr = getattr(self, self.attr_d[g[0]])
168 func = getattr(attr, self.op_d[g[1]])
169 if g[1] == '!':
170 print "%s.%s.%s(%s)" % \
171 ('self',self.attr_d[g[0]],self.op_d[g[1]],g[2])
172 else:
173 print "%s.%s.%s()" % \
174 ('self',self.attr_d[g[0]],self.op_d[g[1]])
175 continue
176 m = self.rexp2.match(item)
177 if not m: raise ValueError
178 g = list(m.groups())
179 if g[3]: g[3] = int(g[3])
180 else: g[3] = 0;
181 g[4] = int(g[4]) - 1
182 if g[1] in '<>^_':
183 if g[3]: print "%s.%s.%s(%s,%d)" % \
184 ('self',self.attr_d[g[0]],self.op_d[g[1]],winlist[g[4]],
185 g[3])
186 else: print "%s.%s.%s(%s)" % \
187 ('self',self.attr_d[g[0]],self.op_d[g[1]],winlist[g[4]])
188 else:
189 if g[3]: print "%s.%s.%s(%s,%s,%d)" % \
190 ('self',self.attr_d[g[0]],self.op_d[g[1]],winlist[g[4]],
191 self.cmp_d[g[2]],g[3])
192 else: print "%s.%s.%s(%s,%s)" % \
193 ('self',self.attr_d[g[0]],self.op_d[g[1]],winlist[g[4]],
194 self.cmp_d[g[2]])
195
196 if __name__=='__main__':
197 from wxPython.wx import *
198
199 class TestLayoutf(wxFrame):
200 def __init__(self, parent):
201 wxFrame.__init__(self, parent, -1, 'Test Layout Constraints',
202 wxPyDefaultPosition, wxSize(500, 300))
203 EVT_CLOSE(self, self.OnCloseWindow)
204
205 self.SetAutoLayout(True)
206 EVT_BUTTON(self, 100, self.OnButton)
207 EVT_BUTTON(self, 101, self.OnAbout)
208
209 self.panelA = wxWindow(self, -1, wxPyDefaultPosition, wxPyDefaultSize, wxSIMPLE_BORDER)
210 self.panelA.SetBackgroundColour(wxBLUE)
211 self.panelA.SetConstraints(Layoutf('t=t10#1;l=l10#1;b=b10#1;r%r50#1',(self,)))
212
213 self.panelB = wxWindow(self, -1, wxPyDefaultPosition, wxPyDefaultSize, wxSIMPLE_BORDER)
214 self.panelB.SetBackgroundColour(wxRED)
215 self.panelB.SetConstraints(Layoutf('t=t10#1;r=r10#1;b%b30#1;l>10#2', (self,self.panelA)))
216
217 self.panelC = wxWindow(self, -1, wxPyDefaultPosition, wxPyDefaultSize, wxSIMPLE_BORDER)
218 self.panelC.SetBackgroundColour(wxWHITE)
219 self.panelC.SetConstraints(Layoutf('t_10#3;r=r10#1;b=b10#1;l>10#2', (self,self.panelA,self.panelB)))
220
221 b = wxButton(self.panelA, 101, ' About: ')
222 b.SetConstraints(Layoutf('X=X#1;Y=Y#1;h*;w%w50#1', (self.panelA,)))
223
224 b = wxButton(self.panelB, 100, ' Panel B ')
225 b.SetConstraints(Layoutf('t=t2#1;r=r4#1;h*;w*', (self.panelB,)))
226
227 self.panelD = wxWindow(self.panelC, -1, wxPyDefaultPosition, wxPyDefaultSize, wxSIMPLE_BORDER)
228 self.panelD.SetBackgroundColour(wxGREEN)
229 self.panelD.SetConstraints(Layoutf('b%h50#1;r%w50#1;h=h#2;w=w#2', (self.panelC, b)))
230
231 b = wxButton(self.panelC, 100, ' Panel C ')
232 b.SetConstraints(Layoutf('t_#1;l>#1;h*;w*', (self.panelD,)))
233
234 wxStaticText(self.panelD, -1, "Panel D", wxPoint(4, 4)).SetBackgroundColour(wxGREEN)
235
236 def OnButton(self, event):
237 self.Close(True)
238
239 def OnAbout(self, event):
240 try:
241 from dialogs import wxScrolledMessageDialog
242 msg = wxScrolledMessageDialog(self, Layoutf.__doc__, "about")
243 msg.ShowModal()
244 except:
245 print msg
246
247 def OnCloseWindow(self, event):
248 self.Destroy()
249
250 class TestApp(wxApp):
251 def OnInit(self):
252 frame = TestLayoutf(NULL)
253 frame.Show(1)
254 self.SetTopWindow(frame)
255 return 1
256
257 app = TestApp(0)
258 app.MainLoop()
259
260
261
262
263