more custom classes support

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44806 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Roman Rolinsky
2007-03-14 18:33:45 +00:00
parent 5647b95a66
commit c0d5ae7447
3 changed files with 88 additions and 31 deletions

View File

@@ -128,6 +128,9 @@ class ID_NEW:
REF = wx.NewId() REF = wx.NewId()
COMMENT = wx.NewId() COMMENT = wx.NewId()
CUSTOM = wx.NewId()
for i in range(99): wx.NewId() # reserve IDs for custom controls
LAST = wx.NewId() LAST = wx.NewId()
@@ -377,7 +380,17 @@ class PullDownMenu:
ID_NEW.HELP_BUTTON: ('wxID_HELP', '&Help'), ID_NEW.HELP_BUTTON: ('wxID_HELP', '&Help'),
ID_NEW.CONTEXT_HELP_BUTTON: ('wxID_CONTEXT_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) res = xrc.XmlResource('', xmlFlags)
xrc.XmlResource.Set(res) # set as global xrc.XmlResource.Set(res) # set as global
# Register handlers # Register handlers
addHandlers(res) addHandlers()
# 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))
res.Load('memory:xxx.xrc') res.Load('memory:xxx.xrc')
try: try:
if xxx.__class__ == xxxFrame: if xxx.__class__ == xxxFrame:
@@ -1013,6 +1017,9 @@ class XML_Tree(wx.TreeCtrl):
inf = sys.exc_info() inf = sys.exc_info()
wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1]) wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1])
wx.LogError('Error loading resource') wx.LogError('Error loading resource')
# Cleanup
res.Unload('xxx.xrc')
xrc.XmlResource.Set(None)
wx.MemoryFSHandler.RemoveFile('xxx.xrc') wx.MemoryFSHandler.RemoveFile('xxx.xrc')
def CloseTestWindow(self): def CloseTestWindow(self):
@@ -1137,6 +1144,9 @@ class XML_Tree(wx.TreeCtrl):
m.AppendSeparator() m.AppendSeparator()
m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node') m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node')
m.Append(ID_NEW.COMMENT, 'comment', 'Create comment 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 # Select correct label for create menu
if not needInsert: if not needInsert:
if self.shift: if self.shift:

View File

@@ -40,6 +40,9 @@ if __name__ == '__main__':
else: else:
basePath = os.path.dirname(__file__) basePath = os.path.dirname(__file__)
# Remember system path
sys_path = sys.path
# 1 adds CMD command to Help menu # 1 adds CMD command to Help menu
debug = 0 debug = 0
@@ -51,7 +54,7 @@ select "Append Child", and then any command.<P>
Or just press one of the buttons on the tools palette.<P> Or just press one of the buttons on the tools palette.<P>
Enter XML ID, change properties, create children.<P> Enter XML ID, change properties, create children.<P>
To test your interface select Test command (View menu).<P> To test your interface select Test command (View menu).<P>
Consult README file for the details.</HTML> Consult README.txt file for the details.</HTML>
""" """
defaultIDs = {xxxPanel:'PANEL', xxxDialog:'DIALOG', xxxFrame:'FRAME', defaultIDs = {xxxPanel:'PANEL', xxxDialog:'DIALOG', xxxFrame:'FRAME',
@@ -71,13 +74,13 @@ class ScrolledMessageDialog(wx.Dialog):
wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY) wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY)
text.SetFont(g.modernFont()) text.SetFont(g.modernFont())
dc = wx.WindowDC(text) dc = wx.WindowDC(text)
# !!! possible bug - GetTextExtent without font returns sysfont dims
w, h = dc.GetFullTextExtent(' ', g.modernFont())[:2] w, h = dc.GetFullTextExtent(' ', g.modernFont())[:2]
ok = wx.Button(self, wx.ID_OK, "OK") 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.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok)))
text.SetSize((w * 80 + 30, h * 40)) text.SetSize((w * 80 + 30, h * 40))
text.ShowPosition(1) text.ShowPosition(1) # scroll to the first line
ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,))) ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!35', (self,)))
self.SetAutoLayout(True) self.SetAutoLayout(True)
self.Fit() self.Fit()
self.CenterOnScreen(wx.BOTH) self.CenterOnScreen(wx.BOTH)
@@ -182,7 +185,7 @@ class Frame(wx.Frame):
menu = wx.Menu() menu = wx.Menu()
menu.Append(wx.ID_ABOUT, '&About...', 'About XCRed') menu.Append(wx.ID_ABOUT, '&About...', 'About XCRed')
self.ID_README = wx.NewId() 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: if debug:
self.ID_DEBUG_CMD = wx.NewId() self.ID_DEBUG_CMD = wx.NewId()
menu.Append(self.ID_DEBUG_CMD, 'CMD', 'Python command line') 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 # Create a copy of clipboard pickled element
success = success_node = False success = success_node = False
if wx.TheClipboard.Open(): if wx.TheClipboard.Open():
data = wx.CustomDataObject('XRCED') try:
if wx.TheClipboard.IsSupported(data.GetFormat()): data = wx.CustomDataObject('XRCED')
success = wx.TheClipboard.GetData(data)
if not success: # try other format
data = wx.CustomDataObject('XRCED_node')
if wx.TheClipboard.IsSupported(data.GetFormat()): if wx.TheClipboard.IsSupported(data.GetFormat()):
success_node = wx.TheClipboard.GetData(data) try:
wx.TheClipboard.Close() 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: if not success and not success_node:
wx.MessageBox( wx.MessageBox(
@@ -1086,7 +1096,10 @@ Homepage: http://xrced.sourceforge.net\
xxx = MakeEmptyCommentXXX(parent) xxx = MakeEmptyCommentXXX(parent)
else: else:
# Create empty element # 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) xxx = MakeEmptyXXX(parent, className)
# Insert new node, register undo # Insert new node, register undo
@@ -1367,6 +1380,7 @@ Homepage: http://xrced.sourceforge.net\
self.maxIDs[cl] = 0 self.maxIDs[cl] = 0
# Handlers # Handlers
clearHandlers() clearHandlers()
g.pullDownMenu.clearCustom()
def SetModified(self, state=True): def SetModified(self, state=True):
self.modified = state self.modified = state
@@ -1397,6 +1411,8 @@ Homepage: http://xrced.sourceforge.net\
self.dataFile = path = os.path.abspath(path) self.dataFile = path = os.path.abspath(path)
dir = os.path.dirname(path) dir = os.path.dirname(path)
if dir: os.chdir(dir) if dir: os.chdir(dir)
# Allow importing modules from the same directory
sys.path = sys_path + [dir]
tree.SetData(dom) tree.SetData(dom)
self.SetTitle(progname + ': ' + os.path.basename(path)) self.SetTitle(progname + ': ' + os.path.basename(path))
conf.localconf = self.CreateLocalConf(self.dataFile) conf.localconf = self.CreateLocalConf(self.dataFile)

View File

@@ -919,10 +919,11 @@ class xxxUnknown(xxxObject):
################################################################################ ################################################################################
# Comment # Comment
_handlers = [] _handlers = [] # custom handler classes/funcs
_CFuncPtr = None _CFuncPtr = None # ctypes function type
def register(hndlr): def register(hndlr):
"""Register hndlr function or XmlResourceHandler class."""
if _CFuncPtr and isinstance(hndlr, _CFuncPtr): if _CFuncPtr and isinstance(hndlr, _CFuncPtr):
_handlers.append(hndlr) _handlers.append(hndlr)
return return
@@ -934,24 +935,31 @@ def register(hndlr):
_handlers.append(hndlr) _handlers.append(hndlr)
def load_dl(path, localname=''): 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: try:
import ctypes import ctypes
global _CFuncPtr global _CFuncPtr
_CFuncPtr = ctypes._CFuncPtr _CFuncPtr = ctypes._CFuncPtr
except ImportError: except ImportError:
wx.LogError('ctypes module not found') wx.LogError('ctypes module not found')
globals()[localname] = None
return return
try: try:
dl = ctypes.CDLL(path) dl = ctypes.CDLL(path)
if not localname:
localname = os.path.basename(os.path.splitext(dl._name)[0])
globals()[localname] = dl globals()[localname] = dl
# Register AddXmlHandlers() if exists
try:
register(dl.AddXmlHandlers)
except:
pass
except: except:
wx.LogError('error loading dynamic library: %s', path) wx.LogError('error loading dynamic library: %s' % path)
print traceback.print_exc() print traceback.print_exc()
# Called when creating test window # Called when creating test window
def addHandlers(res): def addHandlers():
for h in _handlers: for h in _handlers:
if _CFuncPtr and isinstance(h, _CFuncPtr): if _CFuncPtr and isinstance(h, _CFuncPtr):
try: try:
@@ -961,7 +969,7 @@ def addHandlers(res):
print traceback.print_exc() print traceback.print_exc()
else: else:
try: try:
res.AddHandler(apply(h, ())) xrc.XmlResource.Get().AddHandler(apply(h, ()))
except: except:
wx.LogError('error adding XmlHandler: "%s"' % h) wx.LogError('error adding XmlHandler: "%s"' % h)
print traceback.print_exc() print traceback.print_exc()
@@ -970,6 +978,28 @@ def clearHandlers():
global _handlers global _handlers
_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): class xxxParamComment(xxxParam):
def __init__(self, node): def __init__(self, node):
xxxNode.__init__(self, node) xxxNode.__init__(self, node)
@@ -1002,6 +1032,7 @@ class xxxComment(xxxObject):
################################################################################ ################################################################################
# Mapping of XRC names to xxx classes
xxxDict = { xxxDict = {
'wxPanel': xxxPanel, 'wxPanel': xxxPanel,
'wxDialog': xxxDialog, 'wxDialog': xxxDialog,