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

How come no g_signal_connect wrapper? #207

Closed
Stretto opened this issue Jul 7, 2017 · 4 comments
Closed

How come no g_signal_connect wrapper? #207

Stretto opened this issue Jul 7, 2017 · 4 comments

Comments

@Stretto
Copy link

Stretto commented Jul 7, 2017

There is a Signals.connectData but no Signals.connect, is there any reason for this?

@MikeWey
Copy link
Member

MikeWey commented Jul 7, 2017

It's not wrapped because it's a macro, and not a function.

That means it's not available in the gir files used by the generator, and would need to be added manually. In this case the macro calls g_signal_connect_data with null as the destroyNotify callback.

@deviator
Copy link
Contributor

Please add connection to custom signals to widget!

Need for situation like this.

Temporary workaround, maybe helpful for somebody

import gtk.Widget;
import gdk.Event;
import gobject.ObjectG;
import gobject.Signals;

class CustomSignals
{
    this() {}

    void connect(Widget widget, string signal, bool delegate(Event, Widget) dlg)
    {
        auto wrapper = new Wrapper(widget, dlg);
        Signals.connectData(widget, signal,
                            cast(GCallback)&callback,
                            cast(void*)wrapper,
                            cast(GClosureNotify)&destroyCallback,
                            cast(ConnectFlags)0
                            );
    }

protected:
    class Wrapper
    {
        Widget widget;
        bool delegate(Event, Widget) dlg;

        this(Widget widget, bool delegate(Event, Widget) dlg)
        {
            this.widget = widget;
            this.dlg = dlg;
            wrappers ~= this;
        }

        bool opCall(Event e) { return dlg(e, widget); }

        void selfRemove()
        {
            import std.algorithm : filter;
            import std.array : array;
            wrappers = wrappers.filter!(a => this !is a).array;
        }
    }

    Wrapper[] wrappers;

    extern(C) static int callback(void* widgetStruct, GdkEvent* event, Wrapper wrapper)
    { return wrapper(ObjectG.getDObject!Event(event)); }

    extern(C) static void destroyCallback(Wrapper wrapper, void* closure)
    { wrapper.selfRemove(); }
}

Using:

auto csig = new CustomSignals;
csig.connect(myWidget, "some-signal", (Event e, Widget w) { /+ do something +/ });

@MikeWey
Copy link
Member

MikeWey commented Aug 12, 2017

Need for situation like this.

For that example you can use addOnNotify from ObjectG.

my_stack.addOnNotify(&vc_changed, "visible-child");

For g_signal_connect we should combine it with the DelegatePointer from #137 so it will work with signals that have different parameters then Event and Widget.

@MikeWey
Copy link
Member

MikeWey commented Feb 7, 2018

master now has a overload of gobject.Signals.Signals.connect that allows connecting D delegates, functions, or even structs/classes with an 'opCall' defined.

So you could do this for the example above:

Signals.connect(myWidget, "some-signal", (Event e, Widget w) { /+ do something +/ });

@MikeWey MikeWey closed this as completed Feb 7, 2018
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

3 participants