Virgil Dupras committed ddd1188

Allow UI scripts to import units that are from the same folder.

  • Participants
  • Parent commits 40b5c86

Comments (0)

Files changed (3)

File docs/basics.rst

 Of course, as is the case with XIB's your custom class will be instantiated with the same arguments
 as a typical ``NSTableView`` would.
+Import from modules
+Because UI scripts are Python modules, it's possible to import from other modules. The folder in
+which the UI script is will be in ``PYTHONPATH``, so you can do stuff like add a ```` unit
+and then do ``from common import MyLabelSubclass`` in your UI scripts.
+The only thing to remember, however, is that the magic that goes on in UI scripts to put all xibless
+classes in your UI script's global namespace doesn't work for imported modules. Therefore, if your
+module use any xibless classes, you have to import them yourself from the ``xibless`` package (and
+you'll have to figure out where they live in the package). That's far from ideal, I'll fix that
+some day.

File xibless/

+import sys
+import os
 import os.path as op
 import tempfile
 import shutil
     module_globals = {name: globals()[name] for name in to_include}
     module_globals['args'] = args
     module_locals = {}
+    sys.path.insert(0, op.dirname(modulePath))
     execfile(modulePath, module_globals, module_locals)
+    del sys.path[0]
     assert 'result' in module_locals
     tmpl = CodeTemplate(UNIT_TMPL)
     if runmode:
         owner._name = 'nil'
         ownerclass = 'id'
         ownerimport = None
+        # We do this to avoid custom OBJC classes definition from preventing compilation.
         for value in module_locals.values():
-            if hasattr(value, 'OBJC_CLASS'):
+            if hasattr(value, 'OBJC_CLASS') and hasattr(value.__class__, 'OBJC_CLASS'):
                 value.OBJC_CLASS = value.__class__.OBJC_CLASS
         ownerclass = module_locals.get('ownerclass', 'id')
     tmpPath = tempfile.mkdtemp()
     destPath = op.join(tmpPath, 'runtemplate')
     shutil.copytree(runtemplatePath, destPath)
-    shutil.copy(modulePath, op.join(destPath, ''))
+    wscriptPath = op.join(destPath, 'wscript')
+    with open(wscriptPath, 'rt') as fp:
+        wscriptContent =
+    wscriptContent = wscriptContent.replace('{{script_path}}', op.abspath(modulePath))
+    with open(wscriptPath, 'wt') as fp:
+        fp.write(wscriptContent)
     cmd = 'cd "%s" && python ./waf configure && python ./waf && open build/ -W && cd ../.. && rm -r "%s"' % (destPath, tmpPath)
     p = Popen(cmd, shell=True)

File xibless/runtemplate/wscript

-#! /usr/bin/env python
+#!/usr/bin/env python
 import plistlib
 import xibless
 top = '.'
 out = 'build'
+SCRIPT_PATH = "{{script_path}}"
 def options(opt):
 def build(ctx):
     xibless.generate('', 'autogen/MainMenu.h')
-    xibless.generate('', 'autogen/MainScript.h', runmode=True)
+    xibless.generate(SCRIPT_PATH, 'autogen/MainScript.h', runmode=True)
     infoplist = ctx.srcnode.find_node("Info.plist")
     info = plistlib.readPlist(infoplist.abspath())
     appname = info['CFBundleName']