[perl-Gtk2] Wrap GtkInfoBar (new in gtk+ 2.18)



commit c6992187ee4b747848c8df17e9fc8e0faf6d0bac
Author: Quentin Sculo <squentin free fr>
Date:   Tue Apr 13 19:30:24 2010 +0200

    Wrap GtkInfoBar (new in gtk+ 2.18)
    
    Privately export the helper routines for response id handling from
    GtkDialog.xs and reuse them in GtkInfoBar.xs.

 MANIFEST           |    3 +
 gtk2perl-private.h |   10 +++
 maps-2.18          |    1 +
 t/GtkInfoBar.t     |   61 +++++++++++++++
 xs/GtkDialog.xs    |   53 ++++++++-----
 xs/GtkInfoBar.xs   |  218 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 xs_files-2.18      |    1 +
 7 files changed, 326 insertions(+), 21 deletions(-)
---
diff --git a/MANIFEST b/MANIFEST
index cea7043..a770067 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -92,6 +92,7 @@ maps-2.10
 maps-2.12
 maps-2.14
 maps-2.16
+maps-2.18
 maps-2.2
 maps-2.4
 maps-2.6
@@ -217,6 +218,7 @@ t/GtkIconView.t
 t/GtkImage.t
 t/GtkImageMenuItem.t
 t/GtkIMContext.t
+t/GtkInfoBar.t
 t/GtkInputDialog.t
 t/GtkInvisible.t
 t/GtkItemFactory.t
@@ -440,6 +442,7 @@ xs/GtkImageMenuItem.xs
 xs/GtkIMContext.xs
 xs/GtkIMContextSimple.xs
 xs/GtkIMMulticontext.xs
+xs/GtkInfoBar.xs
 xs/GtkInputDialog.xs
 xs/GtkInvisible.xs
 xs/GtkItem.xs
diff --git a/gtk2perl-private.h b/gtk2perl-private.h
index f580818..e6d25be 100644
--- a/gtk2perl-private.h
+++ b/gtk2perl-private.h
@@ -43,4 +43,14 @@ gboolean gtk2perl_tree_view_row_separator_func (GtkTreeModel *model,
 				                gpointer      data);
 #endif
 
+/* Implemented in GtkDialog.xs. */
+gint gtk2perl_dialog_response_id_from_sv (SV * sv);
+SV * gtk2perl_dialog_response_id_to_sv (gint response);
+void gtk2perl_dialog_response_marshal (GClosure * closure,
+                                       GValue * return_value,
+                                       guint n_param_values,
+                                       const GValue * param_values,
+                                       gpointer invocation_hint,
+                                       gpointer marshal_data);
+
 #endif /* _GTK2PERL_PRIVATE_H_ */
