pidgin/pidgintooltip.c

changeset 40939
bf7c5e88e5e7
parent 40496
6941fece679b
equal deleted inserted replaced
40938:1c25eac61c19 40939:bf7c5e88e5e7
40 typedef struct 40 typedef struct
41 { 41 {
42 GtkWidget *widget; 42 GtkWidget *widget;
43 gpointer userdata; 43 gpointer userdata;
44 PidginTooltipPaint paint_tooltip; 44 PidginTooltipPaint paint_tooltip;
45 union { 45 PidginTooltipCreateForTree create_tooltip;
46 struct { 46 GtkTreePath *path;
47 PidginTooltipCreateForTree create_tooltip;
48 GtkTreePath *path;
49 } treeview;
50 struct {
51 PidginTooltipCreate create_tooltip;
52 } widget;
53 } common;
54 } PidginTooltipData; 47 } PidginTooltipData;
55 48
56 static void 49 static void
57 initialize_tooltip_delay() 50 initialize_tooltip_delay()
58 { 51 {
68 } 61 }
69 62
70 static void 63 static void
71 destroy_tooltip_data(PidginTooltipData *data) 64 destroy_tooltip_data(PidginTooltipData *data)
72 { 65 {
73 if (data->common.treeview.path) 66 if (data->path) {
74 gtk_tree_path_free(data->common.treeview.path); 67 gtk_tree_path_free(data->path);
68 }
75 pidgin_tooltip_destroy(); 69 pidgin_tooltip_destroy();
76 g_free(data); 70 g_free(data);
77 } 71 }
78 72
79 void pidgin_tooltip_destroy() 73 void pidgin_tooltip_destroy()
219 } 213 }
220 214
221 static void 215 static void
222 reset_data_treepath(PidginTooltipData *data) 216 reset_data_treepath(PidginTooltipData *data)
223 { 217 {
224 gtk_tree_path_free(data->common.treeview.path); 218 gtk_tree_path_free(data->path);
225 data->common.treeview.path = NULL; 219 data->path = NULL;
226 } 220 }
227 221
228 static void 222 static gboolean
229 pidgin_tooltip_draw(PidginTooltipData *data) 223 pidgin_tooltip_timeout(gpointer userdata)
230 { 224 {
231 GtkWidget *tipwindow; 225 PidginTooltipData *data = (PidginTooltipData *)userdata;
232 int w, h;
233
234 pidgin_tooltip_destroy();
235
236 pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget);
237 pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window();
238 pidgin_tooltip.paint_tooltip = data->paint_tooltip;
239
240 if (!data->common.widget.create_tooltip(tipwindow, data->userdata, &w, &h)) {
241 if (tipwindow == pidgin_tooltip.tipwindow)
242 pidgin_tooltip_destroy();
243 return;
244 }
245
246 setup_tooltip_window_position(data->userdata, w, h);
247 }
248
249 static void
250 pidgin_tooltip_draw_tree(PidginTooltipData *data)
251 {
252 GtkWidget *tipwindow; 226 GtkWidget *tipwindow;
253 GtkTreePath *path = NULL; 227 GtkTreePath *path = NULL;
254 int w, h; 228 int w, h;
229
230 pidgin_tooltip.timeout = 0;
255 231
256 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(data->widget), 232 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(data->widget),
257 pidgin_tooltip.tip_rect.x, 233 pidgin_tooltip.tip_rect.x,
258 pidgin_tooltip.tip_rect.y + (pidgin_tooltip.tip_rect.height/2), 234 pidgin_tooltip.tip_rect.y + (pidgin_tooltip.tip_rect.height/2),
259 &path, NULL, NULL, NULL)) { 235 &path, NULL, NULL, NULL)) {
260 pidgin_tooltip_destroy(); 236 pidgin_tooltip_destroy();
261 return; 237 return FALSE;
262 } 238 }
263 239
264 if (data->common.treeview.path) { 240 if (data->path) {
265 if (gtk_tree_path_compare(data->common.treeview.path, path) == 0) { 241 if (gtk_tree_path_compare(data->path, path) == 0) {
266 gtk_tree_path_free(path); 242 gtk_tree_path_free(path);
267 return; 243 return FALSE;
268 } 244 }
269 gtk_tree_path_free(data->common.treeview.path); 245 gtk_tree_path_free(data->path);
270 data->common.treeview.path = NULL; 246 data->path = NULL;
271 } 247 }
272 248
273 pidgin_tooltip_destroy(); 249 pidgin_tooltip_destroy();
274 250
275 pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget); 251 pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget);
276 pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window(); 252 pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window();
277 pidgin_tooltip.paint_tooltip = data->paint_tooltip; 253 pidgin_tooltip.paint_tooltip = data->paint_tooltip;
278 254
279 if (!data->common.treeview.create_tooltip(tipwindow, path, data->userdata, &w, &h)) { 255 if (!data->create_tooltip(tipwindow, path, data->userdata, &w, &h)) {
280 if (tipwindow == pidgin_tooltip.tipwindow) 256 if (tipwindow == pidgin_tooltip.tipwindow)
281 pidgin_tooltip_destroy(); 257 pidgin_tooltip_destroy();
282 gtk_tree_path_free(path); 258 gtk_tree_path_free(path);
283 return; 259 return FALSE;
284 } 260 }
285 261
286 setup_tooltip_window_position(data->userdata, w, h); 262 setup_tooltip_window_position(data->userdata, w, h);
287 263
288 data->common.treeview.path = path; 264 data->path = path;
289 g_signal_connect_swapped(G_OBJECT(pidgin_tooltip.tipwindow), "destroy", 265 g_signal_connect_swapped(G_OBJECT(pidgin_tooltip.tipwindow), "destroy",
290 G_CALLBACK(reset_data_treepath), data); 266 G_CALLBACK(reset_data_treepath), data);
291 } 267
292
293 static gboolean
294 pidgin_tooltip_timeout(gpointer data)
295 {
296 PidginTooltipData *tdata = data;
297 pidgin_tooltip.timeout = 0;
298 if (GTK_IS_TREE_VIEW(tdata->widget))
299 pidgin_tooltip_draw_tree(data);
300 else
301 pidgin_tooltip_draw(data);
302 return FALSE; 268 return FALSE;
303 } 269 }
304 270
305 static gboolean 271 static gboolean
306 row_motion_cb(GtkWidget *tv, GdkEventMotion *event, gpointer userdata) 272 row_motion_cb(GtkWidget *tv, GdkEventMotion *event, gpointer userdata)
347 PidginTooltipCreateForTree create_tooltip, PidginTooltipPaint paint_tooltip) 313 PidginTooltipCreateForTree create_tooltip, PidginTooltipPaint paint_tooltip)
348 { 314 {
349 PidginTooltipData *tdata = g_new0(PidginTooltipData, 1); 315 PidginTooltipData *tdata = g_new0(PidginTooltipData, 1);
350 tdata->widget = tree; 316 tdata->widget = tree;
351 tdata->userdata = userdata; 317 tdata->userdata = userdata;
352 tdata->common.treeview.create_tooltip = create_tooltip; 318 tdata->create_tooltip = create_tooltip;
353 tdata->paint_tooltip = paint_tooltip; 319 tdata->paint_tooltip = paint_tooltip;
354 320
355 g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata); 321 g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata);
356 g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); 322 g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL);
357 g_signal_connect(G_OBJECT(tree), "scroll-event", G_CALLBACK(widget_leave_cb), NULL); 323 g_signal_connect(G_OBJECT(tree), "scroll-event", G_CALLBACK(widget_leave_cb), NULL);
358 g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata); 324 g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata);
359 return TRUE; 325 return TRUE;
360 } 326 }
361
362 static gboolean
363 widget_motion_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
364 {
365 initialize_tooltip_delay();
366
367 pidgin_tooltip_destroy();
368 if (!enable_tooltips)
369 return FALSE;
370
371 pidgin_tooltip.timeout = g_timeout_add(tooltip_delay, (GSourceFunc)pidgin_tooltip_timeout, data);
372 return FALSE;
373 }
374
375 gboolean pidgin_tooltip_setup_for_widget(GtkWidget *widget, gpointer userdata,
376 PidginTooltipCreate create_tooltip, PidginTooltipPaint paint_tooltip)
377 {
378 PidginTooltipData *wdata = g_new0(PidginTooltipData, 1);
379 wdata->widget = widget;
380 wdata->userdata = userdata;
381 wdata->common.widget.create_tooltip = create_tooltip;
382 wdata->paint_tooltip = paint_tooltip;
383
384 g_signal_connect(G_OBJECT(widget), "motion-notify-event", G_CALLBACK(widget_motion_cb), wdata);
385 g_signal_connect(G_OBJECT(widget), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL);
386 g_signal_connect(G_OBJECT(widget), "scroll-event", G_CALLBACK(widget_leave_cb), NULL);
387 g_signal_connect_swapped(G_OBJECT(widget), "destroy", G_CALLBACK(destroy_tooltip_data), wdata);
388 return TRUE;
389 }
390

mercurial