im.pidgin.pidgin: b7ae28ad92ca5e196b41a7357f4a185b3dd99bd6
sadrul at pidgin.im
sadrul at pidgin.im
Thu Dec 27 20:55:54 EST 2007
-----------------------------------------------------------------
Revision: b7ae28ad92ca5e196b41a7357f4a185b3dd99bd6
Ancestor: 561d7f407332ec3fa6e4ab58c85a3bc7a2f2d8b7
Author: sadrul at pidgin.im
Date: 2007-12-28T01:38:41
Branch: im.pidgin.pidgin
Modified files:
ChangeLog.API pidgin/gtkblist.c pidgin/gtkconv.c
pidgin/gtkroomlist.c pidgin/pidgintooltip.c
pidgin/pidgintooltip.h
ChangeLog:
Use the new tooltip functions to draw the tooltips in the conversation window.
-------------- next part --------------
============================================================
--- ChangeLog.API c6e4a44408dd86cfd6b5862214f98650de372d34
+++ ChangeLog.API 1eed46b5a8c1f238af7e6e4066bc78be353bf89e
@@ -21,8 +21,9 @@ version 2.4.0 (??/??/????):
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:
============================================================
--- pidgin/gtkblist.c 590fca78d5a5b0bc0b4ce04d5a2ae08efb2ee88c
+++ pidgin/gtkblist.c 2bbbdbe2e5f44a3223a0cfcb79bb5fa293b97136
@@ -2659,8 +2659,6 @@ pidgin_blist_paint_tip(GtkWidget *widget
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 @@ pidgin_blist_paint_tip(GtkWidget *widget
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 @@ pidgin_blist_paint_tip(GtkWidget *widget
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 @@ pidgin_blist_create_tooltip_for_node(Gtk
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) ||
============================================================
--- pidgin/gtkconv.c 55d4da1507970e28e2f50016a532c810205c5193
+++ pidgin/gtkconv.c cc83e9254ea60579bb4299f8988ef028f4bd0fcf
@@ -67,6 +67,7 @@
#include "gtkthemes.h"
#include "gtkutils.h"
#include "pidginstock.h"
+#include "pidgintooltip.h"
#include "gtknickcolors.h"
@@ -164,8 +165,6 @@ static gboolean infopane_press_cb(GtkWid
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 @@ setup_chat_topic(PidginConversation *gtk
}
}
+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 @@ setup_chat_userlist(PidginConversation *
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,33 +4559,13 @@ setup_chat_userlist(PidginConversation *
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;
+ PidginConversation *gtkconv = userdata;
- g_return_val_if_fail (tooltip.gtkconv == gtkconv, FALSE);
-
conv = gtkconv->active_conv;
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name));
@@ -4579,103 +4587,6 @@ pidgin_conv_tooltip_timeout(PidginConver
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 @@ setup_common_pane(PidginConversation *gt
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 @@ pidgin_conv_destroy(PurpleConversation *
g_source_remove(gtkconv->attach.timer);
}
- if (tooltip.gtkconv == gtkconv)
- reset_tooltip();
-
g_free(gtkconv);
}
@@ -6925,10 +6831,8 @@ pidgin_conv_update_buddy_icon(PurpleConv
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);
============================================================
--- pidgin/gtkroomlist.c ef8ddcc7b918edb4d17e12007a002b0fe904beaa
+++ pidgin/gtkroomlist.c b867cc15dd6f9308170b1df530f7d985be65b152
@@ -356,8 +356,6 @@ pidgin_roomlist_paint_tooltip(GtkWidget
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;
============================================================
--- pidgin/pidgintooltip.c cd6a6fa0dffab80b474d0b30b5c521c3893ffad1
+++ pidgin/pidgintooltip.c 319c94ffce55c8ae998dfcfc646eb80e7133f7bc
@@ -43,15 +43,22 @@ typedef struct
{
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 @@ pidgin_tooltip_expose_event(GtkWidget *w
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 @@ reset_data_treepath(PidginTooltipData *d
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 @@ pidgin_tooltip_draw(PidginTooltipData *d
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_draw(PidginTooltipData *d
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
}
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 @@ gboolean pidgin_tooltip_setup_for_treevi
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;
+}
+
============================================================
--- pidgin/pidgintooltip.h bbed4651d99afbdcce545469a0798617b8da5844
+++ pidgin/pidgintooltip.h d62c7d559246acccd89e0fc2c1e59d7c4603b8c4
@@ -77,6 +77,20 @@ gboolean pidgin_tooltip_setup_for_treevi
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 *widg
*/
void pidgin_tooltip_show(GtkWidget *widget, gpointer userdata,
PidginTooltipCreate create_cb, PidginTooltipPaint paint_cb);
+
#endif
More information about the Commits
mailing list