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

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]