changeset 13930:3dbcbc5e57e1

[gaim-migrate @ 16457] Enable resizing (Alt+r, then the arrow keys, then enter/escape to end). It 'works', but needs fine-tuning. But I am going to put it off for a later date. Some other minor decoration tweaks. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sat, 08 Jul 2006 02:11:11 +0000
parents 59af3aecf580
children 917a71dd02eb
files console/libgnt/gntbox.c console/libgnt/gntbutton.c console/libgnt/gntentry.c console/libgnt/gntlabel.c console/libgnt/gntmain.c console/libgnt/gnttextview.c console/libgnt/gnttree.c console/libgnt/gntutils.c console/libgnt/gntutils.h console/libgnt/gntwidget.c console/libgnt/gntwidget.h
diffstat 11 files changed, 261 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/console/libgnt/gntbox.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntbox.c	Sat Jul 08 02:11:11 2006 +0000
@@ -39,24 +39,29 @@
 	if (box->title)
 	{
 		gchar *title = g_strdup(box->title);
-		int pos = g_utf8_strlen(title, -1);
+		int pos = g_utf8_strlen(title, -1), right;
 
-		if (pos >= widget->priv.width - 2)
+		if (pos >= widget->priv.width - 4)
 		{
-			g_utf8_strncpy(title, box->title, widget->priv.width - 2);
-			pos = 1;
+			g_utf8_strncpy(title, box->title, widget->priv.width - 4);
+			pos = 2;
+			right = pos + g_utf8_strlen(title, -1);
 		}
 		else
 		{
 			/* XXX: Position of the title might be configurable */
+			right = pos;
 			pos = (widget->priv.width - pos) / 2;
+			right += pos;
 		}
 
 		if (gnt_widget_has_focus(widget))
 			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE));
 		else
 			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE_D));
+		mvwaddch(widget->window, 0, pos-1, ACS_RTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
 		mvwprintw(widget->window, 0, pos, title);
+		mvwaddch(widget->window, 0, right, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
 		g_free(title);
 	}
 	
@@ -273,6 +278,34 @@
 	delwin(win);
 }
 
+static gboolean
+gnt_box_confirm_size(GntWidget *widget, int width, int height)
+{
+	GList *iter;
+	GntBox *box = GNT_BOX(widget);
+	int wchange, hchange;
+	int wc = 0, hc = 0;
+
+	wchange = widget->priv.width - width;
+	hchange = widget->priv.height - height;
+
+	/* XXX: Right now, I am trying to just apply all the changes to 
+	 * just one widget. It should be possible to distribute the
+	 * changes to all the widgets in the box. */
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		GntWidget *wid = iter->data;
+		int w, h;
+
+		gnt_widget_get_size(wid, &w, &h);
+
+		if (gnt_widget_set_size(wid, w - wchange, h - hchange))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 static void
 gnt_box_class_init(GntBoxClass *klass)
 {
@@ -286,6 +319,7 @@
 	parent_class->key_pressed = gnt_box_key_pressed;
 	parent_class->lost_focus = gnt_box_lost_focus;
 	parent_class->gained_focus = gnt_box_gained_focus;
+	parent_class->confirm_size = gnt_box_confirm_size;
 
 	DEBUG;
 }
@@ -293,6 +327,9 @@
 static void
 gnt_box_init(GTypeInstance *instance, gpointer class)
 {
+	/* Initially make both the height and width resizable.
+	 * Update the flags as necessary when widgets are added to it. */
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
 	DEBUG;
 }
 
@@ -344,6 +381,17 @@
 {
 	b->list = g_list_append(b->list, widget);
 	widget->parent = GNT_WIDGET(b);
+
+	if (b->vertical)
+	{
+		if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
+			GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_X);
+	}
+	else
+	{
+		if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
+			GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_Y);
+	}
 }
 
 void gnt_box_set_title(GntBox *b, const char *title)
--- a/console/libgnt/gntbutton.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntbutton.c	Sat Jul 08 02:11:11 2006 +0000
@@ -71,6 +71,8 @@
 {
 	GntButton *button = GNT_BUTTON(instance);
 	button->priv = g_new0(GntButtonPriv, 1);
+
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(button), GNT_WIDGET_GROW_X); /* Can be resized sideways */
 	DEBUG;
 }
 
