mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Clean up the drag and drop code and allow ripping off the Dive Profile
Linus had used some deprecated interfcase and didn't correctly untangle the new window that he created (hiding it the window... very nifty). I think I'm closer to the real solution with a data structure that keeps track of the components of the new top level window that I need to be able to untangle (and eventually, destroy) at the end. The one error I also can't seem to get rid of is the Clean up the drag and drop code and allow ripping of the Dive Profile Gtk-CRITICAL **: IA__gtk_selection_data_set: assertion `length <= 0' failed Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
1d7f5a4de1
commit
f4d50ffa3b
1 changed files with 53 additions and 30 deletions
83
gtk-gui.c
83
gtk-gui.c
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "libdivecomputer.h"
|
#include "libdivecomputer.h"
|
||||||
|
|
||||||
GtkWidget *main_window, *divelist_window;
|
GtkWidget *main_window;
|
||||||
GtkWidget *main_vbox;
|
GtkWidget *main_vbox;
|
||||||
GtkWidget *error_info_bar;
|
GtkWidget *error_info_bar;
|
||||||
GtkWidget *error_label;
|
GtkWidget *error_label;
|
||||||
|
@ -460,34 +460,50 @@ static void switch_page(GtkNotebook *notebook, gint arg1, gpointer user_data)
|
||||||
repaint_dive();
|
repaint_dive();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char notebook_group[] = "123";
|
static const char notebook_name[] = "123";
|
||||||
#define GRP_ID ((void *)notebook_group)
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
GtkWidget *widget;
|
||||||
|
GtkWidget *box;
|
||||||
|
gulong delete_handler;
|
||||||
|
gulong destroy_handler;
|
||||||
|
} notebook_data_t;
|
||||||
|
|
||||||
|
static notebook_data_t nbd[2]; /* we rip at most two notebook pages off */
|
||||||
|
|
||||||
static GtkNotebook *create_new_notebook_window(GtkNotebook *source,
|
static GtkNotebook *create_new_notebook_window(GtkNotebook *source,
|
||||||
GtkWidget *page,
|
GtkWidget *page,
|
||||||
gint x, gint y, gpointer data)
|
gint x, gint y, gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget *win, *notebook, *vbox;
|
GtkWidget *win, *notebook, *vbox;
|
||||||
|
notebook_data_t *nbdp;
|
||||||
|
|
||||||
/* We don't detatch twice */
|
/* pick the right notebook page data and return if both are detached */
|
||||||
if (divelist_window)
|
if (nbd[0].widget == NULL)
|
||||||
|
nbdp = nbd;
|
||||||
|
else if (nbd[1].widget == NULL)
|
||||||
|
nbdp = nbd + 1;
|
||||||
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
divelist_window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
nbdp->name = strdup(gtk_widget_get_name(page));
|
||||||
gtk_window_set_title(GTK_WINDOW(win), "Dive List");
|
nbdp->widget = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title(GTK_WINDOW(win), nbdp->name);
|
||||||
gtk_window_move(GTK_WINDOW(win), x, y);
|
gtk_window_move(GTK_WINDOW(win), x, y);
|
||||||
|
|
||||||
/* Destroying the dive list will kill the application */
|
/* Destroying the dive list will kill the application */
|
||||||
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(on_delete), NULL);
|
nbdp->delete_handler = g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(on_delete), NULL);
|
||||||
g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL);
|
nbdp->destroy_handler = g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL);
|
||||||
|
|
||||||
vbox = gtk_vbox_new(FALSE, 0);
|
nbdp->box = vbox = gtk_vbox_new(FALSE, 0);
|
||||||
gtk_container_add(GTK_CONTAINER(win), vbox);
|
gtk_container_add(GTK_CONTAINER(win), vbox);
|
||||||
|
|
||||||
notebook = gtk_notebook_new();
|
notebook = gtk_notebook_new();
|
||||||
gtk_notebook_set_group(GTK_NOTEBOOK(notebook), GRP_ID);
|
gtk_widget_set_name(notebook, nbdp->name);
|
||||||
|
gtk_notebook_set_group_name(GTK_NOTEBOOK(notebook), notebook_name);
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 6);
|
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 6);
|
||||||
gtk_widget_set_size_request(notebook, 350, 250);
|
gtk_widget_set_size_request(notebook, 450, 350);
|
||||||
|
|
||||||
gtk_widget_show_all(win);
|
gtk_widget_show_all(win);
|
||||||
return GTK_NOTEBOOK(notebook);
|
return GTK_NOTEBOOK(notebook);
|
||||||
|
@ -499,8 +515,8 @@ static void drag_cb(GtkWidget *widget, GdkDragContext *context,
|
||||||
guint info, guint time,
|
guint info, guint time,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkWidget *source, *target;
|
GtkWidget *source;
|
||||||
GtkWidget *tab;
|
notebook_data_t *nbdp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't actually really *use* this yet, but Dirk wants to
|
* We don't actually really *use* this yet, but Dirk wants to
|
||||||
|
@ -508,23 +524,26 @@ static void drag_cb(GtkWidget *widget, GdkDragContext *context,
|
||||||
* this all to figure out which window we're talking about.
|
* this all to figure out which window we're talking about.
|
||||||
*/
|
*/
|
||||||
source = gtk_drag_get_source_widget(context);
|
source = gtk_drag_get_source_widget(context);
|
||||||
target = (GtkWidget *) user_data;
|
if (! strcmp(nbd[0].name,gtk_widget_get_name(source)))
|
||||||
tab = *(GtkWidget **)selection_data->data;
|
nbdp = nbd;
|
||||||
|
else if (! strcmp(nbd[1].name,gtk_widget_get_name(source)))
|
||||||
|
nbdp = nbd + 1;
|
||||||
|
else
|
||||||
|
/* HU? */
|
||||||
|
return;
|
||||||
|
|
||||||
gtk_drag_finish(context, TRUE, TRUE, time);
|
gtk_drag_finish(context, TRUE, TRUE, time);
|
||||||
|
|
||||||
/*
|
/* we no longer need the widget - but getting rid of this is hard;
|
||||||
* Horrible, horrible hack. We hide the old divelist window, and
|
* remove the signal handler, remove the notebook from the box
|
||||||
* set it to NULL. So if we drag the thing back out, we'll create
|
* then destroy the widget (and clear out our data structure) */
|
||||||
* a new window. Ugh.
|
g_signal_handler_disconnect(nbdp->widget,nbdp->delete_handler);
|
||||||
*
|
g_signal_handler_disconnect(nbdp->widget,nbdp->destroy_handler);
|
||||||
* Actually destroying the divelist window triggers the whole
|
gtk_container_remove(GTK_CONTAINER(nbdp->box), source);
|
||||||
* destroy callback, which we don't want.
|
gtk_widget_destroy(nbdp->widget);
|
||||||
*/
|
nbdp->widget = NULL;
|
||||||
if (source != target) {
|
free(nbdp->name);
|
||||||
gtk_widget_hide(divelist_window);
|
nbdp->name = NULL;
|
||||||
divelist_window = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_ui(int argc, char **argv)
|
void init_ui(int argc, char **argv)
|
||||||
|
@ -579,21 +598,25 @@ void init_ui(int argc, char **argv)
|
||||||
/* Notebook for dive info vs profile vs .. */
|
/* Notebook for dive info vs profile vs .. */
|
||||||
notebook = gtk_notebook_new();
|
notebook = gtk_notebook_new();
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 6);
|
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 6);
|
||||||
gtk_notebook_set_group(GTK_NOTEBOOK(notebook), GRP_ID);
|
gtk_notebook_set_group_name(GTK_NOTEBOOK(notebook), notebook_name);
|
||||||
gtk_notebook_set_window_creation_hook(create_new_notebook_window, NULL, NULL);
|
g_signal_connect(notebook, "create-window", G_CALLBACK(create_new_notebook_window), NULL);
|
||||||
gtk_drag_dest_set(notebook, GTK_DEST_DEFAULT_ALL, ¬ebook_target, 1, GDK_ACTION_MOVE);
|
gtk_drag_dest_set(notebook, GTK_DEST_DEFAULT_ALL, ¬ebook_target, 1, GDK_ACTION_MOVE);
|
||||||
g_signal_connect(notebook, "drag-data-received", G_CALLBACK(drag_cb), notebook);
|
g_signal_connect(notebook, "drag-data-received", G_CALLBACK(drag_cb), notebook);
|
||||||
g_signal_connect(notebook, "switch-page", G_CALLBACK(switch_page), NULL);
|
g_signal_connect(notebook, "switch-page", G_CALLBACK(switch_page), NULL);
|
||||||
|
|
||||||
/* Create the actual divelist */
|
/* Create the actual divelist */
|
||||||
dive_list = dive_list_create();
|
dive_list = dive_list_create();
|
||||||
|
gtk_widget_set_name(dive_list, "Dive List");
|
||||||
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_list, gtk_label_new("Dive List"));
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_list, gtk_label_new("Dive List"));
|
||||||
gtk_notebook_set_tab_detachable(GTK_NOTEBOOK(notebook), dive_list, 1);
|
gtk_notebook_set_tab_detachable(GTK_NOTEBOOK(notebook), dive_list, 1);
|
||||||
gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(notebook), dive_list, 1);
|
gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(notebook), dive_list, 1);
|
||||||
|
|
||||||
/* Frame for dive profile */
|
/* Frame for dive profile */
|
||||||
dive_profile = dive_profile_widget();
|
dive_profile = dive_profile_widget();
|
||||||
|
gtk_widget_set_name(dive_profile, "Dive Profile");
|
||||||
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile"));
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile"));
|
||||||
|
gtk_notebook_set_tab_detachable(GTK_NOTEBOOK(notebook), dive_profile, 1);
|
||||||
|
gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(notebook), dive_profile, 1);
|
||||||
|
|
||||||
/* Frame for extended dive info */
|
/* Frame for extended dive info */
|
||||||
dive_info = extended_dive_info_widget();
|
dive_info = extended_dive_info_widget();
|
||||||
|
|
Loading…
Add table
Reference in a new issue