diff console/libgnt/gntbox.c @ 13850:0e1e59770cb0

[gaim-migrate @ 16308] This is my first commit here. So don't yell at me if things get borked. Also, I haven't looked at the auto-thingies yet. So don't puke at the Makefiles. Files in console/libgnt/ are for the 'Gaim/GObjectified Ncurses Toolkit' library. Files in console/ uses libgaim and libgnt. Currently, only the buddylist-ui is 'functional', ie. the buddy-list updates when someone logs on or logs off. It still needs a lot of work. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 22 Jun 2006 08:33:54 +0000
parents
children bbf0470cb348
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbox.c	Thu Jun 22 08:33:54 2006 +0000
@@ -0,0 +1,323 @@
+#include "gntbox.h"
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+
+static void
+gnt_box_draw(GntWidget *widget)
+{
+	GntBox *box = GNT_BOX(widget);
+	GList *iter;
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		gnt_widget_draw(GNT_WIDGET(iter->data));
+	}
+
+	if (box->title)
+	{
+		gchar *title = g_strdup(box->title);
+		int pos = g_utf8_strlen(title, -1);
+
+		if (pos >= widget->priv.width - 2)
+		{
+			g_utf8_strncpy(title, box->title, widget->priv.width - 2);
+			pos = 1;
+		}
+		else
+		{
+			pos = (widget->priv.width - pos - 2) / 2;
+			/*pos = 2;*/
+		}
+		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE));
+		mvwprintw(widget->window, 0, pos, title);
+		g_free(title);
+	}
+	wrefresh(widget->window);
+	
+	DEBUG;
+}
+
+static void
+reposition_children(GntWidget *widget)
+{
+	GList *iter;
+	GntBox *box = GNT_BOX(widget);
+	int w, h, curx, cury, max;
+	gboolean has_border = FALSE;
+	int x, y;
+
+	x = widget->priv.x;
+	y = widget->priv.y;
+	w = h = 0;
+	max = -1;
+	curx = widget->priv.x;
+	cury = widget->priv.y;
+	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
+	{
+		has_border = TRUE;
+		curx += 1;
+		cury += 1;
+		if (!box->vertical)
+			curx++;
+	}
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury);
+		gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
+		if (box->vertical)
+		{
+			cury += h + 1;
+			if (max < w)
+				max = w;
+		}
+		else
+		{
+			curx += w + 2;
+			if (max < h)
+				max = h;
+		}
+	}
+
+	if (has_border)
+	{
+		curx += 2;
+		cury += 1;
+		max += 2;
+	}
+
+	if (box->vertical)
+	{
+		widget->priv.width = max;
+		widget->priv.height = cury - widget->priv.y;
+	}
+	else
+	{
+		widget->priv.width = curx - widget->priv.x;
+		widget->priv.height = max;
+	}
+}
+
+static void
+gnt_box_set_position(GntWidget *widget, int x, int y)
+{
+	gnt_widget_size_request(widget);
+	reposition_children(widget);
+}
+
+static void
+gnt_box_size_request(GntWidget *widget)
+{
+	GntBox *box = GNT_BOX(widget);
+	GList *iter;
+	
+	g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
+
+	if (box->homogeneous)
+	{
+		int max = -1, w, h;
+
+		/* XXX: should probably be changed based on vertical-ness */
+		for (iter = box->list; iter; iter = iter->next)
+		{
+			gnt_widget_get_size(GNT_WIDGET(iter->data), &w, NULL);
+			if (max < w)
+				max = w;
+		}
+
+		for (iter = box->list; iter; iter = iter->next)
+		{
+			gnt_widget_get_size(GNT_WIDGET(iter->data), NULL, &h);
+			gnt_widget_set_size(GNT_WIDGET(iter->data), max, h);
+		}
+	}
+
+	reposition_children(widget);
+}
+
+static void
+gnt_box_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	DEBUG;
+}
+
+static gboolean
+gnt_box_key_pressed(GntWidget *widget, const char *text)
+{
+	GntBox *box = GNT_BOX(widget);
+
+	/*if (box->list == NULL)*/
+		/*return FALSE;*/
+
+	if (box->active == NULL)
+		box->active = box->list;
+
+	if (gnt_widget_key_pressed(box->active->data, text))
+		return TRUE;
+	
+	if (text[0] == 27)
+	{
+		GList *now = NULL;
+		if (strcmp(text+1, GNT_KEY_LEFT) == 0)
+		{
+			now = box->active->prev;
+			if (now == NULL)
+				now = g_list_last(box->list);
+		}
+		else if (strcmp(text+1, GNT_KEY_RIGHT) == 0)
+		{
+			now = box->active->next;
+			if (now == NULL)
+				now = box->list;
+		}
+
+		if (now)
+		{
+			gnt_widget_set_focus(box->active->data, FALSE);
+			box->active = now;
+			gnt_widget_set_focus(box->active->data, TRUE);
+
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static GntWidget *find_focused_widget(GntBox *box)
+{
+	GList *iter;
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		GntWidget *w = iter->data;
+		
+		if (GNT_IS_BOX(w))
+		{
+			if ((w = find_focused_widget(GNT_BOX(w))) != NULL)
+				return w;
+		}
+		else
+		{
+			if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS) &&
+					GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_HAS_FOCUS))
+				return w;
+		}
+	}
+	return NULL;
+}
+
+static void
+gnt_box_lost_focus(GntWidget *widget)
+{
+	GntBox *box = GNT_BOX(widget);
+	GntWidget *p = widget;
+
+	while (p->parent)
+		p = p->parent;
+
+	p = find_focused_widget(GNT_BOX(p));
+	if (p)
+		gnt_widget_set_focus(p, FALSE);
+}
+
+static void
+gnt_box_destroy(GntWidget *w)
+{
+	GntBox *box = GNT_BOX(w);
+	GList *iter;
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		gnt_widget_destroy(iter->data);
+	}
+
+	g_list_free(box->list);
+}
+
+static void
+gnt_box_class_init(GntWidgetClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_box_destroy;
+	parent_class->draw = gnt_box_draw;
+	parent_class->map = gnt_box_map;
+	parent_class->size_request = gnt_box_size_request;
+	parent_class->set_position = gnt_box_set_position;
+	parent_class->key_pressed = gnt_box_key_pressed;
+	parent_class->lost_focus = gnt_box_lost_focus;
+
+	DEBUG;
+}
+
+static void
+gnt_box_init(GTypeInstance *instance, gpointer class)
+{
+	DEBUG;
+}
+
+/******************************************************************************
+ * GntBox API
+ *****************************************************************************/
+GType
+gnt_box_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntBoxClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_box_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntBox),
+			0,						/* n_preallocs		*/
+			gnt_box_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntBox",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_box_new(gboolean homo, gboolean vert)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL);
+	GntBox *box = GNT_BOX(widget);
+
+	box->homogeneous = homo;
+	box->vertical = vert;
+	gnt_widget_set_take_focus(widget, TRUE);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+
+	return widget;
+}
+
+void gnt_box_add_widget(GntBox *b, GntWidget *widget)
+{
+	b->list = g_list_append(b->list, widget);
+	widget->parent = GNT_WIDGET(b);
+}
+
+void gnt_box_set_title(GntBox *b, const char *title)
+{
+	g_free(b->title);
+	b->title = g_strdup(title);
+}
+