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()
|
||||
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:
|
||||
|
@@ -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.<P>
|
||||
Or just press one of the buttons on the tools palette.<P>
|
||||
Enter XML ID, change properties, create children.<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',
|
||||
@@ -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,13 +536,20 @@ class Frame(wx.Frame):
|
||||
# Create a copy of clipboard pickled element
|
||||
success = success_node = False
|
||||
if wx.TheClipboard.Open():
|
||||
try:
|
||||
data = wx.CustomDataObject('XRCED')
|
||||
if wx.TheClipboard.IsSupported(data.GetFormat()):
|
||||
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:
|
||||
@@ -1086,6 +1096,9 @@ Homepage: http://xrced.sourceforge.net\
|
||||
xxx = MakeEmptyCommentXXX(parent)
|
||||
else:
|
||||
# Create empty element
|
||||
if evt.GetId() >= ID_NEW.CUSTOM:
|
||||
className = pullDownMenu.customMap[evt.GetId()]
|
||||
else:
|
||||
className = pullDownMenu.createMap[evt.GetId()]
|
||||
xxx = MakeEmptyXXX(parent, className)
|
||||
|
||||
@@ -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)
|
||||
|
@@ -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:
|
||||
wx.LogError('error loading dynamic library: %s', path)
|
||||
pass
|
||||
except:
|
||||
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,
|
||||
|
Reference in New Issue
Block a user