changeset 221:79ef86f3b325

Make properties tabs reorderable through drag'n drop. Order is preserved during the whole session. When a new properties dialog is open, it uses the last order used. Currently, order isn't saved to rc file.
author zas_
date Wed, 02 Apr 2008 12:12:50 +0000
parents 7670d5653e1f
children 77f1bcc6c161
files src/info.c
diffstat 1 files changed, 98 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/info.c	Wed Apr 02 10:40:54 2008 +0000
+++ b/src/info.c	Wed Apr 02 12:12:50 2008 +0000
@@ -41,8 +41,18 @@
 	void (*func_sync)(InfoData *id, gpointer data);
 	void (*func_image)(InfoData *id, gpointer data);
 	gpointer data;
+	TabData *(*func_new)(InfoData *id);
+	GtkWidget *child;
 };
 
+typedef struct _InfoTabsPos InfoTabsPos;
+struct _InfoTabsPos
+{
+	TabData *(*func)(InfoData *id);
+	gint pos;
+};
+
+static GList *info_tabs_pos_list = NULL;
 
 /*
  *-------------------------------------------------------------------
@@ -105,6 +115,7 @@
 
 	label = gtk_label_new(_("Exif"));
 	gtk_notebook_append_page(GTK_NOTEBOOK(id->notebook), bar, label);
+	gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(id->notebook), bar, TRUE);
 	gtk_widget_show(bar);
 
 	/* register */
@@ -113,6 +124,8 @@
 	td->func_sync = info_tab_exif_sync;
 	td->func_image = info_tab_exif_image;
 	td->data = bar;
+	td->func_new = info_tab_exif_new;
+	td->child = bar;
 
 	return td;
 }
@@ -166,6 +179,7 @@
 
 	label = gtk_label_new(_("Keywords"));
 	gtk_notebook_append_page(GTK_NOTEBOOK(id->notebook), tab->bar_info, label);
+	gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(id->notebook), tab->bar_info, TRUE);
 	gtk_widget_show(tab->bar_info);
 
 	/* register */
@@ -174,6 +188,8 @@
 	td->func_sync = info_tab_meta_sync;
 	td->func_image = NULL;
 	td->data = tab;
+	td->func_new = info_tab_meta_new;
+	td->child = tab->bar_info;
 
 	return td;
 }
@@ -379,6 +395,7 @@
 
 	label = gtk_label_new(_("General"));
 	gtk_notebook_append_page(GTK_NOTEBOOK(id->notebook), table, label);
+	gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(id->notebook), table, TRUE);
 	gtk_widget_show(table);
 
 	/* register */
@@ -387,6 +404,8 @@
 	td->func_sync = info_tab_general_sync;
 	td->func_image = info_tab_general_image;
 	td->data = tab;
+	td->func_new = info_tab_general_new;
+	td->child = table;
 
 	return td;
 }
@@ -435,11 +454,53 @@
 	id->tab_list = NULL;
 }
 
+static InfoTabsPos *info_tabs_pos_new(gpointer func, gint pos)
+{
+	InfoTabsPos *t = g_new0(InfoTabsPos, 1);
+	t->func = func;
+	t->pos = pos;
+
+	return t;
+}
+
+static void info_tabs_pos_list_append(gpointer func)
+{
+	static gint pos = 0;
+
+	info_tabs_pos_list = g_list_append(info_tabs_pos_list, info_tabs_pos_new(func, pos++));
+}
+
+static gint compare_info_tabs_pos(gconstpointer a, gconstpointer b)
+{
+	InfoTabsPos *ta = (InfoTabsPos *) a;
+	InfoTabsPos *tb = (InfoTabsPos *) b;
+
+	if (ta->pos > tb->pos) return 1;
+	return -1;
+}
+
 static void info_tabs_init(InfoData *id)
 {
-	id->tab_list = g_list_append(id->tab_list, info_tab_general_new(id));
-	id->tab_list = g_list_append(id->tab_list, info_tab_meta_new(id));
-	id->tab_list = g_list_append(id->tab_list, info_tab_exif_new(id));
+	GList *work;
+
+	if (!info_tabs_pos_list)
+		{
+		/* First run, default tabs order is defined here. */
+		info_tabs_pos_list_append(info_tab_general_new);
+		info_tabs_pos_list_append(info_tab_meta_new);
+		info_tabs_pos_list_append(info_tab_exif_new);
+		}
+	else
+		info_tabs_pos_list = g_list_sort(info_tabs_pos_list, compare_info_tabs_pos);
+
+	work = info_tabs_pos_list;
+	while (work)
+		{
+		InfoTabsPos *t = work->data;
+		work = work->next;
+
+		id->tab_list = g_list_append(id->tab_list, t->func(id));
+		}
 }
 
 /*
@@ -471,6 +532,37 @@
 	image_change_fd(id->image, fd, 0.0);
 }
 
+static void info_notebook_reordered_cb(GtkNotebook *notebook, GtkWidget *child, guint page_num, gpointer data)
+{
+	InfoData *id = data;
+	GList *work;
+
+	info_tabs_sync(id, 0);
+
+	/* Save current tabs position to be able to restore them later. */
+	work = id->tab_list;
+	while (work)
+		{
+		GList *tabpos;
+		TabData *td = work->data;
+		gint pos = gtk_notebook_page_num(GTK_NOTEBOOK(id->notebook), GTK_WIDGET(td->child));
+		work = work->next;
+
+		tabpos = info_tabs_pos_list;
+		while (tabpos)
+			{
+			InfoTabsPos *t = tabpos->data;
+			tabpos = tabpos->next;
+
+			if (t->func == td->func_new)
+				{
+				t->pos = pos;
+				break;
+				}
+			}	
+	}
+}
+
 /*
  *-------------------------------------------------------------------
  * drag n drop (dropping not supported!)
@@ -730,6 +822,9 @@
 	id->notebook = gtk_notebook_new();
 	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(id->notebook), GTK_POS_TOP);
 	gtk_box_pack_start(GTK_BOX(main_vbox), id->notebook, TRUE, TRUE, 5);
+	g_signal_connect(G_OBJECT(id->notebook), "page-reordered",
+			 G_CALLBACK(info_notebook_reordered_cb), id);
+
 	gtk_widget_show(id->notebook);
 
 	pref_spacer(main_vbox, PREF_PAD_GAP);