diff --git a/maps-2.18 b/maps-2.18
new file mode 100644
index 0000000..db45a65
--- /dev/null
+++ b/maps-2.18
@@ -0,0 +1 @@
+GTK_TYPE_INFO_BAR	GtkInfoBar	GtkObject	Gtk2::InfoBar
diff --git a/t/GtkInfoBar.t b/t/GtkInfoBar.t
new file mode 100644
index 0000000..f49979e
--- /dev/null
+++ b/t/GtkInfoBar.t
@@ -0,0 +1,61 @@
+#!/usr/bin/perl
+# vim: set syntax=perl :
+#
+# $Id$
+#
+# GtkInfoBar Tests
+
+use Gtk2::TestHelper tests => 15, at_least_version=> [2,18,0];
+
+ok( my $win = Gtk2::Window->new('toplevel') );
+
+my $infobar=Gtk2::InfoBar->new;
+isa_ok ($infobar, 'Gtk2::InfoBar', 'new');
+$win->add($infobar);
+
+isa_ok ($infobar->get_action_area, 'Gtk2::Widget','get_action_area');
+isa_ok ($infobar->get_content_area, 'Gtk2::Widget','get_content_area');
+
+isa_ok( $infobar->add_button(test3=>3), 'Gtk2::Widget', 'add_button');
+is( button_count($infobar), 1, 'add_button count');
+$infobar->add_buttons(test4=>4,test5=>5);
+is( button_count($infobar), 3, 'add_buttons');
+
+my $button=Gtk2::Button->new("action_widget");
+$infobar->add_action_widget($button, 6);
+is( button_count($infobar), 4, 'add_action_widget');
+
+my $infobar2=Gtk2::InfoBar->new(
+	'gtk-ok' => 'ok', 'test2' => 2,
+);
+isa_ok ($infobar2, 'Gtk2::InfoBar', 'new_with_buttons');
+is( button_count($infobar2), 2, 'new_with_buttons buttons count');
+
+$infobar->set_response_sensitive(6,FALSE);
+is( $button->is_sensitive, FALSE, 'set_response_sensitive');
+
+$infobar->set_message_type('error');
+is( $infobar->get_message_type, 'error', '[gs]et_message_type');
+
+$infobar->set_default_response(4);
+ok( 1,'set_default_response');
+
+$infobar->signal_connect( response => sub {
+		my ($infobar,$response)= _;
+		my $expected=$infobar->{expected_response};
+		ok( $response eq $expected, "response '$expected'" );
+		1;
+	});
+$infobar->response( $infobar->{expected_response}=5 );
+$infobar->response( $infobar->{expected_response}='ok' );
+
+
+sub button_count
+{	my @b=$_[0]->get_action_area->get_children;
+	return scalar @b;
+}
+
+__END__
+
+Copyright (C) 2010 by the gtk2-perl team (see the file AUTHORS for the
+full list).  See LICENSE for more information.
diff --git a/xs/GtkDialog.xs b/xs/GtkDialog.xs
index 152650d..baf184c 100644
--- a/xs/GtkDialog.xs
+++ b/xs/GtkDialog.xs
@@ -23,14 +23,19 @@
 #include <gperl_marshal.h>
 
 /*
+ * The next three functions are also used in GtkInfoBar.xs, thus they are not
+ * declared static.
+ */
+
+/*
  * GtkDialog interprets the response id as completely user-defined for
  * positive values, and as special enums for negative values.  so, we
  * will handle the response_id as a plain SV so we can implement this
  * special behavior.
  */
 
-static gint
-sv_to_response_id (SV * sv)
+gint
+gtk2perl_dialog_response_id_from_sv (SV * sv)
 {
 	int n;
 	if (looks_like_number (sv))
@@ -40,8 +45,8 @@ sv_to_response_id (SV * sv)
 	return n;
 }
 
