comparison console/libgnt/gntwidget.c @ 13878:0d0ab1e39d0a

[gaim-migrate @ 16355] 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. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Tue, 27 Jun 2006 02:33:55 +0000
parents 5642f4658b59
children 5c750626eaa5
comparison
equal deleted inserted replaced
13877:765bbdf29d04 13878:0d0ab1e39d0a
217 * should release @obj. 217 * should release @obj.
218 */ 218 */
219 void 219 void
220 gnt_widget_destroy(GntWidget *obj) 220 gnt_widget_destroy(GntWidget *obj)
221 { 221 {
222 int id;
222 g_return_if_fail(GNT_IS_WIDGET(obj)); 223 g_return_if_fail(GNT_IS_WIDGET(obj));
224
225 if ((id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "gnt:queue_update"))))
226 {
227 g_source_remove(id);
228 g_object_set_data(G_OBJECT(obj), "gnt:queue_update", NULL);
229 }
223 230
224 gnt_widget_hide(obj); 231 gnt_widget_hide(obj);
225 delwin(obj->window); 232 delwin(obj->window);
226 if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) 233 if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING))
227 g_object_run_dispose(G_OBJECT(obj)); 234 g_object_run_dispose(G_OBJECT(obj));
242 void 249 void
243 gnt_widget_draw(GntWidget *widget) 250 gnt_widget_draw(GntWidget *widget)
244 { 251 {
245 /* Draw the widget */ 252 /* Draw the widget */
246 DEBUG; 253 DEBUG;
254 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING))
255 return;
256
257 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING);
247 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) 258 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED))
259 {
248 gnt_widget_map(widget); 260 gnt_widget_map(widget);
249 261 gnt_screen_occupy(widget);
250 if (widget->window) 262 }
251 { 263
252 delwin(widget->window); 264 if (widget->window == NULL)
253 } 265 {
254 266 /* XXX: It may be necessary to make sure the size hasn't changed */
255 widget->window = newwin(widget->priv.height, widget->priv.width, 267 widget->window = newwin(widget->priv.height, widget->priv.width,
256 widget->priv.y, widget->priv.x); 268 widget->priv.y, widget->priv.x);
257 wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); 269 wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
270 }
271
258 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) 272 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
259 {
260 box(widget->window, 0, 0); 273 box(widget->window, 0, 0);
261 }
262 else 274 else
263 werase(widget->window); 275 werase(widget->window);
264 276
265 #if 0 277 #if 0
266 /* XXX: No shadow for now :( */ 278 /* XXX: No shadow for now :( */
267 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_SHADOW)) 279 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_SHADOW))
268 { 280 {
269 widget->back = newwin(widget->priv.height, widget->priv.width, 281 widget->back = newwin(widget->priv.height, widget->priv.width,
274 mvwchgat(widget->back, 0, 0, widget->priv.height, 286 mvwchgat(widget->back, 0, 0, widget->priv.height,
275 A_REVERSE | A_BLINK, 0, 0); 287 A_REVERSE | A_BLINK, 0, 0);
276 touchline(widget->back, 0, widget->priv.height); 288 touchline(widget->back, 0, widget->priv.height);
277 wrefresh(widget->back); 289 wrefresh(widget->back);
278 } 290 }
291
292 wrefresh(widget->window);
279 #endif 293 #endif
280
281 wrefresh(widget->window);
282 g_signal_emit(widget, signals[SIG_DRAW], 0); 294 g_signal_emit(widget, signals[SIG_DRAW], 0);
295 gnt_widget_queue_update(widget);
296 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING);
283 } 297 }
284 298
285 gboolean 299 gboolean
286 gnt_widget_key_pressed(GntWidget *widget, const char *keys) 300 gnt_widget_key_pressed(GntWidget *widget, const char *keys)
287 { 301 {
299 } 313 }
300 314
301 void 315 void
302 gnt_widget_hide(GntWidget *widget) 316 gnt_widget_hide(GntWidget *widget)
303 { 317 {
304 int i;
305
306 /* XXX: Currently it simply empties the window. Ideally, it will
307 * detect what windows are immediately beneath this one, and cause
308 * those windows to redraw themselves by emitting the approrpiate
309 * expose signal. */
310
311 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); 318 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
312 werase(widget->window); 319 werase(widget->window);
313 wrefresh(widget->window); 320 gnt_screen_release(widget);
314 } 321 }
315 322
316 void 323 void
317 gnt_widget_set_position(GntWidget *wid, int x, int y) 324 gnt_widget_set_position(GntWidget *wid, int x, int y)
318 { 325 {
385 void gnt_widget_activate(GntWidget *widget) 392 void gnt_widget_activate(GntWidget *widget)
386 { 393 {
387 g_signal_emit(widget, signals[SIG_ACTIVATE], 0); 394 g_signal_emit(widget, signals[SIG_ACTIVATE], 0);
388 } 395 }
389 396
397 static gboolean
398 update_queue_callback(gpointer data)
399 {
400 GntWidget *widget = GNT_WIDGET(data);
401
402 if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update"))
403 return FALSE;
404 gnt_screen_update(widget);
405 g_object_set_data(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(FALSE));
406 return FALSE;
407 }
408
409 void gnt_widget_queue_update(GntWidget *widget)
410 {
411 while (widget->parent)
412 widget = widget->parent;
413
414 if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update"))
415 {
416 int id = g_timeout_add(0, update_queue_callback, widget);
417 g_object_set_data(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id));
418 }
419 }
420