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