-static SV *
-response_id_to_sv (gint response)
+SV *
+gtk2perl_dialog_response_id_to_sv (gint response)
 {
 	return gperl_convert_back_enum_pass_unknown (GTK_TYPE_RESPONSE_TYPE,
 	                                             response);
@@ -55,7 +60,7 @@ this custom marshaller allows us to catch and convert enum codes like those
 returned by $dialog->run , instead of requiring the callback to deal with
 the raw negative numeric values for the predefined constants.
 */
-static void
+void
 gtk2perl_dialog_response_marshal (GClosure * closure,
                                   GValue * return_value,
                                   guint n_param_values,
@@ -81,7 +86,7 @@ gtk2perl_dialog_response_marshal (GClosure * closure,
 	/* the second parameter for this signal is defined as an int
 	 * but is actually a response code, and can have GtkResponseType
 	 * values. */
-	XPUSHs (sv_2mortal (response_id_to_sv
+	XPUSHs (sv_2mortal (gtk2perl_dialog_response_id_to_sv
 				(g_value_get_int (param_values + 1))));
 
 	GPERL_CLOSURE_MARSHAL_PUSH_DATA;
@@ -368,7 +373,8 @@ gtk_dialog_new (class, ...)
 		/* skip the first 4 stack items --- we've already seen them! */
 		for (i = 4; i < items; i += 2) {
 			gchar * text = SvGChar (ST (i));
-			int response_id = sv_to_response_id (ST (i+1));
+			int response_id =
+				gtk2perl_dialog_response_id_from_sv (ST (i+1));
 			gtk_dialog_add_button (GTK_DIALOG (dialog), text,
 			                       response_id);
 		}
@@ -413,7 +419,7 @@ SV *
 gtk_dialog_run (dialog)
 	GtkDialog * dialog
     CODE:
-	RETVAL = response_id_to_sv (gtk_dialog_run (dialog));
+	RETVAL = gtk2perl_dialog_response_id_to_sv (gtk_dialog_run (dialog));
     OUTPUT:
 	RETVAL
 
@@ -428,7 +434,7 @@ gtk_dialog_response (dialog, response_id)
 	GtkDialog * dialog
 	SV        * response_id
     C_ARGS:
-	dialog, sv_to_response_id (response_id)
+	dialog, gtk2perl_dialog_response_id_from_sv (response_id)
 
 
 
@@ -444,7 +450,8 @@ gtk_dialog_add_button (dialog, button_text, response_id)
 	SV          * response_id
     CODE:
 	RETVAL = gtk_dialog_add_button (dialog, button_text,
-	                                sv_to_response_id (response_id));
+	                                gtk2perl_dialog_response_id_from_sv (
+	                                  response_id));
     OUTPUT:
 	RETVAL
 
@@ -454,18 +461,19 @@ Like calling C<< $dialog->add_button >> repeatedly, except you don't get the
 created widgets back.  The buttons go from left to right, so the first button
 added will be the left-most one.
 =cut
-void 
+void
 gtk_dialog_add_buttons (dialog, ...)
 	GtkDialog * dialog
     PREINIT:
 	int i;
     CODE:
-	if( !(items % 2) )
+	if (!(items % 2))
 		croak("gtk_dialog_add_buttons: odd number of parameters");
 	/* we can't make var args, so we'll call add_button for each */
-	for( i = 1; i < items; i += 2 )
-		gtk_dialog_add_button(dialog, SvGChar(ST(i)), 
-			sv_to_response_id(ST(i+1)));
+	for (i = 1; i < items; i += 2)
+		gtk_dialog_add_button (dialog, SvGChar (ST (i)),
+		                       gtk2perl_dialog_response_id_from_sv (
+		                         ST (i+1)));
 
 =for apidoc
 =for arg response_id (GtkResponseType)
@@ -478,7 +486,8 @@ gtk_dialog_set_response_sensitive (dialog, response_id, setting)
 	gboolean    setting
     CODE:
 	gtk_dialog_set_response_sensitive (dialog,
-	                                   sv_to_response_id (response_id),
+	                                   gtk2perl_dialog_response_id_from_sv (
+	                                     response_id),
 	                                   setting);
 
 =for apidoc
@@ -489,10 +498,10 @@ gtk_dialog_add_action_widget (dialog, child, response_id)
 	GtkDialog   * dialog
 	GtkWidget   * child
 	SV          * response_id
-    PREINIT:
     CODE:
 	gtk_dialog_add_action_widget (dialog, child,
-	                              sv_to_response_id (response_id));
+	                              gtk2perl_dialog_response_id_from_sv (
+	                                response_id));
 
 
 =for apidoc
@@ -504,7 +513,8 @@ gtk_dialog_set_default_response (dialog, response_id)
 	SV        * response_id
     CODE:
 	gtk_dialog_set_default_response (dialog,
-	                                 sv_to_response_id (response_id));
+	                                 gtk2perl_dialog_response_id_from_sv (
+	                                   response_id));
 
 void
 gtk_dialog_set_has_separator (dialog, setting)
@@ -528,7 +538,8 @@ gtk_dialog_set_alternative_button_order (dialog, ...)
 	if ((n_params = (items - 1)) > 0) {
 		new_order = g_new0 (gint, n_params);
 		for (i = 1; i < items; i++)
-			new_order[i - 1] = sv_to_response_id (ST (i));
+			new_order[i - 1] = gtk2perl_dialog_response_id_from_sv (
+			                     ST (i));
 
 		gtk_dialog_set_alternative_button_order_from_array (
 			dialog, n_params, new_order);
@@ -549,7 +560,7 @@ gtk_dialog_get_response_for_widget (dialog, widget)
 	gint tmp;
     CODE:
 	tmp = gtk_dialog_get_response_for_widget (dialog, widget);
-	RETVAL = response_id_to_sv (tmp);
+	RETVAL = gtk2perl_dialog_response_id_to_sv (tmp);
     OUTPUT:
 	RETVAL
 
diff --git a/xs/GtkInfoBar.xs b/xs/GtkInfoBar.xs
new file mode 100644
index 0000000..65804a1
--- /dev/null
+++ b/xs/GtkInfoBar.xs
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2010 by the gtk2-perl team (see the file AUTHORS)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtk2perl.h"
+#include "gtk2perl-private.h" /* for the custom response id handling */
+#include <gperl_marshal.h>
+
+MODULE = Gtk2::InfoBar	PACKAGE = Gtk2::InfoBar	PREFIX = gtk_info_bar_
+
+BOOT:
+	gperl_signal_set_marshaller_for (GTK_TYPE_INFO_BAR, "response",
+	                                 gtk2perl_dialog_response_marshal);
+
+=for position post_signals
+
+Note that currently in a Perl subclass of C<Gtk2::InfoBar> a class
+closure, ie. class default signal handler, for the C<response> signal
+will be called with the response ID just as an integer, it's not
+turned into an enum string like C<"ok"> the way a handler setup with
+C<signal_connect> receives.
+
+Hopefully this will change in the future, so don't count on it.  In
+the interim the easiest thing to do is install your default handler in
+C<INIT_INSTANCE> with a C<signal_connect>.  (The subtleties of what
+order handlers are called in will differ, but often that doesn't
+matter.)
+
+=cut
+
+=for enum GtkResponseType
+
+The response type is somewhat abnormal as far as gtk2-perl enums go.  In C,
+this enum lists named, predefined integer values for a field that is other
+composed of whatever integer values you like.  In Perl, we allow this to
+be either one of the string constants listed here or any positive integer
+value.  For example, 'ok', 'cancel', 4, and 42 are all valid response ids.
+You cannot use arbitrary string values, they must be integers.  Be careful,
+because unknown string values tend to be mapped to 0.
+
+=cut
+
+
+=for apidoc Gtk2::InfoBar::new_with_buttons
+=for signature $widget = Gtk2::InfoBar->new_with_buttons (...)
+=for arg ... of button-text => response-id pairs.
+
+Alias for the multi-argument version of C<< Gtk2::InfoBar->new >>.
+
+=cut
+
+=for apidoc
+=for signature $widget = Gtk2::InfoBar->new;
+=for signature $widget = Gtk2::InfoBar->new (...)
+=for arg ... of button-text => response-id pairs.
+
+The multi-argument form takes the same list of text => response-id pairs as
+C<< $infobar->add_buttons >>.  Do not pack widgets directly into the infobar;
+add them to C<< $infobar->get_content_area () >>.
+
+Here's a simple example:
+
+ $infobar = Gtk2::InfoBar->new ('gtk-ok'     => 'accept',
+                                'gtk-cancel' => 'reject');
+
+=cut
+GtkWidget *
+gtk_info_bar_new (class, ...)
+    ALIAS:
+	Gtk2::InfoBar::new_with_buttons = 1
+    PREINIT:
+	int i;
+	GtkWidget * info_bar;
+    CODE:
+	PERL_UNUSED_VAR (ix);
+	if (items == 1) {
+		/* the easy way out... */
+		info_bar = gtk_info_bar_new ();
+	} else if ( !(items % 2) ) {
+		croak ("USAGE: Gtk2::InfoBar->new ()\n"
+		       "  or Gtk2::InfoBar->new (...)\n"
+		       "  where ... is a series of button text and response id pairs");
+	} else {
+		/* we can't really pass on a varargs call (at least, i don't
+		 * know how to convert from perl stack to C va_list), so we
+		 * have to duplicate a bit of the functionality of the C
+		 * version.  luckily it's nothing too intense. */
+
+		info_bar = gtk_info_bar_new ();
+
+		for (i = 1; i < items; i += 2) {
+			gchar * text = SvGChar (ST (i));
+			int response_id =
+				gtk2perl_dialog_response_id_from_sv (ST (i+1));
+			gtk_info_bar_add_button (GTK_INFO_BAR (info_bar), text,
+			                         response_id);
+		}
+	}
+	RETVAL = info_bar;
+    OUTPUT:
+	RETVAL
+
+
+GtkWidget *
+gtk_info_bar_add_button (info_bar, button_text, response_id)
+	GtkInfoBar  * info_bar
+	const gchar * button_text
+	SV          * response_id
+    CODE:
+	RETVAL = gtk_info_bar_add_button (info_bar, button_text,
+	                                  gtk2perl_dialog_response_id_from_sv (
+	                                    response_id));
+    OUTPUT:
+	RETVAL
+
+=for apidoc
+=for arg ... of button-text => response-id pairs
+Like calling C<< $infobar->add_button >> repeatedly, except you don't get the
+created widgets back.  The buttons go from left to right, so the first button
+added will be the left-most one.
+=cut
+void
+gtk_info_bar_add_buttons (info_bar, ...)
+	GtkInfoBar * info_bar
+    PREINIT:
+	int i;
+    CODE:
+	if (!(items % 2))
+		croak("gtk_info_bar_add_buttons: odd number of parameters");
+	/* we can't make var args, so we'll call add_button for each */
+	for (i = 1; i < items; i += 2)
+		gtk_info_bar_add_button (info_bar, SvGChar (ST (i)),
+		                         gtk2perl_dialog_response_id_from_sv (
+		                           ST (i+1)));
+
+=for apidoc
+=for arg response_id (GtkResponseType)
+=cut
+void
+gtk_info_bar_add_action_widget (info_bar, child, response_id)
+	GtkInfoBar  * info_bar
+	GtkWidget   * child
+	SV          * response_id
+    CODE:
+	gtk_info_bar_add_action_widget (info_bar, child,
+	                                gtk2perl_dialog_response_id_from_sv (
+	                                  response_id));
+
+=for apidoc
+=for arg response_id (GtkResponseType)
+Enable or disable an action button by its I<$response_id>.
+=cut
+void
+gtk_info_bar_set_response_sensitive (info_bar, response_id, setting)
+	GtkInfoBar * info_bar
+	SV         * response_id
+	gboolean    setting
+    CODE:
+	gtk_info_bar_set_response_sensitive (
+		info_bar,
+		gtk2perl_dialog_response_id_from_sv (response_id),
+		setting);
+
+
+=for apidoc
+=for arg response_id (GtkResponseType)
+=cut
+void
+gtk_info_bar_set_default_response (info_bar, response_id)
+	GtkInfoBar * info_bar
+	SV         * response_id
+    CODE:
+	gtk_info_bar_set_default_response (info_bar,
+	                                   gtk2perl_dialog_response_id_from_sv (
+	                                     response_id));
+
+=for apidoc
+=for arg response_id (GtkResponseType)
+=cut
+void
+gtk_info_bar_response (info_bar, response_id)
+	GtkInfoBar * info_bar
+	SV         * response_id
+    C_ARGS:
+	info_bar, gtk2perl_dialog_response_id_from_sv (response_id)
+
+
+void
+gtk_info_bar_set_message_type (info_bar, type);
+	GtkInfoBar * info_bar
+	GtkMessageType type
+
+GtkMessageType
+gtk_info_bar_get_message_type (info_bar);
+	GtkInfoBar * info_bar
+
+GtkWidget *
+gtk_info_bar_get_action_area (info_bar)
+	GtkInfoBar * info_bar
+
+GtkWidget *
+gtk_info_bar_get_content_area (info_bar)
+	GtkInfoBar * info_bar
+
+
diff --git a/xs_files-2.18 b/xs_files-2.18
new file mode 100644
index 0000000..a650343
--- /dev/null
+++ b/xs_files-2.18
@@ -0,0 +1 @@
+xs/GtkInfoBar.xs



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