]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/mixins/inspect.py
1 #----------------------------------------------------------------------------
2 # Name: wx.lib.mixins.inspect
3 # Purpose: A mix-in class that can add PyCrust-based inspection of the
4 # app's widgets and sizers.
10 # Copyright: (c) 2006 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------------
14 # NOTE: This class was originally based on ideas sent to the
15 # wxPython-users mail list by Dan Eloff.
23 class InspectionMixin(object):
25 This class is intended to be used as a mix-in with the wx.App
26 class. When used it will add the ability to popup a
27 InspectionFrame window where the widget under the mouse cursor
28 will be selected in the tree and loaded into the shell's namespace
29 as 'obj'. The default key sequence to activate the inspector is
30 Ctrl-Alt-I (or Cmd-Alt-I on Mac) but this can be changed via
31 parameters to the `Init` method, or the application can call
32 `ShowInspectionTool` from other event handlers if desired.
34 To use this class simply derive a class from wx.App and
35 InspectionMixin and then call the `Init` method from the app's
38 def Init(self
, pos
=(-1, -1), size
=(850,700), config
=None, locals=None,
39 alt
=True, cmd
=True, shift
=False, keyCode
=ord('I')):
41 Make the event binding that will activate the InspectionFrame window.
43 self
.Bind(wx
.EVT_KEY_DOWN
, self
._OnKeyPress
)
52 self
._keyCode
= keyCode
55 def _OnKeyPress(self
, evt
):
57 Event handler, check for our hot-key. Normally it is
58 Ctrl-Alt-I but that can be changed by what is passed to the
61 if evt
.AltDown() == self
._alt
and \
62 evt
.CmdDown() == self
._cmd
and \
63 evt
.ShiftDown() == self
._shift
and \
64 evt
.GetKeyCode() == self
._keyCode
:
65 self
.ShowInspectionTool()
70 def ShowInspectionTool(self
):
72 Show the Inspection tool, creating it if neccesary.
75 self
._tool
= InspectionFrame(parent
=self
.GetTopWindow(),
81 # get the current widget under the mouse
82 wnd
= wx
.FindWindowAtPointer()
83 self
._tool
.SetObj(wnd
)
89 #---------------------------------------------------------------------------
91 class InspectionFrame(wx
.Frame
):
93 This class is the frame that holds the wxPython inspection tools.
94 The toolbar and splitter windows are also managed here. The
95 contents of the splitter windows are handled by other classes.
97 def __init__(self
, wnd
=None, locals=None, config
=None,
98 app
=None, title
="wxPython Widget Inspection Tool",
101 wx
.Frame
.__init
__(self
, *args
, **kw
)
103 self
.includeSizers
= False
108 self
.outerSplitter
= wx
.SplitterWindow(self
,style
=wx
.SP_3D|wx
.SP_LIVE_UPDATE
)
109 self
.innerSplitter
= wx
.SplitterWindow(self
.outerSplitter
,style
=wx
.SP_3D|wx
.SP_LIVE_UPDATE
)
110 self
.tree
= InspectionTree(self
.outerSplitter
)
111 self
.info
= InspectionInfoPanel(self
.innerSplitter
)
116 "Python %s on %s\nNOTE: The 'obj' variable refers to the selected object."
117 % (sys
.version
.split()[0], sys
.platform
))
118 self
.crust
= wx
.py
.crust
.Crust(self
.innerSplitter
, locals=locals,
120 showInterpIntro
=False,
122 self
.locals = self
.crust
.shell
.interp
.locals
123 self
.crust
.shell
.interp
.introText
= ''
124 self
.locals['obj'] = self
.obj
= wnd
125 self
.locals['app'] = app
126 self
.locals['wx'] = wx
127 wx
.CallAfter(self
._postStartup
)
129 self
.innerSplitter
.SplitHorizontally(self
.info
, self
.crust
, -225)
130 self
.outerSplitter
.SplitVertically(self
.tree
, self
.innerSplitter
, 280)
131 self
.outerSplitter
.SetMinimumPaneSize(20)
132 self
.innerSplitter
.SetMinimumPaneSize(20)
135 def MakeToolBar(self
):
136 tbar
= self
.CreateToolBar(wx
.TB_HORIZONTAL | wx
.TB_FLAT | wx
.TB_TEXT | wx
.NO_BORDER
)
137 tbar
.SetToolBitmapSize((20,20))
139 refreshBmp
= getRefreshBitmap()
140 findWidgetBmp
= getFindBitmap()
141 showSizersBmp
= getShowSizersBitmap()
142 toggleFillingBmp
= getShowFillingBitmap()
144 refreshTool
= tbar
.AddLabelTool(-1, 'Refresh', refreshBmp
,
145 shortHelp
= 'Refresh widget tree')
146 findWidgetTool
= tbar
.AddLabelTool(-1, 'Find', findWidgetBmp
,
147 shortHelp
='Find new target widget. Click here and\nthen on another widget in the app.')
148 showSizersTool
= tbar
.AddLabelTool(-1, 'Sizers', showSizersBmp
,
149 shortHelp
='Include sizers in widget tree',
151 toggleFillingTool
= tbar
.AddLabelTool(-1, 'Filling', toggleFillingBmp
,
152 shortHelp
='Show PyCrust \'filling\'',
156 self
.Bind(wx
.EVT_TOOL
, self
.OnRefreshTree
, refreshTool
)
157 self
.Bind(wx
.EVT_TOOL
, self
.OnFindWidget
, findWidgetTool
)
158 self
.Bind(wx
.EVT_TOOL
, self
.OnShowSizers
, showSizersTool
)
159 self
.Bind(wx
.EVT_TOOL
, self
.OnToggleFilling
, toggleFillingTool
)
160 self
.Bind(wx
.EVT_UPDATE_UI
, self
.OnShowSizersUI
, showSizersTool
)
161 self
.Bind(wx
.EVT_UPDATE_UI
, self
.OnToggleFillingUI
, toggleFillingTool
)
165 def _postStartup(self
):
166 if self
.crust
.ToolsShown():
167 self
.crust
.ToggleTools()
171 def UpdateInfo(self
):
172 self
.info
.Update(self
.obj
)
174 def SetObj(self
, obj
):
177 self
.locals['obj'] = self
.obj
= obj
179 if not self
.tree
.built
:
180 self
.tree
.BuildTree(obj
, includeSizers
=self
.includeSizers
)
182 self
.tree
.SelectObj(obj
)
185 def RefreshTree(self
):
186 self
.tree
.BuildTree(self
.obj
, includeSizers
=self
.includeSizers
)
189 def OnRefreshTree(self
, evt
):
193 def OnFindWidget(self
, evt
):
194 self
.Bind(wx
.EVT_LEFT_DOWN
, self
.OnLeftDown
)
195 self
.Bind(wx
.EVT_MOUSE_CAPTURE_LOST
, self
.OnCaptureLost
)
197 self
.finding
= wx
.BusyInfo("Click on any widget in the app...")
199 def OnCaptureLost(self
, evt
):
200 self
.Unbind(wx
.EVT_LEFT_DOWN
)
201 self
.Unbind(wx
.EVT_MOUSE_CAPTURE_LOST
)
204 def OnLeftDown(self
, evt
):
206 wnd
= wx
.FindWindowAtPointer()
211 self
.OnCaptureLost(evt
)
214 def OnShowSizers(self
, evt
):
215 self
.includeSizers
= not self
.includeSizers
219 def OnToggleFilling(self
, evt
):
220 self
.crust
.ToggleTools()
223 def OnShowSizersUI(self
, evt
):
224 evt
.Check(self
.includeSizers
)
227 def OnToggleFillingUI(self
, evt
):
229 evt
.Check(self
.crust
.ToolsShown())
233 #---------------------------------------------------------------------------
235 # should inspection frame (and children) be includeed in the tree?
236 INCLUDE_INSPECTOR
= True
238 class InspectionTree(wx
.TreeCtrl
):
240 All of the widgets in the app, and optionally their sizers, are
241 loaded into this tree.
243 def __init__(self
, *args
, **kw
):
244 #s = kw.get('style', 0)
245 #kw['style'] = s | wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT
246 wx
.TreeCtrl
.__init
__(self
, *args
, **kw
)
249 self
.Bind(wx
.EVT_TREE_SEL_CHANGED
, self
.OnSelectionChanged
)
252 def BuildTree(self
, startWidget
, includeSizers
=False):
254 self
.DeleteAllItems()
258 realRoot
= self
.AddRoot('Top-level Windows')
260 for w
in wx
.GetTopLevelWindows():
261 if w
is wx
.GetTopLevelParent(self
) and not INCLUDE_INSPECTOR
:
263 root
= self
._AddWidget
(realRoot
, w
, includeSizers
)
264 self
.roots
.append(root
)
266 # Expand the subtree containing the startWidget, and select it.
267 if not startWidget
or not isinstance(startWidget
, wx
.Window
):
268 startWidget
= wx
.GetApp().GetTopWindow()
269 top
= wx
.GetTopLevelParent(startWidget
)
270 topItem
= self
.FindWidgetItem(top
)
272 self
.ExpandAllChildren(topItem
)
273 self
.SelectObj(startWidget
)
277 def _AddWidget(self
, parentItem
, widget
, includeSizers
):
278 text
= self
.GetTextForWidget(widget
)
279 item
= self
.AppendItem(parentItem
, text
)
280 self
.SetItemPyData(item
, widget
)
282 # Add the sizer and widgets in the sizer, if we're showing them
284 if includeSizers
and widget
.GetSizer() is not None:
285 widgetsInSizer
= self
._AddSizer
(item
, widget
.GetSizer())
287 # Add any children not in the sizer, or all children if we're
288 # not showing the sizers
289 for child
in widget
.GetChildren():
290 if not child
in widgetsInSizer
and not child
.IsTopLevel():
291 self
._AddWidget
(item
, child
, includeSizers
)
296 def _AddSizer(self
, parentItem
, sizer
):
298 text
= self
.GetTextForSizer(sizer
)
299 item
= self
.AppendItem(parentItem
, text
)
300 self
.SetItemPyData(item
, sizer
)
301 self
.SetItemTextColour(item
, "blue")
303 for si
in sizer
.GetChildren():
306 self
._AddWidget
(item
, w
, True)
309 widgets
+= self
._AddSizer
(item
, si
.GetSizer())
311 i
= self
.AppendItem(item
, "Spacer")
312 self
.SetItemPyData(i
, si
)
313 self
.SetItemTextColour(i
, "blue")
317 def FindWidgetItem(self
, widget
):
319 Find the tree item for a widget.
321 for item
in self
.roots
:
322 found
= self
._FindWidgetItem
(widget
, item
)
327 def _FindWidgetItem(self
, widget
, item
):
328 if self
.GetItemPyData(item
) is widget
:
330 child
, cookie
= self
.GetFirstChild(item
)
332 found
= self
._FindWidgetItem
(widget
, child
)
335 child
, cookie
= self
.GetNextChild(item
, cookie
)
339 def GetTextForWidget(self
, widget
):
341 Returns the string to be used in the tree for a widget
343 return "%s (\"%s\")" % (widget
.__class
__.__name
__, widget
.GetName())
345 def GetTextForSizer(self
, sizer
):
347 Returns the string to be used in the tree for a sizer
349 return "%s" % sizer
.__class
__.__name
__
352 def SelectObj(self
, obj
):
353 item
= self
.FindWidgetItem(obj
)
355 self
.EnsureVisible(item
)
356 self
.SelectItem(item
)
359 def OnSelectionChanged(self
, evt
):
360 obj
= self
.GetItemPyData(evt
.GetItem())
361 toolFrm
= wx
.GetTopLevelParent(self
)
365 #---------------------------------------------------------------------------
367 class InspectionInfoPanel(wx
.stc
.StyledTextCtrl
):
369 Used to display information about the currently selected items.
370 Currently just a read-only wx.stc.StyledTextCtrl with some plain
371 text. Should probably add some styles to make things easier to
374 def __init__(self
, *args
, **kw
):
375 wx
.stc
.StyledTextCtrl
.__init
__(self
, *args
, **kw
)
377 from wx
.py
.editwindow
import FACES
378 self
.StyleSetSpec(wx
.stc
.STC_STYLE_DEFAULT
,
379 "face:%(mono)s,size:%(size)d,back:%(backcol)s" % FACES
)
381 self
.SetReadOnly(True)
384 def Update(self
, obj
):
387 st
.append("Item is None or has been destroyed.")
389 elif isinstance(obj
, wx
.Window
):
390 st
+= self
.FmtWidget(obj
)
392 elif isinstance(obj
, wx
.Sizer
):
393 st
+= self
.FmtSizer(obj
)
395 elif isinstance(obj
, wx
.SizerItem
):
396 st
+= self
.FmtSizerItem(obj
)
398 #self.SetValue('\n'.join(st))
399 self
.SetReadOnly(False)
400 self
.SetText('\n'.join(st
))
401 self
.SetReadOnly(True)
404 def Fmt(self
, name
, value
):
405 if isinstance(value
, (str, unicode)):
406 return " %s = '%s'" % (name
, value
)
408 return " %s = %s" % (name
, value
)
411 def FmtWidget(self
, obj
):
413 st
.append(self
.Fmt('name', obj
.GetName()))
414 st
.append(self
.Fmt('class', obj
.__class
__))
415 st
.append(self
.Fmt('bases', obj
.__class
__.__bases
__))
416 st
.append(self
.Fmt('id', obj
.GetId()))
417 st
.append(self
.Fmt('style', obj
.GetWindowStyle()))
418 st
.append(self
.Fmt('pos', obj
.GetPosition()))
419 st
.append(self
.Fmt('size', obj
.GetSize()))
420 st
.append(self
.Fmt('minsize', obj
.GetMinSize()))
421 st
.append(self
.Fmt('bestsize', obj
.GetBestSize()))
422 st
.append(self
.Fmt('client size',obj
.GetClientSize()))
423 st
.append(self
.Fmt('IsEnabled', obj
.IsEnabled()))
424 st
.append(self
.Fmt('IsShown', obj
.IsShown()))
425 st
.append(self
.Fmt('fg color', obj
.GetForegroundColour()))
426 st
.append(self
.Fmt('bg color', obj
.GetBackgroundColour()))
427 st
.append(self
.Fmt('label', obj
.GetLabel()))
428 if hasattr(obj
, 'GetTitle'):
429 st
.append(self
.Fmt('title', obj
.GetTitle()))
430 if hasattr(obj
, 'GetValue'):
431 st
.append(self
.Fmt('value', obj
.GetValue()))
432 if obj
.GetContainingSizer() is not None:
434 sizer
= obj
.GetContainingSizer()
435 st
+= self
.FmtSizerItem(sizer
.GetItem(obj
))
439 def FmtSizerItem(self
, obj
):
441 st
.append(self
.Fmt('proportion', obj
.GetProportion()))
442 st
.append(self
.Fmt('flag',
443 FlagsFormatter(itemFlags
, obj
.GetFlag())))
444 st
.append(self
.Fmt('border', obj
.GetBorder()))
445 st
.append(self
.Fmt('pos', obj
.GetPosition()))
446 st
.append(self
.Fmt('size', obj
.GetSize()))
447 st
.append(self
.Fmt('minsize', obj
.GetMinSize()))
448 st
.append(self
.Fmt('ratio', obj
.GetRatio()))
449 st
.append(self
.Fmt('IsWindow', obj
.IsWindow()))
450 st
.append(self
.Fmt('IsSizer', obj
.IsSizer()))
451 st
.append(self
.Fmt('IsSpacer', obj
.IsSpacer()))
452 st
.append(self
.Fmt('IsShown', obj
.IsShown()))
453 if isinstance(obj
, wx
.GBSizerItem
):
454 st
.append(self
.Fmt('cellpos', obj
.GetPos()))
455 st
.append(self
.Fmt('cellspan', obj
.GetSpan()))
456 st
.append(self
.Fmt('endpos', obj
.GetEndPos()))
460 def FmtSizer(self
, obj
):
462 st
.append(self
.Fmt('class', obj
.__class
__))
463 st
.append(self
.Fmt('pos', obj
.GetPosition()))
464 st
.append(self
.Fmt('size', obj
.GetSize()))
465 st
.append(self
.Fmt('minsize', obj
.GetMinSize()))
466 if isinstance(obj
, wx
.BoxSizer
):
467 st
.append(self
.Fmt('orientation',
468 FlagsFormatter(orientFlags
, obj
.GetOrientation())))
469 if isinstance(obj
, wx
.GridSizer
):
470 st
.append(self
.Fmt('cols', obj
.GetCols()))
471 st
.append(self
.Fmt('rows', obj
.GetRows()))
472 st
.append(self
.Fmt('vgap', obj
.GetVGap()))
473 st
.append(self
.Fmt('hgap', obj
.GetHGap()))
474 if isinstance(obj
, wx
.FlexGridSizer
):
475 st
.append(self
.Fmt('rowheights', obj
.GetRowHeights()))
476 st
.append(self
.Fmt('colwidths', obj
.GetColWidths()))
477 st
.append(self
.Fmt('flexdir',
478 FlagsFormatter(orientFlags
, obj
.GetFlexibleDirection())))
479 st
.append(self
.Fmt('nonflexmode',
480 FlagsFormatter(flexmodeFlags
, obj
.GetNonFlexibleGrowMode())))
481 if isinstance(obj
, wx
.GridBagSizer
):
482 st
.append(self
.Fmt('emptycell', obj
.GetEmptyCellSize()))
484 if obj
.GetContainingWindow():
485 si
= obj
.GetContainingWindow().GetSizer().GetItem(obj
)
488 st
+= self
.FmtSizerItem(si
)
492 class FlagsFormatter(object):
493 def __init__(self
, d
, val
):
499 for k
in self
.d
.keys():
508 wx
.HORIZONTAL
: 'wx.HORIZONTAL',
509 wx
.VERTICAL
: 'wx.VERTICAL',
514 wx
.BOTTOM
: 'wx.BOTTOM',
516 wx
.RIGHT
: 'wx.RIGHT',
518 wx
.EXPAND
: 'wx.EXPAND',
519 # wx.GROW : 'wx.GROW',
520 wx
.SHAPED
: 'wx.SHAPED',
521 wx
.STRETCH_NOT
: 'wx.STRETCH_NOT',
522 wx
.ALIGN_CENTER
: 'wx.ALIGN_CENTER',
523 wx
.ALIGN_LEFT
: 'wx.ALIGN_LEFT',
524 wx
.ALIGN_RIGHT
: 'wx.ALIGN_RIGHT',
525 wx
.ALIGN_TOP
: 'wx.ALIGN_TOP',
526 wx
.ALIGN_BOTTOM
: 'wx.ALIGN_BOTTOM',
527 wx
.ALIGN_CENTER_VERTICAL
: 'wx.ALIGN_CENTER_VERTICAL',
528 wx
.ALIGN_CENTER_HORIZONTAL
: 'wx.ALIGN_CENTER_HORIZONTAL',
529 wx
.ADJUST_MINSIZE
: 'wx.ADJUST_MINSIZE',
530 wx
.FIXED_MINSIZE
: 'wx.FIXED_MINSIZE',
534 wx
.FLEX_GROWMODE_NONE
: 'wx.FLEX_GROWMODE_NONE',
535 wx
.FLEX_GROWMODE_SPECIFIED
: 'wx.FLEX_GROWMODE_SPECIFIED',
536 wx
.FLEX_GROWMODE_ALL
: 'wx.FLEX_GROWMODE_ALL',
539 #---------------------------------------------------------------------------
540 from wx
import ImageFromStream
, BitmapFromImage
544 def getRefreshData():
546 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
547 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
548 \x00\x02TIDAT8\x8d\x9d\x95\xbfk\xdbP\x10\xc7?\xaaC\'\xa3%\x85d\n\x1c\x04\xba\
549 \x96[:\x14\x8aK;\xe6O\xc8\x90\xc1\xde\r\x9d\x0b\xfa\x13\x84\x97\x0c\xf5\x98\
550 \xc9c\xe9\xd0%i\xe2\xad\x14D\x97\x0c\x15\x86\x83\x0c\xc2\x01\x17\xc3CK\x83\
551 \xcd\xeb\xa0\x1f\x95\x9c\x1f\r=\x10z\xe8\xee\xbe\xef\xbd\xef\xdd}\x15D\xdco\
552 \x11\x0c\x80C\xe0Y\xf9i\x01\x9cD\xf0\xf1\x8e\xf0\x00`\xeb\x1e\x90+\xe0\x1a\
553 \xd8\x01^\xab*\x00I\x92 "\xdf#\xb3\x17\xa5o\xaf\x01\xee\x81\xe0\xc9\x06\xd8)\
554 p,"_\xaao\xaaJ\x1c\xc7\xc4qL\x05\x0c "\x9f\x80\xe32\xa72OT\x00A\xe1\xf0\x8dg\
555 \x01\xacT\xd5\xa7i\xea\xb3,\xf3\xaa\xea\x81\x95\x88\xfc\xde\x88=\xadqJ\xb0\
556 \x01\xb0\x02\xfcd2\xf1I\x92T\xc9\xde9\xe7\x9ds>\xcb2\x9fe\x99\x07\xbc\xaa\
557 \xfa$I\xfcd2\xa9\x00W\xc0 jpx%"k3\xeb\xec\xef\xef\xb3\xbb\xbb\xcb\xf9\xf9y\
558 \x8b\xdbn\xb7\x0b\x80s\x0e\x80<\xcf\x9b\xd7\xef\x98\xd9\x15@\xc5\xe1\xb5\x99\
559 \xbd\x14\x91\x9b~\xbf_\'?d\xddn\x97~\xbf\x0f\xf0\xcb\xcc\x94\xa2\x88\x04\xc0\
560 @D\x9e\x03\x98\xd9\x10\xe8T\xa7\xf8\x97\x85a\x08\xb0\xa6f\xae\x00\xbd\xa0\
561 \xe4EU}\x96e5o\xce9?\x1a\x8dj\xdfh4j\xf9\x9cs\xb5\x8f\x82\xcb\x0b\x80KU\xf5\
562 \xd3\xe9\xb4&~3\xa1\x0c\xf6\xaaz\x0b0MS?\x9dN\xab\xb8\xcbV\x1f\xe6y\xfe(\xfe\
563 \x1e\x8a\xdf\x02\x16I\x920\x1c\x0e\x01nU\xf7\xe8\xe8\xe8\xceue\x07\x07\x07@1\
564 E\xc0"\x00\xde\x00\xafJ\x7f\xc4\x7f\x14EDb\x003\xfb\xb9\x15\xc1\xd7\x08\x96\
565 \x14\x15\x1f\xaa\xea\xf6\xa3\xd0(\xc6r\xb9\\\xae\xcd\xec\xa4<\xcd\x8f\x8a\
566 \xc3\x1d\x11I\x80\xed\xf1x\xdcj\xda\xfb,\xcfs\xc6\xe31f\xf6TD\xbeQ\x88E-\x0e\
567 {f\xb6\x06\x98\xcdf\xcc\xe7sz\xbd\x1ea\x18\x92\xe7yk\x830\x0c\xe9\xf5z\xcc\
568 \xe7sf\xb3\x19\xe5U;\xc0\x1e\xa58\x04Qq\xdd\x968\x94\x02\xb0\xaaz3M\xd3Z\x1c\
569 (\x84\xe3Nq\xa8\xdb&\x82\xb7\xc0\x19\x05\xc97\xe5(\xc6\xcdS\xff\r\xe5\x9d\
570 \x88@1%ge.@\x10D\x05h\xb5SK`E\xe4\xd0\xcc\xde7\x05\x16\xf8\x00|\xe6\xb6\xc0\
571 \xb6\x00\xa9\x00\x1b\xef\xc7\xfe\x02\x82\xc6\x9a?\xea\xc8x\xd8\xb0\t\xb9\xf6\
572 \x00\x00\x00\x00IEND\xaeB`\x82'
574 def getRefreshBitmap():
575 return BitmapFromImage(getRefreshImage())
577 def getRefreshImage():
578 stream
= cStringIO
.StringIO(getRefreshData())
579 return ImageFromStream(stream
)
581 #----------------------------------------------------------------------
584 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
585 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
586 \x00\x01\xe6IDAT8\x8d\xa5\xd3\xbdk\x13q\x1c\xc7\xf1W\x9a\x12t\xe8\x18\xcd\
587 \xd6\xa1\x17\x10\x8a\xa8\x8b\x83C\x0c\x9d\xae\x07R\x1d|@\x9d\x02\xa2 \xde\
588 \x1f\xe0t\x93\x7f@\xbb(\x82\xb8\xa4\xb8i;\xa47\xd6\x08\x0e\x1d\xdaB\xc7\\)\
589 \x05\x1fJ\x07\xff\x80\n\xe2pi\x9a\xda\xa6O~\xe0\x0b?\x8e\xef\xef}\xef\xdfS!\
590 \xb1\x97\x84\xeb\xb8\x81\xcb\xf6g\r_\x13\x96\x1c\x93b}\x0f\xf6\x08wq\x05\xf7\
591 p\xad\xaf\xfe\xe0\xd2"#\xf5\x1c>0\xc3}\xb0\x87\x88\xe28\x16\x86\xa1 \x08@\
592 \x96e\xd24\x8d\xa6\xa7\xa7\xa1\x92\xe4\xfd\xcdA\xc0\x82|\x99O\xd1h\xb5Z\x82 \
593 \xb0\xb3S\xdd\xd7T*udY&\x8a"x\x877\x83\x96?$\xdf\xb3J\x1c\xc7=\xd8\xf88\xeb\
594 \xeby\xc1\xceNU\x10\x04\xe28\x86Jw\xce\xa1\x19\x92\x1f@\x14\x86a\x0f\x06\x17\
595 \xba\xd5\x0f\r\xc3\x10"\x07\x0f\xad\x97\xe1\xddAn\xc7\xfc|\x0e\xda\xcd.tlLo_\
596 \x8f\xca\xd0\xb1\x1d\xa7L\x0f\x98e\x19r\x93\xed\xbe\x86\xed\xee\xb7\xfe\x1e\
597 \xfc<\n\xb8\x86V\x9a\xa6J\xa5\xce>h?\xacT\xeaH\xd3T\xadV\x83\xd5A\xc0\xb3\\\
598 \x1bh\'\xdc<\x0cXL\xf8\xbe\xc8\x08\xce5\x9b\xcdj\xa1PP.S.S,\xfe\xb2\xb1\xb1d\
599 vvV\x1c\xc7\xa2(R\xadvt:F\x17\x99\xa8\xf3\xfe\x80a\xd2\x1d$\xf9k\x99\x90\xdf\
600 \xb3\xa8\xbf\xa9V\xabi\xb7\xdb\x1a\rn]\xe5\xdb\x16/^\x1dn\xda{\xcbu\xd6\x16\
601 \xd9\xc2o\xfc\xc0J\xb7Z\x9b\x9b\x9b3\xa8\xac\xac\x18}0\xc9\xfd\xc7s.\x9e\xff\
602 `\xe1\xcbA\xd3\x9e\xe1I\x92\xf0\x19\xb5\x8f\xd3L\xde\x9e\xf3\xf6\xf5\xd4\x01\
603 \xd3S\xdd\xc3\xee\xa4\xf6\x9d\x98\x85OS\x9e<\x9b3\xf3\x12\xd4\xba?;\x9d\xe1I\
604 L\xcf\xf4R\x0e3m4r\xd33\x19\xfek\xdah\xb0\xba\xca\xf2\xb2\xf6\x7f\x01\xfb\
605 \xa1h\xe3\xf9_3n\xb4\xee\xba\xaf\xf1\xb8\x00\x00\x00\x00IEND\xaeB`\x82'
608 return BitmapFromImage(getFindImage())
611 stream
= cStringIO
.StringIO(getFindData())
612 return ImageFromStream(stream
)
614 #----------------------------------------------------------------------
615 def getShowSizersData():
617 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
618 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
619 \x00\x01-IDAT8\x8d\xad\x931N\xc3@\x10E\x9f!\x1dU\xba\x7f\x008\x00\x17@\xe9\
620 \x007\\\x81\x16\xc5\xe2\x0c{\x01\xba Qr\x85H\x89#Rr\r\xe2~\xbaH\xc8\xa2B2\
621 \x05^\xb3$v\xd6\x962\xd2Jc\xff\xd9\xb73;;\x89\xe3\xb86\xea\x12\x1c\xdcJ\xca\
622 \xda43\x9b9X\r\x02J\xca\xcc,\xed\xd0\xc0l\x18\xb0\xb1\xb7\xc0__\xc0\xd3\xc7\
623 \xc1\xf08\x10\xa0\xb8\xac\x9d2\x1a\xda\x13\x18\x07\xf5\x07^\x03\x1c.\xb3\x17\
624 \xd0\xccf\x92\xbc\x9f\x02H\xca\xbd\xd6\xb5\xef$v\xa2\x99\xa5\x92rIyW\xd7\xa3\
625 \x19\xba\xfa\rz\x98\xcfH\x92?\x00g\x86ky\x8b\xa7\x93\x1e0\x07\xab\tl\x16e\
626 \xb9\x954\xae\xb5\xf1\xa2,\xb7\x13\xd8t\x02\xbb`^\xef\x03\x1d\xb9`\xc4\x14\
627 \xdcY\xec\xae\xfc\x9dJ\xe2\x052\xa8\x9b%i\tTmK\xd2\xd2\xfdf\xde\xacX\xfc_S^\
628 \xab\xbb\xc6\xff,\xe6<\x9e\x1f\xcc\xb0\xe2\xea9\xfcNx\x9f\xc2n\x97\xbfy\x88\
629 \x95\x1aZ\xc1\xd9\x14`\x8d5\xff\xfe\x03\xbf\x8a\x9b!\xc0\x10\xb4\x0f\xbcO\
630 \xe6C`\xbe\xc4=`8b\xbb\xd66b\xb1\xf8\xc4\rI\xab\x87\xfd\x00>\xff\xa7/3u\xdc\
631 \xf3\x00\x00\x00\x00IEND\xaeB`\x82'
633 def getShowSizersBitmap():
634 return BitmapFromImage(getShowSizersImage())
636 def getShowSizersImage():
637 stream
= cStringIO
.StringIO(getShowSizersData())
638 return ImageFromStream(stream
)
640 #----------------------------------------------------------------------
641 def getShowFillingData():
643 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
644 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
645 \x00\x00\x99IDAT8\x8d\xd5\xd2\xb1\r\xc3 \x10\x85\xe1\xff"\xcf\x90\x89\xa0O\
646 \xe3\x19\\d\x89["\x8dWp\xe1\x01`"/q)\x12G\xc2r\n\xccEr^\x03\x08\xf4\xe9I\x87\
647 (\xbe\xb98{t\x00\n\x01\xe8\x1b\x9cI!\x7f@\xe0\x0e\xdc\x1a\xc0+\x1b\x10\x003c\
648 \x1c\xeb\xa4a\x90\xe2\xdc\x95\x97\x95\xda^\xf4\xb5\xcc\x80\x1d\t`\xc0\xaco\
649 \xcb}\xca\xbf\xf96kr\xce\xbe`\x8c\xd1\x17L)U\x03\xdb\x12\x05\x18B8R\xaa\xc8\
650 \x9fMYD\xbe\xbd\xab\x06\x1f\xc0\xd2\xe0L\xebF\xb4\xa5\xceN\xce?\x94\'\x9egM\
651 \xd2gvb\xb2\x00\x00\x00\x00IEND\xaeB`\x82'
653 def getShowFillingBitmap():
654 return BitmapFromImage(getShowFillingImage())
656 def getShowFillingImage():
657 stream
= cStringIO
.StringIO(getShowFillingData())
658 return ImageFromStream(stream
)
660 #----------------------------------------------------------------------