diff console/libgnt/gntmain.c @ 13869:5642f4658b59

[gaim-migrate @ 16335] A bunch of stuff that doesn't really do much. I am trying to get the "expose" thingy going where a widget will redraw some of its parts when some other widget covering it is destroyed. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 25 Jun 2006 03:15:41 +0000
parents c1e3f7c75c3f
children 0d0ab1e39d0a
line wrap: on
line diff
--- a/console/libgnt/gntmain.c	Sat Jun 24 22:52:59 2006 +0000
+++ b/console/libgnt/gntmain.c	Sun Jun 25 03:15:41 2006 +0000
@@ -9,6 +9,10 @@
 static int max_x;
 static int max_y;
 
+static GHashTable *nodes;
+
+static void free_node(gpointer data);
+
 void gnt_screen_take_focus(GntWidget *widget)
 {
 	focus_list = g_list_prepend(focus_list, widget);
@@ -95,6 +99,8 @@
 	max_x = getmaxx(stdscr);
 	max_y = getmaxy(stdscr);
 
+	nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node);
+
 	wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
 	noecho();
 	refresh();
@@ -108,3 +114,83 @@
 	g_main_run(loop);
 }
 
+/*********************************
+ * Stuff for 'window management' *
+ *********************************/
+
+typedef struct
+{
+	GntWidget *me;
+	GList *below;		/* List of widgets below me */
+	GList *above;		/* List of widgets above me */
+} GntNode;
+
+static void
+free_node(gpointer data)
+{
+	GntNode *node = data;
+	g_list_free(node->below);
+	g_list_free(node->above);
+	g_free(node);
+}
+
+static void
+check_intersection(gpointer key, gpointer value, gpointer data)
+{
+	GntNode *n = value;
+	GntNode *nu = data;
+
+	if (value == NULL)
+		return;
+
+	if (n->me->priv.x + n->me->priv.width < nu->me->priv.x)
+		return;
+	if (nu->me->priv.x + nu->me->priv.width < n->me->priv.x)
+		return;
+
+	if (n->me->priv.y + n->me->priv.height < nu->me->priv.y)
+		return;
+	if (nu->me->priv.y + nu->me->priv.height < n->me->priv.y)
+		return;
+
+	n->above = g_list_prepend(n->above, nu->me);
+	nu->below = g_list_prepend(nu->below, n->me);
+}
+
+void gnt_screen_occupy(GntWidget *widget)
+{
+	/* XXX: what happens if this is called more than once for the same widget?
+	 *      perhaps _release first? */
+	GntNode *node = g_new0(GntNode, 1);
+	node->me = widget;
+
+	g_hash_table_foreach(nodes, check_intersection, node);
+	g_hash_table_replace(nodes, widget, node);
+}
+
+void gnt_screen_release(GntWidget *widget)
+{
+	GList *iter;
+	GntNode *node = g_hash_table_lookup(nodes, widget);
+	if (node == NULL || node->below == NULL)	/* Yay! Nothing to do. */
+		return;
+
+	/* XXX: This is not going to work.
+	 *      It will be necessary to build a topology and go from there. */
+	for (iter = node->below; iter; iter = iter->next)
+	{
+		GntWidget *w = iter->data;
+		int left, right, top, bottom;
+
+		left = MAX(widget->priv.x, w->priv.x) - w->priv.x;
+		right = MIN(widget->priv.x + widget->priv.width, w->priv.x + w->priv.width) - w->priv.x;
+		
+		top = MAX(widget->priv.y, w->priv.y) - w->priv.y;
+		bottom = MIN(widget->priv.y + widget->priv.height, w->priv.y + w->priv.height) - w->priv.y;
+		
+		gnt_widget_expose(w, left, top, right - left, bottom - top);
+	}
+
+	g_hash_table_remove(nodes, widget);
+}
+