Agar-SVN | 21 Jun 14:49
Favicon

Agar: r8202 - trunk/gui

Author: vedge
Date: 2009-06-21 09:49:32 -0300 (Sun, 21 Jun 2009)
New Revision: 8202

Modified:
   trunk/gui/AG_Table.3
   trunk/gui/button.c
   trunk/gui/checkbox.c
   trunk/gui/combo.c
   trunk/gui/fspinbutton.c
   trunk/gui/mfspinbutton.c
   trunk/gui/numerical.c
   trunk/gui/pixmap.c
   trunk/gui/progress_bar.c
   trunk/gui/radio.c
   trunk/gui/slider.c
   trunk/gui/spinbutton.c
   trunk/gui/table.c
   trunk/gui/ucombo.c
   trunk/gui/widget.h
Log:
- disallow embedding of improper widgets in AG_Table %[W] cells.
- handle out-of-memory condition in AG_TableAddRow() and AG_TableAddCol()
  by returning -1 instead of fatal.

Modified: trunk/gui/AG_Table.3
===================================================================
--- trunk/gui/AG_Table.3	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/AG_Table.3	2009-06-21 12:49:32 UTC (rev 8202)
@@ -278,8 +278,8 @@
 .nr nS 0
 The
 .Fn AG_TableAddCol
-function inserts a new column into the table and returns an integer column
-identifier.
+function inserts a new column into the table, returning the number of the
+new column if successful, or -1 if an error occured.
 .Fa name
 specifies the text to display in the column header.
 .Fa size_spec
@@ -330,7 +330,8 @@
 .nr nS 0
 The
 .Fn AG_TableAddRow
-function inserts a new row into the table.
+function inserts a new row into the table and returns the new row number,
+or -1 if a failure occured.
 The
 .Fa fmt
 argument describes the individual fields (or cells) of this row.
@@ -391,7 +392,10 @@
 .Fa y
 parameters can be ignored.
 .It %[W]
-An arbitrary widget to insert into the table.
+A widget to insert into the table.
+The widget must have the
+.Dv AG_WIDGET_TABLE_EMBEDDABLE
+flag set or the operation will fail.
 Note that for efficiency reasons,
 .Nm
 is not treated like a standard widget container, so widgets that are

Modified: trunk/gui/button.c
===================================================================
--- trunk/gui/button.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/button.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -176,7 +176,8 @@
 	/* TODO replace the unfocused motion flag with a timer */
 	WIDGET(bu)->flags |= AG_WIDGET_FOCUSABLE|
 	                     AG_WIDGET_UNFOCUSED_MOTION|
-			     AG_WIDGET_UNFOCUSED_BUTTONUP;
+			     AG_WIDGET_UNFOCUSED_BUTTONUP|
+			     AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindInt(bu, "state", &bu->state);

