[perl-Gtk3] Add overrides for Gtk3::Dialog



commit 00d70c163f13266b011239b62e7fb65080b2262a
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Tue Jan 8 22:58:40 2013 +0100

    Add overrides for Gtk3::Dialog
    
    Including conversion of predefined response IDs to nick names, so this is an
    API change.

 NEWS             |    5 ++-
 lib/Gtk3.pm      |  122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/zz-GtkDialog.t |   79 +++++++++++++++++++++++++++++++++++
 3 files changed, 205 insertions(+), 1 deletions(-)
---
diff --git a/NEWS b/NEWS
index 73fe8c0..9ab70c5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
 {{$NEXT}}
 
-* Add overrides for Gtk3::Container and Gtk3::Editable.
+* Add overrides for Gtk3::Container.
+* Add overrides for Gtk3::Dialog, including the conversion of predefined
+  response IDs to nick names.  This is an API change.
+* Add overrides for Gtk3::Editable.
 * Add Gtk3::EVENT_PROPAGATE and Gtk3::EVENT_STOP.
 * Test that no double-frees occur for custom Gtk3::Widget subclasses.
 
diff --git a/lib/Gtk3.pm b/lib/Gtk3.pm
index 91cf3e0..79cb120 100644
--- a/lib/Gtk3.pm
+++ b/lib/Gtk3.pm
@@ -59,8 +59,43 @@ my @_GTK_HANDLE_SENTINEL_BOOLEAN_FOR = qw/
 /;
 my @_GTK_USE_GENERIC_SIGNAL_MARSHALLER_FOR = (
   ['Gtk3::Editable', 'insert-text'],
+  ['Gtk3::Dialog',   'response',    \&Gtk3::Dialog::_gtk3_perl_response_converter],
 );
 
+# FIXME: G:O:I should provide some general mechanism wrapping
+# looks_like_number, gperl_try_convert_enum and
+# gperl_convert_back_enum_pass_unknown.  Then this would not be needed.
+my %_GTK_RESPONSE_ID_TO_NICK = (
+   -1 => 'none',
+   -2 => 'reject',
+   -3 => 'accept',
+   -4 => 'delete-event',
+   -5 => 'ok',
+   -6 => 'cancel',
+   -7 => 'close',
+   -8 => 'yes',
+   -9 => 'no',
+  -10 => 'apply',
+  -11 => 'help',
+);
+my %_GTK_RESPONSE_NICK_TO_ID = reverse %_GTK_RESPONSE_ID_TO_NICK;
+my $_GTK_RESPONSE_ID_TO_NICK = sub {
+  exists $_GTK_RESPONSE_ID_TO_NICK{$_[0]}
+    ? $_GTK_RESPONSE_ID_TO_NICK{$_[0]}
+    : $_[0]
+};
+my $_GTK_RESPONSE_NICK_TO_ID = sub {
+  exists $_GTK_RESPONSE_NICK_TO_ID{$_[0]}
+    ? $_GTK_RESPONSE_NICK_TO_ID{$_[0]}
+    : $_[0]
+};
+
+# Converter for the "response" signal.
+sub Gtk3::Dialog::_gtk3_perl_response_converter {
+  my ($dialog, $id) = @_;
+  return ($dialog, $_GTK_RESPONSE_ID_TO_NICK->($id));
+}
+
 # - gdk customization ------------------------------------------------------- #
 
 my @_GDK_HANDLE_SENTINEL_BOOLEAN_FOR = qw/
@@ -597,6 +632,93 @@ sub Gtk3::CssProvider::load_from_data {
     $self, _unpack_unless_array_ref ($data));
 }
 
