From: Roman Rolinsky Date: Wed, 14 Mar 2007 18:33:45 +0000 (+0000) Subject: more custom classes support X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/c0d5ae74472fb4ccc09e8d6ab2571deeb47ef5f7 more custom classes support git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44806 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/wxPython/wx/tools/XRCed/tree.py b/wxPython/wx/tools/XRCed/tree.py index ad64a5a709..098ed7f689 100644 --- a/wxPython/wx/tools/XRCed/tree.py +++ b/wxPython/wx/tools/XRCed/tree.py @@ -128,6 +128,9 @@ class ID_NEW: REF = wx.NewId() COMMENT = wx.NewId() + CUSTOM = wx.NewId() + for i in range(99): wx.NewId() # reserve IDs for custom controls + LAST = wx.NewId() @@ -377,7 +380,17 @@ class PullDownMenu: ID_NEW.HELP_BUTTON: ('wxID_HELP', '&Help'), ID_NEW.CONTEXT_HELP_BUTTON: ('wxID_CONTEXT_HELP', '&Help'), } - + self.clearCustom() + + def clearCustom(self): + # Custom controls + self.custom = [['custom', 'User-defined controls']] + self.customMap = {} + + def addCustom(self, klass): + n = len(self.custom[0])-2 + self.custom[0].append((ID_NEW.CUSTOM + n, klass)) + self.customMap[ID_NEW.CUSTOM + n] = klass ################################################################################ @@ -904,16 +917,7 @@ class XML_Tree(wx.TreeCtrl): res = xrc.XmlResource('', xmlFlags) xrc.XmlResource.Set(res) # set as global # Register handlers - addHandlers(res) - # Test Test.py - #import Test - #res.InsertHandler(Test.TestXmlHandler()) - # Test test.so - import ctypes - test = ctypes.CDLL('test.so') - addr = int(str(res.this).split('_')[1], 16) - #test._Z17AddTestXmlHandlerP13wxXmlResource(ctypes.c_void_p(addr)) - #test.AddTestXmlHandler(ctypes.c_void_p(addr)) + addHandlers() res.Load('memory:xxx.xrc') try: if xxx.__class__ == xxxFrame: @@ -1013,6 +1017,9 @@ class XML_Tree(wx.TreeCtrl): inf = sys.exc_info() wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1]) wx.LogError('Error loading resource') + # Cleanup + res.Unload('xxx.xrc') + xrc.XmlResource.Set(None) wx.MemoryFSHandler.RemoveFile('xxx.xrc') def CloseTestWindow(self): @@ -1137,6 +1144,9 @@ class XML_Tree(wx.TreeCtrl): m.AppendSeparator() m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node') m.Append(ID_NEW.COMMENT, 'comment', 'Create comment node') + # Add custom controls menu + if pullDownMenu.customMap: + SetMenu(m, pullDownMenu.custom) # Select correct label for create menu if not needInsert: if self.shift: diff --git a/wxPython/wx/tools/XRCed/xrced.py b/wxPython/wx/tools/XRCed/xrced.py index 5e1068f57b..dda3b7c5b7 100644 --- a/wxPython/wx/tools/XRCed/xrced.py +++ b/wxPython/wx/tools/XRCed/xrced.py @@ -40,6 +40,9 @@ if __name__ == '__main__': else: basePath = os.path.dirname(__file__) +# Remember system path +sys_path = sys.path + # 1 adds CMD command to Help menu debug = 0 @@ -51,7 +54,7 @@ select "Append Child", and then any command.

Or just press one of the buttons on the tools palette.

Enter XML ID, change properties, create children.

To test your interface select Test command (View menu).