--- a/console/libgnt/gntentry.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntentry.c	Sat Jul 08 02:11:11 2006 +0000
@@ -173,6 +173,7 @@
 
 	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
 			GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_GROW_X);
 	
 	DEBUG;
 }
--- a/console/libgnt/gntlabel.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntlabel.c	Sat Jul 08 02:11:11 2006 +0000
@@ -70,6 +70,7 @@
 static void
 gnt_label_init(GTypeInstance *instance, gpointer class)
 {
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
 	DEBUG;
 }
 
--- a/console/libgnt/gntmain.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntmain.c	Sat Jul 08 02:11:11 2006 +0000
@@ -325,6 +325,11 @@
 					mode = GNT_KP_MODE_WINDOW_LIST;
 					show_window_list();
 				}
+				else if (strcmp(buffer + 1, "r") == 0 && focus_list)
+				{
+					/* Resize window */
+					mode = GNT_KP_MODE_RESIZE;
+				}
 			}
 		}
 	}
@@ -405,6 +410,63 @@
 			lock_focus_list = 0;
 		}
 	}
+	else if (mode == GNT_KP_MODE_RESIZE)
+	{
+		if (buffer[0] == '\r' || (buffer[0] == 27 && buffer[1] == 0))
+			mode = GNT_KP_MODE_NORMAL;
+		else if (buffer[0] == 27)
+		{
+			GntWidget *widget = focus_list->data;
+			gboolean changed = FALSE;
+			int width, height;
+
+			gnt_widget_get_size(widget, &width, &height);
+
+			if (strcmp(buffer + 1, GNT_KEY_DOWN) == 0)
+			{
+				if (widget->priv.y + height < Y_MAX)
+				{
+					height++;
+					changed = TRUE;
+				}
+			}
+			else if (strcmp(buffer + 1, GNT_KEY_UP) == 0)
+			{
+				height--;
+				changed = TRUE;
+			}
+			else if (strcmp(buffer + 1, GNT_KEY_LEFT) == 0)
+			{
+				width--;
+				changed = TRUE;
+			}
+			else if (strcmp(buffer + 1, GNT_KEY_RIGHT) == 0)
+			{
+				if (widget->priv.x + width < X_MAX)
+				{
+					width++;
+					changed = TRUE;
+				}
+			}
+
+			if (changed)
+			{
+				GntNode *node = g_hash_table_lookup(nodes, widget);
+				int x, y;
+
+				gnt_widget_get_position(widget, &x, &y);
+
+				hide_panel(node->panel);
+				gnt_widget_set_size(widget, width, height);
+				gnt_widget_set_position(widget, x, y);
+				gnt_widget_draw(widget);
+				replace_panel(node->panel, widget->window);
+				show_panel(node->panel);
+				update_panels();
+				doupdate();
+			}
+		}
+	}
 
 	draw_taskbar();
 	refresh();
@@ -477,11 +539,8 @@
 {
 	GntNode *node;
 
-	if (widget->parent)
-	{
-		while (widget->parent)
-			widget = widget->parent;
-	}
+	while (widget->parent)
+		widget = widget->parent;
 	
 	if (g_hash_table_lookup(nodes, widget))
 		return;		/* XXX: perhaps _update instead? */
@@ -528,11 +587,8 @@
 {
 	GntNode *node;
 	
-	if (widget->parent)
-	{
-		while (widget->parent)
-			widget = widget->parent;
-	}
+	while (widget->parent)
+		widget = widget->parent;
 	
 	gnt_box_sync_children(GNT_BOX(widget));
 	node = g_hash_table_lookup(nodes, widget);
@@ -555,15 +611,13 @@
 	if (!widget)
 		return FALSE;
 
-	if (widget == window_list.window)
-		return TRUE;
-
 	w = widget;
 
 	while (widget->parent)
-	{
 		widget = widget->parent;
-	}
+
+	if (widget == window_list.window)
+		return TRUE;
 
 	if (focus_list && focus_list->data == widget)
 	{
--- a/console/libgnt/gnttextview.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gnttextview.c	Sat Jul 08 02:11:11 2006 +0000
@@ -113,6 +113,9 @@
 static void
 gnt_text_view_init(GTypeInstance *instance, gpointer class)
 {
+	/* XXX: For now, resizing the width is not permitted. This is because
+	 * of the way I am handling wrapped lines. */
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_Y);
 	DEBUG;
 }
 
--- a/console/libgnt/gnttree.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gnttree.c	Sat Jul 08 02:11:11 2006 +0000
@@ -385,6 +385,7 @@
 static void
 gnt_tree_init(GTypeInstance *instance, gpointer class)
 {
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
 	DEBUG;
 }
 
--- a/console/libgnt/gntutils.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntutils.c	Sat Jul 08 02:11:11 2006 +0000
@@ -130,3 +130,39 @@
 			data2);
 }
 
