Mercurial > pidgin.yaz
comparison pidgin/pidgintooltip.c @ 21947:c6b408d16011
merge of '791803b6696dd26a5193ad76f80dbc7c6cb2687a'
and 'e7dd3b30ece9f95dd95249583812659312c457e6'
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Fri, 28 Dec 2007 02:49:23 +0000 |
parents | 3fc5862b834a |
children | c38d72677c8a |
comparison
equal
deleted
inserted
replaced
21923:1981f277ab01 | 21947:c6b408d16011 |
---|---|
41 | 41 |
42 typedef struct | 42 typedef struct |
43 { | 43 { |
44 GtkWidget *widget; | 44 GtkWidget *widget; |
45 gpointer userdata; | 45 gpointer userdata; |
46 PidginTooltipCreateForTree create_tooltip; | |
47 PidginTooltipPaint paint_tooltip; | 46 PidginTooltipPaint paint_tooltip; |
48 GtkTreePath *path; | 47 union { |
48 struct { | |
49 PidginTooltipCreateForTree create_tooltip; | |
50 GtkTreePath *path; | |
51 } treeview; | |
52 struct { | |
53 PidginTooltipCreate create_tooltip; | |
54 } widget; | |
55 } common; | |
49 } PidginTooltipData; | 56 } PidginTooltipData; |
50 | 57 |
51 static void | 58 static void |
52 destroy_tooltip_data(PidginTooltipData *data) | 59 destroy_tooltip_data(PidginTooltipData *data) |
53 { | 60 { |
54 gtk_tree_path_free(data->path); | 61 gtk_tree_path_free(data->common.treeview.path); |
55 g_free(data); | 62 g_free(data); |
56 } | 63 } |
57 | 64 |
58 void pidgin_tooltip_destroy() | 65 void pidgin_tooltip_destroy() |
59 { | 66 { |
68 } | 75 } |
69 | 76 |
70 static gboolean | 77 static gboolean |
71 pidgin_tooltip_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) | 78 pidgin_tooltip_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) |
72 { | 79 { |
73 if (pidgin_tooltip.paint_tooltip) | 80 if (pidgin_tooltip.paint_tooltip) { |
81 gtk_paint_flat_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, | |
82 NULL, widget, "tooltip", 0, 0, -1, -1); | |
74 pidgin_tooltip.paint_tooltip(widget, data); | 83 pidgin_tooltip.paint_tooltip(widget, data); |
84 } | |
75 return FALSE; | 85 return FALSE; |
76 } | 86 } |
77 | 87 |
78 static GtkWidget* | 88 static GtkWidget* |
79 setup_tooltip_window() | 89 setup_tooltip_window() |
182 } | 192 } |
183 | 193 |
184 static void | 194 static void |
185 reset_data_treepath(PidginTooltipData *data) | 195 reset_data_treepath(PidginTooltipData *data) |
186 { | 196 { |
187 gtk_tree_path_free(data->path); | 197 gtk_tree_path_free(data->common.treeview.path); |
188 data->path = NULL; | 198 data->common.treeview.path = NULL; |
189 } | 199 } |
190 | 200 |
191 static void | 201 static void |
192 pidgin_tooltip_draw(PidginTooltipData *data) | 202 pidgin_tooltip_draw(PidginTooltipData *data) |
203 { | |
204 GtkWidget *tipwindow; | |
205 int w, h; | |
206 | |
207 pidgin_tooltip_destroy(); | |
208 | |
209 pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget); | |
210 pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window(); | |
211 pidgin_tooltip.paint_tooltip = data->paint_tooltip; | |
212 | |
213 if (!data->common.widget.create_tooltip(tipwindow, data->userdata, &w, &h)) { | |
214 if (tipwindow == pidgin_tooltip.tipwindow) | |
215 pidgin_tooltip_destroy(); | |
216 return; | |
217 } | |
218 | |
219 setup_tooltip_window_position(data->userdata, w, h); | |
220 } | |
221 | |
222 static void | |
223 pidgin_tooltip_draw_tree(PidginTooltipData *data) | |
193 { | 224 { |
194 GtkWidget *tipwindow; | 225 GtkWidget *tipwindow; |
195 GtkTreePath *path = NULL; | 226 GtkTreePath *path = NULL; |
196 int w, h; | 227 int w, h; |
197 | 228 |
201 &path, NULL, NULL, NULL)) { | 232 &path, NULL, NULL, NULL)) { |
202 pidgin_tooltip_destroy(); | 233 pidgin_tooltip_destroy(); |
203 return; | 234 return; |
204 } | 235 } |
205 | 236 |
206 if (data->path) { | 237 if (data->common.treeview.path) { |
207 if (gtk_tree_path_compare(data->path, path) == 0) { | 238 if (gtk_tree_path_compare(data->common.treeview.path, path) == 0) { |
208 gtk_tree_path_free(path); | 239 gtk_tree_path_free(path); |
209 return; | 240 return; |
210 } | 241 } |
211 gtk_tree_path_free(data->path); | 242 gtk_tree_path_free(data->common.treeview.path); |
212 data->path = NULL; | 243 data->common.treeview.path = NULL; |
213 } | 244 } |
214 | 245 |
215 pidgin_tooltip_destroy(); | 246 pidgin_tooltip_destroy(); |
216 | 247 |
217 pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget); | 248 pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget); |
218 pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window(); | 249 pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window(); |
219 pidgin_tooltip.paint_tooltip = data->paint_tooltip; | 250 pidgin_tooltip.paint_tooltip = data->paint_tooltip; |
220 | 251 |
221 if (!data->create_tooltip(tipwindow, path, data->userdata, &w, &h)) { | 252 if (!data->common.treeview.create_tooltip(tipwindow, path, data->userdata, &w, &h)) { |
222 pidgin_tooltip_destroy(); | 253 if (tipwindow == pidgin_tooltip.tipwindow) |
254 pidgin_tooltip_destroy(); | |
223 gtk_tree_path_free(path); | 255 gtk_tree_path_free(path); |
224 return; | 256 return; |
225 } | 257 } |
226 | 258 |
227 setup_tooltip_window_position(data->userdata, w, h); | 259 setup_tooltip_window_position(data->userdata, w, h); |
228 | 260 |
229 data->path = path; | 261 data->common.treeview.path = path; |
230 g_signal_connect_swapped(G_OBJECT(tipwindow), "destroy", | 262 g_signal_connect_swapped(G_OBJECT(pidgin_tooltip.tipwindow), "destroy", |
231 G_CALLBACK(reset_data_treepath), data); | 263 G_CALLBACK(reset_data_treepath), data); |
232 } | 264 } |
233 | 265 |
234 static gboolean | 266 static gboolean |
235 pidgin_tooltip_timeout(gpointer data) | 267 pidgin_tooltip_timeout(gpointer data) |
236 { | 268 { |
269 PidginTooltipData *tdata = data; | |
237 pidgin_tooltip.timeout = 0; | 270 pidgin_tooltip.timeout = 0; |
238 pidgin_tooltip_draw(data); | 271 if (GTK_IS_TREE_VIEW(tdata->widget)) |
272 pidgin_tooltip_draw_tree(data); | |
273 else | |
274 pidgin_tooltip_draw(data); | |
239 return FALSE; | 275 return FALSE; |
240 } | 276 } |
241 | 277 |
242 static gboolean | 278 static gboolean |
243 row_motion_cb(GtkWidget *tv, GdkEventMotion *event, gpointer userdata) | 279 row_motion_cb(GtkWidget *tv, GdkEventMotion *event, gpointer userdata) |
274 | 310 |
275 return FALSE; | 311 return FALSE; |
276 } | 312 } |
277 | 313 |
278 static gboolean | 314 static gboolean |
279 row_leave_cb(GtkWidget *tv, GdkEvent *event, gpointer userdata) | 315 widget_leave_cb(GtkWidget *tv, GdkEvent *event, gpointer userdata) |
280 { | 316 { |
281 pidgin_tooltip_destroy(); | 317 pidgin_tooltip_destroy(); |
282 return FALSE; | 318 return FALSE; |
283 } | 319 } |
284 | 320 |
286 PidginTooltipCreateForTree create_tooltip, PidginTooltipPaint paint_tooltip) | 322 PidginTooltipCreateForTree create_tooltip, PidginTooltipPaint paint_tooltip) |
287 { | 323 { |
288 PidginTooltipData *tdata = g_new0(PidginTooltipData, 1); | 324 PidginTooltipData *tdata = g_new0(PidginTooltipData, 1); |
289 tdata->widget = tree; | 325 tdata->widget = tree; |
290 tdata->userdata = userdata; | 326 tdata->userdata = userdata; |
291 tdata->create_tooltip = create_tooltip; | 327 tdata->common.treeview.create_tooltip = create_tooltip; |
292 tdata->paint_tooltip = paint_tooltip; | 328 tdata->paint_tooltip = paint_tooltip; |
293 | 329 |
294 g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata); | 330 g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata); |
295 g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(row_leave_cb), NULL); | 331 g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); |
296 g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata); | 332 g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata); |
297 return TRUE; | 333 return TRUE; |
298 } | 334 } |
299 | 335 |
336 static gboolean | |
337 widget_motion_cb(GtkWidget *widget, GdkEvent *event, gpointer data) | |
338 { | |
339 int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); | |
340 | |
341 pidgin_tooltip_destroy(); | |
342 if (delay == 0) | |
343 return FALSE; | |
344 | |
345 pidgin_tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_tooltip_timeout, data); | |
346 return FALSE; | |
347 } | |
348 | |
349 gboolean pidgin_tooltip_setup_for_widget(GtkWidget *widget, gpointer userdata, | |
350 PidginTooltipCreate create_tooltip, PidginTooltipPaint paint_tooltip) | |
351 { | |
352 PidginTooltipData *wdata = g_new0(PidginTooltipData, 1); | |
353 wdata->widget = widget; | |
354 wdata->userdata = userdata; | |
355 wdata->common.widget.create_tooltip = create_tooltip; | |
356 wdata->paint_tooltip = paint_tooltip; | |
357 | |
358 g_signal_connect(G_OBJECT(widget), "motion-notify-event", G_CALLBACK(widget_motion_cb), wdata); | |
359 g_signal_connect(G_OBJECT(widget), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); | |
360 g_signal_connect_swapped(G_OBJECT(widget), "destroy", G_CALLBACK(g_free), wdata); | |
361 return TRUE; | |
362 } | |
363 |