REF = wx.NewId()
COMMENT = wx.NewId()
+ CUSTOM = wx.NewId()
+ for i in range(99): wx.NewId() # reserve IDs for custom controls
+
LAST = wx.NewId()
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
################################################################################
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:
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):
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:
else:
basePath = os.path.dirname(__file__)
+# Remember system path
+sys_path = sys.path
+
# 1 adds CMD command to Help menu
debug = 0
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',
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)
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')
# 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(
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
self.maxIDs[cl] = 0
# Handlers
clearHandlers()
+ g.pullDownMenu.clearCustom()
def SetModified(self, state=True):
self.modified = state
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)
################################################################################
# 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
_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:
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()
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)
################################################################################
+# Mapping of XRC names to xxx classes
xxxDict = {
'wxPanel': xxxPanel,
'wxDialog': xxxDialog,