]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/layoutf.py
Insure suitable choices of path/drive separator on OS/2.
[wxWidgets.git] / wxPython / wx / lib / layoutf.py
CommitLineData
d14a1e28
RD
1from wxPython.wx import wxLayoutConstraints,\
2 wxTop, wxLeft, wxBottom, wxRight, \
3 wxHeight, wxWidth, wxCentreX, wxCentreY
4import re
5
6class Layoutf(wxLayoutConstraints):
7 """
8The class Layoutf(wxLayoutConstraints) presents a simplification
9of the wxLayoutConstraints syntax. The name Layoutf is choosen
10because of the similarity with C's printf function.
11
12Quick Example:
13
14 lc = Layoutf('t=t#1;l=r10#2;r!100;h%h50#1', (self, self.panel))
15
16is 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
24Usage:
25
26 You can give a constraint string to the Layoutf constructor,
27or 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
31and
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
37constraints, but prints traditional wxLayoutConstraint calls to
38stdout.
39
40 The calls to the Layoutf constructor and pack methods have
41the following argument list:
42
43 (constraint_string, objects_tuple)
44
45Constraint String syntax:
46
47 Constraint directives are separated by semi-colons. You
48generally (always?) need four directives to completely describe a
49subwindow'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>
68type. The following take type 1 (no object to compare with):
69
70 '!': 'Absolute', '?': 'Unconstrained', '*': 'AsIs'
71
72These take type 2 (need to be compared with another object)
73
74 '<': 'LeftOf', '>': 'RightOf', '^': 'Above', '_': 'Below'
75
76These take type 3 (need to be compared to another object
77attribute)
78
79 '=': 'SameAs', '%': 'PercentOf'
80
81For 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
87If the operation takes an (optional) numerical argument, place it
88in [numerical argument]. For type 3 directives, the <compare
89attribute> 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
95Note that these are the same letters as used for <own attribute>,
96so you'll only need to remember one set. Finally, the object
97whose attribute is refered to, is specified by #<compare object
98nr>, where <compare object nr> is the 1-based (stupid, I know,
99but I've gotten used to it) index of the object in the
100objects_tuple argument.
101
102Bugs:
103
104Not entirely happy about the logic in the order of arguments
105after the <compare operation> character.
106
107Not all wxLayoutConstraint methods are included in the
108syntax. However, the type 3 directives are generally the most
109used. Further excuse: wxWindows layout constraints are at the
110time 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
196if __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
1fded56b 262
1fded56b 263