21 Jun 14:49
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 */
RSS Feed