Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Composite Templates #328

Open
Blquinn opened this issue Apr 14, 2021 · 2 comments
Open

Add Support for Composite Templates #328

Blquinn opened this issue Apr 14, 2021 · 2 comments

Comments

@Blquinn
Copy link

Blquinn commented Apr 14, 2021

Composite templates are quite convenient when you use UI files. It would be cool to add them!

https://blogs.gnome.org/tvb/2013/04/09/announcing-composite-widget-templates/

@MikeWey
Copy link
Member

MikeWey commented Apr 14, 2021

I agree, i'll try and investigate when i get some time.

@Blquinn
Copy link
Author

Blquinn commented Apr 14, 2021

@MikeWey I did some d exploration because I wanted to see if we could implement something similar to what PyGobject or Vala has in terms of succinctness with these templates. It's a really nice experience to be able to define the children, the resource path for the ui file and callbacks with attributes.

Best solution I could find was with template mixins and user defined attributes.

import std.stdio;

struct GtkTemplate
{
    string ui_resource;
}

struct GtkChild;
struct GtkCallback;
    
public static GtkTemplate getGtkTemplate(T)() {
    GtkTemplate res;
    static foreach (attr; __traits(getAttributes, T)) {
        static if (is(typeof(attr) == GtkTemplate)) {
            res = attr;
        }
    }
    return res;
}

mixin template GtkTemplateMixin()
{
	private const void initializeTemplate() 
	{
          import std.traits;
  
          const GtkTemplate res = getGtkTemplate!(typeof(this));
          static if (res.ui_resource == "") {
              pragma(msg, "error: widgets using the GtkTemplateMixin must define the @GtkTemplate attribute.");
          }
          static assert(res.ui_resource != "");
  
          static foreach (member; __traits(derivedMembers, typeof(this)))
          {
              static if (hasUDA!(__traits(getMember, this, member), GtkChild)) 
              {
                  // TODO: call gtk_widget_class_bind_child
                  pragma(msg, member, " is a GtkChild");
              }
  
              else static if (hasUDA!(__traits(getMember, this, member), GtkCallback)) 
              {
                  // TODO: call gtk_widget_class_bind_callback
                  pragma(msg, member, " is a GtkCallback");
              }
          }
	}
}

/////////////////////////////////////
// What the user sees.

@GtkTemplate("/the/ui/file.ui")
class MyWidget
{
	@GtkChild string object_property;

	this()
	{
		mixin GtkTemplateMixin;
		initializeTemplate();
	}

	@GtkCallback
	private void foo() {
	}
}

void main()
{
	auto w = new MyWidget();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants