I need a GtkProgressBar that can be drag by mouse. So I write the following code and it work well in gtk+-2.x:
1. #include <gtk/gtk.h> 2. 3. gboolean progress_button_release (GtkWidget *progress, GdkEvent *event, gpointer data); 4. gboolean progress_button_press (GtkWidget *progress, GdkEvent *event, gpointer data); 5. gboolean progress_motion_notify (GtkWidget *progress, GdkEvent *event, gpointer data); 6. 7. int main (int argc, char* argv[]) 8. { 9. GtkWidget *window; 10. GtkWidget *label; 11. GtkWidget *progress; 12. GtkWidget *vbox; 13. 14. gtk_init (&argc, &argv); 15. 16. window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 17. gtk_widget_set_size_request (window, 400, 300); 18. 19. label = gtk_label_new ("mouse progress bar"); 20. gtk_widget_show (label); 21. 22. progress = gtk_progress_bar_new (); 23. gtk_widget_show (progress); 24. gtk_widget_set_size_request (progress, -1, 30); 25. gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), 0.2); 26. 27. gtk_widget_add_events (progress, GDK_BUTTON_RELEASE_MASK | 28. GDK_BUTTON_PRESS_MASK | 29. GDK_POINTER_MOTION_MASK ); 30. g_signal_connect (progress, "button-release-event", 31. G_CALLBACK (progress_button_release), NULL); 32. g_signal_connect (progress, "button-press-event", 33. G_CALLBACK (progress_button_press), NULL); 34. g_signal_connect (progress, "motion-notify-event", 35. G_CALLBACK (progress_motion_notify), NULL); 36. 37. 38. vbox = gtk_vbox_new (FALSE, 5); 39. gtk_widget_show (vbox); 40. 41. gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 5); 42. gtk_box_pack_start (GTK_BOX(vbox), progress, TRUE, FALSE, 5); 43. 44. gtk_container_add (GTK_CONTAINER(window), vbox); 45. 46. gtk_widget_show (window); 47. 48. gtk_main (); 49. 50. return 0; 51. } 52. 53. gboolean 54. progress_button_release (GtkWidget *progress, GdkEvent *event, gpointer data) 55. { 56. GdkEventButton *eb = (GdkEventButton *)event; 57. GtkAllocation allocation; 58. gint pressed; 59. 60. pressed = (gint)g_object_get_data (G_OBJECT(progress), "pressed"); 61. #if GTK_MINOR_VERSION >= 18 62. gtk_widget_get_allocation (progress, &allocation); 63. #else 64. allocation = progress->allocation; 65. #endif 66. if (pressed) 67. gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), eb->x / (allocation.width * 1.0)); 68. 69. g_object_set_data (G_OBJECT(progress), "pressed", (gpointer)0); 70. return FALSE; 71. } 72. 73. gboolean 74. progress_button_press (GtkWidget *progress, GdkEvent *event, gpointer data) 75. { 76. g_object_set_data (G_OBJECT(progress), "pressed", (gpointer)1); 77. return FALSE; 78. } 79. 80. gboolean 81. progress_motion_notify (GtkWidget *progress, GdkEvent *event, gpointer data) 82. { 83. GdkEventMotion *em = (GdkEventMotion *)event; 84. gint pressed; 85. GtkAllocation allocation; 86. 87. pressed = (gint)g_object_get_data (G_OBJECT(progress), "pressed"); 88. #if GTK_MINOR_VERSION >= 18 89. gtk_widget_get_allocation (progress, &allocation); 90. #else 91. allocation = progress->allocation; 92. #endif 93. if (pressed) 94. { 95. gdouble fraction = em->x / (allocation.width * 1.0); 96. if (fraction > 1.0) 97. fraction = 1.0; 98. if (fraction < 0.0) 99. fraction = 0.0; 100. gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), fraction); 101. } 102. 103. return FALSE; 104. } But it cannot work in Gtk+-3.0, I read the souce code in gtk+-3.0 tar.bz2 ($GTK_SOURCE_ROOT/tests/testinput.c), and modify my code after testinput.c: #include <gtk/gtk.h> gboolean progress_button_release (GtkWidget *progress, GdkEvent *event, gpointer data); gboolean progress_button_press (GtkWidget *progress, GdkEvent *event, gpointer data); gboolean progress_motion_notify (GtkWidget *progress, GdkEvent *event, gpointer data); int main (int argc, char* argv[]) { GtkWidget *window; GtkWidget *label; GtkWidget *progress; GtkWidget *vbox; GList *devices, *walk; GdkDeviceManager *device_manager; GdkEventMask event_mask; gtk_init (&argc, &argv); device_manager = gdk_display_get_device_manager (gdk_display_get_default ()); devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (window, 400, 300); label = gtk_label_new ("mouse progress bar"); gtk_widget_show (label); progress = gtk_progress_bar_new (); gtk_widget_show (progress); gtk_widget_set_size_request (progress, -1, 20); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), 0.2); event_mask = GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_PROXIMITY_OUT_MASK; gtk_widget_set_events (progress, event_mask); for (walk = devices; walk; walk = walk->next) { gtk_widget_set_device_events (progress, walk->data, event_mask); gdk_device_set_mode (walk->data, GDK_MODE_SCREEN); } gtk_widget_set_can_focus (progress, TRUE); gtk_widget_grab_focus (progress); g_signal_connect (progress, "button-release-event", G_CALLBACK (progress_button_release), NULL); g_signal_connect (progress, "button-press-event", G_CALLBACK (progress_button_press), NULL); g_signal_connect (progress, "motion-notify-event", G_CALLBACK (progress_motion_notify), NULL); vbox = gtk_vbox_new (FALSE, 5); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX(vbox), progress, TRUE, FALSE, 5); gtk_container_add (GTK_CONTAINER(window), vbox); gtk_widget_show (window); gtk_main (); return 0; } gboolean progress_button_release (GtkWidget *progress, GdkEvent *event, gpointer data) { GdkEventButton *eb = (GdkEventButton *)event; GtkAllocation allocation; gint pressed; pressed = (gint)g_object_get_data (G_OBJECT(progress), "pressed"); #if GTK_MINOR_VERSION >= 18 || GTK_MAJOR_VERSION >= 3 gtk_widget_get_allocation (progress, &allocation); #else allocation = progress->allocation; #endif if (pressed) gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), eb->x / (allocation.width * 1.0)); g_object_set_data (G_OBJECT(progress), "pressed", (gpointer)0); return FALSE; } gboolean progress_button_press (GtkWidget *progress, GdkEvent *event, gpointer data) { g_object_set_data (G_OBJECT(progress), "pressed", (gpointer)1); g_print ("%s\n", __func__); return FALSE; } gboolean progress_motion_notify (GtkWidget *progress, GdkEvent *event, gpointer data) { GdkEventMotion *em = (GdkEventMotion *)event; gint pressed; GtkAllocation allocation; pressed = (gint)g_object_get_data (G_OBJECT(progress), "pressed"); #if GTK_MINOR_VERSION >= 18 || GTK_MAJOR_VERSION >= 3 gtk_widget_get_allocation (progress, &allocation); #else allocation = progress->allocation; #endif if (pressed) { gdouble fraction = em->x / (allocation.width * 1.0); if (fraction > 1.0) fraction = 1.0; if (fraction < 0.0) fraction = 0.0; gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), fraction); } return FALSE; } But it cannot work as before. Any one know why? Thinks. _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list