pidgin/pidginavatar.c

branch
gtk4
changeset 41536
ba0797a477e7
parent 41479
3d2e114380f6
child 41564
661f4b3b8298
equal deleted inserted replaced
41535:0dee7089dc5a 41536:ba0797a477e7
23 #include <glib/gi18n-lib.h> 23 #include <glib/gi18n-lib.h>
24 24
25 #include "pidgin/pidginavatar.h" 25 #include "pidgin/pidginavatar.h"
26 26
27 struct _PidginAvatar { 27 struct _PidginAvatar {
28 GtkEventBox parent; 28 GtkBox parent;
29 29
30 GtkWidget *icon; 30 GtkWidget *icon;
31 31
32 GdkPixbufAnimation *animation; 32 GdkPixbufAnimation *animation;
33 gboolean animate; 33 gboolean animate;
43 PROP_CONVERSATION, 43 PROP_CONVERSATION,
44 N_PROPERTIES, 44 N_PROPERTIES,
45 }; 45 };
46 static GParamSpec *properties[N_PROPERTIES] = {NULL, }; 46 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
47 47
48 G_DEFINE_TYPE(PidginAvatar, pidgin_avatar, GTK_TYPE_EVENT_BOX) 48 G_DEFINE_TYPE(PidginAvatar, pidgin_avatar, GTK_TYPE_BOX)
49 49
50 /****************************************************************************** 50 /******************************************************************************
51 * Actions 51 * Actions
52 *****************************************************************************/ 52 *****************************************************************************/
53 static void 53 static void
65 65
66 icon = purple_buddy_get_icon(avatar->buddy); 66 icon = purple_buddy_get_icon(avatar->buddy);
67 67
68 if(icon != NULL) { 68 if(icon != NULL) {
69 GtkFileChooser *chooser = GTK_FILE_CHOOSER(native); 69 GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
70 GFile *file = NULL;
70 gchar *filename = NULL; 71 gchar *filename = NULL;
71 72
72 filename = gtk_file_chooser_get_filename(chooser); 73 file = gtk_file_chooser_get_file(chooser);
74 filename = g_file_get_path(file);
73 75
74 purple_buddy_icon_save_to_filename(icon, filename, NULL); 76 purple_buddy_icon_save_to_filename(icon, filename, NULL);
75 77
76 g_free(filename); 78 g_free(filename);
77 } 79 }
97 99
98 account = purple_buddy_get_account(avatar->buddy); 100 account = purple_buddy_get_account(avatar->buddy);
99 name = purple_buddy_get_name(avatar->buddy); 101 name = purple_buddy_get_name(avatar->buddy);
100 filename = g_strdup_printf("%s.%s", purple_normalize(account, name), ext); 102 filename = g_strdup_printf("%s.%s", purple_normalize(account, name), ext);
101 103
102 window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(avatar))); 104 window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(avatar)));
103 native = gtk_file_chooser_native_new(_("Save Avatar"), 105 native = gtk_file_chooser_native_new(_("Save Avatar"),
104 window, 106 window,
105 GTK_FILE_CHOOSER_ACTION_SAVE, 107 GTK_FILE_CHOOSER_ACTION_SAVE,
106 _("_Save"), 108 _("_Save"),
107 _("_Cancel")); 109 _("_Cancel"));
108 g_signal_connect(G_OBJECT(native), "response", 110 g_signal_connect(G_OBJECT(native), "response",
109 G_CALLBACK(pidgin_avatar_save_response_cb), avatar); 111 G_CALLBACK(pidgin_avatar_save_response_cb), avatar);
110 112
111 chooser = GTK_FILE_CHOOSER(native); 113 chooser = GTK_FILE_CHOOSER(native);
112 114
113 gtk_file_chooser_set_do_overwrite_confirmation(chooser, TRUE); 115 gtk_file_chooser_set_current_name(chooser, filename);
114 gtk_file_chooser_set_filename(chooser, filename);
115 g_free(filename); 116 g_free(filename);
116 117
117 gtk_native_dialog_show(GTK_NATIVE_DIALOG(native)); 118 gtk_native_dialog_show(GTK_NATIVE_DIALOG(native));
118 } 119 }
119 120
121 pidgin_avatar_set_custom_response_cb(GtkNativeDialog *native, gint response, 122 pidgin_avatar_set_custom_response_cb(GtkNativeDialog *native, gint response,
122 gpointer data) 123 gpointer data)
123 { 124 {
124 PidginAvatar *avatar = PIDGIN_AVATAR(data); 125 PidginAvatar *avatar = PIDGIN_AVATAR(data);
125 GtkFileChooser *chooser = GTK_FILE_CHOOSER(native); 126 GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
127 GFile *file = NULL;
126 gchar *filename = NULL; 128 gchar *filename = NULL;
127 129
128 if(response != GTK_RESPONSE_ACCEPT || !PURPLE_IS_BUDDY(avatar->buddy)) { 130 if(response != GTK_RESPONSE_ACCEPT || !PURPLE_IS_BUDDY(avatar->buddy)) {
129 gtk_native_dialog_destroy(native); 131 gtk_native_dialog_destroy(native);
130 132
131 return; 133 return;
132 } 134 }
133 135
134 filename = gtk_file_chooser_get_filename(chooser); 136 file = gtk_file_chooser_get_file(chooser);
137 filename = g_file_get_path(file);
135 if(filename != NULL) { 138 if(filename != NULL) {
136 PurpleContact *contact = purple_buddy_get_contact(avatar->buddy); 139 PurpleContact *contact = purple_buddy_get_contact(avatar->buddy);
137 PurpleBlistNode *node = PURPLE_BLIST_NODE(contact); 140 PurpleBlistNode *node = PURPLE_BLIST_NODE(contact);
138 141
139 purple_buddy_icons_node_set_custom_icon_from_file(node, filename); 142 purple_buddy_icons_node_set_custom_icon_from_file(node, filename);
148 { 151 {
149 PidginAvatar *avatar = PIDGIN_AVATAR(data); 152 PidginAvatar *avatar = PIDGIN_AVATAR(data);
150 GtkFileChooserNative *native = NULL; 153 GtkFileChooserNative *native = NULL;
151 GtkWindow *window = NULL; 154 GtkWindow *window = NULL;
152 155
153 window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(avatar))); 156 window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(avatar)));
154 native = gtk_file_chooser_native_new(_("Set Custom Avatar"), 157 native = gtk_file_chooser_native_new(_("Set Custom Avatar"),
155 window, 158 window,
156 GTK_FILE_CHOOSER_ACTION_OPEN, 159 GTK_FILE_CHOOSER_ACTION_OPEN,
157 _("_Set Custom"), 160 _("_Set Custom"),
158 _("_Cancel")); 161 _("_Cancel"));
273 276
274 g_set_object(&avatar->animation, animation); 277 g_set_object(&avatar->animation, animation);
275 278
276 if(GDK_IS_PIXBUF_ANIMATION(avatar->animation)) { 279 if(GDK_IS_PIXBUF_ANIMATION(avatar->animation)) {
277 if(avatar->animate) { 280 if(avatar->animate) {
278 gtk_image_set_from_animation(GTK_IMAGE(avatar->icon), 281 gtk_image_set_from_pixbuf(GTK_IMAGE(avatar->icon),
279 avatar->animation); 282 GDK_PIXBUF(avatar->animation));
280 } else { 283 } else {
281 GdkPixbuf *frame = NULL; 284 GdkPixbuf *frame = NULL;
282 285
283 frame = gdk_pixbuf_animation_get_static_image(avatar->animation); 286 frame = gdk_pixbuf_animation_get_static_image(avatar->animation);
284 287
293 296
294 /****************************************************************************** 297 /******************************************************************************
295 * Callbacks 298 * Callbacks
296 *****************************************************************************/ 299 *****************************************************************************/
297 static gboolean 300 static gboolean
298 pidgin_avatar_button_press_handler(GtkWidget *widget, GdkEventButton *event, 301 pidgin_avatar_button_press_handler(G_GNUC_UNUSED GtkGestureClick *event,
302 G_GNUC_UNUSED gint n_press,
303 gdouble x,
304 gdouble y,
299 gpointer data) 305 gpointer data)
300 { 306 {
301 PidginAvatar *avatar = PIDGIN_AVATAR(data); 307 PidginAvatar *avatar = PIDGIN_AVATAR(data);
302 GtkBuilder *builder = NULL; 308 GtkBuilder *builder = NULL;
303 GtkWidget *menu = NULL; 309 GtkWidget *menu = NULL;
304 GMenuModel *model = NULL; 310 GMenuModel *model = NULL;
305 311
306 if(!gdk_event_triggers_context_menu((GdkEvent *)event)) {
307 return FALSE;
308 }
309
310 builder = gtk_builder_new_from_resource("/im/pidgin/Pidgin3/Avatar/menu.ui"); 312 builder = gtk_builder_new_from_resource("/im/pidgin/Pidgin3/Avatar/menu.ui");
311 model = (GMenuModel *)gtk_builder_get_object(builder, "menu"); 313 model = (GMenuModel *)gtk_builder_get_object(builder, "menu");
312 314
313 menu = gtk_popover_menu_new(); 315 menu = gtk_popover_menu_new_from_model(model);
314 gtk_popover_bind_model(GTK_POPOVER(menu), model, NULL); 316 gtk_widget_set_parent(menu, GTK_WIDGET(avatar));
315 gtk_popover_set_relative_to(GTK_POPOVER(menu), GTK_WIDGET(avatar));
316 gtk_popover_set_pointing_to(GTK_POPOVER(menu), 317 gtk_popover_set_pointing_to(GTK_POPOVER(menu),
317 &(const GdkRectangle){(int)event->x, (int)event->y, 0, 0}); 318 &(const GdkRectangle){(int)x, (int)y, 0, 0});
318 319
319 g_clear_object(&builder); 320 g_clear_object(&builder);
320 321
321 gtk_popover_popup(GTK_POPOVER(menu)); 322 gtk_popover_popup(GTK_POPOVER(menu));
322 323
349 350
350 pidgin_avatar_update(avatar); 351 pidgin_avatar_update(avatar);
351 } 352 }
352 353
353 static gboolean 354 static gboolean
354 pidgin_avatar_enter_notify_handler(GtkWidget *widget, GdkEvent *event, 355 pidgin_avatar_enter_notify_handler(G_GNUC_UNUSED GtkEventControllerMotion *event,
356 G_GNUC_UNUSED gdouble x,
357 G_GNUC_UNUSED gdouble y,
355 gpointer data) 358 gpointer data)
356 { 359 {
357 PidginAvatar *avatar = PIDGIN_AVATAR(widget); 360 PidginAvatar *avatar = PIDGIN_AVATAR(data);
358 361
359 pidgin_avatar_set_animate(avatar, TRUE); 362 pidgin_avatar_set_animate(avatar, TRUE);
360 363
361 return FALSE; 364 return FALSE;
362 } 365 }
363 366
364 static gboolean 367 static gboolean
365 pidgin_avatar_leave_notify_handler(GtkWidget *widget, GdkEvent *event, 368 pidgin_avatar_leave_notify_handler(G_GNUC_UNUSED GtkEventControllerMotion *event,
366 gpointer user_data) 369 gpointer data)
367 { 370 {
368 PidginAvatar *avatar = PIDGIN_AVATAR(widget); 371 PidginAvatar *avatar = PIDGIN_AVATAR(data);
369 372
370 pidgin_avatar_set_animate(avatar, FALSE); 373 pidgin_avatar_set_animate(avatar, FALSE);
371 374
372 return FALSE; 375 return FALSE;
373 } 376 }
525 528
526 avatar->animate = animate; 529 avatar->animate = animate;
527 530
528 if(GDK_IS_PIXBUF_ANIMATION(avatar->animation)) { 531 if(GDK_IS_PIXBUF_ANIMATION(avatar->animation)) {
529 if(avatar->animate) { 532 if(avatar->animate) {
530 gtk_image_set_from_animation(GTK_IMAGE(avatar->icon), 533 gtk_image_set_from_pixbuf(GTK_IMAGE(avatar->icon),
531 avatar->animation); 534 GDK_PIXBUF(avatar->animation));
532 } else { 535 } else {
533 GdkPixbuf *frame = NULL; 536 GdkPixbuf *frame = NULL;
534 537
535 frame = gdk_pixbuf_animation_get_static_image(avatar->animation); 538 frame = gdk_pixbuf_animation_get_static_image(avatar->animation);
536 539

mercurial