]>
Commit | Line | Data |
---|---|---|
caeac82e RD |
1 | __author__ = "E. A. Tacao <e.a.tacao |at| estadao.com.br>" |
2 | __date__ = "12 Fev 2006, 22:00 GMT-03:00" | |
3 | __version__ = "0.03" | |
4 | __doc__ = """ | |
5 | ButtonTreeCtrlPanel is a widget where one can place check buttons, tri-state | |
6 | check buttons, radio buttons, both, and the ability to display them | |
7 | hierarchically. | |
8 | ||
9 | ||
10 | About: | |
11 | ||
12 | ButtonTreeCtrlPanel is distributed under the wxWidgets license. | |
13 | ||
14 | For all kind of problems, requests, enhancements, bug reports, etc, | |
15 | please drop me an e-mail. | |
16 | ||
17 | For updates please visit <http://j.domaindlx.com/elements28/wxpython/>. | |
18 | """ | |
19 | ||
20 | import cStringIO | |
21 | ||
22 | import wx | |
23 | from wx.lib.newevent import NewEvent | |
24 | ||
25 | #---------------------------------------------------------------------------- | |
26 | ||
27 | (ButtonTreeCtrlPanelEvent, EVT_BUTTONTREECTRLPANEL) = NewEvent() | |
28 | EVT_CHANGED = EVT_BUTTONTREECTRLPANEL | |
29 | ||
30 | #---------------------------------------------------------------------------- | |
31 | ||
32 | class ButtonTreeCtrlPanel(wx.Panel): | |
33 | def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, | |
34 | size=wx.DefaultSize, style=wx.WANTS_CHARS): | |
35 | wx.Panel.__init__(self, parent, id, pos, size, style) | |
36 | ||
37 | self.tree = wx.TreeCtrl(self, style=wx.TR_NO_LINES|wx.TR_HIDE_ROOT) | |
38 | ||
39 | il = self.il = wx.ImageList(16, 16) | |
40 | self.tree.SetImageList(il) | |
41 | ||
42 | for bl in ["checkbox_checked", "checkbox_unchecked", "checkbox_tri", | |
43 | "radiobox_checked", "radiobox_unchecked"]: | |
44 | setattr(self, bl, il.Add(getattr(self, "get%sBitmap" % bl)())) | |
45 | ||
46 | bmp = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_TOOLBAR, (16, 16)) | |
47 | self.empty_bitmap = il.Add(bmp) | |
48 | ||
49 | self.root = self.tree.AddRoot("Root Item for ButtonTreeCtrlPanel") | |
50 | ||
51 | self.Bind(wx.EVT_SIZE, self.OnSize) | |
52 | self.tree.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftClicks) | |
53 | self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftClicks) | |
54 | self.tree.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick) | |
55 | ||
56 | self.allitems = [] | |
57 | ||
58 | wx.CallAfter(self.OnSize) | |
59 | ||
60 | ||
61 | def _doLogicTest(self, style, value, item): | |
62 | if style in [wx.CHK_2STATE, wx.CHK_3STATE]: | |
63 | n = [self.checkbox_unchecked, self.checkbox_checked, \ | |
64 | self.checkbox_tri][value] | |
65 | ||
66 | self.tree.SetPyData(item, (value, style)) | |
67 | self.tree.SetItemImage(item, n, wx.TreeItemIcon_Normal) | |
68 | ||
69 | elif style == wx.RB_SINGLE: | |
70 | if value: | |
71 | parent = self.tree.GetItemParent(item) | |
72 | (child, cookie) = self.tree.GetFirstChild(parent) | |
73 | ||
74 | if self.tree.GetPyData(child): | |
75 | self.tree.SetPyData(child, (False, wx.RB_SINGLE)) | |
76 | self.tree.SetItemImage(child, self.radiobox_unchecked, \ | |
77 | wx.TreeItemIcon_Normal) | |
78 | ||
79 | for x in range(1, self.tree.GetChildrenCount(parent, False)): | |
80 | (child, cookie) = self.tree.GetNextChild(parent, cookie) | |
81 | ||
82 | if self.tree.GetPyData(child): | |
83 | self.tree.SetPyData(child, (False, wx.RB_SINGLE)) | |
84 | self.tree.SetItemImage(child, self.radiobox_unchecked, \ | |
85 | wx.TreeItemIcon_Normal) | |
86 | ||
87 | self.tree.SetPyData(item, (True, wx.RB_SINGLE)) | |
88 | self.tree.SetItemImage(item, self.radiobox_checked, \ | |
89 | wx.TreeItemIcon_Normal) | |
90 | ||
91 | else: | |
92 | self.tree.SetPyData(item, (False, wx.RB_SINGLE)) | |
93 | self.tree.SetItemImage(item, self.radiobox_unchecked, \ | |
94 | wx.TreeItemIcon_Normal) | |
95 | ||
96 | ||
97 | def _getItems(self, parent=None, value=None): | |
98 | if not parent: | |
99 | parent = self.root | |
100 | cil = [] | |
101 | (child, cookie) = self.tree.GetFirstChild(parent) | |
102 | if child.IsOk(): | |
103 | d = self.tree.GetPyData(child) | |
104 | if value is None or (d and d[0] == value): | |
105 | cil.append(child) | |
106 | for x in range(1, self.tree.GetChildrenCount(parent, False)): | |
107 | (child, cookie) = self.tree.GetNextChild(parent, cookie) | |
108 | if child.IsOk(): | |
109 | d = self.tree.GetPyData(child) | |
110 | if value is None or (d and d[0] == value): | |
111 | cil.append(child) | |
112 | return cil | |
113 | ||
114 | ||
115 | def AddItem(self, label, bmp=None, parent=None, style=None, value=False): | |
116 | v = None | |
117 | ||
118 | if bmp: | |
119 | n = self.il.Add(bmp) | |
120 | if not parent: | |
121 | parent = self.root | |
122 | if style is not None: | |
123 | v = (value, style) | |
124 | ||
125 | this_item = self.tree.AppendItem(parent, label) | |
126 | self.tree.SetPyData(this_item, v) | |
127 | ||
128 | if v: | |
129 | self._doLogicTest(style, value, this_item) | |
130 | else: | |
131 | if bmp is None: | |
132 | bmp = self.empty_bitmap | |
133 | else: | |
134 | bmp = self.il.Add(bmp) | |
135 | ||
136 | self.tree.SetItemImage(this_item, bmp, wx.TreeItemIcon_Normal) | |
137 | ||
138 | self.allitems.append(this_item) | |
139 | [self.tree.Expand(x) for x in self.allitems] | |
140 | ||
141 | return this_item | |
142 | ||
143 | ||
144 | def ExpandItem(self, item): | |
145 | self.tree.Expand(item) | |
146 | ||
147 | ||
148 | def CollapseItem(self, item): | |
149 | self.tree.Collapse(item) | |
150 | ||
151 | ||
152 | def EnsureFirstVisible(self): | |
153 | (child, cookie) = self.tree.GetFirstChild(self.root) | |
154 | if child.IsOk(): | |
155 | self.tree.SelectItem(child) | |
156 | self.tree.EnsureVisible(child) | |
157 | ||
158 | ||
159 | def SetItemValue(self, item, value): | |
160 | data = self.tree.GetPyData(item) | |
161 | if data: | |
162 | self._doLogicTest(data[1], value, item) | |
163 | ||
164 | ||
165 | def GetItemValue(self, item): | |
166 | data = self.tree.GetPyData(item) | |
167 | if data: | |
168 | return data[0] | |
169 | else: | |
170 | return None | |
171 | ||
172 | ||
173 | def GetItemByLabel(self, label, parent=None): | |
174 | r = None | |
175 | for item in self._getItems(parent): | |
176 | if self.tree.GetItemText(item) == label: | |
177 | r = item; break | |
178 | return r | |
179 | ||
180 | ||
181 | def GetAllItems(self): | |
182 | return self.allitems | |
183 | ||
184 | ||
185 | def GetRootItems(self): | |
186 | cil = [] | |
187 | for x in range(0, len(self.allitems)): | |
188 | d = self.tree.GetPyData(self.allitems[x]) | |
189 | if not d: | |
190 | cil.append(self.allitems[x]) | |
191 | return cil | |
192 | ||
193 | ||
194 | def GetStringRootItems(self): | |
195 | return [self.tree.GetItemText(x) for x in self.GetRootItems] | |
196 | ||
197 | ||
198 | def GetItemsUnchecked(self, parent=None): | |
199 | return self._getItems(parent, 0) | |
200 | ||
201 | ||
202 | def GetItemsChecked(self, parent=None): | |
203 | return self._getItems(parent, 1) | |
204 | ||
205 | ||
206 | def GetItemsTri(self, parent=None): | |
207 | return self._getItems(parent, 2) | |
208 | ||
209 | ||
210 | def GetStringItemsUnchecked(self, parent=None): | |
211 | return [self.tree.GetItemText(x) \ | |
212 | for x in self.GetItemsUnchecked(parent)] | |
213 | ||
214 | ||
215 | def GetStringItemsChecked(self, parent=None): | |
216 | return [self.tree.GetItemText(x) for x in self.GetItemsChecked(parent)] | |
217 | ||
218 | ||
219 | def GetStringItemsTri(self, parent=None): | |
220 | return [self.tree.GetItemText(x) for x in self.GetItemsTri(parent)] | |
221 | ||
222 | ||
223 | def OnRightClick(self, evt): | |
224 | item, flags = self.tree.HitTest(evt.GetPosition()) | |
225 | self.tree.SelectItem(item) | |
226 | ||
227 | ||
228 | def OnLeftClicks(self, evt): | |
229 | item, flags = self.tree.HitTest(evt.GetPosition()) | |
230 | if item: | |
231 | text, data = self.tree.GetItemText(item), self.tree.GetPyData(item) | |
232 | if data: | |
233 | style = data[1] | |
234 | if style == wx.CHK_2STATE: | |
235 | value = not data[0] | |
236 | elif style == wx.CHK_3STATE: | |
237 | value = data[0] + 1 | |
238 | if value == 3: value = 0 | |
239 | else: | |
240 | value = True | |
241 | ||
242 | self._doLogicTest(style, value, item) | |
243 | ||
244 | if value <> data[0]: | |
245 | nevt = ButtonTreeCtrlPanelEvent(obj=self, id=self.GetId(), | |
246 | item=item, val=value) | |
247 | wx.PostEvent(self, nevt) | |
248 | ||
249 | evt.Skip() | |
250 | ||
251 | ||
252 | def OnSize(self, evt=None): | |
253 | self.tree.SetSize(self.GetClientSize()) | |
254 | ||
255 | # # Images generated by encode_bitmaps.py ----------------------------- | |
256 | ||
257 | def getcheckbox_uncheckedData(self): | |
258 | return \ | |
259 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
260 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
261 | \x00\x00AIDAT8\x8d\xed\x93;\x0e\x00 \x14\xc2\xca\xd3\xfb\xdf\xd8\xcf\xac\x83\ | |
262 | \x89\xe2dd\xa7\xe9\x00R$\x9c\x84\xd5\x062@\xab\xa5\xed\x16\x15I\xf7\x0cf\xea\ | |
263 | *\xb3\xadm\xf0\x01O\x00\x86!\x9dL\xda6\x90{\xe7\x0e\xbf\x98\x0c*\xf3\x13\xe2\ | |
264 | e\x00\x00\x00\x00IEND\xaeB`\x82' | |
265 | ||
266 | def getcheckbox_uncheckedBitmap(self): | |
267 | return wx.BitmapFromImage(self.getcheckbox_uncheckedImage()) | |
268 | ||
269 | def getcheckbox_uncheckedImage(self): | |
270 | stream = cStringIO.StringIO(self.getcheckbox_uncheckedData()) | |
271 | return wx.ImageFromStream(stream) | |
272 | ||
273 | #---------------------------------------------------------------------- | |
274 | def getradiobox_checkedData(self): | |
275 | return \ | |
276 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
277 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
278 | \x00\x00qIDAT8\x8d\xadR\xd1\x12\x80 \x08\x03\xed\xff\xffX\xe9\xa9n\xd1\xe6\ | |
279 | \xd9\x11o\xca6\x18\xe0\xde\xbaU\xa2\x95\xd8fv\xa8D\xcc\x11\xf8\xf6\xd6\x9d\ | |
280 | \xe1<[\xc8\xc4\x17!\t=\x04\x90\x9c\x81*Gg\xc0\xdaU\x16n\x81\xab\x02\x02c\x8e\ | |
281 | `\x95\xf1On\x01A\xab\xb9\x94\xd7(\x05\xd0\x8a\xf2o&\xb6\xa0\x08,O;`\x9e\xd5\ | |
282 | \x1c\xfe=\xa4\x95\xd0\xf6)\x7f\x8d\xf2\x1aO_y@8\xb08r\xf9\x00\x00\x00\x00IEN\ | |
283 | D\xaeB`\x82' | |
284 | ||
285 | def getradiobox_checkedBitmap(self): | |
286 | return wx.BitmapFromImage(self.getradiobox_checkedImage()) | |
287 | ||
288 | def getradiobox_checkedImage(self): | |
289 | stream = cStringIO.StringIO(self.getradiobox_checkedData()) | |
290 | return wx.ImageFromStream(stream) | |
291 | ||
292 | #---------------------------------------------------------------------- | |
293 | def getradiobox_uncheckedData(self): | |
294 | return \ | |
295 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
296 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
297 | \x00\x00gIDAT8\x8d\xcd\x92K\x12\x800\x08C\x81z\xff\x1bk\xbb\xd2\xc1\x98t\xea\ | |
298 | \xe0Bv\x1d\xc8k\xf8\xb8G\xb3JDImf\x9bJ\xf4c\xef\xf9\xed\xd1\x9c\xd59\xb6\x80\ | |
299 | \xc2\x87\x00@7@\x16c\xa1\xca\xd1\x190\xbb\xaa\x85\x0bp\xfe\xa0\ns.\xbb)o\xe1\ | |
300 | G\x00\xd6\x1f\x06\x9b\x13u\xc0 \n\xfc\xed!\xcd@\xcb\xa7\xfc6\xca[\x18\xdf\ | |
301 | \x0e0Ao\x7fq\xe8\x00\x00\x00\x00IEND\xaeB`\x82' | |
302 | ||
303 | def getradiobox_uncheckedBitmap(self): | |
304 | return wx.BitmapFromImage(self.getradiobox_uncheckedImage()) | |
305 | ||
306 | def getradiobox_uncheckedImage(self): | |
307 | stream = cStringIO.StringIO(self.getradiobox_uncheckedData()) | |
308 | return wx.ImageFromStream(stream) | |
309 | ||
310 | #---------------------------------------------------------------------- | |
311 | def getcheckbox_checkedData(self): | |
312 | return \ | |
313 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
314 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
315 | \x00\x00gIDAT8\x8d\xad\x93Q\x0e\x800\x08C[\xe6\xfdo\xac\xf3k\x89\xa9\xb01\ | |
316 | \x91o^S\xa0\x90\xd6P)+\xd1\x00\x0e\x00\xe8\xd7\xd9wAZ\xe3\x7f\x0eTuV\xea6\ | |
317 | \xed \x1a3%0\xdb\xd1K@\x9bW\x0bv\x1d\x0c\xe8\tG\xfb\tG\xc8\xc0\xae\x806\xaf.\ | |
318 | \xe3:\x18P\xe6\xac\xe1\x08\x19\x18\x90 }\x89t9\xca\xac\xbe\xf3\r?\xc9(*%&\ | |
319 | \xec\x9b\x00\x00\x00\x00IEND\xaeB`\x82' | |
320 | ||
321 | def getcheckbox_checkedBitmap(self): | |
322 | return wx.BitmapFromImage(self.getcheckbox_checkedImage()) | |
323 | ||
324 | def getcheckbox_checkedImage(self): | |
325 | stream = cStringIO.StringIO(self.getcheckbox_checkedData()) | |
326 | return wx.ImageFromStream(stream) | |
327 | ||
328 | #---------------------------------------------------------------------- | |
329 | def getcheckbox_triData(self): | |
330 | return \ | |
331 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
332 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
333 | \x00\x00pIDAT8\x8d\xad\x93A\x0e\x800\x08\x04\x97\xea\xab\xd4\xa3\xfah\xf5h\ | |
334 | \xfdV{jb\x08 \x8a\x9c\x99\xcd\xd0l\x89R\x87\xc8\xa4\x10\r\xa0\x07\x80i\x1c\ | |
335 | \xca[\xf0\xcc\x17\xfdg\xc0S\xad\xe1\xb6n\x83c\xdf\xc43]\x01\x1a,\x06\xf0e\ | |
336 | \x0bV\r\x1at\x87\xe7e\x15\xdfG=\xc1\x03\x8b\x01|\xd9\x82U\x83\x06=\xc1j\x80\ | |
337 | \x17\x06X\x91\xbeT:\\e\x8a~\xe7\nM\x85%\xe1\xceT8v\x00\x00\x00\x00IEND\xaeB`\ | |
338 | \x82' | |
339 | ||
340 | def getcheckbox_triBitmap(self): | |
341 | return wx.BitmapFromImage(self.getcheckbox_triImage()) | |
342 | ||
343 | def getcheckbox_triImage(self): | |
344 | stream = cStringIO.StringIO(self.getcheckbox_triData()) | |
345 | return wx.ImageFromStream(stream) | |
346 | ||
347 | ||
348 | # | |
349 | ## | |
350 | ### eof |