On 3/20/07, Jef Driesen <[EMAIL PROTECTED]> wrote:
> I am writing my first gtkmm application (actually my first GUI
> application). To get familiar with the toolkit (both gtk and gtkmm), I
> studied the code of some existing applications. And in one of those
> applications I found a construct that I would like to use in my own
> application, but I don't know how to port the gtk code to gtkmm.
>
> The main application contains a treeview and a secondary dialog is used
> to edit the treeview entries. But if you try to edit an entry that is
> already "open", the existing dialog is activated instead of creating a
> new one (see code snippet below). How can I do this in C++?
>
> And how do I automatically destroy the dialog after clicking the (close)
> button?
>
> /* myobject_treeview.c */
>
> GtkWidget* main_window = ...;
> myobject* obj = ...;
> GtkWidget* dialog = myobject_dialog_new (main_window, obj);
> gtk_widget_show (dialog);
>
> /* myobject_dialog.c */
>
> static GHashTable *dialogs = NULL;
>
> GtkWidget* myobject_dialog_new (GtkWidget* parent, myobject* obj)
> {
>     if (!dialogs) {
>        dialogs = g_hash_table_new (NULL, NULL);
>     }
>
>     dialog = g_hash_table_lookup (dialogs, obj);
>     if (dialog) {
>        gtk_window_present (GTK_WINDOW (dialog));
>        return dialog;
>     }
>
>     dialog = gtk_dialog_new ();
>
>     g_hash_table_insert (dialogs, obj, dialog);
>
>     g_signal_connect (close_button,
>              "clicked",
>              G_CALLBACK (myobject_dialog_close_clicked_cb),
>              dialog);
>
>     g_signal_connect (dialog,
>              "destroy",
>              G_CALLBACK (myobject_dialog_destroy_cb),
>              obj);
>
>     g_signal_connect_object (parent,
>              "destroy",
>              G_CALLBACK (myobject_dialog_parent_destroy_cb),
>              dialog,
>              0);
> }
>
> static void
> myobject_dialog_destroy_cb (GtkWidget *parent, myobject *obj)
> {
>     g_hash_table_remove (dialogs, obj);
> }
>
> static void
> myobject_dialog_parent_destroy_cb (GtkWidget *parent, GtkWidget *dialog)
> {
>     gtk_widget_destroy (dialog);
> }
>
> static void
> myobject_dialog_close_clicked_cb (GtkWidget *button, GtkWidget *dialog)
> {
>     gtk_widget_destroy (dialog);
> }

Well, first of all, you'd probably want to replace the g_hash_table
stuff with a std::map<> type.  You might even want to store the Dialog
pointer in a smart pointer so that when you remove the item from the
std::map, the Dialog is deleted automatically.  Something like this:

std::map<myobject*, boost::shared_ptr<Gtk::Dialog> > dialogs;

// when you need to add a new dialog to the cache:
dialogs[obj] = boost::shared_ptr<Gtk::Dialog>(new Gtk::Dialog());

// then in a signal handler: this should remove the item from the map and
// automatically free the dialog you allocated earlier since you're
using a smart pointer
dialogs.erase (obj);

The signal handling should be pretty similar to the existing code, but
would use libsigc++ type signal connections instead of the
g_signal_connect() stuff.  for example:
   g_signal_connect (close_button,
            "clicked",
            G_CALLBACK (myobject_dialog_close_clicked_cb),
            dialog);
would become something like:
close_button.signal_clicked ().connect
(sigc::ptr_fun(myobject_dialog_close_clicked_cb));

But it might be easier to just create a new Dialog class that inherits
from Gtk::Dialog and provide implementations for its virtual signal
handler methods (such as on_delete_event(), etc) instead of manually
connecting to the signals.
Hope that helps. (note that I haven't tested any of the code snippets I posted)
-- 
jonner
_______________________________________________
gtkmm-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to