Modified: trunk/gui/checkbox.c
===================================================================
--- trunk/gui/checkbox.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/checkbox.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -177,7 +177,8 @@
 {
 	AG_Checkbox *cb = obj;

-	WIDGET(cb)->flags |= AG_WIDGET_FOCUSABLE;
+	WIDGET(cb)->flags |= AG_WIDGET_FOCUSABLE|
+	                     AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindInt(cb, "state", &cb->state);

Modified: trunk/gui/combo.c
===================================================================
--- trunk/gui/combo.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/combo.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -212,6 +212,8 @@
 {
 	AG_Combo *com = obj;

+	WIDGET(com)->flags |= AG_WIDGET_TABLE_EMBEDDABLE;
+
 	com->flags = 0;
 	com->panel = NULL;
 	com->wSaved = 0;

Modified: trunk/gui/fspinbutton.c
===================================================================
--- trunk/gui/fspinbutton.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/fspinbutton.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -271,6 +271,8 @@
 Init(void *obj)
 {
 	AG_FSpinbutton *fsu = obj;
+	
+	WIDGET(fsu)->flags |= AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindDouble(fsu, "value", &fsu->value);
 	AG_BindDouble(fsu, "min", &fsu->min);

Modified: trunk/gui/mfspinbutton.c
===================================================================
--- trunk/gui/mfspinbutton.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/mfspinbutton.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -240,7 +240,8 @@
 {
 	AG_MFSpinbutton *fsu = obj;

-	WIDGET(fsu)->flags |= AG_WIDGET_FOCUSABLE;
+	WIDGET(fsu)->flags |= AG_WIDGET_FOCUSABLE|
+	                      AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindDouble(fsu, "xvalue", &fsu->xvalue);
 	AG_BindDouble(fsu, "yvalue", &fsu->yvalue);

Modified: trunk/gui/numerical.c
===================================================================
--- trunk/gui/numerical.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/numerical.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -554,7 +554,8 @@
 {
 	AG_Numerical *num = obj;

-	WIDGET(num)->flags |= AG_WIDGET_FOCUSABLE;
+	WIDGET(num)->flags |= AG_WIDGET_FOCUSABLE|
+	                      AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindDouble(num, "value", &num->value);
 	AG_BindDouble(num, "min", &num->min);

Modified: trunk/gui/pixmap.c
===================================================================
--- trunk/gui/pixmap.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/pixmap.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -272,6 +272,8 @@
 Init(void *obj)
 {
 	AG_Pixmap *px = obj;
+	
+	WIDGET(px)->flags |= AG_WIDGET_TABLE_EMBEDDABLE;

 	px->flags = AG_PIXMAP_UPDATE;
 	px->n = 0;

Modified: trunk/gui/progress_bar.c
===================================================================
--- trunk/gui/progress_bar.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/progress_bar.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -73,7 +73,8 @@
 	AG_ProgressBar *pb = obj;

 	WIDGET(pb)->flags |= AG_WIDGET_UNFOCUSED_BUTTONUP|
-	                     AG_WIDGET_UNFOCUSED_MOTION;
+	                     AG_WIDGET_UNFOCUSED_MOTION|
+			     AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindInt(pb, "value", &pb->value);
 	AG_BindInt(pb, "min", &pb->min);

Modified: trunk/gui/radio.c
===================================================================
--- trunk/gui/radio.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/radio.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -326,7 +326,8 @@
 {
 	AG_Radio *rad = obj;

-	WIDGET(rad)->flags |= AG_WIDGET_FOCUSABLE|AG_WIDGET_UNFOCUSED_MOTION;
+	WIDGET(rad)->flags |= AG_WIDGET_FOCUSABLE|AG_WIDGET_UNFOCUSED_MOTION|
+	                      AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindInt(rad, "value", &rad->value);

Modified: trunk/gui/slider.c
===================================================================
--- trunk/gui/slider.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/slider.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -635,7 +635,8 @@

 	WIDGET(sl)->flags |= AG_WIDGET_UNFOCUSED_BUTTONUP|
 	                     AG_WIDGET_UNFOCUSED_MOTION|
-			     AG_WIDGET_FOCUSABLE;
+			     AG_WIDGET_FOCUSABLE|
+			     AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindInt(sl, "value", &sl->value);
 	AG_BindInt(sl, "min", &sl->min);

Modified: trunk/gui/spinbutton.c
===================================================================
--- trunk/gui/spinbutton.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/spinbutton.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -170,6 +170,8 @@
 Init(void *obj)
 {
 	AG_Spinbutton *sbu = obj;
+	
+	WIDGET(sbu)->flags |= AG_WIDGET_TABLE_EMBEDDABLE;

 	AG_BindInt(sbu, "value", &sbu->value);
 	AG_BindInt(sbu, "min", &sbu->min);

Modified: trunk/gui/table.c
===================================================================
--- trunk/gui/table.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/table.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -630,6 +630,8 @@
 	if (t->flags & AG_TABLE_WIDGETS)
 		UpdateEmbeddedWidgets(t);

+	AG_PushTextState();
+
 	rCol.y = 0;
 	rCol.h = t->hCol + t->r.h - 2;
 	rCell.h = t->hRow;
@@ -706,6 +708,8 @@
 		    AG_COLOR(TABLE_LINE_COLOR));
 	}
 	t->flags &= ~(AG_TABLE_REDRAW_CELLS);
+
+	AG_PopTextState();
 }

 AG_MenuItem *
@@ -1634,12 +1638,17 @@
     int (*sort_fn)(const void *, const void *))
 {
 	AG_TableCol *tc, *lc;
+	AG_TableCol *colsNew;
 	Uint m, n;

 	AG_ObjectLock(t);

 	/* Initialize the column information structure. */
-	t->cols = Realloc(t->cols, (t->n+1)*sizeof(AG_TableCol));
+	if ((colsNew = realloc(t->cols, (t->n+1)*sizeof(AG_TableCol))) == NULL) {
+		goto outofmem;
+	}
+	t->cols = colsNew;
+
 	tc = &t->cols[t->n];
 	if (name != NULL) {
 		Strlcpy(tc->name, name, sizeof(tc->name));
@@ -1654,10 +1663,12 @@
 	tc->pool = NULL;
 	tc->mpool = 0;

-	/* XXX CONTEXT */
+	AG_PushTextState();
 	AG_TextColor(TEXT_COLOR);
 	tc->surface = (name == NULL) ? -1 :
 	    AG_WidgetMapSurface(t, AG_TextRender(name));
+	AG_PopTextState();
+
 	if (t->n > 0) {
 		lc = &t->cols[t->n - 1];
 		tc->x = lc->x+lc->w;
@@ -1682,13 +1693,22 @@

 	/* Resize the row arrays. */
 	for (m = 0; m < t->m; m++) {
-		t->cells[m] = Realloc(t->cells[m],
-		    (t->n+1)*sizeof(AG_TableCell));
+		AG_TableCell *cellsNew;
+
+		if ((cellsNew = realloc(t->cells[m],
+		    (t->n+1)*sizeof(AG_TableCell))) == NULL) {
+			goto outofmem;
+		}
+		t->cells[m] = cellsNew;
 		AG_TableInitCell(t, &t->cells[m][t->n]);
 	}
 	n = t->n++;
 	AG_ObjectUnlock(t);
 	return (n);
+outofmem:
+	AG_SetError("Out of memory for column");
+	AG_ObjectUnlock(t);
+	return (-1);
 }

 void
@@ -1709,14 +1729,23 @@
 	char fmt[64], *sp = &fmt[0];
 	va_list ap;
 	Uint n, rv;
+	AG_TableCell **cellsNew;

 	Strlcpy(fmt, fmtp, sizeof(fmt));

 	AG_ObjectLock(t);

+	if ((cellsNew = realloc(t->cells, (t->m+1)*sizeof(AG_TableCell)))
+	    == NULL) {
+		goto outofmem;
+	}
+	if ((cellsNew[t->m] = malloc(t->n*sizeof(AG_TableCell))) == NULL) {
+		free(cellsNew);
+		goto outofmem;
+	}
+	t->cells = cellsNew;
+
 	va_start(ap, fmtp);
-	t->cells = Realloc(t->cells, (t->m+1)*sizeof(AG_TableCell));
-	t->cells[t->m] = Malloc(t->n*sizeof(AG_TableCell));
 	for (n = 0; n < t->n; n++) {
 		AG_TableCell *c = &t->cells[t->m][n];
 		char *s = AG_Strsep(&sp, ":"), *sc;
@@ -1787,6 +1816,13 @@
 				a.h = 0;
 				c->type = AG_CELL_WIDGET;
 				c->widget = c->data.p;
+				if (!(c->widget->flags &
+				      AG_WIDGET_TABLE_EMBEDDABLE)) {
+					AG_SetError("%s widgets are not "
+					            "%%[W]-embeddable",
+					    AGOBJECT_CLASS(c->widget)->name);
+					goto fail;
+				}
 				AG_ObjectAttach(t, c->widget);
 				AG_WidgetSizeAlloc(c->widget, &a);
 				t->flags |= AG_TABLE_WIDGETS;
@@ -1886,6 +1922,11 @@
 	rv = t->m++;
 	AG_ObjectUnlock(t);
 	return (rv);
+outofmem:
+	AG_SetError("Out of memory for new cell");
+fail:
+	AG_ObjectUnlock(t);
+	return (-1);
 }

 int

Modified: trunk/gui/ucombo.c
===================================================================
--- trunk/gui/ucombo.c	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/ucombo.c	2009-06-21 12:49:32 UTC (rev 8202)
@@ -155,7 +155,8 @@
 {
 	AG_UCombo *com = obj;

-	WIDGET(com)->flags |= AG_WIDGET_UNFOCUSED_BUTTONUP;
+	WIDGET(com)->flags |= AG_WIDGET_UNFOCUSED_BUTTONUP|
+	                      AG_WIDGET_TABLE_EMBEDDABLE;

 	com->flags = 0;
 	com->panel = NULL;

Modified: trunk/gui/widget.h
===================================================================
--- trunk/gui/widget.h	2009-06-21 12:42:57 UTC (rev 8201)
+++ trunk/gui/widget.h	2009-06-21 12:49:32 UTC (rev 8202)
@@ -75,6 +75,7 @@
 #define AG_WIDGET_UNFOCUSED_KEYDOWN	0x10000 /* All mousebuttondown events */
 #define AG_WIDGET_UNFOCUSED_KEYUP	0x20000 /* All mousebuttondown events */
 #define AG_WIDGET_DEBUG_RSENS		0x40000 /* Debug sensitivity rect */
+#define AG_WIDGET_TABLE_EMBEDDABLE	0x80000	/* Can be used in AG_Table(3) */
 #define AG_WIDGET_EXPAND		(AG_WIDGET_HFILL|AG_WIDGET_VFILL)

 	int x, y;			/* Coordinates in container */

Gmane