[vala/wip/gtktemplate] Add support for GtkBuilder widget templates



commit f990ed0045158be832e3ecf2da79ce326eced7aa
Author: Luca Bruno <lucabru src gnome org>
Date:   Mon Apr 29 23:04:47 2013 +0200

    Add support for GtkBuilder widget templates

 codegen/Makefile.am              |    1 +
 codegen/valaccodebasemodule.vala |    6 ++
 codegen/valagasyncmodule.vala    |    2 +-
 codegen/valagtkmodule.vala       |  118 ++++++++++++++++++++++++++++++++++++++
 codegen/valagtypemodule.vala     |    5 ++
 vala/valaattribute.vala          |    4 +-
 vala/valacodenode.vala           |    6 +-
 vala/valamethod.vala             |    4 +
 8 files changed, 140 insertions(+), 6 deletions(-)
---
diff --git a/codegen/Makefile.am b/codegen/Makefile.am
index ac99790..5a427a3 100644
--- a/codegen/Makefile.am
+++ b/codegen/Makefile.am
@@ -36,6 +36,7 @@ libvala_la_VALASOURCES = \
        valagerrormodule.vala \
        valagirwriter.vala \
        valagobjectmodule.vala \
+       valagtkmodule.vala \
        valagsignalmodule.vala \
        valagtypemodule.vala \
        valagvariantmodule.vala \
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 332c9ba..457328a 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -321,6 +321,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        public Class gsource_type;
        public TypeSymbol type_module_type;
        public TypeSymbol dbus_proxy_type;
+       public Class gtk_widget_type;
 
        public bool in_plugin = false;
        public string module_init_param_name;
@@ -493,6 +494,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                dbus_proxy_type = (TypeSymbol) glib_ns.scope.lookup ("DBusProxy");
 
+               var gtk_ns = root_symbol.scope.lookup ("Gtk");
+               if (gtk_ns != null) {
+                       gtk_widget_type = (Class) gtk_ns.scope.lookup ("Widget");
+               }
+
                header_file = new CCodeFile ();
                header_file.is_header = true;
                internal_header_file = new CCodeFile ();
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index b40965c..3317c7f 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -22,7 +22,7 @@
 
 using GLib;
 