-Consult README file for the details. +Consult README.txt file for the details. """ defaultIDs = {xxxPanel:'PANEL', xxxDialog:'DIALOG', xxxFrame:'FRAME', @@ -71,13 +74,13 @@ class ScrolledMessageDialog(wx.Dialog): wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY) text.SetFont(g.modernFont()) dc = wx.WindowDC(text) - # !!! possible bug - GetTextExtent without font returns sysfont dims w, h = dc.GetFullTextExtent(' ', g.modernFont())[:2] ok = wx.Button(self, wx.ID_OK, "OK") + ok.SetDefault() text.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok))) text.SetSize((w * 80 + 30, h * 40)) - text.ShowPosition(1) - ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,))) + text.ShowPosition(1) # scroll to the first line + ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!35', (self,))) self.SetAutoLayout(True) self.Fit() self.CenterOnScreen(wx.BOTH) @@ -182,7 +185,7 @@ class Frame(wx.Frame): menu = wx.Menu() menu.Append(wx.ID_ABOUT, '&About...', 'About XCRed') self.ID_README = wx.NewId() - menu.Append(self.ID_README, '&Readme...', 'View the README file') + menu.Append(self.ID_README, '&Readme...\tF1', 'View the README file') if debug: self.ID_DEBUG_CMD = wx.NewId() menu.Append(self.ID_DEBUG_CMD, 'CMD', 'Python command line') @@ -533,14 +536,21 @@ class Frame(wx.Frame): # Create a copy of clipboard pickled element success = success_node = False if wx.TheClipboard.Open(): - data = wx.CustomDataObject('XRCED') - if wx.TheClipboard.IsSupported(data.GetFormat()): - success = wx.TheClipboard.GetData(data) - if not success: # try other format - data = wx.CustomDataObject('XRCED_node') + try: + data = wx.CustomDataObject('XRCED') if wx.TheClipboard.IsSupported(data.GetFormat()): - success_node = wx.TheClipboard.GetData(data) - wx.TheClipboard.Close() + try: + success = wx.TheClipboard.GetData(data) + except: + # there is a problem if XRCED_node is in clipboard + # but previous SetData was for XRCED + pass + if not success: # try other format + data = wx.CustomDataObject('XRCED_node') + if wx.TheClipboard.IsSupported(data.GetFormat()): + success_node = wx.TheClipboard.GetData(data) + finally: + wx.TheClipboard.Close() if not success and not success_node: wx.MessageBox( @@ -1086,7 +1096,10 @@ Homepage: http://xrced.sourceforge.net\ xxx = MakeEmptyCommentXXX(parent) else: # Create empty element - className = pullDownMenu.createMap[evt.GetId()] + if evt.GetId() >= ID_NEW.CUSTOM: + className = pullDownMenu.customMap[evt.GetId()] + else: + className = pullDownMenu.createMap[evt.GetId()] xxx = MakeEmptyXXX(parent, className) # Insert new node, register undo @@ -1367,6 +1380,7 @@ Homepage: http://xrced.sourceforge.net\ self.maxIDs[cl] = 0 # Handlers clearHandlers() + g.pullDownMenu.clearCustom() def SetModified(self, state=True): self.modified = state @@ -1397,6 +1411,8 @@ Homepage: http://xrced.sourceforge.net\ self.dataFile = path = os.path.abspath(path) dir = os.path.dirname(path) if dir: os.chdir(dir) + # Allow importing modules from the same directory + sys.path = sys_path + [dir] tree.SetData(dom) self.SetTitle(progname + ': ' + os.path.basename(path)) conf.localconf = self.CreateLocalConf(self.dataFile) diff --git a/wxPython/wx/tools/XRCed/xxx.py b/wxPython/wx/tools/XRCed/xxx.py index 1ee0ffa5a3..ecae28d752 100644 --- a/wxPython/wx/tools/XRCed/xxx.py +++ b/wxPython/wx/tools/XRCed/xxx.py @@ -919,10 +919,11 @@ class xxxUnknown(xxxObject): ################################################################################ # Comment -_handlers = [] -_CFuncPtr = None +_handlers = [] # custom handler classes/funcs +_CFuncPtr = None # ctypes function type def register(hndlr): + """Register hndlr function or XmlResourceHandler class.""" if _CFuncPtr and isinstance(hndlr, _CFuncPtr): _handlers.append(hndlr) return @@ -934,24 +935,31 @@ def register(hndlr): _handlers.append(hndlr) def load_dl(path, localname=''): + """Load shared/dynamic library into xxx namespace.""" + if not localname: + localname = os.path.basename(os.path.splitext(path)[0]) try: import ctypes global _CFuncPtr _CFuncPtr = ctypes._CFuncPtr except ImportError: wx.LogError('ctypes module not found') + globals()[localname] = None return try: dl = ctypes.CDLL(path) - if not localname: - localname = os.path.basename(os.path.splitext(dl._name)[0]) globals()[localname] = dl + # Register AddXmlHandlers() if exists + try: + register(dl.AddXmlHandlers) + except: + pass except: - wx.LogError('error loading dynamic library: %s', path) + wx.LogError('error loading dynamic library: %s' % path) print traceback.print_exc() # Called when creating test window -def addHandlers(res): +def addHandlers(): for h in _handlers: if _CFuncPtr and isinstance(h, _CFuncPtr): try: @@ -961,7 +969,7 @@ def addHandlers(res): print traceback.print_exc() else: try: - res.AddHandler(apply(h, ())) + xrc.XmlResource.Get().AddHandler(apply(h, ())) except: wx.LogError('error adding XmlHandler: "%s"' % h) print traceback.print_exc() @@ -970,6 +978,28 @@ def clearHandlers(): global _handlers _handlers = [] +def custom(klassName, klass='unknown'): + """Define custom control based on xrcClass. + + klass: new object name + xrcClass: name of an existing XRC object class or + a class object defining class parameters. + """ + if type(klass) is str: + # Copy correct xxx class under new name + kl = xxxDict[klass] + xxxClass = types.ClassType('xxx' + klassName, kl.__bases__, kl.__dict__) + else: + xxxClass = klass + # Register param IDs + for param in klass.allParams + klass.paramDict.keys(): + if not paramIDs.has_key(param): + paramIDs[param] = wx.NewId() + # Insert in dictionaty + xxxDict[klassName] = xxxClass + # Add to menu + g.pullDownMenu.addCustom(klassName) + class xxxParamComment(xxxParam): def __init__(self, node): xxxNode.__init__(self, node) @@ -1002,6 +1032,7 @@ class xxxComment(xxxObject): ################################################################################ +# Mapping of XRC names to xxx classes xxxDict = { 'wxPanel': xxxPanel, 'wxDialog': xxxDialog,