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 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 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

@deviator deviator commented Aug 11, 2017

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 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 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 Feb 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants