Parent Directory | Revision Log
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 |