summaryrefslogtreecommitdiff
path: root/gi/_gtktemplate.py
diff options
context:
space:
mode:
Diffstat (limited to 'gi/_gtktemplate.py')
-rw-r--r--gi/_gtktemplate.py49
1 files changed, 40 insertions, 9 deletions
diff --git a/gi/_gtktemplate.py b/gi/_gtktemplate.py
index 15f6b2c5..a631a6eb 100644
--- a/gi/_gtktemplate.py
+++ b/gi/_gtktemplate.py
@@ -17,26 +17,57 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
+from collections import abc
from functools import partial
from gi.repository import GLib, GObject, Gio
+def _extract_handler_and_args(obj_or_map, handler_name):
+ handler = None
+ if isinstance(obj_or_map, abc.Mapping):
+ handler = obj_or_map.get(handler_name, None)
+ else:
+ handler = getattr(obj_or_map, handler_name, None)
+
+ if handler is None:
+ raise AttributeError('Handler %s not found' % handler_name)
+
+ args = ()
+ if isinstance(handler, abc.Sequence):
+ if len(handler) == 0:
+ raise TypeError("Handler %s tuple can not be empty" % handler)
+ args = handler[1:]
+ handler = handler[0]
+
+ elif not callable(handler):
+ raise TypeError('Handler %s is not a method, function or tuple' % handler)
+
+ return handler, args
+
+
def define_builder_scope():
from gi.repository import Gtk
class BuilderScope(GObject.GObject, Gtk.BuilderScope):
- def __init__(self):
+ def __init__(self, scope_object=None):
super().__init__()
+ self._scope_object = scope_object
def do_create_closure(self, builder, func_name, flags, obj):
- current_object = builder.get_current_object()
+ current_object = builder.get_current_object() or self._scope_object
- if func_name not in current_object.__gtktemplate_methods__:
- return None
+ if not self._scope_object:
+ current_object = builder.get_current_object()
+ if func_name not in current_object.__gtktemplate_methods__:
+ return None
- current_object.__gtktemplate_handlers__.add(func_name)
+ current_object.__gtktemplate_handlers__.add(func_name)
+ handler_name = current_object.__gtktemplate_methods__[func_name]
+ else:
+ current_object = self._scope_object
+ handler_name = func_name
swapped = int(flags & Gtk.BuilderClosureFlags.SWAPPED)
if swapped:
@@ -44,12 +75,12 @@ def define_builder_scope():
"%r not supported" % GObject.ConnectFlags.SWAPPED)
return None
- handler_name = current_object.__gtktemplate_methods__[func_name]
- handler = getattr(current_object, handler_name)
+ handler, args = _extract_handler_and_args(current_object, handler_name)
+
if obj:
- return partial(handler, swap_data=obj)
+ return partial(handler, *args, swap_data=obj)
- return handler
+ return partial(handler, *args)
return BuilderScope