Mercurial > pidgin.yaz
changeset 21945:3fc5862b834a
Use the new tooltip functions to draw the tooltips in the conversation window.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Fri, 28 Dec 2007 01:38:41 +0000 |
parents | c2c66ffcdfa7 |
children | ddd53c9174bc |
files | ChangeLog.API pidgin/gtkblist.c pidgin/gtkconv.c pidgin/gtkroomlist.c pidgin/pidgintooltip.c pidgin/pidgintooltip.h |
diffstat | 6 files changed, 147 insertions(+), 161 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog.API Thu Dec 27 16:29:58 2007 +0000 +++ b/ChangeLog.API Fri Dec 28 01:38:41 2007 +0000 @@ -21,8 +21,9 @@ smileys in the text. (Florian 'goutnet' Delizy) * pidgin_auto_parent_window to make a window transient for a suitable parent window. - * pidgin_tooltip_setup_for_treeview, pidgin_tooltip_destroy and - pidgin_tooltip_show to simplify the process of drawing tooltips. + * pidgin_tooltip_setup_for_treeview, pidgin_tooltip_destroy, + pidgin_tooltip_show and pidgin_tooltip_setup_for_widget to simplify + the process of drawing tooltips. Finch: libgnt:
--- a/pidgin/gtkblist.c Thu Dec 27 16:29:58 2007 +0000 +++ b/pidgin/gtkblist.c Fri Dec 28 01:38:41 2007 +0000 @@ -2659,8 +2659,6 @@ return FALSE; style = gtkblist->tipwindow->style; - gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, - NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); max_text_width = 0; max_avatar_width = 0; @@ -2707,6 +2705,7 @@ gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); } + if(td->avatar) { if (dir == GTK_TEXT_DIR_RTL) gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, @@ -2717,7 +2716,7 @@ current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); } - if (!td->avatar_is_prpl_icon) + if (!td->avatar_is_prpl_icon && td->prpl_icon) gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->prpl_icon, 0, 0, prpl_col, @@ -2792,6 +2791,11 @@ PurpleBlistNode *node = data; int width, height; + if (gtkblist->tooltipdata) { + gtkblist->tipwindow = NULL; + pidgin_blist_destroy_tooltip_data(); + } + gtkblist->tipwindow = widget; if(PURPLE_BLIST_NODE_IS_CHAT(node) || PURPLE_BLIST_NODE_IS_BUDDY(node) ||
--- a/pidgin/gtkconv.c Thu Dec 27 16:29:58 2007 +0000 +++ b/pidgin/gtkconv.c Fri Dec 28 01:38:41 2007 +0000 @@ -67,6 +67,7 @@ #include "gtkthemes.h" #include "gtkutils.h" #include "pidginstock.h" +#include "pidgintooltip.h" #include "gtknickcolors.h" @@ -164,8 +165,6 @@ static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); -static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv); -static gboolean pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv); static void hide_conv(PidginConversation *gtkconv, gboolean closetimer); static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, @@ -4434,6 +4433,36 @@ } } +static gboolean +pidgin_conv_userlist_create_tooltip(GtkWidget *tipwindow, GtkTreePath *path, + gpointer userdata, int *w, int *h) +{ + PidginConversation *gtkconv = userdata; + GtkTreeIter iter; + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list)); + PurpleConversation *conv = gtkconv->active_conv; + PurpleBlistNode *node; + PurplePluginProtocolInfo *prpl_info; + PurpleAccount *account = purple_conversation_get_account(conv); + char *who = NULL; + + if (account->gc == NULL) + return FALSE; + + if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)) + return FALSE; + + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); + + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl); + node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who)); + if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) + pidgin_blist_draw_tooltip(node, gtkconv->infopane); + + g_free(who); + return FALSE; +} + static void setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned) { @@ -4488,14 +4517,13 @@ g_signal_connect(G_OBJECT(list), "button_press_event", G_CALLBACK(right_click_chat_cb), gtkconv); - g_signal_connect(G_OBJECT(list), "motion-notify-event", - G_CALLBACK(pidgin_userlist_motion_cb), gtkconv); - g_signal_connect(G_OBJECT(list), "leave-notify-event", - G_CALLBACK(pidgin_conv_leave_cb), gtkconv); g_signal_connect(G_OBJECT(list), "popup-menu", G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); + pidgin_tooltip_setup_for_treeview(list, gtkconv, + pidgin_conv_userlist_create_tooltip, NULL); + rend = gtk_cell_renderer_text_new(); g_object_set(rend, "foreground-set", TRUE, @@ -4531,32 +4559,12 @@ gtk_container_add(GTK_CONTAINER(sw), list); } -/* Stuff used to display tooltips on the infopane */ -static struct { - int timeout; - PidginConversation *gtkconv; /* This is the Pidgin conversation that - triggered the tooltip */ - int userlistx; - int userlisty; -} tooltip; - -static void -reset_tooltip() -{ - if (tooltip.timeout != 0) { - g_source_remove(tooltip.timeout); - tooltip.timeout = 0; - } - tooltip.gtkconv = NULL; -} - static gboolean -pidgin_conv_tooltip_timeout(PidginConversation *gtkconv) +pidgin_conv_create_tooltip(GtkWidget *tipwindow, gpointer userdata, int *w, int *h) { PurpleBlistNode *node = NULL; PurpleConversation *conv; - - g_return_val_if_fail (tooltip.gtkconv == gtkconv, FALSE); + PidginConversation *gtkconv = userdata; conv = gtkconv->active_conv; if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { @@ -4579,103 +4587,6 @@ return FALSE; } -static gboolean -pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv) -{ - pidgin_blist_tooltip_destroy(); - reset_tooltip(); - return FALSE; -} - -static gboolean -pidgin_conv_motion_cb (GtkWidget *infopane, GdkEventMotion *event, PidginConversation *gtkconv) -{ - int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); - - pidgin_blist_tooltip_destroy(); - if (delay == 0) - return FALSE; - - if (tooltip.timeout != 0) - g_source_remove(tooltip.timeout); - - tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_conv_tooltip_timeout, gtkconv); - tooltip.gtkconv = gtkconv; - return FALSE; -} - -static gboolean -pidgin_userlist_tooltip_timeout(PidginConversation *gtkconv) -{ - PurplePluginProtocolInfo *prpl_info; - PurpleConversation *conv = gtkconv->active_conv; - PidginChatPane *gtkchat; - PurpleBlistNode *node = NULL; - PurpleAccount *account; - GtkTreePath *path; - GtkTreeIter iter; - GtkTreeModel *model; - GtkTreeViewColumn *column; - gchar *who; - int x, y; - - gtkchat = gtkconv->u.chat; - account = purple_conversation_get_account(conv); - - if (account->gc == NULL) - return FALSE; - - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl); - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); - - if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), - tooltip.userlistx, tooltip.userlisty, &path, &column, &x, &y)) - return FALSE; - - gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); - gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); - - node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who)); - if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) - pidgin_blist_draw_tooltip(node, gtkconv->infopane); - - g_free(who); - gtk_tree_path_free(path); - - - return FALSE; -} - -static gboolean -pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv) -{ - PurpleConversation *conv; - PurpleAccount *account; - int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); - - pidgin_blist_tooltip_destroy(); - if (delay == 0) - return FALSE; - - if (tooltip.timeout != 0) - g_source_remove(tooltip.timeout); - tooltip.timeout = 0; - - conv = gtkconv->active_conv; - account = purple_conversation_get_account(conv); - - if (account->gc == NULL) - return FALSE; - - tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_userlist_tooltip_timeout, gtkconv); - tooltip.gtkconv = gtkconv; - tooltip.userlistx = event->x; - tooltip.userlisty = event->y; - - return FALSE; -} - static GtkWidget * setup_common_pane(PidginConversation *gtkconv) { @@ -4705,10 +4616,8 @@ g_signal_connect(G_OBJECT(event_box), "button-press-event", G_CALLBACK(infopane_press_cb), gtkconv); - g_signal_connect(G_OBJECT(event_box), "motion-notify-event", - G_CALLBACK(pidgin_conv_motion_cb), gtkconv); - g_signal_connect(G_OBJECT(event_box), "leave-notify-event", - G_CALLBACK(pidgin_conv_leave_cb), gtkconv); + pidgin_tooltip_setup_for_widget(event_box, gtkconv, + pidgin_conv_create_tooltip, NULL); gtkconv->infopane = gtk_cell_view_new(); gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); @@ -5214,9 +5123,6 @@ g_source_remove(gtkconv->attach.timer); } - if (tooltip.gtkconv == gtkconv) - reset_tooltip(); - g_free(gtkconv); } @@ -6925,10 +6831,8 @@ GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); g_signal_connect(G_OBJECT(event), "button-press-event", G_CALLBACK(icon_menu), gtkconv); - g_signal_connect(G_OBJECT(event), "motion-notify-event", - G_CALLBACK(pidgin_conv_motion_cb), gtkconv); - g_signal_connect(G_OBJECT(event), "leave-notify-event", - G_CALLBACK(pidgin_conv_leave_cb), gtkconv); + + pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL); gtk_widget_show(event); gtkconv->u.im->icon = gtk_image_new_from_pixbuf(scale);
--- a/pidgin/gtkroomlist.c Thu Dec 27 16:29:58 2007 +0000 +++ b/pidgin/gtkroomlist.c Fri Dec 28 01:38:41 2007 +0000 @@ -356,8 +356,6 @@ GtkTextDirection dir = gtk_widget_get_direction(GTK_WIDGET(grl->tree)); style = grl->tipwindow->style; - gtk_paint_flat_box(style, grl->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, - NULL, grl->tipwindow, "tooltip", 0, 0, -1, -1); max_text_width = 0;
--- a/pidgin/pidgintooltip.c Thu Dec 27 16:29:58 2007 +0000 +++ b/pidgin/pidgintooltip.c Fri Dec 28 01:38:41 2007 +0000 @@ -43,15 +43,22 @@ { GtkWidget *widget; gpointer userdata; - PidginTooltipCreateForTree create_tooltip; PidginTooltipPaint paint_tooltip; - GtkTreePath *path; + union { + struct { + PidginTooltipCreateForTree create_tooltip; + GtkTreePath *path; + } treeview; + struct { + PidginTooltipCreate create_tooltip; + } widget; + } common; } PidginTooltipData; static void destroy_tooltip_data(PidginTooltipData *data) { - gtk_tree_path_free(data->path); + gtk_tree_path_free(data->common.treeview.path); g_free(data); } @@ -70,8 +77,11 @@ static gboolean pidgin_tooltip_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { - if (pidgin_tooltip.paint_tooltip) + if (pidgin_tooltip.paint_tooltip) { + gtk_paint_flat_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, + NULL, widget, "tooltip", 0, 0, -1, -1); pidgin_tooltip.paint_tooltip(widget, data); + } return FALSE; } @@ -184,14 +194,35 @@ static void reset_data_treepath(PidginTooltipData *data) { - gtk_tree_path_free(data->path); - data->path = NULL; + gtk_tree_path_free(data->common.treeview.path); + data->common.treeview.path = NULL; } static void pidgin_tooltip_draw(PidginTooltipData *data) { GtkWidget *tipwindow; + int w, h; + + pidgin_tooltip_destroy(); + + pidgin_tooltip.widget = gtk_widget_get_toplevel(data->widget); + pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window(); + pidgin_tooltip.paint_tooltip = data->paint_tooltip; + + if (!data->common.widget.create_tooltip(tipwindow, data->userdata, &w, &h)) { + if (tipwindow == pidgin_tooltip.tipwindow) + pidgin_tooltip_destroy(); + return; + } + + setup_tooltip_window_position(data->userdata, w, h); +} + +static void +pidgin_tooltip_draw_tree(PidginTooltipData *data) +{ + GtkWidget *tipwindow; GtkTreePath *path = NULL; int w, h; @@ -203,13 +234,13 @@ return; } - if (data->path) { - if (gtk_tree_path_compare(data->path, path) == 0) { + if (data->common.treeview.path) { + if (gtk_tree_path_compare(data->common.treeview.path, path) == 0) { gtk_tree_path_free(path); return; } - gtk_tree_path_free(data->path); - data->path = NULL; + gtk_tree_path_free(data->common.treeview.path); + data->common.treeview.path = NULL; } pidgin_tooltip_destroy(); @@ -218,24 +249,29 @@ pidgin_tooltip.tipwindow = tipwindow = setup_tooltip_window(); pidgin_tooltip.paint_tooltip = data->paint_tooltip; - if (!data->create_tooltip(tipwindow, path, data->userdata, &w, &h)) { - pidgin_tooltip_destroy(); + if (!data->common.treeview.create_tooltip(tipwindow, path, data->userdata, &w, &h)) { + if (tipwindow == pidgin_tooltip.tipwindow) + pidgin_tooltip_destroy(); gtk_tree_path_free(path); return; } setup_tooltip_window_position(data->userdata, w, h); - data->path = path; - g_signal_connect_swapped(G_OBJECT(tipwindow), "destroy", + data->common.treeview.path = path; + g_signal_connect_swapped(G_OBJECT(pidgin_tooltip.tipwindow), "destroy", G_CALLBACK(reset_data_treepath), data); } static gboolean pidgin_tooltip_timeout(gpointer data) { + PidginTooltipData *tdata = data; pidgin_tooltip.timeout = 0; - pidgin_tooltip_draw(data); + if (GTK_IS_TREE_VIEW(tdata->widget)) + pidgin_tooltip_draw_tree(data); + else + pidgin_tooltip_draw(data); return FALSE; } @@ -276,7 +312,7 @@ } static gboolean -row_leave_cb(GtkWidget *tv, GdkEvent *event, gpointer userdata) +widget_leave_cb(GtkWidget *tv, GdkEvent *event, gpointer userdata) { pidgin_tooltip_destroy(); return FALSE; @@ -288,12 +324,40 @@ PidginTooltipData *tdata = g_new0(PidginTooltipData, 1); tdata->widget = tree; tdata->userdata = userdata; - tdata->create_tooltip = create_tooltip; + tdata->common.treeview.create_tooltip = create_tooltip; tdata->paint_tooltip = paint_tooltip; g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata); - g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(row_leave_cb), NULL); + g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata); return TRUE; } +static gboolean +widget_motion_cb(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); + + pidgin_tooltip_destroy(); + if (delay == 0) + return FALSE; + + pidgin_tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_tooltip_timeout, data); + return FALSE; +} + +gboolean pidgin_tooltip_setup_for_widget(GtkWidget *widget, gpointer userdata, + PidginTooltipCreate create_tooltip, PidginTooltipPaint paint_tooltip) +{ + PidginTooltipData *wdata = g_new0(PidginTooltipData, 1); + wdata->widget = widget; + wdata->userdata = userdata; + wdata->common.widget.create_tooltip = create_tooltip; + wdata->paint_tooltip = paint_tooltip; + + g_signal_connect(G_OBJECT(widget), "motion-notify-event", G_CALLBACK(widget_motion_cb), wdata); + g_signal_connect(G_OBJECT(widget), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); + g_signal_connect_swapped(G_OBJECT(widget), "destroy", G_CALLBACK(g_free), wdata); + return TRUE; +} +
--- a/pidgin/pidgintooltip.h Thu Dec 27 16:29:58 2007 +0000 +++ b/pidgin/pidgintooltip.h Fri Dec 28 01:38:41 2007 +0000 @@ -77,6 +77,20 @@ PidginTooltipCreateForTree create_cb, PidginTooltipPaint paint_cb); /** + * Setup tooltip drawing functions for any widget. + * + * @param widget The widget + * @param userdata The userdata to send to the callback functions + * @param create_cb Callback function to create the tooltip for the widget + * @param paint_cb Callback function to paint the tooltip + * + * @return @c TRUE if the tooltip callbacks were setup correctly. + * @since 2.4.0 + */ +gboolean pidgin_tooltip_setup_for_widget(GtkWidget *widget, gpointer userdata, + PidginTooltipCreate create_tooltip, PidginTooltipPaint paint_tooltip); + +/** * Destroy the tooltip. * @since 2.4.0 */ @@ -94,4 +108,5 @@ */ void pidgin_tooltip_show(GtkWidget *widget, gpointer userdata, PidginTooltipCreate create_cb, PidginTooltipPaint paint_cb); + #endif