-public class Vala.GAsyncModule : GSignalModule {
+public class Vala.GAsyncModule : GtkModule {
        CCodeStruct generate_data_struct (Method m) {
                string dataname = Symbol.lower_case_to_camel_case (get_ccode_name (m)) + "Data";
                var data = new CCodeStruct ("_" + dataname);
diff --git a/codegen/valagtkmodule.vala b/codegen/valagtkmodule.vala
new file mode 100644
index 0000000..f3d9bb4
--- /dev/null
+++ b/codegen/valagtkmodule.vala
@@ -0,0 +1,118 @@
+/* valagtkmodule.vala
+ *
+ * Copyright (C) 2013  Jürg Billeter
+ * Copyright (C) 2013  Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Luca Bruno <lucabru src gnome org>
+ */
+
+
+public class Vala.GtkModule : GSignalModule {
+       private bool is_gtk_template (Class? cl) {
+               return cl != null && gtk_widget_type != null && cl.is_subtype_of (gtk_widget_type) && 
cl.get_attribute ("GtkTemplate") != null;
+       }
+
+       public override void generate_class_init (Class cl) {
+               base.generate_class_init (cl);
+
+               if (!is_gtk_template (cl)) {
+                       return;
+               }
+
+               /* Gtk builder widget template */
+               var ui = cl.get_attribute_string ("GtkTemplate", "ui");
+               if (ui == null) {
+                       Report.error (cl.source_reference, "Empty ui file declaration for GtkBuilder widget 
template");
+                       cl.error = true;
+                       return;
+               }
+
+               var call = new CCodeFunctionCall (new CCodeIdentifier 
("gtk_widget_class_set_template_from_resource"));
+               call.add_argument (new CCodeIdentifier ("GTK_WIDGET_CLASS (klass)"));
+               call.add_argument (new CCodeConstant ("\""+cl.get_attribute_string ("GtkTemplate", 
"ui")+"\""));
+               ccode.add_expression (call);
+       }
+
+       public override void visit_field (Field f) {
+               base.visit_field (f);
+
+               var cl = current_class;
+               if (!is_gtk_template (cl)) {
+                       return;
+               }
+
+               if (f.binding != MemberBinding.INSTANCE || f.get_attribute ("GtkChild") == null) {
+                       return;
+               }
+
+               push_context (class_init_context);
+
+               var gtk_name = f.get_attribute_string ("GtkChild", "name", f.name);
+               var internal_child = f.get_attribute_bool ("GtkChild", "internal");
+
+               var offset = new CCodeFunctionCall (new CCodeIdentifier ("G_STRUCT_OFFSET"));
+               offset.add_argument (new CCodeIdentifier ("%sPrivate".printf (get_ccode_name (cl))));
+               offset.add_argument (new CCodeIdentifier (get_ccode_name (f)));
+
+               var call = new CCodeFunctionCall (new CCodeIdentifier ("gtk_widget_class_automate_child"));
+               call.add_argument (new CCodeIdentifier ("GTK_WIDGET_CLASS (klass"));
+               call.add_argument (new CCodeConstant ("\"%s\"".printf (gtk_name)));
+               call.add_argument (new CCodeConstant (internal_child ? "TRUE" : "FALSE"));
+               call.add_argument (offset);
+               ccode.add_expression (call);
+
+               pop_context ();
+       }
+
+       public override void visit_method (Method m) {
+               base.visit_method (m);
+
+               var cl = current_class;
+               if (!is_gtk_template (cl)) {
+                       return;
+               }
+
+               if (m.binding != MemberBinding.INSTANCE || m.get_attribute ("GtkCallback") == null) {
+                       return;
+               }
+
+               push_context (class_init_context);
+
+               var gtk_name = m.get_attribute_string ("GtkCallback", "name", get_ccode_name (m));
+
+               var call = new CCodeFunctionCall (new CCodeIdentifier ("gtk_widget_class_declare_callback"));
+               call.add_argument (new CCodeIdentifier ("GTK_WIDGET_CLASS (klass"));
+               call.add_argument (new CCodeConstant ("\"%s\"".printf (gtk_name)));
+               call.add_argument (new CCodeIdentifier (get_ccode_name (m)));
+               ccode.add_expression (call);
+
+               pop_context ();
+       }
+
+
+       public override void generate_instance_init (Class cl) {
+               if (!is_gtk_template (cl)) {
+                       return;
+               }
+
+               var call = new CCodeFunctionCall (new CCodeIdentifier ("gtk_widget_init_template"));
+               call.add_argument (new CCodeIdentifier ("GTK_WIDGET (self)"));
+               ccode.add_expression (call);
+       }
+}
+
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 3be2d29..604456a 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -1166,6 +1166,9 @@ public class Vala.GTypeModule : GErrorModule {
        public virtual void generate_class_init (Class cl) {
        }
 
+       public virtual void generate_instance_init (Class cl) {
+       }
+
        private void begin_class_init_function (Class cl) {
                push_context (class_init_context);
 
@@ -1570,6 +1573,8 @@ public class Vala.GTypeModule : GErrorModule {
                        func.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), 
"priv"), ccall);
                }
 
+               generate_instance_init (cl);
+
                pop_context ();
        }
 
diff --git a/vala/valaattribute.vala b/vala/valaattribute.vala
index 63258e1..a3ce48b 100644
--- a/vala/valaattribute.vala
+++ b/vala/valaattribute.vala
@@ -73,11 +73,11 @@ public class Vala.Attribute : CodeNode {
         * @param name argument name
         * @return     string value
         */
-       public string? get_string (string name) {
+       public string? get_string (string name, string? default_value = null) {
                string value = args.get (name);
 
                if (value == null) {
-                       return null;
+                       return default_value;
                }
 
                /* remove quotes */
diff --git a/vala/valacodenode.vala b/vala/valacodenode.vala
index 3872a46..5413ed4 100644
--- a/vala/valacodenode.vala
+++ b/vala/valacodenode.vala
@@ -206,12 +206,12 @@ public abstract class Vala.CodeNode {
         * @param argument  argument name
         * @return          string value
         */
-       public string? get_attribute_string (string attribute, string argument) {
+       public string? get_attribute_string (string attribute, string argument, string? default_value = null) 
{
                var a = get_attribute (attribute);
                if (a == null) {
-                       return null;
+                       return default_value;
                }
-               return a.get_string (argument);
+               return a.get_string (argument, default_value);
        }
 
        /**
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index cf02d60..f45dc3e 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -779,6 +779,10 @@ public class Vala.Method : Subroutine {
                        }
                }
 
+               if (get_attribute ("GtkCallback") != null) {
+                       used = true;
+               }
+
                return !error;
        }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]