Re: destroying (by closing) a modeless GtkMessageDialog ?



On Fri, Jun 08, 2012 at 09:53:03AM +0200, Giuseppe Penone wrote:
> what about:
> 1) create the dialog no modal
> 2) connect the delete event and all the buttons to the destroy of the dialog
> 3) show the dialog
> this should be non blocking, am I right?
> 
> 

It was painful to get it right. The point is that I should avoid using Glib::RefPtr; 
for reference, here are two examples, one in plain C with GTK3.4, and another in C++ with GtkMM3.4.


####################### example in C
    /* example basiledestroydialog.c for GTK3 by basile starynkevitch net.
       It works well with gtk 3.4 on Debian/Sid/AMD64 */

    #include <gtk/gtk.h>

    /* create a modeless dialog with the close button destoying it */
    static void
    create_dialog_cb (GtkWidget * but, gpointer data)
    {
      static int cnt;
      GtkWidget *dial = NULL;
      g_assert (GTK_IS_BUTTON (but));
      g_assert (data == NULL);
      cnt++;
      dial = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
    				 "dialog #%d", cnt);
      gtk_message_dialog_format_secondary_markup
        (GTK_MESSAGE_DIALOG (dial),
         "clicking on <i>Close</i> button will destroy this dialog @%p",
         (void *) dial);
      /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
      g_signal_connect_swapped (dial, "response",
    			    G_CALLBACK (gtk_widget_destroy), dial);
      gtk_widget_show_all (dial);
    }

    int
    main (int argc, char **argv)
    {
      GtkWidget *window = NULL;
      GtkWidget *button = NULL;
      gtk_init (&argc, &argv);
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      /* Sets the title. */
      gtk_window_set_title (GTK_WINDOW (window), "example " __FILE__);
      /* Sets the border width of the window. */
      gtk_container_set_border_width (GTK_CONTAINER (window), 10);
      /* Creates a new button with the label "Click Me". */
      button = gtk_button_new_with_label ("Click Me");
      gtk_container_add (GTK_CONTAINER (window), button);
      g_signal_connect (button, "clicked", G_CALLBACK (create_dialog_cb), NULL);
      g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
      g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
      gtk_widget_show_all (window);

      gtk_main ();

      return 0;
    }

    /****************
     ** Local Variables: ;;
     ** compile-command: "gcc -std=gnu99 -Wall -g basiledestroydialog.c $(pkg-config --cflags --libs gtk+-x11-3.0) -o basiledestroydialog.bin" ;;
     ** End: ;;
     ****************/




###################################### example in C++


    /* example basilemmdestroydialog.cc for GTKMM3 by basile starynkevitch net.
       works with gtkmm 3.4 on Debian/Sid/AMD64 */

    /** indent with
     astyle -c -gnu -s2 basilemmdestroydialog.cc
    **/

    #include <gtkmm.h>

    class MyDialog : public Gtk::MessageDialog {
    public:
      MyDialog(const Glib::ustring&title)
        : Gtk::MessageDialog(title,
                             false,
                             Gtk::MESSAGE_INFO,
                             Gtk::BUTTONS_CLOSE,
                             false) {
      }
      virtual ~MyDialog () {};
      void destroy_me_cb (int) {
        delete this;
      };
    }; // end class MyDialog


    static void
    on_button_click_cb(void)
    {
      static int cnt;
      cnt++;
      MyDialog* dialp =
        new MyDialog(Glib::ustring::compose("dialog #%1", cnt));
      dialp->property_secondary_use_markup () = true;
      dialp->property_secondary_text () =
        "click on <i>Close</i> will destroy this dialog";
      dialp->signal_response().connect(sigc::mem_fun(*dialp,&MyDialog::destroy_me_cb));
      dialp->show_all();
    }

    int
    main (int argc, char **argv)
    {
      Glib::RefPtr<Gtk::Application> app =
        Gtk::Application::create(argc, argv,
                                 "net.starynkevitch.examples.basilemmdestroydialog");
      app->register_application();
      Gtk::ApplicationWindow window;
      window.set_title("example " __FILE__);
      Gtk::Button button ("click me");
      window.set_border_width(10);
      window.add(button);
      button.signal_clicked().connect(sigc::ptr_fun(&on_button_click_cb));
      button.show();
      return app->run(window);
    }

    /****************
     ** Local Variables: ;;
     ** compile-command: "g++ -std=gnu++11 -Wall -g basilemmdestroydialog.cc $(pkg-config --cflags --libs gtkmm-3.0) -o basilemmdestroydialog.bin" ;;
     ** End: ;;
     ****************/

####################################################


What was hard (for me) to get right is the fact that I should use raw pointers (not smart ones)
and have a callback doing 
  delete this

Regards.
-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***


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