Mercurial > pidgin
comparison gtk/gtkblist.c @ 15238:ea246204cf36
[gaim-migrate @ 18028]
Draw a small "close-button" in the buddylist-headline when the cursor is moved
over it. I was drawing the close button all the time first, but showing it only
on hover seemed like a better idea.
Clicking the close-button will close the headline box without triggering the
callback.
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Wed, 20 Dec 2006 09:28:29 +0000 |
parents | 01fec6defb33 |
children | ebe19ec7c78c |
comparison
equal
deleted
inserted
replaced
15237:658f815e2b58 | 15238:ea246204cf36 |
---|---|
59 | 59 |
60 #include <gdk/gdkkeysyms.h> | 60 #include <gdk/gdkkeysyms.h> |
61 #include <gtk/gtk.h> | 61 #include <gtk/gtk.h> |
62 #include <gdk/gdk.h> | 62 #include <gdk/gdk.h> |
63 | 63 |
64 #define HEADLINE_CLOSE_SIZE 12 | |
65 | |
64 typedef struct | 66 typedef struct |
65 { | 67 { |
66 GaimAccount *account; | 68 GaimAccount *account; |
67 | 69 |
68 GtkWidget *window; | 70 GtkWidget *window; |
266 gaim_prefs_set_int("/gaim/gtk/blist/x", x); | 268 gaim_prefs_set_int("/gaim/gtk/blist/x", x); |
267 gaim_prefs_set_int("/gaim/gtk/blist/y", y); | 269 gaim_prefs_set_int("/gaim/gtk/blist/y", y); |
268 gaim_prefs_set_int("/gaim/gtk/blist/width", event->width); | 270 gaim_prefs_set_int("/gaim/gtk/blist/width", event->width); |
269 gaim_prefs_set_int("/gaim/gtk/blist/height", event->height); | 271 gaim_prefs_set_int("/gaim/gtk/blist/height", event->height); |
270 | 272 |
273 gtk_widget_set_size_request(gtkblist->headline_label, | |
274 gaim_prefs_get_int("/gaim/gtk/blist/width")-25,-1); | |
271 /* continue to handle event normally */ | 275 /* continue to handle event normally */ |
272 return FALSE; | 276 return FALSE; |
273 } | 277 } |
274 | 278 |
275 static void gtk_blist_menu_info_cb(GtkWidget *w, GaimBuddy *b) | 279 static void gtk_blist_menu_info_cb(GtkWidget *w, GaimBuddy *b) |
3671 return TRUE; | 3675 return TRUE; |
3672 return FALSE; | 3676 return FALSE; |
3673 } | 3677 } |
3674 | 3678 |
3675 static gboolean | 3679 static gboolean |
3680 headline_hover_close(int x, int y) | |
3681 { | |
3682 GtkWidget *w = gtkblist->headline_hbox; | |
3683 if (x <= w->allocation.width && x >= w->allocation.width - HEADLINE_CLOSE_SIZE && | |
3684 y >= 0 && y <= HEADLINE_CLOSE_SIZE) | |
3685 return TRUE; | |
3686 return FALSE; | |
3687 } | |
3688 | |
3689 static gboolean | |
3676 headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, GaimGtkBuddyList *gtkblist) | 3690 headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, GaimGtkBuddyList *gtkblist) |
3677 { | 3691 { |
3678 gdk_window_set_cursor(widget->window, gtkblist->hand_cursor); | 3692 gdk_window_set_cursor(widget->window, gtkblist->hand_cursor); |
3693 | |
3694 if (gtkblist->headline_close) { | |
3695 #if GTK_CHECK_VERSION(2,2,0) | |
3696 gdk_draw_pixbuf(widget->window, NULL, gtkblist->headline_close, | |
3697 #else | |
3698 gdk_pixbuf_render_to_drawable(gtkblist->headline_close, | |
3699 GDK_DRAWABLE(widget->window), NULL, | |
3700 #endif | |
3701 0, 0, | |
3702 widget->allocation.width - 2 - HEADLINE_CLOSE_SIZE, 2, | |
3703 HEADLINE_CLOSE_SIZE, HEADLINE_CLOSE_SIZE, | |
3704 GDK_RGB_DITHER_NONE, 0, 0); | |
3705 gtk_paint_focus(widget->style, widget->window, GTK_STATE_PRELIGHT, | |
3706 NULL, widget, NULL, | |
3707 widget->allocation.width - HEADLINE_CLOSE_SIZE - 3, 1, | |
3708 HEADLINE_CLOSE_SIZE + 2, HEADLINE_CLOSE_SIZE + 2); | |
3709 } | |
3710 | |
3679 return FALSE; | 3711 return FALSE; |
3680 } | 3712 } |
3713 | |
3714 #if 0 | |
3715 static gboolean | |
3716 headline_box_motion_cb(GtkWidget *widget, GdkEventMotion *event, GaimGtkBuddyList *gtkblist) | |
3717 { | |
3718 gaim_debug_fatal("motion", "%d %d\n", (int)event->x, (int)event->y); | |
3719 if (headline_hover_close((int)event->x, (int)event->y)) | |
3720 gtk_paint_focus(widget->style, widget->window, GTK_STATE_PRELIGHT, | |
3721 NULL, widget, NULL, | |
3722 widget->allocation.width - HEADLINE_CLOSE_SIZE - 3, 1, | |
3723 HEADLINE_CLOSE_SIZE + 2, HEADLINE_CLOSE_SIZE + 2); | |
3724 return FALSE; | |
3725 } | |
3726 #endif | |
3681 | 3727 |
3682 static gboolean | 3728 static gboolean |
3683 headline_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, GaimGtkBuddyList *gtkblist) | 3729 headline_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, GaimGtkBuddyList *gtkblist) |
3684 { | 3730 { |
3685 gdk_window_set_cursor(widget->window, gtkblist->arrow_cursor); | 3731 gdk_window_set_cursor(widget->window, gtkblist->arrow_cursor); |
3732 if (gtkblist->headline_close) { | |
3733 GdkRectangle rect = {widget->allocation.width - 3 - HEADLINE_CLOSE_SIZE, 1, | |
3734 HEADLINE_CLOSE_SIZE + 2, HEADLINE_CLOSE_SIZE + 2}; | |
3735 gdk_window_invalidate_rect(widget->window, &rect, TRUE); | |
3736 } | |
3686 return FALSE; | 3737 return FALSE; |
3687 } | 3738 } |
3688 | 3739 |
3689 static gboolean | 3740 static gboolean |
3690 headline_click_callback(gpointer data) | 3741 headline_click_callback(gpointer data) |
3695 | 3746 |
3696 static gboolean | 3747 static gboolean |
3697 headline_box_press_cb(GtkWidget *widget, GdkEventButton *event, GaimGtkBuddyList *gtkblist) | 3748 headline_box_press_cb(GtkWidget *widget, GdkEventButton *event, GaimGtkBuddyList *gtkblist) |
3698 { | 3749 { |
3699 gtk_widget_hide(gtkblist->headline_hbox); | 3750 gtk_widget_hide(gtkblist->headline_hbox); |
3700 if (gtkblist->headline_callback) | 3751 if (gtkblist->headline_callback && !headline_hover_close((int)event->x, (int)event->y)) |
3701 g_idle_add((GSourceFunc)headline_click_callback, gtkblist->headline_data); | 3752 g_idle_add((GSourceFunc)headline_click_callback, gtkblist->headline_data); |
3702 return TRUE; | 3753 return TRUE; |
3703 } | 3754 } |
3704 | 3755 |
3705 /***********************************/ | 3756 /***********************************/ |
3822 } | 3873 } |
3823 | 3874 |
3824 static gboolean | 3875 static gboolean |
3825 paint_headline_hbox (GtkWidget *widget, | 3876 paint_headline_hbox (GtkWidget *widget, |
3826 GdkEventExpose *event, | 3877 GdkEventExpose *event, |
3827 gpointer user_data) | 3878 gpointer user_data) |
3828 { | 3879 { |
3829 gtk_paint_flat_box (widget->style, | 3880 gtk_paint_flat_box (widget->style, |
3830 widget->window, | 3881 widget->window, |
3831 GTK_STATE_NORMAL, | 3882 GTK_STATE_NORMAL, |
3832 GTK_SHADOW_OUT, | 3883 GTK_SHADOW_OUT, |
3833 NULL, | 3884 NULL, |
3834 widget, | 3885 widget, |
3835 "tooltip", | 3886 "tooltip", |
3836 widget->allocation.x + 1, | 3887 widget->allocation.x + 1, |
3837 widget->allocation.y + 1, | 3888 widget->allocation.y + 1, |
3838 widget->allocation.width - 2, | 3889 widget->allocation.width - 2, |
3839 widget->allocation.height - 2); | 3890 widget->allocation.height - 2); |
3840 | 3891 return FALSE; |
3841 return FALSE; | |
3842 } | 3892 } |
3843 | 3893 |
3844 static void | 3894 static void |
3845 headline_style_set (GtkWidget *widget, | 3895 headline_style_set (GtkWidget *widget, |
3846 GtkStyle *prev_style) | 3896 GtkStyle *prev_style) |
4042 "expose_event", | 4092 "expose_event", |
4043 G_CALLBACK (paint_headline_hbox), | 4093 G_CALLBACK (paint_headline_hbox), |
4044 NULL); | 4094 NULL); |
4045 gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips"); | 4095 gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips"); |
4046 | 4096 |
4097 gtkblist->headline_close = gtk_widget_render_icon(ebox, GTK_STOCK_CLOSE, -1, NULL); | |
4098 if (gtkblist->headline_close) { | |
4099 GdkPixbuf *scale = gdk_pixbuf_scale_simple(gtkblist->headline_close, | |
4100 HEADLINE_CLOSE_SIZE, HEADLINE_CLOSE_SIZE, GDK_INTERP_BILINEAR); | |
4101 gdk_pixbuf_unref(gtkblist->headline_close); | |
4102 gtkblist->headline_close = scale; | |
4103 } | |
4104 | |
4047 gtkblist->hand_cursor = gdk_cursor_new (GDK_HAND2); | 4105 gtkblist->hand_cursor = gdk_cursor_new (GDK_HAND2); |
4048 gtkblist->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); | 4106 gtkblist->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); |
4107 | |
4049 g_signal_connect(G_OBJECT(ebox), "enter-notify-event", G_CALLBACK(headline_box_enter_cb), gtkblist); | 4108 g_signal_connect(G_OBJECT(ebox), "enter-notify-event", G_CALLBACK(headline_box_enter_cb), gtkblist); |
4050 g_signal_connect(G_OBJECT(ebox), "leave-notify-event", G_CALLBACK(headline_box_leave_cb), gtkblist); | 4109 g_signal_connect(G_OBJECT(ebox), "leave-notify-event", G_CALLBACK(headline_box_leave_cb), gtkblist); |
4051 g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(headline_box_press_cb), gtkblist); | 4110 g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(headline_box_press_cb), gtkblist); |
4111 #if 0 | |
4112 /* I couldn't get this to work. The idea was to draw the focus-border only | |
4113 * when hovering over the close image. So for now, the focus-border is | |
4114 * always there. -- sad */ | |
4115 gtk_widget_set_events(ebox, gtk_widget_get_events(ebox) | GDK_POINTER_MOTION_HINT_MASK); | |
4116 g_signal_connect(G_OBJECT(ebox), "motion-notify-event", G_CALLBACK(headline_box_motion_cb), gtkblist); | |
4117 #endif | |
4052 | 4118 |
4053 /****************************** GtkTreeView **********************************/ | 4119 /****************************** GtkTreeView **********************************/ |
4054 sw = gtk_scrolled_window_new(NULL,NULL); | 4120 sw = gtk_scrolled_window_new(NULL,NULL); |
4055 gtk_widget_show(sw); | 4121 gtk_widget_show(sw); |
4056 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE); | 4122 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE); |
4830 { | 4896 { |
4831 if (!gtkblist) | 4897 if (!gtkblist) |
4832 return; | 4898 return; |
4833 | 4899 |
4834 gaim_signals_disconnect_by_handle(gtkblist); | 4900 gaim_signals_disconnect_by_handle(gtkblist); |
4901 | |
4902 if (gtkblist->headline_close) | |
4903 gdk_pixbuf_unref(gtkblist->headline_close); | |
4835 | 4904 |
4836 gtk_widget_destroy(gtkblist->window); | 4905 gtk_widget_destroy(gtkblist->window); |
4837 | 4906 |
4838 gaim_gtk_blist_tooltip_destroy(); | 4907 gaim_gtk_blist_tooltip_destroy(); |
4839 | 4908 |