+sub Gtk3::Dialog::add_action_widget {
+  Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'add_action_widget',
+    $_[0], $_[1], $_GTK_RESPONSE_NICK_TO_ID->($_[2]));
+}
+
+sub Gtk3::Dialog::add_button {
+  Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'add_button',
+    $_[0], $_[1], $_GTK_RESPONSE_NICK_TO_ID->($_[2]));
+}
+
+sub Gtk3::Dialog::add_buttons {
+  my ($dialog, @rest) = @_;
+  for (my $i = 0; $i < @rest; $i += 2) {
+    $dialog->add_button ($rest[$i], $rest[$i+1]);
+  }
+}
+
+sub Gtk3::Dialog::get_response_for_widget {
+  my $id = Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'get_response_for_widget', @_);
+  return $_GTK_RESPONSE_ID_TO_NICK->($id);
+}
+
+sub Gtk3::Dialog::get_widget_for_response {
+  return Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'get_widget_for_response',
+    $_[0], $_GTK_RESPONSE_NICK_TO_ID->($_[1]));
+}
+
+sub Gtk3::Dialog::new {
+  my ($class, $title, $parent, $flags, @rest) = @_;
+  if (@_ == 1) {
+    return Glib::Object::Introspection->invoke (
+      $_GTK_BASENAME, 'Dialog', 'new', @_);
+  } elsif ((@_ < 4) || (@rest % 2)){
+    croak ("Usage: Gtk3::Dialog->new ()\n" .
+           "  or Gtk3::Dialog->new (TITLE, PARENT, FLAGS, ...)\n" .
+           "  where ... is a series of button text and response id pairs");
+  } else {
+    my $dialog = Gtk3::Dialog->new;
+    defined $title and $dialog->set_title ($title);
+    defined $parent and $dialog->set_transient_for ($parent);
+    $flags & 'modal' and $dialog->set_modal (Glib::TRUE);
+    $flags & 'destroy-with-parent' and $dialog->set_destroy_with_parent (Glib::TRUE);
+    $dialog->add_buttons (@rest);
+    return $dialog;
+  }
+}
+
+sub Gtk3::Dialog::new_with_buttons {
+  &Gtk3::Dialog::new;
+}
+
+sub Gtk3::Dialog::response {
+  return Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'response',
+    $_[0], $_GTK_RESPONSE_NICK_TO_ID->($_[1]));
+}
+
+sub Gtk3::Dialog::run {
+  my $id = Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'run', @_);
+  return $_GTK_RESPONSE_ID_TO_NICK->($id);
+}
+
+sub Gtk3::Dialog::set_alternative_button_order {
+  my ($dialog, @rest) = @_;
+  return unless @rest;
+  Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'set_alternative_button_order_from_array',
+    $dialog, [map { $_GTK_RESPONSE_NICK_TO_ID->($_) } @rest]);
+}
+
+sub Gtk3::Dialog::set_default_response {
+  Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'set_default_response',
+    $_[0], $_GTK_RESPONSE_NICK_TO_ID->($_[1]));
+}
+
+sub Gtk3::Dialog::set_response_sensitive {
+  Glib::Object::Introspection->invoke (
+    $_GTK_BASENAME, 'Dialog', 'set_response_sensitive',
+    $_[0], $_GTK_RESPONSE_NICK_TO_ID->($_[1]), $_[2]);
+}
+
 sub Gtk3::Editable::insert_text {
   return Glib::Object::Introspection->invoke (
     $_GTK_BASENAME, 'Editable', 'insert_text',
diff --git a/t/zz-GtkDialog.t b/t/zz-GtkDialog.t
new file mode 100644
index 0000000..28067eb
--- /dev/null
+++ b/t/zz-GtkDialog.t
@@ -0,0 +1,79 @@
+#!/usr/bin/env perl
+#
+# Based on Gtk2/t/GtkDialog.t
+#
+BEGIN { require './t/inc/setup.pl' };
+
+use strict;
+use warnings;
+
+plan tests => 15;
+
+my $win = Gtk3::Window->new ('toplevel');
+
+# a constructor-made dialog, run
+my $d1 = Gtk3::Dialog->new ('Test Dialog', $win,
+                            [qw/destroy-with-parent/],
+                           'gtk-cancel', 2, 'gtk-quit', 3);
+my $btn1 = $d1->add_button ('Another', 4);
+Glib::Idle->add (sub { $btn1->clicked; 0; });
+is ($d1->run, 4);
+$d1->hide;
+
+# a hand-made dialog, run
+my $d2 = Gtk3::Dialog->new;
+$d2->add_button ('First Button', 0);
+my $btn2 = $d2->add_button ('gtk-ok', 1);
+$d2->add_buttons ('gtk-cancel', 2, 'gtk-quit', 3, 'Last Button', 4);
+$d2->add_action_widget (Gtk3::Button->new('Uhh'), 'help');
+$d2->set_default_response ('cancel');
+$d2->set_response_sensitive (4, Glib::TRUE);
+$d2->signal_connect (response => sub { is ($_[1], 1); 1; });
+Glib::Idle->add (sub { $btn2->clicked; 0; });
+is ($d2->run, 1);
+$d2->hide;
+
+# a constructor-made dialog, show
+my $d3 = Gtk3::Dialog->new_with_buttons ('Test Dialog', $win,
+                                         [qw/destroy-with-parent/],
+                                         'gtk-ok', 22, 'gtk-quit', 33);
+my $btn3 = $d3->add_button('Another', 44);
+my $btn4 = $d3->add_button('Help', 'help');
+$d3->set_response_sensitive ('help', Glib::TRUE);
+is ($d3->get_response_for_widget ($btn3), 44);
+is ($d3->get_response_for_widget ($btn4), 'help');
+is ($d3->get_widget_for_response (44), $btn3);
+is ($d3->get_widget_for_response ('help'), $btn4);
+$d3->get_content_area->pack_start (Gtk3::Label->new ('This is just a test.'), 0, 0, 0);
+$d3->get_action_area->pack_start (Gtk3::Label->new ('<- Actions'), 0, 0, 0);
+$d3->signal_connect (response => sub { is ($_[1], 44); 1; });
+$btn3->clicked;
+
+# make sure that known response types are converted to strings for the reponse
+# signal of Gtk3::Dialog and its ancestors
+foreach my $package (qw/Gtk3::Dialog Gtk3::AboutDialog/) {
+  my $d = $package->new;
+  my $b = $d->add_button ('First Button', 'ok');
+  $d->signal_connect (response => sub {
+    is ($_[1], 'ok', "$package response");
+    Gtk3::EVENT_STOP;
+  });
+  Glib::Idle->add( sub {
+    $b->clicked;
+    Glib::SOURCE_REMOVE;
+  });
+  is ($d->run, 'ok', "$package run");
+  $d->hide;
+}
+
+{
+  my $d = Gtk3::Dialog->new;
+  $d->set_alternative_button_order (2, 3);
+  $d->set_alternative_button_order (qw(ok cancel accept), 3);
+  $d->set_alternative_button_order;
+
+  my $screen = Gtk3::Gdk::Screen->get_default;
+  ok (defined Gtk3::alternative_dialog_button_order ($screen));
+  ok (defined Gtk3::alternative_dialog_button_order (undef));
+  ok (defined Gtk3::alternative_dialog_button_order);
+}



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