diff options
39 files changed, 1881 insertions, 681 deletions
@@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 51da0db76..76ce67342 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 51da0db76..76ce67342 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 51da0db76..76ce67342 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 51da0db76..76ce67342 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 51da0db76..76ce67342 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 51da0db76..76ce67342 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,78 @@ +2001-04-24 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_previous_line): + (gtk_text_layout_move_iter_to_next_line): fix these two for + invisible text, lots of other stuff still hosed. + + * gtk/gtkcolorsel.c (gtk_color_selection_set_change_palette_hook): + new function, replaces the get/set palette stuff. This function + is intended for use by libgnomeui which should set the hook to a + thing which sets the palette in GConf, and we need the + GConf-to-xsettings proxy which will result in the change being + propagated back to the GTK app. + + * gtk/gtkaccelgroup.c (gtk_accel_group_add): add note to warning + about unusable signals that it may be because the signal has + parameters. + + * gtk/gtkwidget.c (gtk_widget_modify_style): always copy the + style, otherwise gtkrc.c won't know to create a new GtkStyle for + it. + (gtk_widget_modify_color_component): call + gtk_widget_modify_style() so the rc style will get copied. + (gtk_widget_modify_font): ditto + + * gtk/gtkrc.c: make a couple variables static + + * gtk/gtkcolorseldialog.c (gtk_color_selection_dialog_init): hide + help button by default, since it does nothing + + * gtk/gtkcolorsel.c: add tooltips, work on key navigation, fool + around with UI + + * gtk/gtkentry.c (gtk_entry_realize): request enter/leave notify + so we can have tooltips + + * gtk/gtkhsv.c (gtk_hsv_realize): request enter/leave notify so we + can have tooltips + + * gdk/gdkimage.h: mark gdk_image_new_bitmap with + GDK_ENABLE_BROKEN, because its memory behavior is completely + hosed. + + * gtk/gtknotebook.c: remove key press handler, replace with + binding set, add numeric keypad support + + * gtk/gtktextview.c (gtk_text_view_class_init): accept KP_Delete + + * gtk/gtktext.c (gtk_text_key_press): add a bunch of KP keysyms + + * gtk/gtkentry.c (gtk_entry_class_init): accept GDK_KP_Delete in + addition to plain Delete + + * gtk/gtktextview.c (gtk_text_view_key_press_event): accept + GDK_KP_Enter in addition to GDK_Return + + * gtk/gtkfontsel.c (gtk_font_selection_size_key_press): connect to + activate on entry instead of key press + (gtk_font_selection_on_clist_key_press): get + rid of this signal handler, not needed with new font sel. + + * gtk/gtkfilesel.c (gtk_file_selection_key_press): remove a + no-longer-needed emit_stop_by_name(), just return TRUE + + * gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.c: remove keybindings + cruft, this widget is no longer focusable. + + * gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkvscale.c, + gtk/gtkhscale.c: Get rid of trough_keys virtual function, add + move_slider action signal, add binding set for vscale/hscale, in + the process support numeric keypad + + * gtk/gtkentry.c (gtk_entry_class_init): Add keypad bindings; + make GDK_Return and GDK_KP_Enter activate the entry via + binding set, instead of hardcoded. + Fri Apr 27 20:27:21 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreeview.[hc]: Massive reorder/cleanup of a lot of the diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index e26054055..50e2c3d9f 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -6,6 +6,7 @@ democodedir=$(datadir)/gtk-2.0/demo ## demo app, which means alphabetized by demo title, not filename demos = @STRIP_BEGIN@ \ button_box.c \ + colorsel.c \ dialog.c \ drawingarea.c \ images.c \ diff --git a/demos/gtk-demo/colorsel.c b/demos/gtk-demo/colorsel.c new file mode 100644 index 000000000..dc1836e0d --- /dev/null +++ b/demos/gtk-demo/colorsel.c @@ -0,0 +1,110 @@ +/* Color Selector + * + * GtkColorSelection lets the user choose a color. GtkColorSelectionDialog is + * a prebuilt dialog containing a GtkColorSelection. + * + */ + +#include <gtk/gtk.h> + +static GtkWidget *window = NULL; +static GtkWidget *da; +static GdkColor color; +static GtkWidget *frame; + +static void +change_color_callback (GtkWidget *button, + gpointer data) +{ + GtkWidget *dialog; + GtkColorSelection *colorsel; + gint response; + + dialog = gtk_color_selection_dialog_new ("Changing color"); + + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); + + colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (dialog)->colorsel); + + gtk_color_selection_set_previous_color (colorsel, &color); + gtk_color_selection_set_current_color (colorsel, &color); + gtk_color_selection_set_has_palette (colorsel, TRUE); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + if (response == GTK_RESPONSE_OK) + { + gtk_color_selection_get_current_color (colorsel, + &color); + + gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &color); + } + + gtk_widget_destroy (dialog); +} + +GtkWidget * +do_colorsel (void) +{ + GtkWidget *vbox; + GtkWidget *button; + GtkWidget *alignment; + + if (!window) + { + color.red = 0; + color.blue = 65535; + color.green = 0; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "Color Selection"); + + gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window); + + gtk_container_set_border_width (GTK_CONTAINER (window), 8); + + vbox = gtk_vbox_new (FALSE, 8); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); + gtk_container_add (GTK_CONTAINER (window), vbox); + + /* + * Create the color swatch area + */ + + + frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); + + da = gtk_drawing_area_new (); + /* set a minimum size */ + gtk_widget_set_usize (da, 200, 200); + /* set the color */ + gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &color); + + gtk_container_add (GTK_CONTAINER (frame), da); + + alignment = gtk_alignment_new (1.0, 0.5, 0.0, 0.0); + + button = gtk_button_new_with_mnemonic ("_Change the above color"); + gtk_container_add (GTK_CONTAINER (alignment), button); + + gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0); + + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (change_color_callback), + NULL); + } + + if (!GTK_WIDGET_VISIBLE (window)) + { + gtk_widget_show_all (window); + } + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 05abdb0a4..9d2956317 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2001-04-20 Havoc Pennington <hp@redhat.com> + + * gdk/tmpl/images.sgml: add warning about gtk_image_new_bitmap + Wed Apr 25 12:33:03 2001 Owen Taylor <otaylor@redhat.com> * gtk/tmpl/gtktreeitem.sgml: Add note about GTK_ENABLE_BROKEN. diff --git a/docs/reference/gdk/tmpl/images.sgml b/docs/reference/gdk/tmpl/images.sgml index 1fe14205c..d74af57c8 100644 --- a/docs/reference/gdk/tmpl/images.sgml +++ b/docs/reference/gdk/tmpl/images.sgml @@ -105,6 +105,9 @@ and if that fails then %GDK_IMAGE_NORMAL will be used. <!-- ##### FUNCTION gdk_image_new_bitmap ##### --> <para> Creates a new #GdkImage with a depth of 1 from the given data. +<warning><para>THIS FUNCTION IS INCREDIBLY BROKEN. The passed-in data must +be allocated by malloc() (NOT g_malloc()) and will be freed when the +image is freed.</para></warning> </para> @visual: the #GdkVisual to use for the image. diff --git a/docs/reference/gtk/tmpl/gtkcolorsel.sgml b/docs/reference/gtk/tmpl/gtkcolorsel.sgml index b5dcb93cd..8b3be5876 100644 --- a/docs/reference/gtk/tmpl/gtkcolorsel.sgml +++ b/docs/reference/gtk/tmpl/gtkcolorsel.sgml @@ -85,45 +85,6 @@ Retrieve the currently selected color value. blue, and opacity. -<!-- ##### FUNCTION gtk_color_selection_set_palette_color ##### --> -<para> - -</para> - -@colorsel: -@index: -@color: -<!-- # Unused Parameters # --> -@x: -@y: - - -<!-- ##### FUNCTION gtk_color_selection_get_palette_color ##### --> -<para> - -</para> - -@colorsel: -@index: -@color: -@Returns: -<!-- # Unused Parameters # --> -@x: -@y: - - -<!-- ##### FUNCTION gtk_color_selection_unset_palette_color ##### --> -<para> - -</para> - -@colorsel: -@index: -<!-- # Unused Parameters # --> -@x: -@y: - - <!-- ##### FUNCTION gtk_color_selection_is_adjusting ##### --> <para> diff --git a/docs/reference/gtk/tmpl/gtknotebook.sgml b/docs/reference/gtk/tmpl/gtknotebook.sgml index 9e22ef178..9ff69802b 100644 --- a/docs/reference/gtk/tmpl/gtknotebook.sgml +++ b/docs/reference/gtk/tmpl/gtknotebook.sgml @@ -336,6 +336,22 @@ Compatibility macro; in gtkcompat.h. @tab_vborder: +<!-- ##### SIGNAL GtkNotebook::focus-tab ##### --> +<para> + +</para> + +@notebook: the object which received the signal. +@arg1: + +<!-- ##### SIGNAL GtkNotebook::select-page ##### --> +<para> + +</para> + +@notebook: the object which received the signal. +@arg1: + <!-- ##### SIGNAL GtkNotebook::switch-page ##### --> <para> Emitted when the user or a function changes the current page. diff --git a/docs/reference/gtk/tmpl/gtkrange.sgml b/docs/reference/gtk/tmpl/gtkrange.sgml index 8dd893097..63fb9f0f6 100644 --- a/docs/reference/gtk/tmpl/gtkrange.sgml +++ b/docs/reference/gtk/tmpl/gtkrange.sgml @@ -65,6 +65,15 @@ GtkRange @setting: +<!-- ##### SIGNAL GtkRange::move-slider ##### --> +<para> + +</para> + +@range: the object which received the signal. +@arg1: +@arg2: + <!-- ##### ARG GtkRange:update-policy ##### --> <para> diff --git a/gdk/gdkimage.h b/gdk/gdkimage.h index 2c631b356..c8d74f3d4 100644 --- a/gdk/gdkimage.h +++ b/gdk/gdkimage.h @@ -59,10 +59,6 @@ struct _GdkImageClass GType gdk_image_get_type (void) G_GNUC_CONST; -GdkImage* gdk_image_new_bitmap (GdkVisual *visual, - gpointer data, - gint width, - gint height); GdkImage* gdk_image_new (GdkImageType type, GdkVisual *visual, gint width, @@ -85,6 +81,13 @@ guint32 gdk_image_get_pixel (GdkImage *image, gint x, gint y); +#ifdef GDK_ENABLE_BROKEN +GdkImage* gdk_image_new_bitmap (GdkVisual *visual, + gpointer data, + gint width, + gint height); +#endif /* GDK_ENABLE_BROKEN */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtkaccelgroup.c b/gtk/gtkaccelgroup.c index d1c27581d..1f078ff00 100644 --- a/gtk/gtkaccelgroup.c +++ b/gtk/gtkaccelgroup.c @@ -381,7 +381,7 @@ gtk_accel_group_add (GtkAccelGroup *accel_group, if (!query.signal_id || query.n_params > 0) { g_warning ("gtk_accel_group_add(): signal \"%s\" in the `%s' class ancestry" - "cannot be used as accelerator signal", + "cannot be used as accelerator signal (perhaps it has parameters)", accel_signal, gtk_type_name (GTK_OBJECT_TYPE (object))); diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index ff4bcbbe6..5900ad960 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -57,8 +57,15 @@ #include "gtkentry.h" #include "gtkbutton.h" #include "gtkhseparator.h" +#include "gtktooltips.h" +#include "gtkinvisible.h" +#include "gtkmenuitem.h" +#include "gtkmain.h" +#include "gtksettings.h" #include "gtkintl.h" +#include <string.h> + /* Number of elements in the custom palatte */ #define GTK_CUSTOM_PALETTE_WIDTH 10 #define GTK_CUSTOM_PALETTE_HEIGHT 2 @@ -89,9 +96,6 @@ struct _ColorSelectionPrivate guint default_set : 1; guint default_alpha_set : 1; - /* The color dropper */ - guint moving_dropper : 1; - gdouble color[COLORSEL_NUM_CHANNELS]; gdouble old_color[COLORSEL_NUM_CHANNELS]; @@ -110,24 +114,45 @@ struct _ColorSelectionPrivate /* The Palette code */ GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT]; - GtkWidget *last_palette; /* The color_sample stuff */ GtkWidget *sample_area; GtkWidget *old_sample; GtkWidget *cur_sample; GtkWidget *colorsel; + + /* Tooltips group */ + GtkTooltips *tooltips; + + /* Window for grabbing on */ + GtkWidget *dropper_grab_widget; }; static void gtk_color_selection_init (GtkColorSelection *colorsel); static void gtk_color_selection_class_init (GtkColorSelectionClass *klass); static void gtk_color_selection_destroy (GtkObject *object); +static void gtk_color_selection_finalize (GObject *object); static void update_color (GtkColorSelection *colorsel); +static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel); +static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel, + gint index, + GdkColor *color); +static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel, + gint index, + GdkColor *color); +static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel, + gint index); + static gpointer parent_class = NULL; static guint color_selection_signals[LAST_SIGNAL] = { 0 }; +static gchar* default_colors = "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90"; + +static GtkColorSelectionChangePaletteFunc change_palette_hook = NULL; + +static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT]; /* The cursor for the dropper */ #define DROPPER_WIDTH 17 @@ -500,6 +525,12 @@ color_sample_new (GtkColorSelection *colorsel) priv->sample_area = gtk_hbox_new (FALSE, 0); priv->old_sample = gtk_drawing_area_new (); priv->cur_sample = gtk_drawing_area_new (); + + /* We need enter/leave to do tooltips */ + gtk_widget_add_events (priv->old_sample, + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); + gtk_widget_add_events (priv->cur_sample, + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample, TRUE, TRUE, 0); @@ -515,6 +546,15 @@ color_sample_new (GtkColorSelection *colorsel) color_sample_setup_dnd (colorsel, priv->old_sample); color_sample_setup_dnd (colorsel, priv->cur_sample); + + gtk_tooltips_set_tip (priv->tooltips, + priv->old_sample, + _("The previously-selected color, for comparison to the color you're selecting now. You can drag this color to a palette entry, or select this color as current by dragging it to the other color swatch alongside."), NULL); + + + gtk_tooltips_set_tip (priv->tooltips, + priv->cur_sample, + _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL); gtk_widget_show_all (priv->sample_area); } @@ -525,8 +565,8 @@ color_sample_new (GtkColorSelection *colorsel) * The palette area code * */ -#define CUSTOM_PALETTE_ENTRY_WIDTH 16 -#define CUSTOM_PALETTE_ENTRY_HEIGHT 16 +#define CUSTOM_PALETTE_ENTRY_WIDTH 20 +#define CUSTOM_PALETTE_ENTRY_HEIGHT 20 static void palette_get_color (GtkWidget *drawing_area, gdouble *color) @@ -558,9 +598,6 @@ palette_paint (GtkWidget *drawing_area, GdkRectangle *area, gpointer data) { - GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data); - ColorSelectionPrivate *priv = colorsel->private_data; - if (drawing_area->window == NULL) return; @@ -570,7 +607,7 @@ palette_paint (GtkWidget *drawing_area, area->width, area->height); - if (priv->last_palette == drawing_area) + if (GTK_WIDGET_HAS_FOCUS (drawing_area)) { GdkGC *gc; gdouble color[4]; @@ -589,50 +626,6 @@ palette_paint (GtkWidget *drawing_area, } } -static void -palette_expose (GtkWidget *drawing_area, - GdkEventExpose *event, - gpointer data) -{ - if (drawing_area->window == NULL) - return; - - palette_paint (drawing_area, &(event->area), data); -} - -static gint -palette_press (GtkWidget *drawing_area, - GdkEventButton *event, - gpointer data) -{ - GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data); - ColorSelectionPrivate *priv = colorsel->private_data; - - if (priv->last_palette != NULL) - gtk_widget_queue_clear (priv->last_palette); - - priv->last_palette = drawing_area; - - if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0) - { - gdouble color[4]; - palette_get_color (drawing_area, color); - gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color); - } - - gtk_widget_queue_clear (priv->last_palette); - return TRUE; -} - -static void -palette_unset_color (GtkWidget *drawing_area) -{ - if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0) - return; - - gtk_widget_reset_rc_styles (drawing_area); - gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0)); -} static void palette_drag_begin (GtkWidget *widget, @@ -690,21 +683,72 @@ palette_drag_handle (GtkWidget *widget, } static void +palette_drag_end (GtkWidget *widget, + GdkDragContext *context, + gpointer data) +{ + gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL); +} + +/* Changes the model color */ +static void +palette_change_color (GtkWidget *drawing_area, + GtkColorSelection *colorsel, + gdouble *color) +{ + gint x, y; + ColorSelectionPrivate *priv; + GdkColor gdk_color; + + g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel)); + g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area)); + + priv = colorsel->private_data; + + gdk_color.red = color[0]*65535; + gdk_color.green = color[1]*65535; + gdk_color.blue = color[2]*65535; + + x = 0; + while (x < GTK_CUSTOM_PALETTE_WIDTH) + { + y = 0; + while (y < GTK_CUSTOM_PALETTE_HEIGHT) + { + if (priv->custom_palette[x][y] == drawing_area) + goto out; + + ++y; + } + + ++x; + } + + out: + + g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT); + + current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color; + + if (change_palette_hook) + (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT); +} + +/* Changes the view color */ +static void palette_set_color (GtkWidget *drawing_area, GtkColorSelection *colorsel, gdouble *color) { - GtkRcStyle *rc_style; gdouble *new_color = g_new (double, 4); gdouble *old_color; + GdkColor gdk_color; - rc_style = gtk_rc_style_new (); - rc_style->bg[GTK_STATE_NORMAL].red = color[0]*65535; - rc_style->bg[GTK_STATE_NORMAL].green = color[1]*65535; - rc_style->bg[GTK_STATE_NORMAL].blue = color[2]*65535; - rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG; - gtk_rc_style_ref (rc_style); - gtk_widget_modify_style (drawing_area, rc_style); + gdk_color.red = color[0]*65535; + gdk_color.green = color[1]*65535; + gdk_color.blue = color[2]*65535; + + gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color); if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0) { @@ -744,11 +788,132 @@ palette_set_color (GtkWidget *drawing_area, } static void -palette_drag_end (GtkWidget *widget, - GdkDragContext *context, - gpointer data) +palette_expose (GtkWidget *drawing_area, + GdkEventExpose *event, + gpointer data) { - gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL); + if (drawing_area->window == NULL) + return; + + palette_paint (drawing_area, &(event->area), data); +} + +static void +popup_position_func (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) +{ + GtkWidget *widget; + GtkRequisition req; + gint root_x, root_y; + + widget = GTK_WIDGET (user_data); + + g_return_if_fail (GTK_WIDGET_REALIZED (widget)); + + gdk_window_get_origin (widget->window, &root_x, &root_y); + + gtk_widget_size_request (GTK_WIDGET (menu), &req); + + /* Put corner of menu centered on color cell */ + *x = root_x + widget->allocation.width / 2; + *y = root_y + widget->allocation.height / 2; + + /* Ensure sanity */ + *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); +} + +static void +save_color_selected (GtkWidget *menuitem, + gpointer data) +{ + GtkColorSelection *colorsel; + GtkWidget *drawing_area; + ColorSelectionPrivate *priv; + + drawing_area = GTK_WIDGET (data); + + colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area), + "gtk-color-sel")); + + priv = colorsel->private_data; + + palette_change_color (drawing_area, colorsel, priv->color); +} + +static void +do_popup (GtkColorSelection *colorsel, + GtkWidget *drawing_area, + guint32 timestamp) +{ + GtkWidget *menu; + GtkWidget *mi; + GtkWidget *label; + + g_object_set_data (G_OBJECT (drawing_area), + "gtk-color-sel", + colorsel); + + menu = gtk_menu_new (); + + label = gtk_label_new_with_mnemonic (_("_Save color here")); + mi = gtk_menu_item_new (); + gtk_container_add (GTK_CONTAINER (mi), label); + + gtk_signal_connect (GTK_OBJECT (mi), "activate", + GTK_SIGNAL_FUNC (save_color_selected), + drawing_area); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + + gtk_widget_show_all (mi); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, + popup_position_func, drawing_area, + 3, timestamp); +} + + +static gint +palette_press (GtkWidget *drawing_area, + GdkEventButton *event, + gpointer data) +{ + GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data); + + gtk_widget_grab_focus (drawing_area); + + if (event->button == 1 && + event->type == GDK_BUTTON_PRESS) + { + if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0) + { + gdouble color[4]; + palette_get_color (drawing_area, color); + gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color); + } + } + + if (event->button == 3 && + event->type == GDK_BUTTON_PRESS) + { + do_popup (colorsel, drawing_area, event->time); + } + + return TRUE; +} + +static void +palette_unset_color (GtkWidget *drawing_area) +{ + if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0) + return; + + gtk_widget_reset_rc_styles (drawing_area); + gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0)); } static void @@ -780,7 +945,7 @@ palette_drop_handle (GtkWidget *widget, color[1] = (gdouble)vals[1] / 0xffff; color[2] = (gdouble)vals[2] / 0xffff; color[3] = (gdouble)vals[3] / 0xffff; - palette_set_color (widget, GTK_COLOR_SELECTION (data), color); + palette_change_color (widget, GTK_COLOR_SELECTION (data), color); gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color); } @@ -789,37 +954,63 @@ palette_activate (GtkWidget *widget, GdkEventKey *event, gpointer data) { - GtkColorSelection *colorsel = data; - ColorSelectionPrivate *priv; - + /* should have a drawing area subclass with an activate signal */ if ((event->keyval == ' ') || (event->keyval == GDK_Return)) { - priv = colorsel->private_data; - palette_set_color (widget, GTK_COLOR_SELECTION (data), priv->color); + if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "color_set")) != 0) + { + gdouble color[4]; + palette_get_color (widget, color); + gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color); + } return TRUE; } return FALSE; } +static void +palette_popup (GtkWidget *widget, + gpointer data) +{ + GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data); + + do_popup (colorsel, widget, GDK_CURRENT_TIME); +} + + static GtkWidget* palette_new (GtkColorSelection *colorsel) { GtkWidget *retval; + ColorSelectionPrivate *priv; static const GtkTargetEntry targets[] = { { "application/x-color", 0 } }; + + priv = colorsel->private_data; retval = gtk_drawing_area_new (); + + GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS); + gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0)); - gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK); + gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_EXPOSURE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK); gtk_signal_connect (GTK_OBJECT (retval), "expose_event", GTK_SIGNAL_FUNC (palette_expose), colorsel); gtk_signal_connect (GTK_OBJECT (retval), "button_press_event", GTK_SIGNAL_FUNC (palette_press), colorsel); + gtk_signal_connect (GTK_OBJECT (retval), "key_press_event", + GTK_SIGNAL_FUNC (palette_activate), colorsel); + gtk_signal_connect (GTK_OBJECT (retval), "popup_menu", + GTK_SIGNAL_FUNC (palette_popup), colorsel); gtk_drag_dest_set (retval, GTK_DEST_DEFAULT_HIGHLIGHT | @@ -832,9 +1023,11 @@ palette_new (GtkColorSelection *colorsel) GTK_SIGNAL_FUNC (palette_drag_end), NULL); gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received", GTK_SIGNAL_FUNC (palette_drop_handle), colorsel); - gtk_signal_connect (GTK_OBJECT (retval), "key_press_event", - GTK_SIGNAL_FUNC (palette_activate), colorsel); - + + gtk_tooltips_set_tip (priv->tooltips, + retval, + _("This is a palette entry used for quick access to commonly-used colors. Double click it to make this color the current color. To change this entry, drag a color swatch here or right-click it and select \"Save color here.\""), + NULL); return retval; } @@ -870,7 +1063,7 @@ initialize_cursor (void) } static void -grab_color_at_mouse (GtkWidget *button, +grab_color_at_mouse (GtkWidget *invisible, gint x_root, gint y_root, gpointer data) @@ -905,15 +1098,29 @@ grab_color_at_mouse (GtkWidget *button, } static void -mouse_motion (GtkWidget *button, +shutdown_eyedropper (GtkWidget *widget) +{ + GtkColorSelection *colorsel; + ColorSelectionPrivate *priv; + + colorsel = GTK_COLOR_SELECTION (widget); + priv = colorsel->private_data; + + gdk_keyboard_ungrab (gtk_get_current_event_time ()); + gdk_pointer_ungrab (gtk_get_current_event_time ()); + gtk_grab_remove (priv->dropper_grab_widget); +} + +static void +mouse_motion (GtkWidget *invisible, GdkEventMotion *event, gpointer data) { - grab_color_at_mouse (button, event->x_root, event->y_root, data); + grab_color_at_mouse (invisible, event->x_root, event->y_root, data); } static gboolean -mouse_release (GtkWidget *button, +mouse_release (GtkWidget *invisible, GdkEventButton *event, gpointer data) { @@ -921,36 +1128,77 @@ mouse_release (GtkWidget *button, ColorSelectionPrivate *priv; priv = colorsel->private_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (button), + if (event->button != 1) + return FALSE; + + grab_color_at_mouse (invisible, event->x_root, event->y_root, data); + + shutdown_eyedropper (GTK_WIDGET (data)); + + gtk_signal_disconnect_by_func (GTK_OBJECT (invisible), GTK_SIGNAL_FUNC (mouse_motion), data); - gtk_signal_disconnect_by_func (GTK_OBJECT (button), + gtk_signal_disconnect_by_func (GTK_OBJECT (invisible), GTK_SIGNAL_FUNC (mouse_release), data); - - grab_color_at_mouse (button, event->x_root, event->y_root, data); - gdk_pointer_ungrab (0); + return TRUE; } /* Helper Functions */ + +static gboolean mouse_press (GtkWidget *invisible, + GdkEventButton *event, + gpointer data); + +static gboolean +key_press (GtkWidget *invisible, + GdkEventKey *event, + gpointer data) +{ + if (event->keyval == GDK_Escape) + { + shutdown_eyedropper (data); + + gtk_signal_disconnect_by_func (GTK_OBJECT (invisible), + GTK_SIGNAL_FUNC (mouse_press), + data); + gtk_signal_disconnect_by_func (GTK_OBJECT (invisible), + GTK_SIGNAL_FUNC (key_press), + data); + + return TRUE; + } + + return FALSE; +} + static gboolean -mouse_press (GtkWidget *button, +mouse_press (GtkWidget *invisible, GdkEventButton *event, gpointer data) { GtkColorSelection *colorsel = data; ColorSelectionPrivate *priv; priv = colorsel->private_data; + + if (event->type == GDK_BUTTON_PRESS && + event->button == 1) + { + gtk_signal_connect (GTK_OBJECT (invisible), "motion_notify_event", + GTK_SIGNAL_FUNC (mouse_motion), + data); + gtk_signal_connect (GTK_OBJECT (invisible), "button_release_event", + GTK_SIGNAL_FUNC (mouse_release), + data); + gtk_signal_disconnect_by_func (GTK_OBJECT (invisible), + GTK_SIGNAL_FUNC (mouse_press), + data); + gtk_signal_disconnect_by_func (GTK_OBJECT (invisible), + GTK_SIGNAL_FUNC (key_press), + data); + return TRUE; + } - gtk_signal_connect (GTK_OBJECT (button), "motion_notify_event", - GTK_SIGNAL_FUNC (mouse_motion), - data); - gtk_signal_connect (GTK_OBJECT (button), "button_release_event", - GTK_SIGNAL_FUNC (mouse_release), - data); - gtk_signal_disconnect_by_func (GTK_OBJECT (button), - GTK_SIGNAL_FUNC (mouse_press), - data); - return TRUE; + return FALSE; } /* when the button is clicked */ @@ -964,30 +1212,43 @@ get_screen_color (GtkWidget *button) { initialize_cursor (); } - - /* Why do we do this? Because the "clicked" signal will be emitted after the "button_released" - signal. We don't want to do this stuff again, though, or else it will get trapped here. So, - priv->moving_dropper is initialized to FALSE at the initialization of the colorselector, - it is initialized to true when we start waiting for the user to click the the dropper on a - color, and whenver it is true when this function starts to execute, we set it to false. */ - if (priv->moving_dropper == FALSE) + + if (priv->dropper_grab_widget == NULL) { - priv->moving_dropper = TRUE; + priv->dropper_grab_widget = gtk_invisible_new (); - gtk_signal_connect (GTK_OBJECT (button), "button_press_event", - GTK_SIGNAL_FUNC (mouse_press), colorsel); + gtk_widget_add_events (priv->dropper_grab_widget, + GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); - gdk_pointer_grab (button->window, - FALSE, - GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK, - NULL, - picker_cursor, - 0); + gtk_widget_show (priv->dropper_grab_widget); } - else + + if (gdk_keyboard_grab (priv->dropper_grab_widget->window, + FALSE, + gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS) { - priv->moving_dropper = FALSE; + g_warning ("Failed to grab keyboard to do eyedropper"); + return; } + + if (gdk_pointer_grab (priv->dropper_grab_widget->window, + FALSE, + GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK, + NULL, + picker_cursor, + gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS) + { + gdk_keyboard_ungrab (GDK_CURRENT_TIME); + g_warning ("Failed to grab pointer to do eyedropper"); + return; + } + + gtk_grab_add (priv->dropper_grab_widget); + + gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "button_press_event", + GTK_SIGNAL_FUNC (mouse_press), colorsel); + gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "key_press_event", + GTK_SIGNAL_FUNC (key_press), colorsel); } static void @@ -1125,24 +1386,6 @@ opacity_entry_changed (GtkWidget *opacity_entry, g_free (text); } -static gboolean -widget_focus_in (GtkWidget *drawing_area, - GdkEventFocus *event, - gpointer data) -{ - GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data); - ColorSelectionPrivate *priv = colorsel->private_data; - - /* This signal is connected to by all of the widgets except the "Set Color" button - * This will let you add a color to the currently selected palette - */ - - priv->last_palette = NULL; - - return FALSE; -} - - static void make_label_spinbutton (GtkColorSelection *colorsel, GtkWidget **spinbutton, @@ -1150,10 +1393,12 @@ make_label_spinbutton (GtkColorSelection *colorsel, GtkWidget *table, gint i, gint j, - gint channel_type) + gint channel_type, + const gchar *tooltip) { GtkWidget *label; GtkAdjustment *adjust; + ColorSelectionPrivate *priv = colorsel->private_data; if (channel_type == COLORSEL_HUE) { @@ -1166,8 +1411,8 @@ make_label_spinbutton (GtkColorSelection *colorsel, gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel); *spinbutton = gtk_spin_button_new (adjust, 10.0, 0); - gtk_signal_connect (GTK_OBJECT (*spinbutton), "focus_in_event", - GTK_SIGNAL_FUNC (widget_focus_in), colorsel); + gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL); + gtk_signal_connect (GTK_OBJECT (adjust), "value_changed", GTK_SIGNAL_FUNC (adjustment_changed), GINT_TO_POINTER (channel_type)); @@ -1204,12 +1449,7 @@ set_selected_palette (GtkColorSelection *colorsel, int x, int y) { ColorSelectionPrivate *priv = colorsel->private_data; - if (priv->last_palette != NULL) - gtk_widget_queue_clear (priv->last_palette); - - priv->last_palette = priv->custom_palette[x][y]; - - gtk_widget_queue_clear (priv->last_palette); + gtk_widget_grab_focus (priv->custom_palette[x][y]); } static double @@ -1273,45 +1513,82 @@ update_color (GtkColorSelection *colorsel) priv->changing = FALSE; } + static void -add_button_pressed (GtkWidget *button, - GtkColorSelection *colorsel) +fill_palette_from_string (const gchar *str) { - ColorSelectionPrivate *priv; - gint i, j; + GdkColor *colors = NULL; + gint n_colors = 0; + + if (str == NULL) + return; - priv = colorsel->private_data; + if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors)) + return; + + if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT)) + n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT; + + memcpy (current_colors, colors, sizeof (GdkColor) * n_colors); + + g_free (colors); +} + +static void +palette_change_notify_class (GObject *object, + GParamSpec *pspec) +{ + gchar *str = NULL; + + g_object_get (object, pspec->name, &str, NULL); + + fill_palette_from_string (str); + + g_free (str); +} + +static void +update_palette (GtkColorSelection *colorsel) +{ + gint i, j; - for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++) + for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++) { - for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++) + for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++) { - /* Either last_palette is set and we're on it, or it's an empty palette */ - if ((priv->last_palette && priv->last_palette == priv->custom_palette[i][j]) || - ((priv->last_palette == NULL) && - (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[i][j]), - "color_set")) == 0))) - { - palette_set_color (priv->custom_palette[i][j], colorsel, priv->color); - - /* forward the selection */ - if ((i == GTK_CUSTOM_PALETTE_WIDTH - 1) && (j == GTK_CUSTOM_PALETTE_HEIGHT - 1)) - set_selected_palette (colorsel, 0, 0); - else if (i == GTK_CUSTOM_PALETTE_WIDTH - 1) - set_selected_palette (colorsel, 0, j + 1); - else - set_selected_palette (colorsel, i + 1, j); - - return; - } + gint index; + + index = i * GTK_CUSTOM_PALETTE_WIDTH + j; + + gtk_color_selection_set_palette_color (colorsel, + index, + ¤t_colors[index]); } } +} + +static void +palette_change_notify_instance (GObject *object, + GParamSpec *pspec, + gpointer data) +{ + update_palette (GTK_COLOR_SELECTION (data)); +} + +static void +default_change_palette_func (const GdkColor *colors, + gint n_colors) +{ + gchar *str; + + str = gtk_color_selection_palette_to_string (colors, n_colors); - /* the palette is totally full. Add to the first one totally arbitrarily */ - palette_set_color (priv->custom_palette[0][0], colorsel, priv->color); + gtk_settings_set_string_property (gtk_settings_get_global (), + "gtk-color-palette", + str, + "gtk_color_selection_palette_to_string"); - /* forward the selection */ - set_selected_palette (colorsel, 1, 0); + g_free (str); } GtkType @@ -1343,13 +1620,16 @@ static void gtk_color_selection_class_init (GtkColorSelectionClass *klass) { GtkObjectClass *object_class; + GObjectClass *gobject_class; - object_class = (GtkObjectClass*) klass; + object_class = GTK_OBJECT_CLASS (klass); + gobject_class = G_OBJECT_CLASS (klass); parent_class = gtk_type_class (GTK_TYPE_VBOX); object_class->destroy = gtk_color_selection_destroy; - + gobject_class->finalize = gtk_color_selection_finalize; + color_selection_signals[COLOR_CHANGED] = gtk_signal_new ("color_changed", GTK_RUN_FIRST, @@ -1357,9 +1637,26 @@ gtk_color_selection_class_init (GtkColorSelectionClass *klass) GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed), gtk_marshal_VOID__VOID, GTK_TYPE_NONE, 0); + + gtk_settings_install_property (gtk_settings_get_global (), + g_param_spec_string ("gtk-color-palette", + _("Custom palette"), + _("Palette to use in the color selector"), + default_colors, + G_PARAM_READWRITE)); + + fill_palette_from_string (default_colors); + + change_palette_hook = default_change_palette_func; + + g_signal_connect_data (G_OBJECT (gtk_settings_get_global ()), + "notify::gtk-color-palette", + G_CALLBACK (palette_change_notify_class), + NULL, NULL, FALSE, FALSE); } /* widget functions */ + static void gtk_color_selection_init (GtkColorSelection *colorsel) { @@ -1378,8 +1675,8 @@ gtk_color_selection_init (GtkColorSelection *colorsel) priv->changing = FALSE; priv->default_set = FALSE; priv->default_alpha_set = FALSE; - priv->last_palette = NULL; - priv->moving_dropper = FALSE; + + priv->tooltips = gtk_tooltips_new (); gtk_box_set_spacing (GTK_BOX (colorsel), 4); top_hbox = gtk_hbox_new (FALSE, 8); @@ -1392,6 +1689,8 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15); gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0); + gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel, + _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL); hbox = gtk_hbox_new (FALSE, 4); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); @@ -1404,8 +1703,7 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); button = gtk_button_new (); - gtk_signal_connect (GTK_OBJECT (button), "focus_in_event", - GTK_SIGNAL_FUNC (widget_focus_in), colorsel); + gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel); gtk_signal_connect (GTK_OBJECT (button), "clicked", @@ -1417,6 +1715,10 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gdk_pixmap_unref (mask); gtk_container_add (GTK_CONTAINER (button), dropper_image); gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); + + gtk_tooltips_set_tip (priv->tooltips, + button, + _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL); top_right_vbox = gtk_vbox_new (FALSE, 4); gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0); @@ -1425,12 +1727,18 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 4); - make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE); - make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION); - make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE); - make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED); - make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN); - make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE); + make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE, + _("Position on the color wheel.")); + make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION, + _("\"Deepness\" of the color.")); + make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE, + _("Brightness of the color.")); + make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED, + _("Amount of red light in the color.")); + make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN, + _("Amount of green light in the color.")); + make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE, + _("Amount of blue light in the color.")); gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4); priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:")); @@ -1439,6 +1747,9 @@ gtk_color_selection_init (GtkColorSelection *colorsel) adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0)); gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel); priv->opacity_slider = gtk_hscale_new (adjust); + gtk_tooltips_set_tip (priv->tooltips, + priv->opacity_slider, + _("Transparency of the currently-selected color."), NULL); gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label), priv->opacity_slider); gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE); @@ -1448,13 +1759,12 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5); priv->opacity_entry = gtk_entry_new (); gtk_widget_set_usize (priv->opacity_entry, 40, 0); - gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "focus_in_event", - GTK_SIGNAL_FUNC (widget_focus_in), colorsel); + gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate", GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel); gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5); - label = gtk_label_new_with_mnemonic (_("He_x Value:")); + label = gtk_label_new_with_mnemonic (_("Color _Name:")); gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); priv->hex_entry = gtk_entry_new (); @@ -1464,6 +1774,10 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate", GTK_SIGNAL_FUNC (hex_changed), colorsel); + gtk_tooltips_set_tip (priv->tooltips, + priv->hex_entry, + _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL); + gtk_widget_set_usize (priv->hex_entry, 75, -1); gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15); gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6); @@ -1480,20 +1794,32 @@ gtk_color_selection_init (GtkColorSelection *colorsel) } } set_selected_palette (colorsel, 0, 0); - priv->palette_frame = gtk_frame_new (_("Custom Palette")); + priv->palette_frame = gtk_frame_new (NULL); + label = gtk_label_new_with_mnemonic (_("_Palette")); + gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), + priv->custom_palette[0][0]); + gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0); vbox = gtk_vbox_new (FALSE, 4); gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); - button = gtk_button_new_with_mnemonic (_("Set _Color")); - - gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_button_pressed), colorsel); - - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); gtk_widget_show_all (top_hbox); + + /* Set default colors */ + + update_palette (colorsel); + + g_signal_connect_data (G_OBJECT (gtk_settings_get_global ()), + "notify::gtk-color-palette", + G_CALLBACK (palette_change_notify_instance), + colorsel, NULL, FALSE, FALSE); + + /* hide unused stuff */ if (priv->has_opacity == FALSE) { @@ -1512,6 +1838,27 @@ static void gtk_color_selection_destroy (GtkObject *object) { GtkColorSelection *cselection = GTK_COLOR_SELECTION (object); + ColorSelectionPrivate *priv = cselection->private_data; + + if (priv->dropper_grab_widget) + { + gtk_widget_destroy (priv->dropper_grab_widget); + priv->dropper_grab_widget = NULL; + } + + if (priv->tooltips) + { + gtk_object_destroy (priv->tooltips); + priv->tooltips = NULL; + } + + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +static void +gtk_color_selection_finalize (GObject *object) +{ + GtkColorSelection *cselection = GTK_COLOR_SELECTION (object); if (cselection->private_data) { @@ -1519,11 +1866,10 @@ gtk_color_selection_destroy (GtkObject *object) cselection->private_data = NULL; } - GTK_OBJECT_CLASS (parent_class)->destroy (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } - /** * gtk_color_selection_new: * @@ -1969,7 +2315,7 @@ gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel) * Set the palette located at at @index to have @color set as its color. * **/ -void +static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel, gint index, GdkColor *color) @@ -2005,7 +2351,7 @@ gtk_color_selection_set_palette_color (GtkColorSelection *colorsel, * Return value: TRUE if the palette located at @index has a color set. FALSE * if it doesn't. **/ -gboolean +static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel, gint index, GdkColor *color) @@ -2043,7 +2389,7 @@ gtk_color_selection_get_palette_color (GtkColorSelection *colorsel, * Change the palette located @index to have no color set. * **/ -void +static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel, gint index) { @@ -2069,7 +2415,7 @@ gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel, * * Return value: the maximum number of palette indexes **/ -gint +static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel) { return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT; @@ -2097,3 +2443,163 @@ gtk_color_selection_is_adjusting (GtkColorSelection *colorsel) return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel))); } + + +/** + * gtk_color_selection_palette_from_string: + * @str: a string encoding a color palette + * @colors: return location for allocated array of GdkColor + * @n_colors: return location for length of array + * + * Parses a color palette string; the string is a colon-separated + * list of color names readable by gdk_color_parse(). + * + * Return value: %TRUE if a palette was successfully parsed + **/ +gboolean +gtk_color_selection_palette_from_string (const gchar *str, + GdkColor **colors, + gint *n_colors) +{ + GdkColor *retval; + gint count; + gchar *p; + gchar *start; + gchar *copy; + + count = 0; + retval = NULL; + copy = g_strdup (str); + + start = copy; + p = copy; + while (TRUE) + { + if (*p == ':' || *p == '\0') + { + gboolean done = TRUE; + + if (start == p) + { + goto failed; /* empty entry */ + } + + if (*p) + { + *p = '\0'; + done = FALSE; + } + + retval = g_renew (GdkColor, retval, count + 1); + if (!gdk_color_parse (start, retval + count)) + { + goto failed; + } + + ++count; + + if (done) + break; + else + start = p + 1; + } + + ++p; + } + + g_free (copy); + + if (colors) + *colors = retval; + else + g_free (retval); + + if (n_colors) + *n_colors = count; + + return TRUE; + + failed: + g_free (copy); + g_free (retval); + + if (colors) + *colors = NULL; + if (n_colors) + *n_colors = 0; + + return FALSE; +} + +/** + * gtk_color_selection_palette_to_string: + * @colors: an array of colors + * @n_colors: length of the array + * + * Encodes a palette as a string, useful for persistent storage. + * + * Return value: allocated string encoding the palette + **/ +gchar* +gtk_color_selection_palette_to_string (const GdkColor *colors, + gint n_colors) +{ + gint i; + gchar **strs = NULL; + gchar *retval; + + if (n_colors == 0) + return g_strdup (""); + + strs = g_new0 (gchar*, n_colors + 1); + + i = 0; + while (i < n_colors) + { + gchar *ptr; + + strs[i] = + g_strdup_printf ("#%2X%2X%2X", + colors[i].red / 256, + colors[i].green / 256, + colors[i].blue / 256); + + for (ptr = strs[i]; *ptr; ptr++) + if (*ptr == ' ') + *ptr = '0'; + + ++i; + } + + retval = g_strjoinv (":", strs); + + g_strfreev (strs); + + return retval; +} + +/** + * gtk_color_selection_set_change_palette_hook: + * @func: a function to call when the custom palette needs saving + * + * Installs a global function to be called whenever the user tries to + * modify the palette in a color selection. This function should save + * the new palette contents, and update the GtkSettings property + * "gtk-color-palette" so all GtkColorSelection widgets will be modified. + * + * Return value: the previous change palette hook (that was replaced) + **/ +GtkColorSelectionChangePaletteFunc +gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func) +{ + GtkColorSelectionChangePaletteFunc old; + + old = change_palette_hook; + + change_palette_hook = func; + + return old; +} + + + diff --git a/gtk/gtkcolorsel.h b/gtk/gtkcolorsel.h index 9c09f70c7..85d1328d6 100644 --- a/gtk/gtkcolorsel.h +++ b/gtk/gtkcolorsel.h @@ -47,6 +47,9 @@ typedef struct _GtkColorSelection GtkColorSelection; typedef struct _GtkColorSelectionClass GtkColorSelectionClass; +typedef void (* GtkColorSelectionChangePaletteFunc) (const GdkColor *colors, + gint n_colors); + struct _GtkColorSelection { GtkVBox parent_instance; @@ -63,7 +66,7 @@ struct _GtkColorSelectionClass }; -/* ColorSelection */ +/* ColorSelection */ GtkType gtk_color_selection_get_type (void) G_GNUC_CONST; GtkWidget *gtk_color_selection_new (void); @@ -91,17 +94,16 @@ void gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel, void gtk_color_selection_get_previous_color (GtkColorSelection *colorsel, GdkColor *color); guint16 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel); -gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel); -gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel, - gint index, - GdkColor *color); -void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel, - gint index, - GdkColor *color); -void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel, - gint index); + gboolean gtk_color_selection_is_adjusting (GtkColorSelection *colorsel); +gboolean gtk_color_selection_palette_from_string (const gchar *str, + GdkColor **colors, + gint *n_colors); +gchar* gtk_color_selection_palette_to_string (const GdkColor *colors, + gint n_colors); + +GtkColorSelectionChangePaletteFunc gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func); #ifndef GTK_DISABLE_DEPRECATED /* Deprecated calls: */ diff --git a/gtk/gtkcolorseldialog.c b/gtk/gtkcolorseldialog.c index 54bed6b1a..a80f28e71 100644 --- a/gtk/gtkcolorseldialog.c +++ b/gtk/gtkcolorseldialog.c @@ -109,6 +109,8 @@ gtk_color_selection_dialog_init (GtkColorSelectionDialog *colorseldiag) colorseldiag->help_button = gtk_dialog_add_button (GTK_DIALOG (colorseldiag), GTK_STOCK_HELP, GTK_RESPONSE_HELP); + + gtk_widget_hide (colorseldiag->help_button); } GtkWidget* diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 193ef4912..d7ac30567 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -552,6 +552,12 @@ gtk_entry_class_init (GtkEntryClass *class) add_move_binding (binding_set, GDK_Left, 0, GTK_MOVEMENT_VISUAL_POSITIONS, -1); + add_move_binding (binding_set, GDK_KP_Right, 0, + GTK_MOVEMENT_VISUAL_POSITIONS, 1); + + add_move_binding (binding_set, GDK_KP_Left, 0, + GTK_MOVEMENT_VISUAL_POSITIONS, -1); + add_move_binding (binding_set, GDK_f, GDK_CONTROL_MASK, GTK_MOVEMENT_LOGICAL_POSITIONS, 1); @@ -563,6 +569,12 @@ gtk_entry_class_init (GtkEntryClass *class) add_move_binding (binding_set, GDK_Left, GDK_CONTROL_MASK, GTK_MOVEMENT_WORDS, -1); + + add_move_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK, + GTK_MOVEMENT_WORDS, 1); + + add_move_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK, + GTK_MOVEMENT_WORDS, -1); add_move_binding (binding_set, GDK_a, GDK_CONTROL_MASK, GTK_MOVEMENT_PARAGRAPH_ENDS, -1); @@ -581,6 +593,12 @@ gtk_entry_class_init (GtkEntryClass *class) add_move_binding (binding_set, GDK_End, 0, GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1); + + add_move_binding (binding_set, GDK_KP_Home, 0, + GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1); + + add_move_binding (binding_set, GDK_KP_End, 0, + GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1); add_move_binding (binding_set, GDK_Home, GDK_CONTROL_MASK, GTK_MOVEMENT_BUFFER_ENDS, -1); @@ -588,12 +606,31 @@ gtk_entry_class_init (GtkEntryClass *class) add_move_binding (binding_set, GDK_End, GDK_CONTROL_MASK, GTK_MOVEMENT_BUFFER_ENDS, 1); + add_move_binding (binding_set, GDK_KP_Home, GDK_CONTROL_MASK, + GTK_MOVEMENT_BUFFER_ENDS, -1); + + add_move_binding (binding_set, GDK_KP_End, GDK_CONTROL_MASK, + GTK_MOVEMENT_BUFFER_ENDS, 1); + + /* Activate */ + + gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, + "activate", 0); + + gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, + "activate", 0); + /* Deleting text */ gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0, "delete_from_cursor", 2, GTK_TYPE_ENUM, GTK_DELETE_CHARS, GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, 0, + "delete_from_cursor", 2, + GTK_TYPE_ENUM, GTK_DELETE_CHARS, + GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_d, GDK_CONTROL_MASK, "delete_from_cursor", 2, GTK_TYPE_ENUM, GTK_DELETE_CHARS, @@ -609,6 +646,11 @@ gtk_entry_class_init (GtkEntryClass *class) GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS, GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, GDK_CONTROL_MASK, + "delete_from_cursor", 2, + GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS, + GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_d, GDK_MOD1_MASK, "delete_from_cursor", 2, GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS, @@ -882,7 +924,9 @@ gtk_entry_realize (GtkWidget *widget) GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK); + GDK_POINTER_MOTION_HINT_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); @@ -1463,11 +1507,6 @@ gtk_entry_key_press (GtkWidget *widget, /* Activate key bindings */ return TRUE; - else if (event->keyval == GDK_Return) - { - gtk_widget_activate (widget); - return TRUE; - } return FALSE; } diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c index 2a982efc4..6da7f1eb2 100644 --- a/gtk/gtkfilesel.c +++ b/gtk/gtkfilesel.c @@ -1430,8 +1430,6 @@ gtk_file_selection_key_press (GtkWidget *widget, g_free (text); - gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event"); - return TRUE; } diff --git a/gtk/gtkfontsel.c b/gtk/gtkfontsel.c index 62e654d7b..1ddbd2eb8 100644 --- a/gtk/gtkfontsel.c +++ b/gtk/gtkfontsel.c @@ -86,13 +86,6 @@ static void gtk_font_selection_select_font (GtkWidget *w, gint column, GdkEventButton *bevent, gpointer data); -static gint gtk_font_selection_on_clist_key_press (GtkWidget *clist, - GdkEventKey *event, - GtkFontSelection *fs); -static gboolean gtk_font_selection_select_next (GtkFontSelection *fs, - GtkWidget *clist, - gint step); - static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs); static void gtk_font_selection_show_available_styles (GtkFontSelection *fs); @@ -106,8 +99,7 @@ static void gtk_font_selection_select_style (GtkWidget *w, static void gtk_font_selection_select_best_size (GtkFontSelection *fs); static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs); -static gint gtk_font_selection_size_key_press (GtkWidget *w, - GdkEventKey *event, +static void gtk_font_selection_size_activate (GtkWidget *w, gpointer data); static void gtk_font_selection_select_size (GtkWidget *w, gint row, @@ -206,8 +198,8 @@ gtk_font_selection_init(GtkFontSelection *fontsel) gtk_widget_show (fontsel->size_entry); gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2, GTK_FILL, 0, 0, 0); - gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "key_press_event", - (GtkSignalFunc) gtk_font_selection_size_key_press, + gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "activate", + (GtkSignalFunc) gtk_font_selection_size_activate, fontsel); fontsel->font_label = gtk_label_new_with_mnemonic (_("_Family:")); @@ -285,9 +277,10 @@ gtk_font_selection_init(GtkFontSelection *fontsel) GTK_SIGNAL_FUNC(gtk_font_selection_select_font), fontsel); GTK_WIDGET_SET_FLAGS (fontsel->font_clist, GTK_CAN_FOCUS); - gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "key_press_event", - GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press), - fontsel); + + gtk_signal_connect_after (GTK_OBJECT (fontsel->font_clist), "expose_event", + GTK_SIGNAL_FUNC(gtk_font_selection_expose_list), + fontsel); gtk_font_selection_show_available_styles (fontsel); @@ -295,10 +288,6 @@ gtk_font_selection_init(GtkFontSelection *fontsel) GTK_SIGNAL_FUNC(gtk_font_selection_select_style), fontsel); GTK_WIDGET_SET_FLAGS (fontsel->font_style_clist, GTK_CAN_FOCUS); - gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist), - "key_press_event", - GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press), - fontsel); gtk_font_selection_show_available_sizes (fontsel); @@ -306,9 +295,6 @@ gtk_font_selection_init(GtkFontSelection *fontsel) GTK_SIGNAL_FUNC(gtk_font_selection_select_size), fontsel); GTK_WIDGET_SET_FLAGS (fontsel->size_clist, GTK_CAN_FOCUS); - gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "key_press_event", - GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press), - fontsel); /* create the text entry widget */ text_frame = gtk_frame_new (_("Preview:")); @@ -477,59 +463,6 @@ gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel) pango_font_map_free_families (families, n_families); } -static gint -gtk_font_selection_on_clist_key_press (GtkWidget *clist, - GdkEventKey *event, - GtkFontSelection *fontsel) -{ -#ifdef FONTSEL_DEBUG - g_message("In on_clist_key_press\n"); -#endif - if (event->keyval == GDK_Up) - return gtk_font_selection_select_next (fontsel, clist, -1); - else if (event->keyval == GDK_Down) - return gtk_font_selection_select_next (fontsel, clist, 1); - else - return FALSE; -} - - -static gboolean -gtk_font_selection_select_next (GtkFontSelection *fontsel, - GtkWidget *clist, - gint step) -{ - GList *selection; - gint current_row, row; - - selection = GTK_CLIST(clist)->selection; - if (!selection) - return FALSE; - current_row = GPOINTER_TO_INT (selection->data); - - /* Stop the normal clist key handler from being run. */ - gtk_signal_emit_stop_by_name (GTK_OBJECT (clist), "key_press_event"); - - for (row = current_row + step; - row >= 0 && row < GTK_CLIST(clist)->rows; - row += step) - { - /* If this is the style clist, make sure that the item is not a charset - entry. */ - if (clist == fontsel->font_style_clist) - if (GPOINTER_TO_INT (gtk_clist_get_row_data(GTK_CLIST(clist), row)) == -1) - continue; - - /* Now we've found the row to select. */ - if (gtk_clist_row_is_visible(GTK_CLIST(clist), row) - != GTK_VISIBILITY_FULL) - gtk_clist_moveto(GTK_CLIST(clist), row, -1, (step < 0) ? 0 : 1, 0); - gtk_clist_select_row(GTK_CLIST(clist), row, 0); - break; - } - return TRUE; -} - static int compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b) { @@ -699,31 +632,24 @@ gtk_font_selection_select_best_size (GtkFontSelection *fontsel) /* If the user hits return in the font size entry, we change to the new font size. */ -static gint -gtk_font_selection_size_key_press (GtkWidget *w, - GdkEventKey *event, - gpointer data) +static void +gtk_font_selection_size_activate (GtkWidget *w, + gpointer data) { GtkFontSelection *fontsel; gint new_size; gchar *text; fontsel = GTK_FONT_SELECTION (data); + + text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry)); + new_size = atoi (text) * PANGO_SCALE; - if (event->keyval == GDK_Return) + if (fontsel->font_desc->size != new_size) { - text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry)); - new_size = atoi (text) * PANGO_SCALE; - - if (fontsel->font_desc->size != new_size) - { - fontsel->font_desc->size = new_size; - gtk_font_selection_load_font (fontsel); - } - return TRUE; + fontsel->font_desc->size = new_size; + gtk_font_selection_load_font (fontsel); } - - return FALSE; } /* This is called when a size is selected in the list. */ diff --git a/gtk/gtkhscale.c b/gtk/gtkhscale.c index 1f654518e..43739548b 100644 --- a/gtk/gtkhscale.c +++ b/gtk/gtkhscale.c @@ -29,6 +29,7 @@ #include "gtksignal.h" #include "gdk/gdkkeysyms.h" #include "gtkintl.h" +#include "gtkbindings.h" #define SCALE_CLASS(w) GTK_SCALE_GET_CLASS (w) #define RANGE_CLASS(w) GTK_RANGE_GET_CLASS (w) @@ -65,10 +66,7 @@ static void gtk_hscale_pos_background (GtkHScale *hscale, gint *h); static void gtk_hscale_draw_slider (GtkRange *range); static void gtk_hscale_draw_value (GtkScale *scale); -static gboolean gtk_hscale_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos); + static void gtk_hscale_clear_background (GtkRange *range); @@ -97,6 +95,12 @@ gtk_hscale_get_type (void) return hscale_type; } +#define add_slider_binding(binding_set, keyval, mask, scroll, trough) \ + gtk_binding_entry_add_signal (binding_set, keyval, mask, \ + "move_slider", 2, \ + GTK_TYPE_SCROLL_TYPE, scroll, \ + GTK_TYPE_TROUGH_TYPE, trough) + static void gtk_hscale_class_init (GtkHScaleClass *class) { @@ -105,7 +109,8 @@ gtk_hscale_class_init (GtkHScaleClass *class) GtkWidgetClass *widget_class; GtkRangeClass *range_class; GtkScaleClass *scale_class; - + GtkBindingSet *binding_set; + gobject_class = (GObjectClass*) class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; @@ -123,7 +128,6 @@ gtk_hscale_class_init (GtkHScaleClass *class) range_class->trough_click = _gtk_range_default_htrough_click; range_class->motion = _gtk_range_default_hmotion; range_class->draw_slider = gtk_hscale_draw_slider; - range_class->trough_keys = gtk_hscale_trough_keys; range_class->clear_background = gtk_hscale_clear_background; scale_class->draw_value = gtk_hscale_draw_value; @@ -135,7 +139,45 @@ gtk_hscale_class_init (GtkHScaleClass *class) _("The GtkAdjustment that determines the values to use for this HScale."), GTK_TYPE_ADJUSTMENT, G_PARAM_READWRITE)); + binding_set = gtk_binding_set_by_class (object_class); + + add_slider_binding (binding_set, GDK_Left, 0, + GTK_SCROLL_STEP_LEFT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Left, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_LEFT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Left, 0, + GTK_SCROLL_STEP_LEFT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_LEFT, GTK_TROUGH_NONE); + + + add_slider_binding (binding_set, GDK_Right, 0, + GTK_SCROLL_STEP_RIGHT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Right, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_RIGHT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Right, 0, + GTK_SCROLL_STEP_RIGHT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_RIGHT, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Home, 0, + GTK_SCROLL_NONE, GTK_TROUGH_START); + add_slider_binding (binding_set, GDK_KP_Home, 0, + GTK_SCROLL_NONE, GTK_TROUGH_START); + + + add_slider_binding (binding_set, GDK_End, 0, + GTK_SCROLL_NONE, GTK_TROUGH_END); + + add_slider_binding (binding_set, GDK_KP_End, 0, + GTK_SCROLL_NONE, GTK_TROUGH_END); } static void @@ -555,38 +597,3 @@ gtk_hscale_draw_value (GtkScale *scale) g_object_unref (G_OBJECT (layout)); } } - -static gboolean -gtk_hscale_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos) -{ - gint return_val = FALSE; - switch (key->keyval) - { - case GDK_Left: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *scroll = GTK_SCROLL_PAGE_LEFT; - else - *scroll = GTK_SCROLL_STEP_LEFT; - break; - case GDK_Right: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *scroll = GTK_SCROLL_PAGE_RIGHT; - else - *scroll = GTK_SCROLL_STEP_RIGHT; - break; - case GDK_Home: - return_val = TRUE; - *pos = GTK_TROUGH_START; - break; - case GDK_End: - return_val = TRUE; - *pos = GTK_TROUGH_END; - break; - } - return return_val; -} diff --git a/gtk/gtkhscrollbar.c b/gtk/gtkhscrollbar.c index 0518ae1d0..63fc1c6cc 100644 --- a/gtk/gtkhscrollbar.c +++ b/gtk/gtkhscrollbar.c @@ -58,10 +58,6 @@ static void gtk_hscrollbar_draw_step_forw (GtkRange *range); static void gtk_hscrollbar_draw_step_back (GtkRange *range); static void gtk_hscrollbar_slider_update (GtkRange *range); static void gtk_hscrollbar_calc_slider_size (GtkHScrollbar *hscrollbar); -static gboolean gtk_hscrollbar_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos); GtkType gtk_hscrollbar_get_type (void) @@ -112,7 +108,6 @@ gtk_hscrollbar_class_init (GtkHScrollbarClass *class) range_class->draw_step_back = gtk_hscrollbar_draw_step_back; range_class->slider_update = gtk_hscrollbar_slider_update; range_class->trough_click = _gtk_range_default_htrough_click; - range_class->trough_keys = gtk_hscrollbar_trough_keys; range_class->motion = _gtk_range_default_hmotion; g_object_class_install_property (gobject_class, @@ -464,38 +459,3 @@ gtk_hscrollbar_calc_slider_size (GtkHScrollbar *hscrollbar) } } } - -static gboolean -gtk_hscrollbar_trough_keys(GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos) -{ - gint return_val = FALSE; - switch (key->keyval) - { - case GDK_Left: - return_val = TRUE; - *scroll = GTK_SCROLL_STEP_BACKWARD; - break; - case GDK_Right: - return_val = TRUE; - *scroll = GTK_SCROLL_STEP_FORWARD; - break; - case GDK_Home: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *scroll = GTK_SCROLL_PAGE_BACKWARD; - else - *pos = GTK_TROUGH_START; - break; - case GDK_End: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *scroll = GTK_SCROLL_PAGE_FORWARD; - else - *pos = GTK_TROUGH_END; - break; - } - return return_val; -} diff --git a/gtk/gtkhsv.c b/gtk/gtkhsv.c index 26f10e63c..2f8b0a086 100644 --- a/gtk/gtkhsv.c +++ b/gtk/gtkhsv.c @@ -331,7 +331,9 @@ gtk_hsv_realize (GtkWidget *widget) attr.event_mask |= (GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK); + | GDK_POINTER_MOTION_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK); attr_mask = GDK_WA_X | GDK_WA_Y; @@ -1275,14 +1277,17 @@ paint_triangle (GtkHSV *hsv, gdk_rgb_gc_set_foreground (priv->gc, 0x000000); else gdk_rgb_gc_set_foreground (priv->gc, 0xffffff); + +#define OUTER_RADIUS 4 +#define INNER_RADIUS 3 gdk_draw_arc (drawable, priv->gc, FALSE, - xx - 3, yy - 3, - 6, 6, + xx - OUTER_RADIUS, yy - OUTER_RADIUS, + OUTER_RADIUS * 2, OUTER_RADIUS * 2, 0, 360 * 64); gdk_draw_arc (drawable, priv->gc, FALSE, - xx - 2, yy - 2, - 4, 4, + xx - INNER_RADIUS, yy - INNER_RADIUS, + INNER_RADIUS * 2, INNER_RADIUS * 2, 0, 360 * 64); } diff --git a/gtk/gtkmarshal.list b/gtk/gtkmarshal.list index 1746d351f..12ec4108d 100644 --- a/gtk/gtkmarshal.list +++ b/gtk/gtkmarshal.list @@ -48,6 +48,7 @@ VOID:BOXED,UINT VOID:BOXED,UINT,FLAGS VOID:BOXED,UINT,UINT VOID:ENUM +VOID:ENUM,ENUM VOID:ENUM,FLOAT VOID:ENUM,FLOAT,BOOL VOID:ENUM,INT diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list index 1746d351f..12ec4108d 100644 --- a/gtk/gtkmarshalers.list +++ b/gtk/gtkmarshalers.list @@ -48,6 +48,7 @@ VOID:BOXED,UINT VOID:BOXED,UINT,FLAGS VOID:BOXED,UINT,UINT VOID:ENUM +VOID:ENUM,ENUM VOID:ENUM,FLOAT VOID:ENUM,FLOAT,BOOL VOID:ENUM,INT diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index b86fcdbb8..afabbc4f2 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -33,6 +33,7 @@ #include <gdk/gdkkeysyms.h> #include <stdio.h> #include "gtkintl.h" +#include "gtkbindings.h" #define TAB_OVERLAP 2 @@ -46,6 +47,8 @@ enum { SWITCH_PAGE, + FOCUS_TAB, + SELECT_PAGE, LAST_SIGNAL }; @@ -111,6 +114,11 @@ struct _GtkNotebookPage static void gtk_notebook_class_init (GtkNotebookClass *klass); static void gtk_notebook_init (GtkNotebook *notebook); +static void gtk_notebook_select_page (GtkNotebook *notebook, + gboolean move_focus); +static void gtk_notebook_focus_tab (GtkNotebook *notebook, + GtkNotebookTab type); + /*** GtkObject Methods ***/ static void gtk_notebook_destroy (GtkObject *object); static void gtk_notebook_set_arg (GtkObject *object, @@ -141,8 +149,6 @@ static gint gtk_notebook_leave_notify (GtkWidget *widget, GdkEventCrossing *event); static gint gtk_notebook_motion_notify (GtkWidget *widget, GdkEventMotion *event); -static gint gtk_notebook_key_press (GtkWidget *widget, - GdkEventKey *event); static gint gtk_notebook_focus_in (GtkWidget *widget, GdkEventFocus *event); static void gtk_notebook_draw_focus (GtkWidget *widget); @@ -274,7 +280,8 @@ gtk_notebook_class_init (GtkNotebookClass *class) GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; - + GtkBindingSet *binding_set; + object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; @@ -297,7 +304,6 @@ gtk_notebook_class_init (GtkNotebookClass *class) widget_class->enter_notify_event = gtk_notebook_enter_notify; widget_class->leave_notify_event = gtk_notebook_leave_notify; widget_class->motion_notify_event = gtk_notebook_motion_notify; - widget_class->key_press_event = gtk_notebook_key_press; widget_class->focus_in_event = gtk_notebook_focus_in; widget_class->style_set = gtk_notebook_style_set; @@ -312,6 +318,9 @@ gtk_notebook_class_init (GtkNotebookClass *class) class->switch_page = gtk_notebook_real_switch_page; + class->focus_tab = gtk_notebook_focus_tab; + class->select_page = gtk_notebook_select_page; + gtk_object_add_arg_type ("GtkNotebook::page", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_PAGE); gtk_object_add_arg_type ("GtkNotebook::tab_pos", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_TAB_POS); gtk_object_add_arg_type ("GtkNotebook::tab_border", GTK_TYPE_UINT, GTK_ARG_WRITABLE, ARG_TAB_BORDER); @@ -338,6 +347,60 @@ gtk_notebook_class_init (GtkNotebookClass *class) GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_UINT); + + notebook_signals[FOCUS_TAB] = + g_signal_newc ("focus_tab", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkNotebookClass, focus_tab), + NULL, NULL, + gtk_marshal_VOID__ENUM, + G_TYPE_NONE, 1, + GTK_TYPE_NOTEBOOK_TAB); + + notebook_signals[SELECT_PAGE] = + g_signal_newc ("select_page", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkNotebookClass, select_page), + NULL, NULL, + gtk_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); + + binding_set = gtk_binding_set_by_class (object_class); + + gtk_binding_entry_add_signal (binding_set, + GDK_Return, 0, + "select_page", 1, + G_TYPE_BOOLEAN, TRUE); + + gtk_binding_entry_add_signal (binding_set, + GDK_KP_Enter, 0, + "select_page", 1, + G_TYPE_BOOLEAN, TRUE); + + gtk_binding_entry_add_signal (binding_set, + GDK_space, 0, + "select_page", 1, + G_TYPE_BOOLEAN, FALSE); + + gtk_binding_entry_add_signal (binding_set, + GDK_Home, 0, + "focus_tab", 1, + GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_FIRST); + gtk_binding_entry_add_signal (binding_set, + GDK_KP_Home, 0, + "focus_tab", 1, + GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_FIRST); + gtk_binding_entry_add_signal (binding_set, + GDK_End, 0, + "focus_tab", 1, + GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_LAST); + gtk_binding_entry_add_signal (binding_set, + GDK_KP_End, 0, + "focus_tab", 1, + GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_LAST); } static void @@ -368,6 +431,34 @@ gtk_notebook_init (GtkNotebook *notebook) notebook->have_visible_child = FALSE; } +static void +gtk_notebook_select_page (GtkNotebook *notebook, + gboolean move_focus) +{ + gtk_notebook_page_select (notebook, move_focus); +} + +static void +gtk_notebook_focus_tab (GtkNotebook *notebook, + GtkNotebookTab type) +{ + GList *list; + + switch (type) + { + case GTK_NOTEBOOK_TAB_FIRST: + list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); + if (list) + gtk_notebook_switch_focus_tab (notebook, list); + break; + case GTK_NOTEBOOK_TAB_LAST: + list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE); + if (list) + gtk_notebook_switch_focus_tab (notebook, list); + break; + } +} + /** * gtk_notebook_new: * @@ -509,7 +600,6 @@ gtk_notebook_get_arg (GtkObject *object, * gtk_notebook_enter_notify * gtk_notebook_leave_notify * gtk_notebook_motion_notify - * gtk_notebook_key_press * gtk_notebook_focus_in * gtk_notebook_focus_out * gtk_notebook_draw_focus @@ -1237,45 +1327,6 @@ gtk_notebook_motion_notify (GtkWidget *widget, } static gint -gtk_notebook_key_press (GtkWidget *widget, - GdkEventKey *event) -{ - GtkNotebook *notebook; - GList *list; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - notebook = GTK_NOTEBOOK (widget); - - if (!notebook->children || !notebook->show_tabs) - return FALSE; - - switch (event->keyval) - { - case GDK_Home: - list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); - if (list) - gtk_notebook_switch_focus_tab (notebook, list); - return TRUE; - case GDK_End: - list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE); - if (list) - gtk_notebook_switch_focus_tab (notebook, list); - return TRUE; - case GDK_Return: - gtk_notebook_page_select (GTK_NOTEBOOK (widget), TRUE); - return TRUE; - case GDK_space: - gtk_notebook_page_select (GTK_NOTEBOOK (widget), FALSE); - return TRUE; - } - - return FALSE; -} - -static gint gtk_notebook_focus_in (GtkWidget *widget, GdkEventFocus *event) { diff --git a/gtk/gtknotebook.h b/gtk/gtknotebook.h index 8e110b678..c908ce431 100644 --- a/gtk/gtknotebook.h +++ b/gtk/gtknotebook.h @@ -45,6 +45,12 @@ extern "C" { #define GTK_NOTEBOOK_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_NOTEBOOK, GtkNotebookClass)) +typedef enum +{ + GTK_NOTEBOOK_TAB_FIRST, + GTK_NOTEBOOK_TAB_LAST +} GtkNotebookTab; + typedef struct _GtkNotebook GtkNotebook; typedef struct _GtkNotebookClass GtkNotebookClass; typedef struct _GtkNotebookPage GtkNotebookPage; @@ -86,6 +92,14 @@ struct _GtkNotebookClass void (* switch_page) (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num); + + /* Action signals for keybindings */ + void (* select_page) (GtkNotebook *notebook, + gboolean move_focus); + + void (* focus_tab) (GtkNotebook *notebook, + GtkNotebookTab type); + }; /*********************************************************** diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index e47118602..8d9269fc3 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -43,6 +43,11 @@ enum { PROP_UPDATE_POLICY }; +enum { + MOVE_SLIDER, + LAST_SIGNAL +}; + static void gtk_range_class_init (GtkRangeClass *klass); static void gtk_range_init (GtkRange *range); static void gtk_range_set_property (GObject *object, @@ -63,8 +68,6 @@ static gint gtk_range_button_release (GtkWidget *widget, GdkEventButton *event); static gint gtk_range_motion_notify (GtkWidget *widget, GdkEventMotion *event); -static gint gtk_range_key_press (GtkWidget *widget, - GdkEventKey *event); static gint gtk_range_enter_notify (GtkWidget *widget, GdkEventCrossing *event); static gint gtk_range_leave_notify (GtkWidget *widget, @@ -74,6 +77,10 @@ static gint gtk_range_scroll_event (GtkWidget *widget, static void gtk_range_style_set (GtkWidget *widget, GtkStyle *previous_style); +static void gtk_range_move_slider (GtkRange *range, + GtkScrollType scroll, + GtkTroughType trough); + static void gtk_real_range_draw_trough (GtkRange *range); static void gtk_real_range_draw_slider (GtkRange *range); static gint gtk_real_range_timer (GtkRange *range); @@ -96,6 +103,7 @@ static void gtk_range_trough_vdims (GtkRange *range, gint *bottom); static GtkWidgetClass *parent_class = NULL; +static guint signals[LAST_SIGNAL]; GtkType @@ -146,16 +154,18 @@ gtk_range_class_init (GtkRangeClass *class) widget_class->button_release_event = gtk_range_button_release; widget_class->motion_notify_event = gtk_range_motion_notify; widget_class->scroll_event = gtk_range_scroll_event; - widget_class->key_press_event = gtk_range_key_press; widget_class->enter_notify_event = gtk_range_enter_notify; widget_class->leave_notify_event = gtk_range_leave_notify; widget_class->style_set = gtk_range_style_set; - + class->min_slider_size = 7; class->trough = 1; class->slider = 2; class->step_forw = 3; class->step_back = 4; + + class->move_slider = gtk_range_move_slider; + class->draw_background = NULL; class->clear_background = NULL; class->draw_trough = gtk_real_range_draw_trough; @@ -163,10 +173,21 @@ gtk_range_class_init (GtkRangeClass *class) class->draw_step_forw = NULL; class->draw_step_back = NULL; class->trough_click = NULL; - class->trough_keys = NULL; class->motion = NULL; class->timer = gtk_real_range_timer; + signals[MOVE_SLIDER] = + g_signal_newc ("move_slider", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkRangeClass, move_slider), + NULL, NULL, + gtk_marshal_VOID__ENUM_ENUM, + G_TYPE_NONE, 2, + GTK_TYPE_SCROLL_TYPE, + GTK_TYPE_TROUGH_TYPE); + + g_object_class_install_property (gobject_class, PROP_UPDATE_POLICY, g_param_spec_enum ("update_policy", @@ -1138,93 +1159,77 @@ gtk_range_motion_notify (GtkWidget *widget, return TRUE; } -static gint -gtk_range_key_press (GtkWidget *widget, - GdkEventKey *event) +static void +gtk_range_move_slider (GtkRange *range, + GtkScrollType scroll, + GtkTroughType pos) { - GtkRange *range; - gint return_val; - GtkScrollType scroll = GTK_SCROLL_NONE; - GtkTroughType pos = GTK_TROUGH_NONE; - - g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - range = GTK_RANGE (widget); - return_val = FALSE; - - if (RANGE_CLASS (range)->trough_keys) - return_val = (* RANGE_CLASS (range)->trough_keys) (range, event, &scroll, &pos); - - if (return_val) + if (scroll != GTK_SCROLL_NONE) { - if (scroll != GTK_SCROLL_NONE) - { - range->scroll_type = scroll; - - gtk_range_scroll (range, -1); - if (range->old_value != range->adjustment->value) - { - gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed"); - switch (range->scroll_type) - { - case GTK_SCROLL_STEP_LEFT: - if (should_invert (range, TRUE)) - _gtk_range_draw_step_forw (range); - else - _gtk_range_draw_step_back (range); - break; + range->scroll_type = scroll; + + gtk_range_scroll (range, -1); + if (range->old_value != range->adjustment->value) + { + gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed"); + switch (range->scroll_type) + { + case GTK_SCROLL_STEP_LEFT: + if (should_invert (range, TRUE)) + _gtk_range_draw_step_forw (range); + else + _gtk_range_draw_step_back (range); + break; - case GTK_SCROLL_STEP_UP: - if (should_invert (range, FALSE)) - _gtk_range_draw_step_forw (range); - else - _gtk_range_draw_step_back (range); - break; - - case GTK_SCROLL_STEP_RIGHT: - if (should_invert (range, TRUE)) - _gtk_range_draw_step_back (range); - else - _gtk_range_draw_step_forw (range); - break; + case GTK_SCROLL_STEP_UP: + if (should_invert (range, FALSE)) + _gtk_range_draw_step_forw (range); + else + _gtk_range_draw_step_back (range); + break; + + case GTK_SCROLL_STEP_RIGHT: + if (should_invert (range, TRUE)) + _gtk_range_draw_step_back (range); + else + _gtk_range_draw_step_forw (range); + break; - case GTK_SCROLL_STEP_DOWN: - if (should_invert (range, FALSE)) - _gtk_range_draw_step_back (range); - else - _gtk_range_draw_step_forw (range); - break; + case GTK_SCROLL_STEP_DOWN: + if (should_invert (range, FALSE)) + _gtk_range_draw_step_back (range); + else + _gtk_range_draw_step_forw (range); + break; - case GTK_SCROLL_STEP_BACKWARD: - _gtk_range_draw_step_back (range); - break; + case GTK_SCROLL_STEP_BACKWARD: + _gtk_range_draw_step_back (range); + break; - case GTK_SCROLL_STEP_FORWARD: - _gtk_range_draw_step_forw (range); - break; - } - } - } - if (pos != GTK_TROUGH_NONE) - { - if (pos == GTK_TROUGH_START) - range->adjustment->value = range->adjustment->lower; - else if (pos == GTK_TROUGH_END) - range->adjustment->value = - range->adjustment->upper - range->adjustment->page_size; - - if (range->old_value != range->adjustment->value) - { - gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), - "value_changed"); + case GTK_SCROLL_STEP_FORWARD: + _gtk_range_draw_step_forw (range); + break; + } + } + } - _gtk_range_slider_update (range); - _gtk_range_clear_background (range); - } - } + if (pos != GTK_TROUGH_NONE) + { + if (pos == GTK_TROUGH_START) + range->adjustment->value = range->adjustment->lower; + else if (pos == GTK_TROUGH_END) + range->adjustment->value = + range->adjustment->upper - range->adjustment->page_size; + + if (range->old_value != range->adjustment->value) + { + gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), + "value_changed"); + + _gtk_range_slider_update (range); + _gtk_range_clear_background (range); + } } - return return_val; } static gint diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h index e22876bde..b9c27307b 100644 --- a/gtk/gtkrange.h +++ b/gtk/gtkrange.h @@ -92,6 +92,12 @@ struct _GtkRangeClass guint8 step_forw; guint8 step_back; + /* action signals for keybindings */ + void (* move_slider) (GtkRange *range, + GtkScrollType scroll, + GtkTroughType trough); + + /* Completely broken virtual functions, please ignore */ void (* draw_background) (GtkRange *range); void (* clear_background) (GtkRange *range); void (* draw_trough) (GtkRange *range); @@ -103,10 +109,6 @@ struct _GtkRangeClass gint x, gint y, gdouble *jump_perc); - gboolean (* trough_keys) (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *trough); void (* motion) (GtkRange *range, gint xdelta, gint ydelta); diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c index 1788730e4..9480df31b 100644 --- a/gtk/gtkrc.c +++ b/gtk/gtkrc.c @@ -257,10 +257,10 @@ static gchar *module_path[GTK_RC_MAX_MODULE_PATHS]; /* A stack of directories for RC files we are parsing currently. * these are implicitely added to the end of PIXMAP_PATHS */ -GSList *rc_dir_stack = NULL; +static GSList *rc_dir_stack = NULL; /* The files we have parsed, to reread later if necessary */ -GSList *rc_files = NULL; +static GSList *rc_files = NULL; static GtkImageLoader image_loader = NULL; diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 37d5a4349..ac1a1bd2d 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -1970,29 +1970,37 @@ gtk_text_key_press (GtkWidget *widget, switch (event->keyval) { + case GDK_KP_Home: case GDK_Home: if (event->state & GDK_CONTROL_MASK) move_cursor_buffer_ver (text, -1); else gtk_text_move_beginning_of_line (text); break; + case GDK_KP_End: case GDK_End: if (event->state & GDK_CONTROL_MASK) move_cursor_buffer_ver (text, +1); else gtk_text_move_end_of_line (text); break; + case GDK_KP_Page_Up: case GDK_Page_Up: move_cursor_page_ver (text, -1); break; + case GDK_KP_Page_Down: case GDK_Page_Down: move_cursor_page_ver (text, +1); break; /* CUA has Ctrl-Up/Ctrl-Down as paragraph up down */ + case GDK_KP_Up: case GDK_Up: move_cursor_ver (text, -1); break; + case GDK_KP_Down: case GDK_Down: move_cursor_ver (text, +1); break; + case GDK_KP_Left: case GDK_Left: if (event->state & GDK_CONTROL_MASK) gtk_text_move_backward_word (text); else move_cursor_hor (text, -1); break; + case GDK_KP_Right: case GDK_Right: if (event->state & GDK_CONTROL_MASK) gtk_text_move_forward_word (text); @@ -2025,6 +2033,7 @@ gtk_text_key_press (GtkWidget *widget, } break; case GDK_Delete: + case GDK_KP_Delete: if (event->state & GDK_CONTROL_MASK) gtk_text_delete_forward_word (text); else if (event->state & GDK_SHIFT_MASK) @@ -2036,9 +2045,11 @@ gtk_text_key_press (GtkWidget *widget, gtk_text_delete_forward_character (text); break; case GDK_Tab: + case GDK_ISO_Left_Tab: position = text->point.index; gtk_editable_insert_text (GTK_EDITABLE (old_editable), "\t", 1, &position); break; + case GDK_KP_Enter: case GDK_Return: if (event->state & GDK_CONTROL_MASK) gtk_signal_emit_by_name (GTK_OBJECT (text), "activate"); diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index ec61bb250..1355ef8ff 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -2436,38 +2436,74 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout, GSList *tmp_list; PangoLayoutLine *layout_line; GtkTextIter orig; + gboolean update_byte = FALSE; g_return_val_if_fail (layout != NULL, FALSE); g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE); g_return_val_if_fail (iter != NULL, FALSE); orig = *iter; - + + line = _gtk_text_iter_get_text_line (iter); - display = gtk_text_layout_get_line_display (layout, line, FALSE); + display = gtk_text_layout_get_line_display (layout, line, FALSE); line_byte = line_display_iter_to_index (layout, display, iter); - /* FIXME can't use layout until we check display->height > 0) */ + /* If display->height == 0 then the line is invisible, so don't + * move onto it. + */ + while (display->height == 0) + { + GtkTextLine *prev_line; + + prev_line = _gtk_text_line_previous (line); + + if (prev_line == NULL) + { + line_display_index_to_iter (layout, display, iter, 0, 0); + goto out; + } + + gtk_text_layout_free_line_display (layout, display); + + line = prev_line; + display = gtk_text_layout_get_line_display (layout, prev_line, FALSE); + update_byte = TRUE; + } + tmp_list = pango_layout_get_lines (display->layout); layout_line = tmp_list->data; + if (update_byte) + { + line_byte = layout_line->start_index + layout_line->length; + } + if (line_byte < layout_line->length || !tmp_list->next) /* first line of paragraph */ { - GtkTextLine *prev_line = _gtk_text_line_previous (line); + GtkTextLine *prev_line; - /* FIXME keep going back while display->height == 0 */ - - if (prev_line) + prev_line = _gtk_text_line_previous (line); + while (prev_line) { gtk_text_layout_free_line_display (layout, display); + display = gtk_text_layout_get_line_display (layout, prev_line, FALSE); - tmp_list = g_slist_last (pango_layout_get_lines (display->layout)); - layout_line = tmp_list->data; - line_display_index_to_iter (layout, display, iter, - layout_line->start_index + layout_line->length, 0); + if (display->height > 0) + { + tmp_list = g_slist_last (pango_layout_get_lines (display->layout)); + layout_line = tmp_list->data; + + line_display_index_to_iter (layout, display, iter, + layout_line->start_index + layout_line->length, 0); + break; + } + + prev_line = _gtk_text_line_previous (prev_line); } - else + + if (prev_line == NULL) line_display_index_to_iter (layout, display, iter, 0, 0); } else @@ -2491,6 +2527,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout, } } + out: + gtk_text_layout_free_line_display (layout, display); return @@ -2533,6 +2571,9 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout, display = gtk_text_layout_get_line_display (layout, line, FALSE); + if (display->height == 0) + goto next; + if (first) { line_byte = line_display_iter_to_index (layout, display, iter); @@ -2558,6 +2599,8 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout, tmp_list = tmp_list->next; } + next: + gtk_text_layout_free_line_display (layout, display); line = _gtk_text_line_next (line); @@ -2661,7 +2704,7 @@ gtk_text_layout_iter_starts_line (GtkTextLayout *layout, if (line_byte < layout_line->start_index + layout_line->length || !tmp_list->next) { - /* We're located on this line of the para delimiters before + /* We're located on this line or the para delimiters before * it */ gtk_text_layout_free_line_display (layout, display); diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 3f9f6bdb2..2b72204e7 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -683,6 +683,11 @@ gtk_text_view_class_init (GtkTextViewClass *klass) GTK_TYPE_ENUM, GTK_DELETE_CHARS, GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, 0, + "delete_from_cursor", 2, + GTK_TYPE_ENUM, GTK_DELETE_CHARS, + GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_d, GDK_CONTROL_MASK, "delete_from_cursor", 2, GTK_TYPE_ENUM, GTK_DELETE_CHARS, @@ -698,6 +703,11 @@ gtk_text_view_class_init (GtkTextViewClass *klass) GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS, GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, GDK_CONTROL_MASK, + "delete_from_cursor", 2, + GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS, + GTK_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, GDK_d, GDK_MOD1_MASK, "delete_from_cursor", 2, GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS, @@ -2951,7 +2961,8 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event) else if (GTK_WIDGET_CLASS (parent_class)->key_press_event && GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event)) retval = TRUE; - else if (event->keyval == GDK_Return) + else if (event->keyval == GDK_Return || + event->keyval == GDK_KP_Enter) { gtk_text_buffer_insert_interactive_at_cursor (get_buffer (text_view), "\n", 1, text_view->editable); diff --git a/gtk/gtkvscale.c b/gtk/gtkvscale.c index 66c389514..71e4a0e79 100644 --- a/gtk/gtkvscale.c +++ b/gtk/gtkvscale.c @@ -29,6 +29,7 @@ #include "gtksignal.h" #include "gdk/gdkkeysyms.h" #include "gtkintl.h" +#include "gtkbindings.h" #define SCALE_CLASS(w) GTK_SCALE_GET_CLASS (w) @@ -66,10 +67,6 @@ static void gtk_vscale_pos_background (GtkVScale *vscale, gint *h); static void gtk_vscale_draw_slider (GtkRange *range); static void gtk_vscale_draw_value (GtkScale *scale); -static gboolean gtk_vscale_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos); static void gtk_vscale_clear_background (GtkRange *range); GtkType @@ -97,6 +94,12 @@ gtk_vscale_get_type (void) return vscale_type; } +#define add_slider_binding(binding_set, keyval, mask, scroll, trough) \ + gtk_binding_entry_add_signal (binding_set, keyval, mask, \ + "move_slider", 2, \ + GTK_TYPE_SCROLL_TYPE, scroll, \ + GTK_TYPE_TROUGH_TYPE, trough) + static void gtk_vscale_class_init (GtkVScaleClass *class) { @@ -105,6 +108,7 @@ gtk_vscale_class_init (GtkVScaleClass *class) GtkWidgetClass *widget_class; GtkRangeClass *range_class; GtkScaleClass *scale_class; + GtkBindingSet *binding_set; object_class = (GtkObjectClass*) class; gobject_class = G_OBJECT_CLASS (class); @@ -123,7 +127,6 @@ gtk_vscale_class_init (GtkVScaleClass *class) range_class->trough_click = _gtk_range_default_vtrough_click; range_class->motion = _gtk_range_default_vmotion; range_class->draw_slider = gtk_vscale_draw_slider; - range_class->trough_keys = gtk_vscale_trough_keys; range_class->clear_background = gtk_vscale_clear_background; scale_class->draw_value = gtk_vscale_draw_value; @@ -135,6 +138,58 @@ gtk_vscale_class_init (GtkVScaleClass *class) _("The GtkAdjustment that determines the values to use for this VScale."), GTK_TYPE_ADJUSTMENT, G_PARAM_READWRITE)); + + binding_set = gtk_binding_set_by_class (object_class); + + add_slider_binding (binding_set, GDK_Up, 0, + GTK_SCROLL_STEP_UP, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Up, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_UP, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Up, 0, + GTK_SCROLL_STEP_UP, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Up, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_UP, GTK_TROUGH_NONE); + + + add_slider_binding (binding_set, GDK_Down, 0, + GTK_SCROLL_STEP_DOWN, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Down, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_DOWN, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Down, 0, + GTK_SCROLL_STEP_DOWN, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Down, GDK_CONTROL_MASK, + GTK_SCROLL_PAGE_DOWN, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Page_Up, 0, + GTK_SCROLL_PAGE_BACKWARD, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Page_Up, 0, + GTK_SCROLL_PAGE_BACKWARD, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Page_Down, 0, + GTK_SCROLL_PAGE_FORWARD, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_KP_Page_Down, 0, + GTK_SCROLL_PAGE_FORWARD, GTK_TROUGH_NONE); + + add_slider_binding (binding_set, GDK_Home, 0, + GTK_SCROLL_NONE, GTK_TROUGH_START); + + add_slider_binding (binding_set, GDK_KP_Home, 0, + GTK_SCROLL_NONE, GTK_TROUGH_START); + + + add_slider_binding (binding_set, GDK_End, 0, + GTK_SCROLL_NONE, GTK_TROUGH_END); + + add_slider_binding (binding_set, GDK_KP_End, 0, + GTK_SCROLL_NONE, GTK_TROUGH_END); } static void @@ -552,46 +607,3 @@ gtk_vscale_draw_value (GtkScale *scale) g_object_unref (G_OBJECT (layout)); } } - -static gboolean -gtk_vscale_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos) -{ - gint return_val = FALSE; - switch (key->keyval) - { - case GDK_Up: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *scroll = GTK_SCROLL_PAGE_UP; - else - *scroll = GTK_SCROLL_STEP_UP; - break; - case GDK_Down: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *scroll = GTK_SCROLL_PAGE_DOWN; - else - *scroll = GTK_SCROLL_STEP_DOWN; - break; - case GDK_Page_Up: - return_val = TRUE; - *scroll = GTK_SCROLL_PAGE_BACKWARD; - break; - case GDK_Page_Down: - return_val = TRUE; - *scroll = GTK_SCROLL_PAGE_FORWARD; - break; - case GDK_Home: - return_val = TRUE; - *pos = GTK_TROUGH_START; - break; - case GDK_End: - return_val = TRUE; - *pos = GTK_TROUGH_END; - break; - } - return return_val; -} diff --git a/gtk/gtkvscrollbar.c b/gtk/gtkvscrollbar.c index 4f9df1022..f4e7c28f7 100644 --- a/gtk/gtkvscrollbar.c +++ b/gtk/gtkvscrollbar.c @@ -58,10 +58,6 @@ static void gtk_vscrollbar_draw_step_forw (GtkRange *range); static void gtk_vscrollbar_draw_step_back (GtkRange *range); static void gtk_vscrollbar_slider_update (GtkRange *range); static void gtk_vscrollbar_calc_slider_size (GtkVScrollbar *vscrollbar); -static gboolean gtk_vscrollbar_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos); GtkType gtk_vscrollbar_get_type (void) @@ -110,7 +106,6 @@ gtk_vscrollbar_class_init (GtkVScrollbarClass *class) range_class->draw_step_back = gtk_vscrollbar_draw_step_back; range_class->slider_update = gtk_vscrollbar_slider_update; range_class->trough_click = _gtk_range_default_vtrough_click; - range_class->trough_keys = gtk_vscrollbar_trough_keys; range_class->motion = _gtk_range_default_vmotion; g_object_class_install_property (gobject_class, @@ -460,38 +455,3 @@ gtk_vscrollbar_calc_slider_size (GtkVScrollbar *vscrollbar) } } } - -static gboolean -gtk_vscrollbar_trough_keys (GtkRange *range, - GdkEventKey *key, - GtkScrollType *scroll, - GtkTroughType *pos) -{ - gint return_val = FALSE; - switch (key->keyval) - { - case GDK_Up: - return_val = TRUE; - *scroll = GTK_SCROLL_STEP_UP; - break; - case GDK_Down: - return_val = TRUE; - *scroll = GTK_SCROLL_STEP_DOWN; - break; - case GDK_Page_Up: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *pos = GTK_TROUGH_START; - else - *scroll = GTK_SCROLL_PAGE_BACKWARD; - break; - case GDK_Page_Down: - return_val = TRUE; - if (key->state & GDK_CONTROL_MASK) - *pos = GTK_TROUGH_END; - else - *scroll = GTK_SCROLL_PAGE_FORWARD; - break; - } - return return_val; -} diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 3a63ace0f..8e89f6f3e 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -3509,12 +3509,15 @@ gtk_widget_modify_style (GtkWidget *widget, old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_rc_style); - if (style != old_style) - gtk_object_set_data_by_id_full (GTK_OBJECT (widget), - quark_rc_style, - gtk_rc_style_copy (style), - (GtkDestroyNotify)gtk_rc_style_unref); + gtk_object_set_data_by_id_full (GTK_OBJECT (widget), + quark_rc_style, + gtk_rc_style_copy (style), + (GtkDestroyNotify)gtk_rc_style_unref); + /* note that "style" may be invalid here if it was the old + * modifier style and the only reference was our own. + */ + if (GTK_WIDGET_RC_STYLE (widget)) gtk_widget_set_rc_style (widget); } @@ -3529,6 +3532,12 @@ gtk_widget_modify_style (GtkWidget *widget, * modifier style for the widget. If you make changes to this rc * style, you must call gtk_widget_modify_style(), passing in the * returned rc style, to make sure that your changes take effect. + * + * Caution: passing the style back to gtk_widget_modify_style() will + * normally end up destroying it, because gtk_widget_modify_style() copies + * the passed-in style and sets the copy as the new modifier style, + * thus dropping any reference to the old modifier style. Add a reference + * to the modifier style if you want to keep it alive. * * Return value: the modifier style for the widget. This rc style is * owned by the widget. If you want to keep a pointer to value this @@ -3582,8 +3591,7 @@ gtk_widget_modify_color_component (GtkWidget *widget, rc_style->color_flags[state] |= component; - if (GTK_WIDGET_RC_STYLE (widget)) - gtk_widget_set_rc_style (widget); + gtk_widget_modify_style (widget, rc_style); } /** @@ -3701,9 +3709,8 @@ gtk_widget_modify_font (GtkWidget *widget, pango_font_description_free (rc_style->font_desc); rc_style->font_desc = pango_font_description_copy (font_desc); - - if (GTK_WIDGET_RC_STYLE (widget)) - gtk_widget_set_rc_style (widget); + + gtk_widget_modify_style (widget, rc_style); } static void diff --git a/tests/testgtk.c b/tests/testgtk.c index d3b0a5238..5e6cdb105 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -773,6 +773,8 @@ create_toolbar (void) gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); + gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "Enable", "Enable tooltips", NULL, new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]), @@ -3205,6 +3207,9 @@ cmw_color (GtkWidget *widget, GtkWidget *parent) csd=gtk_color_selection_dialog_new ("This is a modal color selection dialog"); + gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (csd)->colorsel), + TRUE); + /* Set as modal */ gtk_window_set_modal (GTK_WINDOW(csd),TRUE); |