Re: GtkBindingSet etc



I got to this point on entry_add_signal.  It means you can populate
bindings from program code.  See if the docs are as clear as mud.

I don't want to much for field accessors, not initially.  So the only
outstanding point would be whether add_path() should take
GtkPathPriorityType enum strings, or integer values, or both.  I think a
priority() field accessor would return an integer, so add_path() might
want to accept an integer, whatever else it does or doesn't do.  (The
point as before being that not all possible values are covered by the
enum members ...)



$binding_set->entry_add_signal (keyval, modifiers, signal_name, type,
    value,...)
        ·   $keyval (integer)

        ·   $modifiers (Gtk2::Gdk::ModifierType)

        ·   $signal_name (string)

        ·   $value (scalar)

        ·   $type (string)

        Add an entry to $binding_set.  $keyval and $modifier are setup to
        invoke $signal_name, with signal parameters given by the $value
        arguments.  Each value is preceded by a type (a string), which must
        be one of

            Glib::Long
            Glib::Double
            Glib::String
            an enum type, ie. subtype of Glib::Enum
            Glib::Flags, or a flags subtype

        For example,

            $binding_set->entry_add_signal
                (Gtk2->keyval_from_name('Return'),
                 [ 'control-mask' ],   # modifiers
                 'some-signal-name',
                 'Glib::Double', 1.5,
                 'Glib::String,  'hello');

        A parameter holds one of the three types Long, Double and String.
        When invoked they're coerced to the parameter types expected by the
        target object or widget.  Use Glib::Long for any integer argument,
        including chars and unichars by ordinal value.  Use Glib::Double
        for both single and double precision floats.

        Flags and enums are held as Longs in the BindingSet.  You can pass
        an enum type and string and "entry_with_signal" will lookup and
        store accordingly.  For example

            $binding_set->entry_add_signal
                (Gtk2->keyval_from_name('Escape), [],
                 'set-direction',
                 'Gtk2::Orientation', 'vertical');

        Likewise flags from an arrayref,

            $binding_set->entry_add_signal
                (Gtk2->keyval_from_name('d'), [],
                 'initiate-drag',
                 'Gtk2::Gdk::DragAction', ['move,'ask']);

        If you've got a Glib::Flags object, rather than just an arrayref,
        then you can just give Glib::Flags as the type and the value is
        taken from the object.  For example,

            my $flags = Gtk2::DebugFlag->new (['tree', 'updates']);
            $binding_set->entry_add_signal
                (Gtk2->keyval_from_name('x'), ['control-mask'],
                 'change-debug',
                 'Glib::Flags', $flags);



=for apidoc
=for signature $binding_set->entry_add_signal (keyval, modifiers, signal_name, type, value,...)
=for arg type (string)
=for arg value (scalar)
=for arg ... (__hide__)
Add an entry to $binding_set.  $keyval and $modifier are setup to
invoke $signal_name, with signal parameters given by the $value
arguments.  Each value is preceded by a type (a string), which must be
one of

    Glib::Long
    Glib::Double
    Glib::String
    an enum type, ie. subtype of Glib::Enum
    Glib::Flags, or a flags subtype

For example,

    $binding_set->entry_add_signal
        (Gtk2->keyval_from_name('Return'),
         [ 'control-mask' ],   # modifiers
         'some-signal-name',
         'Glib::Double', 1.5,
         'Glib::String,  'hello');

A parameter holds one of the three types Long, Double and String.
When invoked they're coerced to the parameter types expected by the
target object or widget.  Use Glib::Long for any integer argument,
including chars and unichars by ordinal value.  Use Glib::Double for
both single and double precision floats.

Flags and enums are held as Longs in the BindingSet.  You can pass an
enum type and string and C<entry_with_signal> will lookup and store
accordingly.  For example

    $binding_set->entry_add_signal
        (Gtk2->keyval_from_name('Escape), [],
         'set-direction',
         'Gtk2::Orientation', 'vertical');

Likewise flags from an arrayref,

    $binding_set->entry_add_signal
        (Gtk2->keyval_from_name('d'), [],
         'initiate-drag',
         'Gtk2::Gdk::DragAction', ['move,'ask']);

If you've got a Glib::Flags object, rather than just an arrayref, then
you can just give Glib::Flags as the type and the value is taken from
the object.  For example,

    my $flags = Gtk2::DebugFlag->new (['tree', 'updates']);
    $binding_set->entry_add_signal
        (Gtk2->keyval_from_name('x'), ['control-mask'],
         'change-debug',
         'Glib::Flags', $flags);
=cut
void
gtk_binding_entry_add_signal (binding_set, keyval, modifiers, signal_name, ...)
        GtkBindingSet *binding_set
        guint keyval
        GdkModifierType modifiers
        const gchar *signal_name
    PREINIT:
        const int first_argnum = 4;
        int count, i;
        GSList *binding_args = NULL;
        GtkBindingArg *ap;
    CODE:
        count = (items - first_argnum);
        if ((count % 2) != 0) {
                croak ("entry_add_signal expects type,value pairs "
                       "(odd number of arguments detected)");
        }
        count /= 2;
        ap = g_new (GtkBindingArg, count);
        for (i = 0; i < count; i += 2) {
                SV *sv_type  = ST(i + first_argnum);
                SV *sv_value = ST(i + first_argnum + 1);
                GType gtype  = gperl_type_from_package(SvPV_nolen(sv_type));

                /* gtype==G_TYPE_NONE for sv_type not registered will fall
                 * through to the default
                 */
                switch (G_TYPE_FUNDAMENTAL (gtype)) {
                case G_TYPE_LONG:
                        ap[i].d.long_data = SvIV(sv_value);
                        break;
                case G_TYPE_DOUBLE:
                        ap[i].d.double_data = SvNV(sv_value);
                        break;
                case G_TYPE_STRING:
                        /* GTK_TYPE_IDENTIFIER comes through here, but
                         * believe that's only a hangover from gtk 1.2 and
                         * needs no special attention.
                         */
                        /* gtk copies the string */
                        ap[i].d.string_data = SvPV_nolen(sv_value);
                        break;

                /* helpers converting to the three basic types ... */
                case G_TYPE_ENUM:
                        /* coerce enum to long */
                        ap[i].d.long_data = gperl_convert_enum(gtype,sv_value);
                        gtype = G_TYPE_LONG;
                        break;
                case G_TYPE_FLAGS:
                        /* coerce flags to long */
                        ap[i].d.long_data = gperl_convert_flags(gtype,sv_value);
                        gtype = G_TYPE_LONG;
                        break;

                default:
                        g_slist_free (binding_args);
                        g_free (ap);
                        croak ("Unrecognised argument type '%s'",
                                SvPV_nolen(sv_type));
                }
                ap[i].arg_type = gtype;
                binding_args = g_slist_append (binding_args, &(ap[i]));
        }
        gtk_binding_entry_add_signall (binding_set, keyval, modifiers,
                                       signal_name, binding_args);
        g_slist_free (binding_args);
        g_free (ap);



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