+void gnt_closure_marshal_BOOLEAN__INT_INT(GClosure *closure,
+										GValue *ret_value,
+										guint n_param_values,
+										const GValue *param_values,
+										gpointer invocation_hint,
+										gpointer marshal_data)
+{
+	typedef gboolean (*func) (gpointer data1, int, int, gpointer data2);
+	register func callback;
+	register GCClosure *cc = (GCClosure*)closure;
+	register gpointer data1, data2;
+	gboolean ret;
+
+	g_return_if_fail(ret_value != NULL);
+	g_return_if_fail(n_param_values == 3);
+
+	if (G_CCLOSURE_SWAP_DATA(closure))
+	{
+		data1 = closure->data;
+		data2 = g_value_peek_pointer(param_values + 0);
+	}
+	else
+	{
+		data1 = g_value_peek_pointer(param_values + 0);
+		data2 = closure->data;
+	}
+
+	callback = (func) (marshal_data ? marshal_data : cc->callback);
+	ret = callback(data1,
+			g_value_get_int(param_values + 1) ,
+			g_value_get_int(param_values + 2) ,
+			data2);
+	g_value_set_boolean(ret_value, ret);
+}
+
+
--- a/console/libgnt/gntutils.h	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntutils.h	Sat Jul 08 02:11:11 2006 +0000
@@ -28,3 +28,10 @@
 										gpointer invocation_hint,
 										gpointer marshal_data);
 
+void gnt_closure_marshal_BOOLEAN__INT_INT(GClosure *closure,
+										GValue *ret_value,
+										guint n_param_values,
+										const GValue *param_values,
+										gpointer invocation_hint,
+										gpointer marshal_data);
+
--- a/console/libgnt/gntwidget.c	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntwidget.c	Sat Jul 08 02:11:11 2006 +0000
@@ -4,6 +4,8 @@
 #include "gntutils.h"
 #include "gnt.h"
 
+#define MIN_SIZE 5
+
 enum
 {
 	SIG_DESTROY,
@@ -15,6 +17,7 @@
 	SIG_ACTIVATE,
 	SIG_EXPOSE,
 	SIG_SIZE_REQUEST,
+	SIG_CONFIRM_SIZE,
 	SIG_POSITION,
 	SIGS
 };
@@ -22,6 +25,8 @@
 static GObjectClass *parent_class = NULL;
 static guint signals[SIGS] = { 0 };
 
+static void init_widget(GntWidget *widget);
+
 static void
 gnt_widget_init(GTypeInstance *instance, gpointer class)
 {
@@ -63,6 +68,18 @@
 		gnt_widget_draw(widget);
 }
 
+static gboolean
+gnt_widget_dummy_confirm_size(GntWidget *widget, int width, int height)
+{
+	if (width < MIN_SIZE || height < MIN_SIZE)
+		return FALSE;
+	if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
+		return FALSE;
+	if (widget->priv.height != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
+		return FALSE;
+	return TRUE;
+}
+
 static void
 gnt_widget_class_init(GntWidgetClass *klass)
 {
@@ -79,6 +96,7 @@
 	klass->map = gnt_widget_map;
 	klass->lost_focus = gnt_widget_focus_change;
 	klass->gained_focus = gnt_widget_focus_change;
+	klass->confirm_size = gnt_widget_dummy_confirm_size;
 	
 	klass->key_pressed = NULL;
 	klass->activate = NULL;
@@ -155,6 +173,14 @@
 					 NULL, NULL,
 					 g_cclosure_marshal_VOID__VOID,
 					 G_TYPE_NONE, 0);
+	signals[SIG_CONFIRM_SIZE] = 
+		g_signal_new("confirm_size",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, confirm_size),
+					 NULL, NULL,
+					 gnt_closure_marshal_BOOLEAN__INT_INT,
+					 G_TYPE_BOOLEAN, 2, G_TYPE_INT, G_TYPE_INT);
 	signals[SIG_KEY_PRESSED] = 
 		g_signal_new("key_pressed",
 					 G_TYPE_FROM_CLASS(klass),
@@ -270,23 +296,8 @@
 		
 		widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow,
 						widget->priv.y, widget->priv.x);
