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:
@@ -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:
|
||||||
|
@@ -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,13 +536,20 @@ 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():
|
||||||
|
try:
|
||||||
data = wx.CustomDataObject('XRCED')
|
data = wx.CustomDataObject('XRCED')
|
||||||
if wx.TheClipboard.IsSupported(data.GetFormat()):
|
if wx.TheClipboard.IsSupported(data.GetFormat()):
|
||||||
|
try:
|
||||||
success = wx.TheClipboard.GetData(data)
|
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
|
if not success: # try other format
|
||||||
data = wx.CustomDataObject('XRCED_node')
|
data = wx.CustomDataObject('XRCED_node')
|
||||||
if wx.TheClipboard.IsSupported(data.GetFormat()):
|
if wx.TheClipboard.IsSupported(data.GetFormat()):
|
||||||
success_node = wx.TheClipboard.GetData(data)
|
success_node = wx.TheClipboard.GetData(data)
|
||||||
|
finally:
|
||||||
wx.TheClipboard.Close()
|
wx.TheClipboard.Close()
|
||||||
|
|
||||||
if not success and not success_node:
|
if not success and not success_node:
|
||||||
@@ -1086,6 +1096,9 @@ Homepage: http://xrced.sourceforge.net\
|
|||||||
xxx = MakeEmptyCommentXXX(parent)
|
xxx = MakeEmptyCommentXXX(parent)
|
||||||
else:
|
else:
|
||||||
# Create empty element
|
# Create empty element
|
||||||
|
if evt.GetId() >= ID_NEW.CUSTOM:
|
||||||
|
className = pullDownMenu.customMap[evt.GetId()]
|
||||||
|
else:
|
||||||
className = pullDownMenu.createMap[evt.GetId()]
|
className = pullDownMenu.createMap[evt.GetId()]
|
||||||
xxx = MakeEmptyXXX(parent, className)
|
xxx = MakeEmptyXXX(parent, className)
|
||||||
|
|
||||||
@@ -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)
|
||||||
|
@@ -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:
|
except:
|
||||||
wx.LogError('error loading dynamic library: %s', path)
|
pass
|
||||||
|
except:
|
||||||
|
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,
|
||||||
|
Reference in New Issue
Block a user