{"action":"opened","issue":{"url":"https://api.github.com/repos/pavouk/lgi/issues/147","repository_url":"https://api.github.com/repos/pavouk/lgi","labels_url":"https://api.github.com/repos/pavouk/lgi/issues/147/labels{/name}","comments_url":"https://api.github.com/repos/pavouk/lgi/issues/147/comments","events_url":"https://api.github.com/repos/pavouk/lgi/issues/147/events","html_url":"https://github.com/pavouk/lgi/issues/147","id":189998707,"number":147,"title":"Add better support for GtkTemplate","user":{"login":"TingPing","id":798838,"avatar_url":"https://avatars.githubusercontent.com/u/798838?v=3","gravatar_id":"","url":"https://api.github.com/users/TingPing","html_url":"https://github.com/TingPing","followers_url":"https://api.github.com/users/TingPing/followers","following_url":"https://api.github.com/users/TingPing/following{/other_user}","gists_url":"https://api.github.com/users/TingPing/gists{/gist_id}","starred_url":"https://api.github.com/users/TingPing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TingPing/subscriptions","organizations_url":"https://api.github.com/users/TingPing/orgs","repos_url":"https://api.github.com/users/TingPing/repos","events_url":"https://api.github.com/users/TingPing/events{/privacy}","received_events_url":"https://api.github.com/users/TingPing/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-11-17T10:05:03Z","updated_at":"2016-11-17T10:05:03Z","closed_at":null,"body":"This is a feature of GtkWidget and GtkBuilder. If unfamiliar https://blogs.gnome.org/tvb/2013/04/09/announcing-composite-widget-templates/\r\n\r\nHere is something I got working but is less than pretty:\r\n\r\n```lua\r\nlocal lgi = require('lgi')\r\nlocal GLib = lgi.require('GLib')\r\nlocal GObject = lgi.require('GObject')\r\nlocal Gtk = lgi.require('Gtk', '3.0')\r\n\r\nlocal Test = lgi.package('Test')\r\n\r\nfunction template_connect_function(builder, object, signal_name, handler_name,\r\n                                   connect_object, flags, class_name)\r\n\tlocal instance = builder:get_object(class_name)\r\n\tassert(instance ~= nil)\r\n\r\n\tlocal handler = instance[handler_name] -- TODO: Readable error\r\n\tassert(connect_object == nil) -- TODO: Handle extra data\r\n\r\n\t-- TODO: This is ugly, should have more direct approach\r\n\tobject['on_' .. signal_name:gsub('%-', '_')]:connect(handler, nil, flags == GObject.ConnectFlags.AFTER)\r\nend\r\n\r\n-- Window ----------------\r\nlocal ui = [[\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<interface>\r\n  <template class=\"TestWindow\" parent=\"GtkApplicationWindow\">\r\n    <property name=\"title\">Title!?</property>\r\n\t<child>\r\n      <object class=\"GtkButton\" id=\"button\">\r\n        <signal name=\"clicked\" handler=\"on_clicked\"/>\r\n        <property name=\"visible\">1</property>\r\n      </object>\r\n    </child>\r\n  </template>\r\n</interface>\r\n]]\r\n\r\nTest:class('Window', Gtk.ApplicationWindow)\r\n\r\nfunction Test.Window._class_init(name, class)\r\n\tGtk.WidgetClass.set_template(class, GLib.Bytes(ui))\r\n\tGtk.WidgetClass.bind_template_child_full(class, \"button\", true, 0)\r\n\tGtk.WidgetClass.set_connect_func(class, function (builder, object, signal_name, handler_name,\r\n                                                      connect_object, flags)\r\n\t\ttemplate_connect_function(builder, object, signal_name, handler_name,\r\n                                  connect_object, flags, tostring(name):gsub('%.', ''))\r\n\tend)\r\nend\r\n\r\nfunction Test.Window._init(instance)\r\n\tGtk.Widget.init_template(instance)\r\n\tinstance.priv.button = instance:get_template_child(instance._type, \"button\")\r\nend\r\n\r\nfunction Test.Window:on_clicked(button)\r\n\tprint('clicked')\r\nend\r\n\r\n-- Application ------------\r\nTest:class('Application', Gtk.Application)\r\nfunction Test.Application:do_activate()\r\n\tself._type._parent.do_activate(self)\r\nend\r\n\r\nfunction Test.Application:do_startup()\r\n\tself._type._parent.do_startup(self)\r\n\r\n\tlocal win = Test.Window({application=self})\r\n\tprint(win.title)\r\n\twin:present()\r\nend\r\n\r\nfunction Test.Application:do_shutdown()\r\n\tself._type._parent.do_shutdown(self)\r\nend\r\n\r\n-- Main ------------\r\nlocal app = Test.Application()\r\napp:run()\r\n```"}}
{"actor":{"display_login":"TingPing"}}