]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/lib/layoutf.py
1 from wxPython
.wx
import wxLayoutConstraints
,\
2 wxTop
, wxLeft
, wxBottom
, wxRight
, \
3 wxHeight
, wxWidth
, wxCentreX
, wxCentreY
6 class Layoutf(wxLayoutConstraints
):
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.
14 lc = Layoutf('t=t#1;l=r10#2;r!100;h%h50#1', (self, self.panel))
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)
26 You can give a constraint string to the Layoutf constructor,
27 or use the 'pack' method. The following are equivalent:
29 lc = Layoutf('t=t#1;l=r#2;r!100;h%h50#1', (self, self.panel))
34 lc.pack('t=t#1;l=r#2;r!100;h%h50#1', (self, self.panel))
36 Besides 'pack' there's also 'debug_pack' which does not set
37 constraints, but prints traditional wxLayoutConstraint calls to
40 The calls to the Layoutf constructor and pack methods have
41 the following argument list:
43 (constraint_string, objects_tuple)
45 Constraint String syntax:
47 Constraint directives are separated by semi-colons. You
48 generally (always?) need four directives to completely describe a
51 A single directive has either of the following forms:
53 1. <own attribute><compare operation>[numerical argument]
54 for example r!100 -> lc.right.Absolute(100) )
55 and w* -> lc.width.AsIs()
57 2. <own attribute><compare operation>[numerical argument]
59 for example t_10#2 (lc.top.Below(<second obj>, 10)
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>,
67 Which one you need is defined by the <compare operation>
68 type. The following take type 1 (no object to compare with):
70 '!': 'Absolute', '?': 'Unconstrained', '*': 'AsIs'
72 These take type 2 (need to be compared with another object)
74 '<': 'LeftOf', '>': 'RightOf', '^': 'Above', '_': 'Below'
76 These take type 3 (need to be compared to another object
79 '=': 'SameAs', '%': 'PercentOf'
81 For all types, the <own attribute> letter can be any of
83 't': 'top', 'l': 'left', 'b': 'bottom',
84 'r': 'right', 'h': 'height', 'w': 'width',
85 'x': 'centreX', 'y': 'centreY'
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
91 't': 'wxTop', 'l': 'wxLeft', 'b': 'wxBottom'
92 'r': 'wxRight', 'h': 'wxHeight', 'w': 'wxWidth',
93 'x': 'wxCentreX', 'y': 'wxCentreY'
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.
104 Not entirely happy about the logic in the order of arguments
105 after the <compare operation> character.
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.
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' }
124 rexp1
= re
.compile('^\s*([tlrbhwxy])\s*([!\?\*])\s*(\d*)\s*$')
125 rexp2
= re
.compile('^\s*([tlrbhwxy])\s*([=%<>^_])\s*([tlrbhwxy]?)\s*(\d*)\s*#(\d+)\s*$')
127 def __init__(self
,pstr
=None,winlist
=None):
128 wxLayoutConstraints
.__init
__(self
)
130 self
.pack(pstr
,winlist
)
132 def pack(self
, pstr
, winlist
):
133 pstr
= string
.lower(pstr
)
134 for item
in string
.split(pstr
,';'):
135 m
= self
.rexp1
.match(item
)
138 attr
= getattr(self
, self
.attr_d
[g
[0]])
139 func
= getattr(attr
, self
.op_d
[g
[1]])
145 m
= self
.rexp2
.match(item
)
146 if not m
: raise ValueError
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])
154 if g
[3]: func(winlist
[g
[4]], g
[3])
155 else: func(winlist
[g
[4]])
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)
161 def debug_pack(self
, pstr
, winlist
):
162 pstr
= string
.lower(pstr
)
163 for item
in string
.split(pstr
,';'):
164 m
= self
.rexp1
.match(item
)
167 attr
= getattr(self
, self
.attr_d
[g
[0]])
168 func
= getattr(attr
, self
.op_d
[g
[1]])
170 print "%s.%s.%s(%s)" % \
171 ('self',self
.attr_d
[g
[0]],self
.op_d
[g
[1]],g
[2])
173 print "%s.%s.%s()" % \
174 ('self',self
.attr_d
[g
[0]],self
.op_d
[g
[1]])
176 m
= self
.rexp2
.match(item
)
177 if not m
: raise ValueError
179 if g
[3]: g
[3] = int(g
[3])
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]],
186 else: print "%s.%s.%s(%s)" % \
187 ('self',self
.attr_d
[g
[0]],self
.op_d
[g
[1]],winlist
[g
[4]])
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]],
196 if __name__
=='__main__':
197 from wxPython
.wx
import *
199 class TestLayoutf(wxFrame
):
200 def __init__(self
, parent
):
201 wxFrame
.__init
__(self
, parent
, -1, 'Test Layout Constraints',
202 wxPyDefaultPosition
, wxSize(500, 300))
204 self
.SetAutoLayout(true
)
205 EVT_BUTTON(self
, 100, self
.OnButton
)
206 EVT_BUTTON(self
, 101, self
.OnAbout
)
208 self
.panelA
= wxWindow(self
, -1, wxPyDefaultPosition
, wxPyDefaultSize
, wxSIMPLE_BORDER
)
209 self
.panelA
.SetBackgroundColour(wxBLUE
)
210 self
.panelA
.SetConstraints(Layoutf('t=t10#1;l=l10#1;b=b10#1;r%r50#1',(self
,)))
212 self
.panelB
= wxWindow(self
, -1, wxPyDefaultPosition
, wxPyDefaultSize
, wxSIMPLE_BORDER
)
213 self
.panelB
.SetBackgroundColour(wxRED
)
214 self
.panelB
.SetConstraints(Layoutf('t=t10#1;r=r10#1;b%b30#1;l>10#2', (self
,self
.panelA
)))
216 self
.panelC
= wxWindow(self
, -1, wxPyDefaultPosition
, wxPyDefaultSize
, wxSIMPLE_BORDER
)
217 self
.panelC
.SetBackgroundColour(wxWHITE
)
218 self
.panelC
.SetConstraints(Layoutf('t_10#3;r=r10#1;b=b10#1;l>10#2', (self
,self
.panelA
,self
.panelB
)))
220 b
= wxButton(self
.panelA
, 101, ' About: ')
221 b
.SetConstraints(Layoutf('X=X#1;Y=Y#1;h*;w%w50#1', (self
.panelA
,)))
223 b
= wxButton(self
.panelB
, 100, ' Panel B ')
224 b
.SetConstraints(Layoutf('t=t2#1;r=r4#1;h*;w*', (self
.panelB
,)))
226 self
.panelD
= wxWindow(self
.panelC
, -1, wxPyDefaultPosition
, wxPyDefaultSize
, wxSIMPLE_BORDER
)
227 self
.panelD
.SetBackgroundColour(wxGREEN
)
228 self
.panelD
.SetConstraints(Layoutf('b%h50#1;r%w50#1;h=h#2;w=w#2', (self
.panelC
, b
)))
230 b
= wxButton(self
.panelC
, 100, ' Panel C ')
231 b
.SetConstraints(Layoutf('t_#1;l>#1;h*;w*', (self
.panelD
,)))
233 wxStaticText(self
.panelD
, -1, "Panel D", wxPoint(4, 4)).SetBackgroundColour(wxGREEN
)
235 def OnButton(self
, event
):
238 def OnAbout(self
, event
):
240 from dialogs
import wxScrolledMessageDialog
241 msg
= wxScrolledMessageDialog(self
, Layoutf
.__doc
__, "about")
246 def OnCloseWindow(self
, event
):
249 class TestApp(wxApp
):
251 frame
= TestLayoutf(NULL
)
253 self
.SetTopWindow(frame
)