From: <sa...@us...> - 2006-06-27 02:34:06
|
Revision: 16355 Author: sadrul Date: 2006-06-26 19:33:55 -0700 (Mon, 26 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16355&view=rev Log Message: ----------- Change the behaviour of the widgets about how they update themselves. This makes things a little better, and hopefully easier to build more stuff on top of this. Modified Paths: -------------- trunk/console/libgnt/gnt.h trunk/console/libgnt/gntbox.c trunk/console/libgnt/gntbox.h trunk/console/libgnt/gntbutton.c trunk/console/libgnt/gntentry.c trunk/console/libgnt/gntlabel.c trunk/console/libgnt/gntmain.c trunk/console/libgnt/gnttree.c trunk/console/libgnt/gntwidget.c trunk/console/libgnt/gntwidget.h Modified: trunk/console/libgnt/gnt.h =================================================================== --- trunk/console/libgnt/gnt.h 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gnt.h 2006-06-27 02:33:55 UTC (rev 16355) @@ -11,3 +11,4 @@ void gnt_screen_release(GntWidget *widget); +void gnt_scree_update(GntWidget *widget); Modified: trunk/console/libgnt/gntbox.c =================================================================== --- trunk/console/libgnt/gntbox.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntbox.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -12,15 +12,11 @@ gnt_box_draw(GntWidget *widget) { GntBox *box = GNT_BOX(widget); - GList *iter; - for (iter = box->list; iter; iter = iter->next) - { - GntWidget *w = GNT_WIDGET(iter->data); - gnt_widget_draw(w); - overwrite(w->window, widget->window); - } + g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL); + gnt_box_sync_children(box); + if (box->title) { gchar *title = g_strdup(box->title); @@ -40,9 +36,6 @@ mvwprintw(widget->window, 0, pos, title); g_free(title); } - wrefresh(widget->window); - - gnt_screen_occupy(widget); DEBUG; } @@ -376,3 +369,16 @@ GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); } +void gnt_box_sync_children(GntBox *box) +{ + GList *iter; + GntWidget *widget = GNT_WIDGET(box); + + for (iter = box->list; iter; iter = iter->next) + { + GntWidget *w = GNT_WIDGET(iter->data); + copywin(w->window, widget->window, 0, 0, w->priv.y - widget->priv.y, w->priv.x - widget->priv.x, + w->priv.height, w->priv.width, FALSE); + } +} + Modified: trunk/console/libgnt/gntbox.h =================================================================== --- trunk/console/libgnt/gntbox.h 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntbox.h 2006-06-27 02:33:55 UTC (rev 16355) @@ -57,6 +57,8 @@ void gnt_box_set_toplevel(GntBox *box, gboolean set); +void gnt_box_sync_children(GntBox *box); + G_END_DECLS #endif /* GNT_BOX_H */ Modified: trunk/console/libgnt/gntbutton.c =================================================================== --- trunk/console/libgnt/gntbutton.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntbutton.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -21,8 +21,6 @@ wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); mvwprintw(widget->window, 1, 1, button->priv->text); - wrefresh(widget->window); - DEBUG; } Modified: trunk/console/libgnt/gntentry.c =================================================================== --- trunk/console/libgnt/gntentry.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntentry.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -22,8 +22,6 @@ if (stop < widget->priv.width) mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop); - wrefresh(widget->window); - DEBUG; } Modified: trunk/console/libgnt/gntlabel.c =================================================================== --- trunk/console/libgnt/gntlabel.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntlabel.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -24,7 +24,6 @@ wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); mvwprintw(widget->window, 0, 0, label->text); - wrefresh(widget->window); DEBUG; } Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntmain.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -142,6 +142,8 @@ if (value == NULL) return; + if (n->me == nu->me) + return; if (n->me->priv.x + n->me->priv.width < nu->me->priv.x) return; @@ -153,15 +155,24 @@ 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); + n->above = g_list_prepend(n->above, nu); + nu->below = g_list_prepend(nu->below, n); } 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); + GntNode *node; + + if (widget->parent) + { + while (widget->parent) + widget = widget->parent; + } + + if (g_hash_table_lookup(nodes, widget)) + return; /* XXX: perhaps _update instead? */ + + node = g_new0(GntNode, 1); node->me = widget; g_hash_table_foreach(nodes, check_intersection, node); @@ -170,16 +181,21 @@ void gnt_screen_release(GntWidget *widget) { + WINDOW *win; GList *iter; GntNode *node = g_hash_table_lookup(nodes, widget); if (node == NULL || node->below == NULL) /* Yay! Nothing to do. */ return; + win = dupwin(widget->window); + werase(win); + /* 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; + GntNode *n = iter->data; + GntWidget *w = n->me; int left, right, top, bottom; left = MAX(widget->priv.x, w->priv.x) - w->priv.x; @@ -188,9 +204,61 @@ 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); + copywin(w->window, win, top, left, + w->priv.y + top, + w->priv.x + left, + w->priv.y + bottom - top - 1, + w->priv.x + right - left - 1, FALSE); + n->above = g_list_remove(n->above, node); } + wrefresh(win); + delwin(win); + g_hash_table_remove(nodes, widget); } +void gnt_screen_update(GntWidget *widget) +{ + GList *iter; + WINDOW *win; + GntNode *node; + + if (widget->parent) + { + while (widget->parent) + widget = widget->parent; + } + + gnt_box_sync_children(widget); + node = g_hash_table_lookup(nodes, widget); + + win = dupwin(widget->window); + + if (node && node->above) + { + /* XXX: Same here: need to build a topology first. */ + for (iter = node->above; iter; iter = iter->next) + { + GntNode *n = iter->data; + GntWidget *w = n->me; + 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; + + copywin(w->window, win, top, left, + w->priv.y + top, + w->priv.x + left, + w->priv.y + bottom - top - 1, + w->priv.x + right - left - 1, FALSE); + } + } + + wrefresh(win); + delwin(win); +} + Modified: trunk/console/libgnt/gnttree.c =================================================================== --- trunk/console/libgnt/gnttree.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gnttree.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -219,7 +219,7 @@ start++; } - wrefresh(widget->window); + gnt_widget_queue_update(widget); } static void @@ -231,8 +231,6 @@ scrollok(widget->window, TRUE); wsetscrreg(widget->window, 0, widget->priv.height - 1); - tree->top = tree->root; - redraw_tree(tree); DEBUG; Modified: trunk/console/libgnt/gntwidget.c =================================================================== --- trunk/console/libgnt/gntwidget.c 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntwidget.c 2006-06-27 02:33:55 UTC (rev 16355) @@ -219,8 +219,15 @@ void gnt_widget_destroy(GntWidget *obj) { + int id; g_return_if_fail(GNT_IS_WIDGET(obj)); + if ((id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "gnt:queue_update")))) + { + g_source_remove(id); + g_object_set_data(G_OBJECT(obj), "gnt:queue_update", NULL); + } + gnt_widget_hide(obj); delwin(obj->window); if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) @@ -244,24 +251,29 @@ { /* Draw the widget */ DEBUG; + if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING)) + return; + + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING); if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) + { gnt_widget_map(widget); + gnt_screen_occupy(widget); + } - if (widget->window) + if (widget->window == NULL) { - delwin(widget->window); + /* XXX: It may be necessary to make sure the size hasn't changed */ + widget->window = newwin(widget->priv.height, widget->priv.width, + widget->priv.y, widget->priv.x); + wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); } - - widget->window = newwin(widget->priv.height, widget->priv.width, - widget->priv.y, widget->priv.x); - wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); + if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) - { box(widget->window, 0, 0); - } else werase(widget->window); - + #if 0 /* XXX: No shadow for now :( */ if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_SHADOW)) @@ -276,10 +288,12 @@ touchline(widget->back, 0, widget->priv.height); wrefresh(widget->back); } -#endif wrefresh(widget->window); +#endif g_signal_emit(widget, signals[SIG_DRAW], 0); + gnt_widget_queue_update(widget); + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING); } gboolean @@ -301,16 +315,9 @@ void gnt_widget_hide(GntWidget *widget) { - int i; - - /* XXX: Currently it simply empties the window. Ideally, it will - * detect what windows are immediately beneath this one, and cause - * those windows to redraw themselves by emitting the approrpiate - * expose signal. */ - wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); werase(widget->window); - wrefresh(widget->window); + gnt_screen_release(widget); } void @@ -387,3 +394,27 @@ g_signal_emit(widget, signals[SIG_ACTIVATE], 0); } +static gboolean +update_queue_callback(gpointer data) +{ + GntWidget *widget = GNT_WIDGET(data); + + if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) + return FALSE; + gnt_screen_update(widget); + g_object_set_data(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(FALSE)); + return FALSE; +} + +void gnt_widget_queue_update(GntWidget *widget) +{ + while (widget->parent) + widget = widget->parent; + + if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) + { + int id = g_timeout_add(0, update_queue_callback, widget); + g_object_set_data(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id)); + } +} + Modified: trunk/console/libgnt/gntwidget.h =================================================================== --- trunk/console/libgnt/gntwidget.h 2006-06-26 19:54:53 UTC (rev 16354) +++ trunk/console/libgnt/gntwidget.h 2006-06-27 02:33:55 UTC (rev 16355) @@ -17,8 +17,7 @@ #define GNT_WIDGET_SET_FLAGS(obj, flags) (GNT_WIDGET_FLAGS(obj) |= flags) #define GNT_WIDGET_UNSET_FLAGS(obj, flags) (GNT_WIDGET_FLAGS(obj) &= ~(flags)) #define GNT_WIDGET_IS_FLAG_SET(obj, flags) (GNT_WIDGET_FLAGS(obj) & (flags)) -#define DEBUG -//#define DEBUG printf("%s\n", __FUNCTION__) +#define DEBUG fprintf(stderr, "%s\n", __FUNCTION__) typedef struct _GnWidget GntWidget; typedef struct _GnWidgetPriv GntWidgetPriv; @@ -28,16 +27,18 @@ typedef enum _GnWidgetFlags { - GNT_WIDGET_DESTROYING = 1 << 0, - GNT_WIDGET_CAN_TAKE_FOCUS= 1 << 1, - GNT_WIDGET_MAPPED = 1 << 2, + GNT_WIDGET_DESTROYING = 1 << 0, + GNT_WIDGET_CAN_TAKE_FOCUS = 1 << 1, + GNT_WIDGET_MAPPED = 1 << 2, /* XXX: Need to set the following two as properties, and setup a callback whenever these * get chnaged. */ - GNT_WIDGET_NO_BORDER = 1 << 3, - GNT_WIDGET_NO_SHADOW = 1 << 4, - GNT_WIDGET_HAS_FOCUS = 1 << 5 + GNT_WIDGET_NO_BORDER = 1 << 3, + GNT_WIDGET_NO_SHADOW = 1 << 4, + GNT_WIDGET_HAS_FOCUS = 1 << 5, + GNT_WIDGET_DRAWING = 1 << 6 } GntWidgetFlags; +/* XXX: I'll have to ask grim what he's using this for in guifications. */ typedef enum _GnParamFlags { GNT_PARAM_SERIALIZABLE = 1 << G_PARAM_USER_SHIFT @@ -112,6 +113,10 @@ void gnt_widget_set_name(GntWidget *widget, const char *name); +/* Widget-subclasses should call this from the draw-callback. + * Applications should just call gnt_widget_draw instead of this. */ +void gnt_widget_queue_update(GntWidget *widget); + G_END_DECLS #endif /* GNT_WIDGET_H */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |