- self._tool.SetObj(wnd)
-
- self._tool.Show()
- self._tool.Raise()
-
-
-#---------------------------------------------------------------------------
-
-class InspectionFrame(wx.Frame):
- """
- This class is the frame that holds the wxPython inspection tools.
- The toolbar and splitter windows are also managed here. The
- contents of the splitter windows are handled by other classes.
- """
- def __init__(self, wnd=None, locals=None, config=None,
- app=None, title="wxPython Widget Inspection Tool",
- *args, **kw):
- kw['title'] = title
- wx.Frame.__init__(self, *args, **kw)
-
- self.includeSizers = False
- self.started = False
-
- self.MakeToolBar()
-
- self.outerSplitter = wx.SplitterWindow(self,style=wx.SP_3D|wx.SP_LIVE_UPDATE)
- self.innerSplitter = wx.SplitterWindow(self.outerSplitter,style=wx.SP_3D|wx.SP_LIVE_UPDATE)
- self.tree = InspectionTree(self.outerSplitter)
- self.info = InspectionInfoPanel(self.innerSplitter)
-
- if not locals:
- locals = {}
- myIntroText = (
- "Python %s on %s\nNOTE: The 'obj' variable refers to the selected object."
- % (sys.version.split()[0], sys.platform))
- self.crust = wx.py.crust.Crust(self.innerSplitter, locals=locals,
- intro=myIntroText,
- showInterpIntro=False,
- )
- self.locals = self.crust.shell.interp.locals
- self.crust.shell.interp.introText = ''
- self.locals['obj'] = self.obj = wnd
- self.locals['app'] = app
- self.locals['wx'] = wx
- wx.CallAfter(self._postStartup)
-
- self.innerSplitter.SplitHorizontally(self.info, self.crust, -225)
- self.outerSplitter.SplitVertically(self.tree, self.innerSplitter, 280)
- self.outerSplitter.SetMinimumPaneSize(20)
- self.innerSplitter.SetMinimumPaneSize(20)
-
-
- def MakeToolBar(self):
- tbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.TB_FLAT | wx.TB_TEXT | wx.NO_BORDER )
- tbar.SetToolBitmapSize((20,20))
-
- refreshBmp = getRefreshBitmap()
- findWidgetBmp = getFindBitmap()
- showSizersBmp = getShowSizersBitmap()
- toggleFillingBmp = getShowFillingBitmap()
-
- refreshTool = tbar.AddLabelTool(-1, 'Refresh', refreshBmp,
- shortHelp = 'Refresh widget tree')
- findWidgetTool = tbar.AddLabelTool(-1, 'Find', findWidgetBmp,
- shortHelp='Find new target widget. Click here and\nthen on another widget in the app.')
- showSizersTool = tbar.AddLabelTool(-1, 'Sizers', showSizersBmp,
- shortHelp='Include sizers in widget tree',
- kind=wx.ITEM_CHECK)
- toggleFillingTool = tbar.AddLabelTool(-1, 'Filling', toggleFillingBmp,
- shortHelp='Show PyCrust \'filling\'',
- kind=wx.ITEM_CHECK)
- tbar.Realize()
-
- self.Bind(wx.EVT_TOOL, self.OnRefreshTree, refreshTool)
- self.Bind(wx.EVT_TOOL, self.OnFindWidget, findWidgetTool)
- self.Bind(wx.EVT_TOOL, self.OnShowSizers, showSizersTool)
- self.Bind(wx.EVT_TOOL, self.OnToggleFilling, toggleFillingTool)
- self.Bind(wx.EVT_UPDATE_UI, self.OnShowSizersUI, showSizersTool)
- self.Bind(wx.EVT_UPDATE_UI, self.OnToggleFillingUI, toggleFillingTool)
-
-
-
- def _postStartup(self):
- if self.crust.ToolsShown():
- self.crust.ToggleTools()
- self.UpdateInfo()
- self.started = True
-
- def UpdateInfo(self):
- self.info.Update(self.obj)
-
- def SetObj(self, obj):
- if self.obj is obj:
- return
- self.locals['obj'] = self.obj = obj
- self.UpdateInfo()
- if not self.tree.built:
- self.tree.BuildTree(obj, includeSizers=self.includeSizers)
- else:
- self.tree.SelectObj(obj)
-
-
- def RefreshTree(self):
- self.tree.BuildTree(self.obj, includeSizers=self.includeSizers)
-
-
- def OnRefreshTree(self, evt):
- self.RefreshTree()
-
-
- def OnFindWidget(self, evt):
- self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
- self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLost)
- self.CaptureMouse()
- self.finding = wx.BusyInfo("Click on any widget in the app...")
-
- def OnCaptureLost(self, evt):
- self.Unbind(wx.EVT_LEFT_DOWN)
- self.Unbind(wx.EVT_MOUSE_CAPTURE_LOST)
- del self.finding
-
- def OnLeftDown(self, evt):
- self.ReleaseMouse()
- wnd = wx.FindWindowAtPointer()
- if wnd is not None:
- self.SetObj(wnd)
- else:
- wx.Bell()
- self.OnCaptureLost(evt)
-
-
- def OnShowSizers(self, evt):
- self.includeSizers = not self.includeSizers
- self.RefreshTree()
-
-
- def OnToggleFilling(self, evt):
- self.crust.ToggleTools()
-
-
- def OnShowSizersUI(self, evt):
- evt.Check(self.includeSizers)
-
-
- def OnToggleFillingUI(self, evt):
- if self.started:
- evt.Check(self.crust.ToolsShown())
-
-
-
-#---------------------------------------------------------------------------
-
-# should inspection frame (and children) be includeed in the tree?
-INCLUDE_INSPECTOR = True
-
-class InspectionTree(wx.TreeCtrl):
- """
- All of the widgets in the app, and optionally their sizers, are
- loaded into this tree.
- """
- def __init__(self, *args, **kw):
- #s = kw.get('style', 0)
- #kw['style'] = s | wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT
- wx.TreeCtrl.__init__(self, *args, **kw)
- self.roots = []
- self.built = False
- self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectionChanged)
-
-
- def BuildTree(self, startWidget, includeSizers=False):
- if self.GetCount():
- self.DeleteAllItems()
- self.roots = []
- self.built = False
-
- realRoot = self.AddRoot('Top-level Windows')
-
- for w in wx.GetTopLevelWindows():
- if w is wx.GetTopLevelParent(self) and not INCLUDE_INSPECTOR:
- continue
- root = self._AddWidget(realRoot, w, includeSizers)
- self.roots.append(root)
-
- # Expand the subtree containing the startWidget, and select it.
- if not startWidget or not isinstance(startWidget, wx.Window):
- startWidget = wx.GetApp().GetTopWindow()
- top = wx.GetTopLevelParent(startWidget)
- topItem = self.FindWidgetItem(top)
- if topItem:
- self.ExpandAllChildren(topItem)
- self.SelectObj(startWidget)
- self.built = True
-
-
- def _AddWidget(self, parentItem, widget, includeSizers):
- text = self.GetTextForWidget(widget)
- item = self.AppendItem(parentItem, text)
- self.SetItemPyData(item, widget)
-
- # Add the sizer and widgets in the sizer, if we're showing them
- widgetsInSizer = []
- if includeSizers and widget.GetSizer() is not None:
- widgetsInSizer = self._AddSizer(item, widget.GetSizer())
-
- # Add any children not in the sizer, or all children if we're
- # not showing the sizers
- for child in widget.GetChildren():
- if not child in widgetsInSizer and not child.IsTopLevel():
- self._AddWidget(item, child, includeSizers)
-
- return item
-
-
- def _AddSizer(self, parentItem, sizer):
- widgets = []
- text = self.GetTextForSizer(sizer)
- item = self.AppendItem(parentItem, text)
- self.SetItemPyData(item, sizer)
- self.SetItemTextColour(item, "blue")
-
- for si in sizer.GetChildren():
- if si.IsWindow():
- w = si.GetWindow()
- self._AddWidget(item, w, True)
- widgets.append(w)
- elif si.IsSizer():
- widgets += self._AddSizer(item, si.GetSizer())
- else:
- i = self.AppendItem(item, "Spacer")
- self.SetItemPyData(i, si)
- self.SetItemTextColour(i, "blue")
- return widgets
-
-
- def FindWidgetItem(self, widget):
- """
- Find the tree item for a widget.
- """
- for item in self.roots:
- found = self._FindWidgetItem(widget, item)
- if found:
- return found
- return None
-
- def _FindWidgetItem(self, widget, item):
- if self.GetItemPyData(item) is widget:
- return item
- child, cookie = self.GetFirstChild(item)
- while child:
- found = self._FindWidgetItem(widget, child)
- if found:
- return found
- child, cookie = self.GetNextChild(item, cookie)
- return None
-
-
- def GetTextForWidget(self, widget):
- """
- Returns the string to be used in the tree for a widget
- """
- return "%s (\"%s\")" % (widget.__class__.__name__, widget.GetName())
-
- def GetTextForSizer(self, sizer):
- """
- Returns the string to be used in the tree for a sizer
- """
- return "%s" % sizer.__class__.__name__
-
-
- def SelectObj(self, obj):
- item = self.FindWidgetItem(obj)
- if item:
- self.EnsureVisible(item)
- self.SelectItem(item)
-
-
- def OnSelectionChanged(self, evt):
- obj = self.GetItemPyData(evt.GetItem())
- toolFrm = wx.GetTopLevelParent(self)
- toolFrm.SetObj(obj)