comparison console/libgnt/gntwidget.c @ 14900:065e7ac30338

[gaim-migrate @ 17672] Rearranging a bunch of stuff. Users shouldn't notice any change, apart from the added ability to bind keys for the window-manager. I will update the manual in a while. I need to know how to revert a commit in case things go terribly wrong. ... I am going to remind everyone that Dido is AWESOME! committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 05 Nov 2006 17:28:33 +0000
parents 5228f8cf2a6a
children 056c8a27668c
comparison
equal deleted inserted replaced
14899:a8f92a837590 14900:065e7ac30338
82 return FALSE; 82 return FALSE;
83 return TRUE; 83 return TRUE;
84 } 84 }
85 85
86 static gboolean 86 static gboolean
87 context_menu(GntWidget *widget, GList *null) 87 context_menu(GntBindable *bind, GList *null)
88 { 88 {
89 gboolean ret = FALSE; 89 gboolean ret = FALSE;
90 g_signal_emit(widget, signals[SIG_CONTEXT_MENU], 0, &ret); 90 g_signal_emit(bind, signals[SIG_CONTEXT_MENU], 0, &ret);
91 return ret; 91 return ret;
92 }
93
94 static gboolean
95 gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint,
96 GValue *return_accu,
97 const GValue *handler_return,
98 gpointer dummy)
99 {
100 gboolean continue_emission;
101 gboolean signal_handled;
102
103 signal_handled = g_value_get_boolean (handler_return);
104 g_value_set_boolean (return_accu, signal_handled);
105 continue_emission = !signal_handled;
106
107 return continue_emission;
108 } 92 }
109 93
110 static void 94 static void
111 gnt_widget_class_init(GntWidgetClass *klass) 95 gnt_widget_class_init(GntWidgetClass *klass)
112 { 96 {
250 0, 234 0,
251 gnt_boolean_handled_accumulator, NULL, 235 gnt_boolean_handled_accumulator, NULL,
252 gnt_closure_marshal_BOOLEAN__VOID, 236 gnt_closure_marshal_BOOLEAN__VOID,
253 G_TYPE_BOOLEAN, 0); 237 G_TYPE_BOOLEAN, 0);
254 238
255 klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
256 (GDestroyNotify)gnt_widget_action_free);
257 klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
258 (GDestroyNotify)gnt_widget_action_param_free);
259
260 /* This is relevant for all widgets */ 239 /* This is relevant for all widgets */
261 gnt_widget_class_register_action(klass, "context-menu", context_menu, 240 gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "context-menu", context_menu,
262 GNT_KEY_POPUP, NULL); 241 GNT_KEY_POPUP, NULL);
263 242
264 gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), klass); 243 gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
265
266 GNTDEBUG; 244 GNTDEBUG;
267 } 245 }
268 246
269 /****************************************************************************** 247 /******************************************************************************
270 * GntWidget API 248 * GntWidget API
285 sizeof(GntWidget), 263 sizeof(GntWidget),
286 0, /* n_preallocs */ 264 0, /* n_preallocs */
287 gnt_widget_init, /* instance_init */ 265 gnt_widget_init, /* instance_init */
288 }; 266 };
289 267
290 type = g_type_register_static(G_TYPE_OBJECT, 268 type = g_type_register_static(GNT_TYPE_BINDABLE,
291 "GntWidget", 269 "GntWidget",
292 &info, G_TYPE_FLAG_ABSTRACT); 270 &info, G_TYPE_FLAG_ABSTRACT);
293 } 271 }
294 272
295 return type; 273 return type;
296 }
297
298 static const char *
299 gnt_widget_remap_keys(GntWidget *widget, const char *text)
300 {
301 const char *remap = NULL;
302 GType type = G_OBJECT_TYPE(widget);
303 GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget));
304
305 if (klass->remaps == NULL)
306 {
307 klass->remaps = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
308 gnt_styles_get_keyremaps(type, klass->remaps);
309 }
310
311 remap = g_hash_table_lookup(klass->remaps, text);
312
313 return (remap ? remap : text);
314 }
315
316 static void
317 gnt_widget_take_focus(GntWidget *widget)
318 {
319 gnt_screen_take_focus(widget);
320 } 274 }
321 275
322 void gnt_widget_set_take_focus(GntWidget *widget, gboolean can) 276 void gnt_widget_set_take_focus(GntWidget *widget, gboolean can)
323 { 277 {
324 if (can) 278 if (can)
348 302
349 void 303 void
350 gnt_widget_show(GntWidget *widget) 304 gnt_widget_show(GntWidget *widget)
351 { 305 {
352 /* Draw the widget and take focus */ 306 /* Draw the widget and take focus */
353 if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) 307 /*if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) {*/
354 { 308 /*gnt_widget_take_focus(widget);*/
355 gnt_widget_take_focus(widget); 309 /*}*/
356 }
357 gnt_widget_draw(widget); 310 gnt_widget_draw(widget);
358 } 311 }
359 312
360 void 313 void
361 gnt_widget_draw(GntWidget *widget) 314 gnt_widget_draw(GntWidget *widget)
363 /* Draw the widget */ 316 /* Draw the widget */
364 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING)) 317 if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING))
365 return; 318 return;
366 319
367 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING); 320 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING);
368 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) 321 if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) {
369 {
370 gnt_widget_map(widget); 322 gnt_widget_map(widget);
371 gnt_screen_occupy(widget);
372 } 323 }
373 324
374 if (widget->window == NULL) 325 if (widget->window == NULL)
375 { 326 {
376 gboolean shadow = TRUE; 327 gboolean shadow = TRUE;
403 354
404 widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow, 355 widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow,
405 widget->priv.y, widget->priv.x); 356 widget->priv.y, widget->priv.x);
406 } 357 }
407 init_widget(widget); 358 init_widget(widget);
359 gnt_screen_occupy(widget);
408 } 360 }
409 361
410 g_signal_emit(widget, signals[SIG_DRAW], 0); 362 g_signal_emit(widget, signals[SIG_DRAW], 0);
411 gnt_widget_queue_update(widget); 363 gnt_widget_queue_update(widget);
412 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING); 364 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING);
413 } 365 }
414 366
415 gboolean 367 gboolean
416 gnt_widget_perform_action_named(GntWidget *widget, const char *name, ...)
417 {
418 GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget));
419 GList *list = NULL;
420 va_list args;
421 GntWidgetAction *action;
422 void *p;
423
424 va_start(args, name);
425 while ((p = va_arg(args, void *)) != NULL)
426 list = g_list_append(list, p);
427 va_end(args);
428
429 action = g_hash_table_lookup(klass->actions, name);
430 if (action && action->u.action) {
431 if (list)
432 return action->u.action(widget, list);
433 else
434 return action->u.action_noparam(widget);
435 }
436 return FALSE;
437 }
438
439 static gboolean
440 gnt_widget_perform_action(GntWidget *widget, const char *keys)
441 {
442 GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget));
443 GntWidgetActionParam *param = g_hash_table_lookup(klass->bindings, keys);
444
445 if (param && param->action) {
446 if (param->list)
447 return param->action->u.action(widget, param->list);
448 else
449 return param->action->u.action_noparam(widget);
450 }
451 return FALSE;
452 }
453
454 gboolean
455 gnt_widget_key_pressed(GntWidget *widget, const char *keys) 368 gnt_widget_key_pressed(GntWidget *widget, const char *keys)
456 { 369 {
457 gboolean ret; 370 gboolean ret;
458 if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) 371 if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS))
459 return FALSE; 372 return FALSE;
460 373
461 if (gnt_widget_perform_action(widget, keys)) 374 if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), keys))
462 return TRUE; 375 return TRUE;
463 376
464 keys = gnt_widget_remap_keys(widget, keys); 377 keys = gnt_bindable_remap_keys(GNT_BINDABLE(widget), keys);
465 g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); 378 g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret);
466 return ret; 379 return ret;
467 } 380 }
468 381
469 gboolean 382 gboolean
705 { 618 {
706 return (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW) && 619 return (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW) &&
707 gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE)); 620 gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE));
708 } 621 }
709 622
710 static void
711 register_binding(GntWidgetClass *klass, const char *name, const char *trigger, GList *list)
712 {
713 GntWidgetActionParam *param;
714 GntWidgetAction *action;
715
716 if (name == NULL || *name == '\0') {
717 g_hash_table_remove(klass->bindings, (char*)trigger);
718 return;
719 }
720
721 action = g_hash_table_lookup(klass->actions, name);
722 if (!action) {
723 g_printerr("GntWidget: Invalid action name %s for %s\n",
724 name, g_type_name(G_OBJECT_CLASS_TYPE(klass)));
725 if (list)
726 g_list_free(list);
727 return;
728 }
729
730 param = g_new0(GntWidgetActionParam, 1);
731 param->action = action;
732 param->list = list;
733 g_hash_table_replace(klass->bindings, g_strdup(trigger), param);
734 }
735
736 void gnt_widget_register_binding(GntWidgetClass *klass, const char *name,
737 const char *trigger, ...)
738 {
739 GList *list = NULL;
740 va_list args;
741 void *data;
742
743 va_start(args, trigger);
744 while ((data = va_arg(args, void *))) {
745 list = g_list_append(list, data);
746 }
747 va_end(args);
748
749 register_binding(klass, name, trigger, list);
750 }
751
752 void gnt_widget_class_register_action(GntWidgetClass *klass, const char *name,
753 GntWidgetActionCallback callback,
754 const char *trigger, ...)
755 {
756 void *data;
757 va_list args;
758 GntWidgetAction *action = g_new0(GntWidgetAction, 1);
759 GList *list;
760
761 action->name = g_strdup(name);
762 action->u.action = callback;
763
764 g_hash_table_replace(klass->actions, g_strdup(name), action);
765
766 if (trigger) {
767 list = NULL;
768 va_start(args, trigger);
769 while ((data = va_arg(args, void *))) {
770 list = g_list_append(list, data);
771 }
772 va_end(args);
773
774 register_binding(klass, name, trigger, list);
775 }
776 }
777
778 void gnt_widget_action_free(GntWidgetAction *action)
779 {
780 g_free(action->name);
781 g_free(action);
782 }
783
784 void gnt_widget_action_param_free(GntWidgetActionParam *param)
785 {
786 g_list_free(param->list); /* XXX: There may be a leak here for string parameters */
787 g_free(param);
788 }
789