Contents of /trunk/src/banner.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (show annotations)
Wed Dec 24 14:17:20 2008 UTC (15 years, 4 months ago) by achadwick
File MIME type: text/plain
File size: 3730 byte(s)
The "look at me still talking when there's mapping to do" update.

UI: Make display more responsive during long busy periods. Use Hildon banners
    if available, or temporary statusbar messages for non-Hildon. Some message
    wording changes.

Bugfix: Prevent some segfaults when tapping screen during a redraw by putting
    a grabby banner in the way.

Etc: Update credits.
1 #include "banner.h"
2 #include <gtk/gtk.h>
3
4 #define YETI_PASSIVE_WIDGET appdata->statusbar->widget
5
6 #ifdef USE_HILDON
7 #include <hildon/hildon.h>
8
9
10
11 // Clear any current animations.
12
13 void banner_clear(appdata_t *appdata) {
14 if (! (appdata->window && appdata->banner))
15 return;
16 if (appdata->banner_is_grabby) {
17 gtk_grab_remove(YETI_PASSIVE_WIDGET);
18 GtkWidget *win, *menu, *menu_att;
19 win = GTK_WIDGET(appdata->window);
20 menu = GTK_WINDOW(hildon_window_get_menu(win));
21 menu_att = gtk_menu_get_attach_widget(hildon_window_get_menu(win));
22 gtk_widget_set_sensitive(win, TRUE);
23 gtk_widget_set_sensitive(menu, TRUE);
24 gtk_widget_set_sensitive(menu_att, TRUE);
25 }
26 gtk_widget_destroy(appdata->banner);
27 g_object_unref(appdata->banner);
28 appdata->banner = NULL;
29 }
30
31
32 // Cancel any animations currently going, and show a brief text message.
33
34 void banner_show_info(appdata_t *appdata, char *text) {
35 if (!appdata->window)
36 return;
37 banner_clear(appdata);
38 appdata->banner = hildon_banner_show_information(
39 GTK_WIDGET(appdata->window), NULL, text);
40 g_object_ref(appdata->banner);
41 gtk_widget_show(appdata->banner);
42 }
43
44 /*
45 * Start a spinner animation going to demonstrate that something's happening
46 * behind the scenes. If `grab` is true, use the Yeti trick to grab the pointer
47 * during the animation: this gives the impression that the app is doing
48 * something while blocking the rest of the UI. banner_busy_stop() and
49 * banner_clear() will ungrab if grab is set.
50 *
51 * Yeti mode:
52 * http://mail.gnome.org/archives/gtk-app-devel-list/2006-May/msg00020.html
53 */
54
55 void banner_busy_start(appdata_t *appdata, gboolean grab, char *text) {
56 if (!appdata->window)
57 return;
58 banner_clear(appdata);
59 appdata->banner = hildon_banner_show_animation(
60 GTK_WIDGET(appdata->window), NULL, text);
61 g_object_ref(appdata->banner);
62 gtk_widget_show(appdata->banner);
63 appdata->banner_is_grabby = grab;
64 if (appdata->banner_is_grabby) {
65 GtkWidget *win, *menu, *menu_att;
66 win = GTK_WIDGET(appdata->window);
67 menu = GTK_WINDOW(hildon_window_get_menu(win));
68 menu_att = gtk_menu_get_attach_widget(hildon_window_get_menu(win));
69 gtk_widget_set_sensitive(win, FALSE);
70 gtk_widget_set_sensitive(menu, FALSE);
71 gtk_widget_set_sensitive(menu_att, FALSE);
72 gtk_grab_add(YETI_PASSIVE_WIDGET);
73 }
74 banner_busy_tick();
75 }
76
77
78 #else // USE_HILDON
79
80 /*
81 * For non-Hildon builds, use the "brief" message in the statusbar to show
82 * what's happening.
83 */
84
85 #include "statusbar.h"
86
87 void banner_show_info(appdata_t *appdata, char *text) {
88 banner_clear(appdata);
89 statusbar_brief(appdata, text, 0);
90 }
91
92 void banner_busy_start(appdata_t *appdata, gboolean grab, char *text) {
93 banner_clear(appdata);
94 statusbar_brief(appdata, text, -1);
95 appdata->banner_is_grabby = grab;
96 if (appdata->banner_is_grabby) {
97 GtkWidget *win;
98 win = GTK_WIDGET(appdata->window);
99 gtk_widget_set_sensitive(win, FALSE);
100 gtk_grab_add(YETI_PASSIVE_WIDGET);
101 }
102 }
103
104 void banner_clear(appdata_t *appdata) {
105 statusbar_brief(appdata, NULL, 0);
106 if (appdata->banner_is_grabby) {
107 GtkWidget *win;
108 win = GTK_WIDGET(appdata->window);
109 gtk_widget_set_sensitive(win, TRUE);
110 gtk_grab_remove(YETI_PASSIVE_WIDGET);
111 }
112 }
113
114
115 #endif //USE_HILDON
116
117
118 // Just an alias right now
119
120 void banner_busy_stop(appdata_t *appdata) {
121 banner_clear(appdata);
122 }
123
124
125 /*
126 * Process any outstanding GTK events to make the app look more responsive
127 * while still allowing long-running things to process in the mainloop.
128 * This could perhaps be generalised; it isn't banner-specific.
129 */
130
131 void banner_busy_tick() {
132 while (gtk_events_pending()) {
133 gtk_main_iteration();
134 }
135 }
136
137
138 // vim:et:ts=8:sw=2:sts=2:ai
139
140