-		wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
 
-		if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
-		{
-			WINDOW *tmp = derwin(widget->window, widget->priv.height, widget->priv.width, 0, 0);
-			box(tmp, 0, 0);
-			delwin(tmp);
-		}
-		else
-			werase(widget->window);
-
-		if (shadow)
-		{
-			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_SHADOW));
-			mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height);
-			mvwhline(widget->window, widget->priv.height, 1, ' ', widget->priv.width);
-		}
+		init_widget(widget);
 	}
 
 	g_signal_emit(widget, signals[SIG_DRAW], 0);
@@ -362,12 +373,65 @@
 	
 }
 
-void
+static void
+init_widget(GntWidget *widget)
+{
+	gboolean shadow = TRUE;
+
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+		shadow = FALSE;
+
+	wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
+	werase(widget->window);
+
+	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
+	{
+		WINDOW *tmp = derwin(widget->window, widget->priv.height, widget->priv.width, 0, 0);
+		box(tmp, 0, 0);
+		delwin(tmp);
+	}
+
+	if (shadow)
+	{
+		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_SHADOW));
+		mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height);
+		mvwhline(widget->window, widget->priv.height, 1, ' ', widget->priv.width);
+	}
+}
+
+gboolean
 gnt_widget_set_size(GntWidget *widget, int width, int height)
 {
-	widget->priv.width = width;
-	widget->priv.height = height;
-	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED);
+	gboolean ret = TRUE;
+
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+		{
+			width--;
+			height--;
+		}
+		g_signal_emit(widget, signals[SIG_CONFIRM_SIZE], 0, width, height, &ret);
+	}
+
+	if (ret)
+	{
+		gboolean shadow = TRUE;
+
+		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+			shadow = FALSE;
+
+		widget->priv.width = width;
+		widget->priv.height = height;
+		if (widget->window)
+			wresize(widget->window, height + shadow, width + shadow);
+		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+			init_widget(widget);
+		else
+			GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED);
+	}
+
+	return ret;
 }
 
 gboolean
--- a/console/libgnt/gntwidget.h	Fri Jul 07 21:57:15 2006 +0000
+++ b/console/libgnt/gntwidget.h	Sat Jul 08 02:11:11 2006 +0000
@@ -36,7 +36,9 @@
 	GNT_WIDGET_NO_SHADOW      = 1 << 4,
 	GNT_WIDGET_HAS_FOCUS      = 1 << 5,
 	GNT_WIDGET_DRAWING        = 1 << 6,
-	GNT_WIDGET_URGENT         = 1 << 7
+	GNT_WIDGET_URGENT         = 1 << 7,
+	GNT_WIDGET_GROW_X         = 1 << 8,
+	GNT_WIDGET_GROW_Y         = 1 << 9,
 } GntWidgetFlags;
 
 /* XXX: I'll have to ask grim what he's using this for in guifications. */
@@ -81,6 +83,7 @@
 	void (*lost_focus)(GntWidget *widget);
 
 	void (*size_request)(GntWidget *widget);
+	gboolean (*confirm_size)(GntWidget *widget, int x, int y);
 	void (*set_position)(GntWidget *widget, int x, int y);
 	gboolean (*key_pressed)(GntWidget *widget, const char *key);
 	void (*activate)(GntWidget *widget);
@@ -104,7 +107,7 @@
 void gnt_widget_set_position(GntWidget *widget, int x, int y);
 void gnt_widget_size_request(GntWidget *widget);
 void gnt_widget_get_size(GntWidget *widget, int *width, int *height);
-void gnt_widget_set_size(GntWidget *widget, int width, int height);
+gboolean gnt_widget_set_size(GntWidget *widget, int width, int height);
 
 gboolean gnt_widget_key_pressed(GntWidget *widget, const char *keys);