From: Havoc Pennington Date: Fri, 26 Jan 2001 21:12:05 +0000 (+0000) Subject: adapt to handle PangoColor X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=ef4356b567e59d98e837ec41993e50d20dd65a46;p=~andy%2Fgtk adapt to handle PangoColor 2001-01-26 Havoc Pennington * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to not offset by TREE_VIEW_HEADER_HEIGHT (gtk_tree_view_tree_to_widget_coords): fix to not offset by TREE_VIEW_HEADER_HEIGHT * configure.in (included_loaders): for me, --with-included-loaders generates the error "the specified loader yes does not exist", i.e. the arg defaults to "yes", so change test for value "" to test for value "yes", and include all loaders in that case. * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly handle TREE_VIEW_VERTICAL_SEPARATOR (gtk_tree_view_bin_expose): fix to consider the row offset as pointing halfway into vertical separator. (gtk_tree_view_draw_node_focus_rect): ditto * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add --gtk-debug=updates, which causes gdk_window_set_debug_updates (TRUE) to be called. * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a debug mode where the invalid region is colored in on invalidate, so you can see the flicker and know whether your redraw code is doing a good job. * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in tree window coordinates (clip rect is in tree window coords) * gtk/Makefile.am: add gtktreednd.[hc] * gtk/gtkliststore.c: implement gtktreednd interfaces. * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support drag-and-drop data operations on a model (so we can set up tree drag-and-drop automatically) * gtk/testgtk.c: Add a window to change sensitivity in the GtkLabel test; add a way to change the entry frame in GtkEntry test * gtk/gtkentry.c (gtk_entry_set_has_frame): (gtk_entry_get_has_frame): new functions to remove the frame around an entry (gtk_entry_size_request): shrink requisition if no frame (gtk_entry_draw_focus): don't draw frame if no frame * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for checks inside a cell renderer (gtk_default_draw_option): ditto for options * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove children from the alignment, not the button (gtk_tree_view_column_init): ref/sink the column, to emulate GObject refcounting. * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): Use theme functions to draw the toggles * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and GdkPangoAttrEmbossed to use in rendering insensitive text * gdk/gdkpango.c (gdk_draw_layout_line): render new properties * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity using new GDK features --- diff --git a/ChangeLog b/ChangeLog index 79db30750..d0e503736 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 79db30750..d0e503736 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 79db30750..d0e503736 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 79db30750..d0e503736 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 79db30750..d0e503736 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 79db30750..d0e503736 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 79db30750..d0e503736 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,79 @@ +2001-01-26 Havoc Pennington + + * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor + + * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to + not offset by TREE_VIEW_HEADER_HEIGHT + (gtk_tree_view_tree_to_widget_coords): fix to not offset by + TREE_VIEW_HEADER_HEIGHT + + * configure.in (included_loaders): for me, --with-included-loaders + generates the error "the specified loader yes does not exist", + i.e. the arg defaults to "yes", so change test for value "" + to test for value "yes", and include all loaders in that case. + + * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function + + * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly + handle TREE_VIEW_VERTICAL_SEPARATOR + (gtk_tree_view_bin_expose): fix to consider the row offset as + pointing halfway into vertical separator. + (gtk_tree_view_draw_node_focus_rect): ditto + + * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add + --gtk-debug=updates, which causes gdk_window_set_debug_updates + (TRUE) to be called. + + * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a + debug mode where the invalid region is colored in on invalidate, + so you can see the flicker and know whether your redraw code is + doing a good job. + + * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in + tree window coordinates (clip rect is in tree window coords) + + * gtk/Makefile.am: add gtktreednd.[hc] + + * gtk/gtkliststore.c: implement gtktreednd interfaces. + + * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support + drag-and-drop data operations on a model (so we can set up tree + drag-and-drop automatically) + + * gtk/testgtk.c: Add a window to change sensitivity in the + GtkLabel test; add a way to change the entry frame in GtkEntry + test + + * gtk/gtkentry.c (gtk_entry_set_has_frame): + (gtk_entry_get_has_frame): new functions to remove the frame + around an entry + (gtk_entry_size_request): shrink requisition if no frame + (gtk_entry_draw_focus): don't draw frame if no frame + + * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for + checks inside a cell renderer + (gtk_default_draw_option): ditto for options + + * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove + children from the alignment, not the button + (gtk_tree_view_column_init): ref/sink the column, to emulate + GObject refcounting. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink + + * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render): + Use theme functions to draw the toggles + + * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors + + * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and + GdkPangoAttrEmbossed to use in rendering insensitive text + + * gdk/gdkpango.c (gdk_draw_layout_line): render new properties + + * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity + using new GDK features + 2001-01-24 * gtk/gtkimage.c: diff --git a/configure.in b/configure.in index 8448e73f7..19652b4c2 100644 --- a/configure.in +++ b/configure.in @@ -914,7 +914,7 @@ AC_ARG_WITH(included_loaders, [ --with-included-loaders=LOADER1,LOADER2,... Bui all_loaders="png,bmp,wbmp,gif,ico,jpeg,pnm,ras,tiff,xpm" included_loaders="" # If no loaders specified, include all -if test "x$with_included_loaders" = x ; then +if test "x$with_included_loaders" = xyes ; then included_loaders="$all_loaders" else included_loaders="$with_included_loaders" diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index 7f4d2e642..53dc4f514 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -31,13 +31,18 @@ struct _GdkPangoContextInfo GdkColormap *colormap; }; +static PangoAttrType gdk_pango_attr_stipple_type; +static PangoAttrType gdk_pango_attr_embossed_type; + static void gdk_pango_get_item_properties (PangoItem *item, PangoUnderline *uline, gint *rise, - PangoAttrColor *fg_color, + PangoColor *fg_color, gboolean *fg_set, - PangoAttrColor *bg_color, + PangoColor *bg_color, gboolean *bg_set, + gboolean *embossed, + GdkBitmap **stipple, gboolean *shape_set, PangoRectangle *ink_rect, PangoRectangle *logical_rect); @@ -70,38 +75,40 @@ gdk_pango_context_get_info (PangoContext *context, gboolean create) static GdkGC * gdk_pango_get_gc (PangoContext *context, - PangoAttrColor *fg_color, + PangoColor *fg_color, + GdkBitmap *stipple, GdkGC *base_gc) { - GdkPangoContextInfo *info; - GdkColormap *colormap; GdkColor color; + GdkGC *result; + GdkPangoContextInfo *info; g_return_val_if_fail (context != NULL, NULL); info = gdk_pango_context_get_info (context, FALSE); - if (info && info->colormap) - colormap = info->colormap; - else - colormap = gdk_colormap_get_system(); - - /* FIXME. FIXME. FIXME. Only works for true color */ - + if (info == NULL || info->colormap == NULL) + { + g_warning ("you must set the colormap on a PangoContext before using it to draw a layout"); + return NULL; + } + color.red = fg_color->red; color.green = fg_color->green; color.blue = fg_color->blue; - if (gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) - { - GdkGC *result = gdk_gc_new (gdk_parent_root); - gdk_gc_copy (result, base_gc); - gdk_gc_set_foreground (result, &color); + result = gdk_gc_new (gdk_parent_root); + gdk_gc_copy (result, base_gc); + gdk_rgb_find_color (info->colormap, &color); + gdk_gc_set_foreground (result, &color); - return result; + if (stipple) + { + gdk_gc_set_fill (result, GDK_STIPPLED); + gdk_gc_set_stipple (result, stipple); } - else - return gdk_gc_ref (base_gc); + + return result; } static void @@ -158,6 +165,8 @@ gdk_draw_layout_line (GdkDrawable *drawable, PangoContext *context; gint x_off = 0; gint rise = 0; + gboolean embossed; + GdkBitmap *stipple; g_return_if_fail (drawable != NULL); g_return_if_fail (gc != NULL); @@ -171,7 +180,7 @@ gdk_draw_layout_line (GdkDrawable *drawable, { PangoUnderline uline = PANGO_UNDERLINE_NONE; PangoLayoutRun *run = tmp_list->data; - PangoAttrColor fg_color, bg_color; + PangoColor fg_color, bg_color; gboolean fg_set, bg_set, shape_set; GdkGC *fg_gc; gint risen_y; @@ -182,6 +191,8 @@ gdk_draw_layout_line (GdkDrawable *drawable, &rise, &fg_color, &fg_set, &bg_color, &bg_set, + &embossed, + &stipple, &shape_set, &ink_rect, &logical_rect); @@ -201,28 +212,48 @@ gdk_draw_layout_line (GdkDrawable *drawable, if (bg_set) { - GdkGC *bg_gc = gdk_pango_get_gc (context, &bg_color, gc); - + GdkGC *bg_gc = gdk_pango_get_gc (context, &bg_color, stipple, gc); + gdk_draw_rectangle (drawable, bg_gc, TRUE, x + (x_off + logical_rect.x) / PANGO_SCALE, risen_y + overall_rect.y / PANGO_SCALE, logical_rect.width / PANGO_SCALE, overall_rect.height / PANGO_SCALE); + if (stipple) + gdk_gc_set_fill (bg_gc, GDK_SOLID); + gdk_pango_free_gc (context, bg_gc); } - if (fg_set) - fg_gc = gdk_pango_get_gc (context, &fg_color, gc); + if (fg_set || stipple) + fg_gc = gdk_pango_get_gc (context, &fg_color, stipple, gc); else fg_gc = gc; - + if (!shape_set) - gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font, - x + x_off / PANGO_SCALE, - risen_y, - run->glyphs); + { + gint gx, gy; + gx = x + x_off / PANGO_SCALE; + gy = risen_y; + + if (embossed) + { + PangoColor color = { 65535, 65535, 65535 }; + GdkGC *white_gc = gdk_pango_get_gc (context, &color, stipple, fg_gc); + gdk_draw_glyphs (drawable, white_gc, run->item->analysis.font, + gx + 1, + gy + 1, + run->glyphs); + gdk_pango_free_gc (context, white_gc); + } + + gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font, + gx, gy, + run->glyphs); + } + switch (uline) { case PANGO_UNDERLINE_NONE: @@ -249,8 +280,8 @@ gdk_draw_layout_line (GdkDrawable *drawable, risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1); break; } - - if (fg_set) + + if (fg_gc != gc) gdk_pango_free_gc (context, fg_gc); x_off += logical_rect.width; @@ -307,10 +338,12 @@ static void gdk_pango_get_item_properties (PangoItem *item, PangoUnderline *uline, gint *rise, - PangoAttrColor *fg_color, + PangoColor *fg_color, gboolean *fg_set, - PangoAttrColor *bg_color, + PangoColor *bg_color, gboolean *bg_set, + gboolean *embossed, + GdkBitmap **stipple, gboolean *shape_set, PangoRectangle *ink_rect, PangoRectangle *logical_rect) @@ -328,6 +361,12 @@ gdk_pango_get_item_properties (PangoItem *item, if (rise) *rise = 0; + + if (embossed) + *embossed = FALSE; + + if (stipple) + *stipple = NULL; while (tmp_list) { @@ -342,7 +381,7 @@ gdk_pango_get_item_properties (PangoItem *item, case PANGO_ATTR_FOREGROUND: if (fg_color) - *fg_color = *((PangoAttrColor *)attr); + *fg_color = ((PangoAttrColor *)attr)->color; if (fg_set) *fg_set = TRUE; @@ -350,7 +389,7 @@ gdk_pango_get_item_properties (PangoItem *item, case PANGO_ATTR_BACKGROUND: if (bg_color) - *bg_color = *((PangoAttrColor *)attr); + *bg_color = ((PangoAttrColor *)attr)->color; if (bg_set) *bg_set = TRUE; @@ -371,9 +410,144 @@ gdk_pango_get_item_properties (PangoItem *item, break; default: + /* stipple_type and embossed_type aren't necessarily + * initialized, but they are 0, which is an + * invalid type so won't occur. + */ + if (stipple && attr->klass->type == gdk_pango_attr_stipple_type) + { + *stipple = ((GdkPangoAttrStipple*)attr)->stipple; + } + else if (embossed && attr->klass->type == gdk_pango_attr_embossed_type) + { + *embossed = ((GdkPangoAttrEmbossed*)attr); + } break; } tmp_list = tmp_list->next; } } + +static PangoAttribute * +gdk_pango_attr_stipple_copy (const PangoAttribute *attr) +{ + const GdkPangoAttrStipple *src = (const GdkPangoAttrStipple*) attr; + + return gdk_pango_attr_stipple_new (src->stipple); +} + +static void +gdk_pango_attr_stipple_destroy (PangoAttribute *attr) +{ + GdkPangoAttrStipple *st = (GdkPangoAttrStipple*) attr; + + if (st->stipple) + g_object_unref (G_OBJECT (st->stipple)); + + g_free (attr); +} + +static gboolean +gdk_pango_attr_stipple_compare (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + const GdkPangoAttrStipple *a = (const GdkPangoAttrStipple*) attr1; + const GdkPangoAttrStipple *b = (const GdkPangoAttrStipple*) attr2; + + return a->stipple == b->stipple; +} + +/** + * gdk_pango_attr_stipple_new: + * @stipple: a bitmap to be set as stipple + * + * Creates a new attribute containing a stipple bitmap to be used when + * rendering the text. + * + * Return value: new #PangoAttribute + **/ + +PangoAttribute * +gdk_pango_attr_stipple_new (GdkBitmap *stipple) +{ + GdkPangoAttrStipple *result; + + static PangoAttrClass klass = { + 0, + gdk_pango_attr_stipple_copy, + gdk_pango_attr_stipple_destroy, + gdk_pango_attr_stipple_compare + }; + + if (!klass.type) + klass.type = gdk_pango_attr_stipple_type = + pango_attr_type_register ("GdkPangoAttrStipple"); + + result = g_new (GdkPangoAttrStipple, 1); + result->attr.klass = &klass; + + if (stipple) + g_object_ref (stipple); + + result->stipple = stipple; + + return (PangoAttribute *)result; +} + +static PangoAttribute * +gdk_pango_attr_embossed_copy (const PangoAttribute *attr) +{ + const GdkPangoAttrEmbossed *e = (const GdkPangoAttrEmbossed*) attr; + + return gdk_pango_attr_embossed_new (e->embossed); +} + +static void +gdk_pango_attr_embossed_destroy (PangoAttribute *attr) +{ + g_free (attr); +} + +static gboolean +gdk_pango_attr_embossed_compare (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + const GdkPangoAttrEmbossed *e1 = (const GdkPangoAttrEmbossed*) attr1; + const GdkPangoAttrEmbossed *e2 = (const GdkPangoAttrEmbossed*) attr2; + + return e1->embossed == e2->embossed; +} + +/** + * gdk_pango_attr_embossed_new: + * @embossed: a bitmap to be set as embossed + * + * Creates a new attribute containing a embossed bitmap to be used when + * rendering the text. + * + * Return value: new #PangoAttribute + **/ + +PangoAttribute * +gdk_pango_attr_embossed_new (gboolean embossed) +{ + GdkPangoAttrEmbossed *result; + + static PangoAttrClass klass = { + 0, + gdk_pango_attr_embossed_copy, + gdk_pango_attr_embossed_destroy, + gdk_pango_attr_embossed_compare + }; + + if (!klass.type) + klass.type = gdk_pango_attr_embossed_type = + pango_attr_type_register ("GdkPangoAttrEmbossed"); + + result = g_new (GdkPangoAttrEmbossed, 1); + result->attr.klass = &klass; + result->embossed = embossed; + + return (PangoAttribute *)result; +} diff --git a/gdk/gdkpango.h b/gdk/gdkpango.h index 8fc91a71f..f553fa01d 100644 --- a/gdk/gdkpango.h +++ b/gdk/gdkpango.h @@ -38,6 +38,26 @@ PangoContext *gdk_pango_context_get (void); void gdk_pango_context_set_colormap (PangoContext *context, GdkColormap *colormap); +/* Attributes use to render insensitive text in GTK+. */ + +typedef struct _GdkPangoAttrStipple GdkPangoAttrStipple; +typedef struct _GdkPangoAttrEmbossed GdkPangoAttrEmbossed; + +struct _GdkPangoAttrStipple +{ + PangoAttribute attr; + GdkBitmap *stipple; +}; + +struct _GdkPangoAttrEmbossed +{ + PangoAttribute attr; + gboolean embossed; +}; + +PangoAttribute *gdk_pango_attr_stipple_new (GdkBitmap *bitmap); +PangoAttribute *gdk_pango_attr_embossed_new (gboolean embossed); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 0a703045f..55d5e9d59 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -1637,6 +1637,7 @@ gdk_window_get_image (GdkDrawable *drawable, static GSList *update_windows = NULL; static guint update_idle = 0; +static gboolean debug_updates = FALSE; static void gdk_window_process_updates_internal (GdkWindow *window) @@ -1659,6 +1660,13 @@ gdk_window_process_updates_internal (GdkWindow *window) GdkRectangle window_rect; gint width, height; + if (debug_updates) + { + /* Make sure we see the red invalid area before redrawing. */ + gdk_flush (); + g_usleep (70000); + } + gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height); window_rect.x = 0; @@ -1725,9 +1733,9 @@ gdk_window_process_updates (GdkWindow *window, g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); - + if (private->update_area) - { + { gdk_window_process_updates_internal (window); update_windows = g_slist_remove (update_windows, window); } @@ -1798,6 +1806,28 @@ gdk_window_invalidate_region (GdkWindow *window, if (!gdk_region_empty (visible_region)) { + if (debug_updates) + { + /* Draw ugly color all over the newly-invalid region */ + GdkRectangle ugly_rect; + GdkGC *ugly_gc; + GdkColor ugly_color = { 0, 60000, 10000, 10000 }; + + ugly_gc = gdk_gc_new (window); + + gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color); + + gdk_region_get_clipbox (visible_region, &ugly_rect); + + gdk_draw_rectangle (window, + ugly_gc, + TRUE, + ugly_rect.x, ugly_rect.y, + ugly_rect.width, ugly_rect.height); + + g_object_unref (G_OBJECT (ugly_gc)); + } + if (private->update_area) { gdk_region_union (private->update_area, visible_region); @@ -1916,3 +1946,8 @@ gdk_window_thaw_updates (GdkWindow *window) gdk_window_update_idle, NULL, NULL); } +void +gdk_window_set_debug_updates (gboolean setting) +{ + debug_updates = setting; +} diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 12ab145ed..435e5868d 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -413,7 +413,8 @@ void gdk_window_process_all_updates (void); void gdk_window_process_updates (GdkWindow *window, gboolean update_children); - +/* Enable/disable flicker, so you can tell if your code is inefficient. */ +void gdk_window_set_debug_updates (gboolean setting); #ifdef __cplusplus } diff --git a/gtk/Makefile.am b/gtk/Makefile.am index bdd2659b5..0869168b6 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -170,6 +170,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \ gtktoolbar.h \ gtktooltips.h \ gtktree.h \ + gtktreednd.h \ gtktreeitem.h \ gtktreemodel.h \ gtktreemodelsimple.h \ @@ -335,6 +336,7 @@ gtk_c_sources = @STRIP_BEGIN@ \ gtktree.c \ gtktreeitem.c \ gtktreedatalist.c \ + gtktreednd.c \ gtktreemodel.c \ gtktreemodelsimple.c \ gtktreemodelsort.c \ diff --git a/gtk/gtk.h b/gtk/gtk.h index f07d5ab9b..a84b83e2d 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -138,6 +138,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtkcellrenderer.c b/gtk/gtkcellrenderer.c index 5324cbe92..d7724f49a 100644 --- a/gtk/gtkcellrenderer.c +++ b/gtk/gtkcellrenderer.c @@ -72,6 +72,10 @@ gtk_cell_renderer_get_type (void) static void gtk_cell_renderer_init (GtkCellRenderer *cell) { + /* FIXME remove on port to GtkObject */ + gtk_object_ref (GTK_OBJECT (cell)); + gtk_object_sink (GTK_OBJECT (cell)); + cell->xpad = 0; cell->ypad = 0; cell->xalign = 0.5; @@ -211,6 +215,27 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell, GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, width, height); } +/** + * gtk_cell_renderer_render: + * @cell: a #GtkCellRenderer + * @window: a #GdkDrawable to draw to + * @widget: the widget owning @window + * @background_area: entire cell area (including tree expanders and maybe padding on the sides) + * @cell_area: area normally rendered by a cell renderer + * @expose_area: area that actually needs updating + * @flags: flags that affect rendering + * + * Invokes the virtual render function of the #GtkCellRenderer. The + * three passed-in rectangles are areas of @window. Most renderers + * will draw to @cell_area; the xalign, yalign, xpad, and ypad fields + * of the #GtkCellRenderer should be honored with respect to + * @cell_area. @background_area includes the blank space around the + * cell, and also the area containing the tree expander; so the + * @background_area rectangles for all cells tile to cover the entire + * @window. Cell renderers can use the @background_area to draw custom expanders, for + * example. @expose_area is a clip rectangle. + * + **/ void gtk_cell_renderer_render (GtkCellRenderer *cell, GdkWindow *window, diff --git a/gtk/gtkcellrenderertoggle.c b/gtk/gtkcellrenderertoggle.c index d6dfa7547..4ff6c7e52 100644 --- a/gtk/gtkcellrenderertoggle.c +++ b/gtk/gtkcellrenderertoggle.c @@ -226,7 +226,9 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, GtkCellRendererToggle *celltoggle = (GtkCellRendererToggle *) cell; gint width, height; gint real_xoffset, real_yoffset; - + GtkShadowType shadow; + GtkStateType state; + width = MIN (TOGGLE_WIDTH, cell_area->width - cell->xpad * 2); height = MIN (TOGGLE_WIDTH, cell_area->height - cell->ypad * 2); @@ -238,57 +240,33 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, real_yoffset = cell->yalign * (cell_area->height - height - (2 * cell->ypad)); real_yoffset = MAX (real_yoffset, 0) + cell->ypad; - gdk_gc_set_clip_rectangle (widget->style->black_gc, cell_area); + shadow = celltoggle->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - if (!celltoggle->radio) + if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) + state = GTK_STATE_SELECTED; + else + state = GTK_STATE_NORMAL; + + if (celltoggle->radio) { - gdk_draw_rectangle (window, - widget->style->black_gc, - FALSE, - cell_area->x + real_xoffset, - cell_area->y + real_yoffset, - width, height); - if (celltoggle->active) - { - gdk_draw_line (window, - widget->style->black_gc, - cell_area->x + real_xoffset, - cell_area->y + real_yoffset, - cell_area->x + real_xoffset + width, - cell_area->y + real_yoffset + height); - gdk_draw_line (window, - widget->style->black_gc, - cell_area->x + real_xoffset + width, - cell_area->y + real_yoffset, - cell_area->x + real_xoffset, - cell_area->y + real_yoffset + height); - } + gtk_paint_option (widget->style, + window, + state, shadow, + cell_area, widget, "cellradio", + cell_area->x + real_xoffset, + cell_area->y + real_yoffset, + width, height); } else { - gdk_draw_arc (window, - widget->style->black_gc, - FALSE, - cell_area->x + real_xoffset, - cell_area->y + real_yoffset, - width, - height, - 0, 360*64); - if (celltoggle->active) - { - gdk_draw_arc (window, - widget->style->black_gc, - TRUE, - cell_area->x + real_xoffset + 2, - cell_area->y + real_yoffset + 2, - width - 4, - height - 4, - 0, 360*64); - } + gtk_paint_check (widget->style, + window, + state, shadow, + cell_area, widget, "cellcheck", + cell_area->x + real_xoffset, + cell_area->y + real_yoffset, + width, height); } - - - gdk_gc_set_clip_rectangle (widget->style->black_gc, NULL); } static gint diff --git a/gtk/gtkdebug.h b/gtk/gtkdebug.h index 78e74d16b..1a03e8af5 100644 --- a/gtk/gtkdebug.h +++ b/gtk/gtkdebug.h @@ -38,7 +38,8 @@ typedef enum { GTK_DEBUG_DND = 1 << 3, GTK_DEBUG_PLUGSOCKET = 1 << 4, GTK_DEBUG_TEXT = 1 << 5, - GTK_DEBUG_TREE = 1 << 6 + GTK_DEBUG_TREE = 1 << 6, + GTK_DEBUG_UPDATES = 1 << 7 } GtkDebugFlag; #ifdef G_ENABLE_DEBUG diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index ecfcb86a8..7f471229e 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -675,6 +675,8 @@ gtk_entry_init (GtkEntry *entry) entry->visible = TRUE; entry->invisible_char = '*'; entry->dnd_position = -1; + + entry->has_frame = TRUE; gtk_drag_dest_set (GTK_WIDGET (entry), GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_HIGHLIGHT, @@ -760,8 +762,17 @@ gtk_entry_realize (GtkWidget *widget) widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, entry); - attributes.x = widget->style->xthickness; - attributes.y = widget->style->ythickness; + if (entry->has_frame) + { + attributes.x = widget->style->xthickness; + attributes.y = widget->style->ythickness; + } + else + { + attributes.x = 0; + attributes.y = 0; + } + attributes.width = widget->allocation.width - attributes.x * 2; attributes.height = requisition.height - attributes.y * 2; attributes.cursor = gdk_cursor_new (GDK_XTERM); @@ -816,6 +827,7 @@ gtk_entry_size_request (GtkWidget *widget, PangoFontMetrics metrics; PangoFont *font; gchar *lang; + gint xborder, yborder; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); @@ -835,10 +847,25 @@ gtk_entry_size_request (GtkWidget *widget, entry->ascent = metrics.ascent; entry->descent = metrics.descent; + + xborder = INNER_BORDER; + yborder = INNER_BORDER; - requisition->width = MIN_ENTRY_WIDTH + (widget->style->xthickness + INNER_BORDER) * 2; + if (entry->has_frame) + { + xborder += widget->style->xthickness; + yborder += widget->style->ythickness; + } + else + { + /* add 1 pixel to draw focus rect in widget->window */ + xborder += 1; + yborder += 1; + } + + requisition->width = MIN_ENTRY_WIDTH + xborder * 2; requisition->height = ((metrics.ascent + metrics.descent) / PANGO_SCALE + - (widget->style->ythickness + INNER_BORDER) * 2); + yborder * 2); } static void @@ -847,7 +874,8 @@ gtk_entry_size_allocate (GtkWidget *widget, { GtkEntry *entry; GtkEditable *editable; - + gint xborder, yborder; + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); g_return_if_fail (allocation != NULL); @@ -856,6 +884,18 @@ gtk_entry_size_allocate (GtkWidget *widget, entry = GTK_ENTRY (widget); editable = GTK_EDITABLE (widget); + if (entry->has_frame) + { + xborder = widget->style->xthickness; + yborder = widget->style->ythickness; + } + else + { + /* 1 pixel for focus rect */ + xborder = 1; + yborder = 1; + } + if (GTK_WIDGET_REALIZED (widget)) { /* We call gtk_widget_get_child_requisition, since we want (for @@ -870,10 +910,10 @@ gtk_entry_size_allocate (GtkWidget *widget, allocation->y + (allocation->height - requisition.height) / 2, allocation->width, requisition.height); gdk_window_move_resize (entry->text_area, - widget->style->xthickness, - widget->style->ythickness, - allocation->width - widget->style->xthickness * 2, - requisition.height - widget->style->ythickness * 2); + xborder, + yborder, + allocation->width - xborder * 2, + requisition.height - yborder * 2); gtk_entry_recompute (entry); } @@ -883,37 +923,45 @@ static void gtk_entry_draw_focus (GtkWidget *widget) { gint width, height; - gint x, y; - + GtkEntry *entry; + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); + entry = GTK_ENTRY (widget); + if (GTK_WIDGET_DRAWABLE (widget)) - { - x = 0; - y = 0; - gdk_window_get_size (widget->window, &width, &height); + { + if (entry->has_frame) + { + gint x = 0, y = 0; - if (GTK_WIDGET_HAS_FOCUS (widget)) - { - x += 1; - y += 1; - width -= 2; - height -= 2; - } + gdk_window_get_size (widget->window, &width, &height); + + if (GTK_WIDGET_HAS_FOCUS (widget)) + { + x += 1; + y += 1; + width -= 2; + height -= 2; + } - gtk_paint_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - NULL, widget, "entry", - x, y, width, height); + gtk_paint_shadow (widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_IN, + NULL, widget, "entry", + x, y, width, height); + } + else + gdk_window_clear (widget->window); + if (GTK_WIDGET_HAS_FOCUS (widget)) - { - gdk_window_get_size (widget->window, &width, &height); - gtk_paint_focus (widget->style, widget->window, - NULL, widget, "entry", - 0, 0, width - 1, height - 1); - } + { + gdk_window_get_size (widget->window, &width, &height); + gtk_paint_focus (widget->style, widget->window, + NULL, widget, "entry", + 0, 0, width - 1, height - 1); + } } } @@ -2582,6 +2630,43 @@ gtk_entry_set_max_length (GtkEntry *entry, entry->text_max_length = max; } +/** + * gtk_entry_set_has_frame: + * @entry: a #GtkEntry + * @setting: new value + * + * Sets whether the entry has a beveled frame around it. + **/ +void +gtk_entry_set_has_frame (GtkEntry *entry, + gboolean setting) +{ + g_return_if_fail (GTK_IS_ENTRY (entry)); + + setting = (setting != FALSE); + + if (entry->has_frame != setting) + gtk_widget_queue_resize (GTK_WIDGET (entry)); + + entry->has_frame = setting; +} + +/** + * gtk_entry_get_has_frame: + * @entry: a #GtkEntry + * + * + * + * Return value: whether the entry has a beveled frame + **/ +gboolean +gtk_entry_get_has_frame (GtkEntry *entry) +{ + g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); + + return entry->has_frame; +} + /* Quick hack of a popup menu */ static void diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index 553837603..c8dbcdd83 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -76,6 +76,8 @@ struct _GtkEntry guint need_im_reset : 1; + guint has_frame : 1; + guint button; guint timer; guint recompute_idle; @@ -138,6 +140,9 @@ void gtk_entry_set_invisible_char (GtkEntry *entry, gunichar ch); void gtk_entry_set_editable (GtkEntry *entry, gboolean editable); +void gtk_entry_set_has_frame (GtkEntry *entry, + gboolean setting); +gboolean gtk_entry_get_has_frame (GtkEntry *entry); /* text is truncated if needed */ void gtk_entry_set_max_length (GtkEntry *entry, guint16 max); diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c index b045f2e60..ef3300430 100644 --- a/gtk/gtkliststore.c +++ b/gtk/gtkliststore.c @@ -22,6 +22,7 @@ #include "gtkliststore.h" #include "gtktreedatalist.h" #include "gtksignal.h" +#include "gtktreednd.h" #include #define G_SLIST(x) ((GSList *) x) @@ -39,6 +40,8 @@ static guint list_store_signals[LAST_SIGNAL] = { 0 }; static void gtk_list_store_init (GtkListStore *list_store); static void gtk_list_store_class_init (GtkListStoreClass *class); static void gtk_list_store_tree_model_init (GtkTreeModelIface *iface); +static void gtk_list_store_drag_source_init(GtkTreeDragSourceIface *iface); +static void gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface); static guint gtk_list_store_get_flags (GtkTreeModel *tree_model); static gint gtk_list_store_get_n_columns (GtkTreeModel *tree_model); static GType gtk_list_store_get_column_type (GtkTreeModel *tree_model, @@ -69,6 +72,15 @@ static gboolean gtk_list_store_iter_parent (GtkTreeModel *tree_mode GtkTreeIter *iter, GtkTreeIter *child); +static gboolean gtk_list_store_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path); +static gboolean gtk_list_store_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data); +static gboolean gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest, + GtkTreePath *dest, + GtkSelectionData *selection_data); + GtkType gtk_list_store_get_type (void) @@ -97,10 +109,30 @@ gtk_list_store_get_type (void) NULL }; + static const GInterfaceInfo drag_source_info = + { + (GInterfaceInitFunc) gtk_list_store_drag_source_init, + NULL, + NULL + }; + + static const GInterfaceInfo drag_dest_info = + { + (GInterfaceInitFunc) gtk_list_store_drag_dest_init, + NULL, + NULL + }; + list_store_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkListStore", &list_store_info, 0); g_type_add_interface_static (list_store_type, GTK_TYPE_TREE_MODEL, &tree_model_info); + g_type_add_interface_static (list_store_type, + GTK_TYPE_TREE_DRAG_SOURCE, + &drag_source_info); + g_type_add_interface_static (list_store_type, + GTK_TYPE_TREE_DRAG_DEST, + &drag_dest_info); } return list_store_type; @@ -167,6 +199,19 @@ gtk_list_store_tree_model_init (GtkTreeModelIface *iface) iface->iter_parent = gtk_list_store_iter_parent; } +static void +gtk_list_store_drag_source_init (GtkTreeDragSourceIface *iface) +{ + iface->drag_data_delete = gtk_list_store_drag_data_delete; + iface->drag_data_get = gtk_list_store_drag_data_get; +} + +static void +gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface) +{ + iface->drag_data_received = gtk_list_store_drag_data_received; +} + static void gtk_list_store_init (GtkListStore *list_store) { @@ -646,21 +691,17 @@ remove_link_saving_prev (GSList *list, return list; } -void -gtk_list_store_remove (GtkListStore *list_store, - GtkTreeIter *iter) +static void +gtk_list_store_remove_silently (GtkListStore *list_store, + GtkTreeIter *iter, + GtkTreePath *path) { - GtkTreePath *path; - - g_return_if_fail (list_store != NULL); - g_return_if_fail (GTK_IS_LIST_STORE (list_store)); - g_return_if_fail (iter->user_data != NULL); - if (G_SLIST (iter->user_data)->data) - _gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data, - list_store->column_headers); - - path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter); + { + _gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data, + list_store->column_headers); + G_SLIST (iter->user_data)->data = NULL; + } { GSList *prev = NULL; @@ -674,6 +715,23 @@ gtk_list_store_remove (GtkListStore *list_store, } list_store->stamp ++; +} + +void +gtk_list_store_remove (GtkListStore *list_store, + GtkTreeIter *iter) +{ + GtkTreePath *path; + + g_return_if_fail (list_store != NULL); + g_return_if_fail (GTK_IS_LIST_STORE (list_store)); + g_return_if_fail (iter->user_data != NULL); + + + path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter); + + gtk_list_store_remove_silently (list_store, iter, path); + gtk_signal_emit_by_name (GTK_OBJECT (list_store), "deleted", path); @@ -901,3 +959,164 @@ gtk_list_store_append (GtkListStore *list_store, path, iter); gtk_tree_path_free (path); } + +static gboolean +gtk_list_store_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path) +{ + GtkTreeIter iter; + g_return_val_if_fail (GTK_IS_LIST_STORE (drag_source), FALSE); + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), + &iter, + path)) + { + gtk_list_store_remove (GTK_LIST_STORE (drag_source), + &iter); + return TRUE; + } + else + { + return FALSE; + } +} + +static gboolean +gtk_list_store_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data) +{ + g_return_val_if_fail (GTK_IS_LIST_STORE (drag_source), FALSE); + + /* Note that we don't need to handle the GTK_TREE_MODEL_ROW + * target, because the default handler does it for us, but + * we do anyway for the convenience of someone maybe overriding the + * default handler. + */ + + if (gtk_selection_data_set_tree_row (selection_data, + GTK_TREE_MODEL (drag_source), + path)) + { + return TRUE; + } + else + { + /* FIXME handle text targets at least. */ + } + + return FALSE; +} + +static gboolean +gtk_list_store_drag_data_received (GtkTreeDragDest *drag_dest, + GtkTreePath *dest, + GtkSelectionData *selection_data) +{ + GtkTreeModel *tree_model; + GtkListStore *list_store; + GtkTreeModel *src_model = NULL; + GtkTreePath *src_path = NULL; + gboolean retval = FALSE; + + g_return_val_if_fail (GTK_IS_LIST_STORE (drag_dest), FALSE); + + tree_model = GTK_TREE_MODEL (drag_dest); + list_store = GTK_LIST_STORE (drag_dest); + + if (gtk_selection_data_get_tree_row (selection_data, + &src_model, + &src_path) && + src_model == tree_model) + { + /* Copy the given row to a new position */ + GtkTreeIter src_iter; + GtkTreeIter dest_iter; + GtkTreePath *prev; + + if (!gtk_tree_model_get_iter (src_model, + &src_iter, + src_path)) + goto out; + + /* Get the path to insert _after_ (dest is the path to insert _before_) */ + prev = gtk_tree_path_copy (dest); + + if (!gtk_tree_path_prev (prev)) + { + /* dest was the first spot in the list; which means we are supposed + * to prepend. + */ + gtk_list_store_prepend (GTK_LIST_STORE (tree_model), + &dest_iter); + + retval = TRUE; + } + else + { + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model), + &dest_iter, + prev)) + { + GtkTreeIter tmp_iter = dest_iter; + gtk_list_store_insert_after (GTK_LIST_STORE (tree_model), + &dest_iter, + &tmp_iter); + retval = TRUE; + } + } + + gtk_tree_path_free (prev); + + /* If we succeeded in creating dest_iter, copy data from src + */ + if (retval) + { + GtkTreeDataList *dl = G_SLIST (src_iter.user_data)->data; + GtkTreeDataList *copy_head = NULL; + GtkTreeDataList *copy_prev = NULL; + GtkTreeDataList *copy_iter = NULL; + gint col; + + col = 0; + while (dl) + { + copy_iter = _gtk_tree_data_list_node_copy (dl, + list_store->column_headers[col]); + + g_print ("copied col %d type %s\n", col, + g_type_name (list_store->column_headers[col])); + + if (copy_head == NULL) + copy_head = copy_iter; + + if (copy_prev) + copy_prev->next = copy_iter; + + copy_prev = copy_iter; + + dl = dl->next; + ++col; + } + + G_SLIST (dest_iter.user_data)->data = copy_head; + + gtk_signal_emit_by_name (GTK_OBJECT (tree_model), + "changed", + NULL, &dest_iter); + } + } + else + { + /* FIXME maybe add some data targets eventually, or handle text + * targets in the simple case. + */ + } + + out: + + if (src_path) + gtk_tree_path_free (src_path); + + return retval; +} diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index d3ba241d4..ebb324efb 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -148,7 +148,8 @@ static const GDebugKey gtk_debug_keys[] = { {"dnd", GTK_DEBUG_DND}, {"plugsocket", GTK_DEBUG_PLUGSOCKET}, {"text", GTK_DEBUG_TEXT}, - {"tree", GTK_DEBUG_TREE} + {"tree", GTK_DEBUG_TREE}, + {"updates", GTK_DEBUG_UPDATES} }; static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey); @@ -346,6 +347,9 @@ gtk_init_check (int *argc, } } } + + if (gtk_debug_flags & GTK_DEBUG_UPDATES) + gdk_window_set_debug_updates (TRUE); /* load gtk modules */ gtk_modules = g_slist_reverse (gtk_modules); diff --git a/gtk/gtkrbtree.c b/gtk/gtkrbtree.c index 8259b91fd..e8bbf2d9d 100644 --- a/gtk/gtkrbtree.c +++ b/gtk/gtkrbtree.c @@ -641,7 +641,12 @@ _gtk_rbtree_node_find_offset (GtkRBTree *tree, GtkRBNode *node) { GtkRBNode *last; - gint retval = node->left->offset; + gint retval; + + g_assert (node); + g_assert (node->left); + + retval = node->left->offset; while (tree && node && node != tree->nil) { @@ -904,6 +909,22 @@ _gtk_rbtree_prev_full (GtkRBTree *tree, } } +gint +_gtk_rbtree_get_depth (GtkRBTree *tree) +{ + GtkRBTree *tmp_tree; + gint depth = 0; + + tmp_tree = tree->parent_tree; + while (tmp_tree) + { + ++depth; + tmp_tree = tmp_tree->parent_tree; + } + + return depth; +} + static void _gtk_rbtree_traverse_pre_order (GtkRBTree *tree, GtkRBNode *node, diff --git a/gtk/gtkrbtree.h b/gtk/gtkrbtree.h index 32aed4417..40c779320 100644 --- a/gtk/gtkrbtree.h +++ b/gtk/gtkrbtree.h @@ -123,6 +123,7 @@ void _gtk_rbtree_prev_full (GtkRBTree *tree, GtkRBTree **new_tree, GtkRBNode **new_node); +gint _gtk_rbtree_get_depth (GtkRBTree *tree); /* This func just checks the integrity of the tree */ /* It will go away later. */ diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index d86986e52..054bf21df 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -2476,8 +2476,34 @@ gtk_default_draw_check (GtkStyle *style, gint width, gint height) { - gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail, - x, y, width, height); + if (detail && strcmp (detail, "cellcheck") == 0) + { + gdk_draw_rectangle (window, + widget->style->fg_gc[state_type], + FALSE, + x, y, + width, height); + + if (shadow_type == GTK_SHADOW_IN) + { + gdk_draw_line (window, + widget->style->fg_gc[state_type], + x, y, + x + width, + y + height); + gdk_draw_line (window, + widget->style->fg_gc[state_type], + x + width, + y, + x, + y + height); + } + } + else + { + gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail, + x, y, width, height); + } } static void @@ -2493,8 +2519,33 @@ gtk_default_draw_option (GtkStyle *style, gint width, gint height) { - gtk_paint_diamond (style, window, state_type, shadow_type, area, widget, - detail, x, y, width, height); + if (detail && strcmp (detail, "cellradio") == 0) + { + gdk_draw_arc (window, + widget->style->fg_gc[state_type], + FALSE, + x, y, + width, + height, + 0, 360*64); + + if (shadow_type == GTK_SHADOW_IN) + { + gdk_draw_arc (window, + widget->style->fg_gc[state_type], + TRUE, + x + 2, + y + 2, + width - 4, + height - 4, + 0, 360*64); + } + } + else + { + gtk_paint_diamond (style, window, state_type, shadow_type, area, widget, + detail, x, y, width, height); + } } static void @@ -3420,6 +3471,155 @@ gtk_default_draw_expander (GtkStyle *style, #undef PM_SIZE } +typedef struct _ByteRange ByteRange; + +struct _ByteRange +{ + guint start; + guint end; +}; + +static ByteRange* +range_new (guint start, + guint end) +{ + ByteRange *br = g_new (ByteRange, 1); + + br->start = start; + br->end = end; + + return br; +} + +static PangoLayout* +get_insensitive_layout (PangoLayout *layout) +{ + GSList *embossed_ranges = NULL; + GSList *stippled_ranges = NULL; + PangoLayoutIter *iter; + GSList *tmp_list = NULL; + PangoLayout *new_layout; + PangoAttrList *attrs; + GdkBitmap *stipple = NULL; + + iter = pango_layout_get_iter (layout); + + do + { + PangoLayoutRun *run; + PangoAttribute *attr; + gboolean need_stipple = FALSE; + ByteRange *br; + + run = pango_layout_iter_get_run (iter); + + if (run) + { + tmp_list = run->item->extra_attrs; + + while (tmp_list != NULL) + { + attr = tmp_list->data; + switch (attr->klass->type) + { + case PANGO_ATTR_FOREGROUND: + case PANGO_ATTR_BACKGROUND: + need_stipple = TRUE; + break; + + default: + break; + } + + if (need_stipple) + break; + + tmp_list = g_slist_next (tmp_list); + } + + br = range_new (run->item->offset, run->item->offset + run->item->length); + + if (need_stipple) + stippled_ranges = g_slist_prepend (stippled_ranges, br); + else + embossed_ranges = g_slist_prepend (embossed_ranges, br); + } + } + while (pango_layout_iter_next_run (iter)); + + pango_layout_iter_free (iter); + + new_layout = pango_layout_copy (layout); + + attrs = pango_layout_get_attributes (new_layout); + + if (attrs == NULL) + { + /* Create attr list if there wasn't one */ + attrs = pango_attr_list_new (); + pango_layout_set_attributes (new_layout, attrs); + pango_attr_list_unref (attrs); + } + + tmp_list = embossed_ranges; + while (tmp_list != NULL) + { + PangoAttribute *attr; + ByteRange *br = tmp_list->data; + + attr = gdk_pango_attr_embossed_new (TRUE); + + attr->start_index = br->start; + attr->end_index = br->end; + + pango_attr_list_change (attrs, attr); + + g_free (br); + + tmp_list = g_slist_next (tmp_list); + } + + g_slist_free (embossed_ranges); + + tmp_list = stippled_ranges; + while (tmp_list != NULL) + { + PangoAttribute *attr; + ByteRange *br = tmp_list->data; + + if (stipple == NULL) + { +#define gray50_width 2 +#define gray50_height 2 + static char gray50_bits[] = { + 0x02, 0x01 + }; + + stipple = gdk_bitmap_create_from_data (NULL, + gray50_bits, gray50_width, + gray50_height); + } + + attr = gdk_pango_attr_stipple_new (stipple); + + attr->start_index = br->start; + attr->end_index = br->end; + + pango_attr_list_change (attrs, attr); + + g_free (br); + + tmp_list = g_slist_next (tmp_list); + } + + g_slist_free (stippled_ranges); + + if (stipple) + g_object_unref (G_OBJECT (stipple)); + + return new_layout; +} + static void gtk_default_draw_layout (GtkStyle *style, GdkWindow *window, @@ -3435,24 +3635,25 @@ gtk_default_draw_layout (GtkStyle *style, g_return_if_fail (window != NULL); if (area) - { - gdk_gc_set_clip_rectangle (style->white_gc, area); - gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area); - } + gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area); - /* FIXME this is frickin' ugly with any kind of attributes set on the - * text being rendered - */ if (state_type == GTK_STATE_INSENSITIVE) - gdk_draw_layout (window, style->white_gc, x + 1, y + 1, layout); + { + PangoLayout *ins; - gdk_draw_layout (window, style->fg_gc[state_type], x, y, layout); + ins = get_insensitive_layout (layout); + + gdk_draw_layout (window, style->fg_gc[state_type], x, y, ins); - if (area) + g_object_unref (G_OBJECT (ins)); + } + else { - gdk_gc_set_clip_rectangle (style->white_gc, NULL); - gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL); + gdk_draw_layout (window, style->fg_gc[state_type], x, y, layout); } + + if (area) + gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL); } static void diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index ff9bdca23..f220646b6 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -1499,9 +1499,9 @@ static void convert_color (GdkColor *result, PangoAttrColor *attr) { - result->red = attr->red; - result->blue = attr->blue; - result->green = attr->green; + result->red = attr->color.red; + result->blue = attr->color.blue; + result->green = attr->color.green; } /* This function is used to convert the preedit string attributes, which are diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index e18340d65..cc2006896 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -4373,7 +4373,7 @@ gtk_text_view_drag_motion (GtkWidget *widget, } else if (gtk_text_buffer_get_selection_bounds (get_buffer (text_view), &start, &end) && - gtk_text_iter_in_range (&newplace, &start, &end)) + gtk_text_iter_in_range (&newplace, &start, &end)) { /* We're inside the selection. */ } diff --git a/gtk/gtktreedatalist.c b/gtk/gtktreedatalist.c index 6fdf9d2e9..b55b730af 100644 --- a/gtk/gtktreedatalist.c +++ b/gtk/gtktreedatalist.c @@ -234,4 +234,48 @@ _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, } } +GtkTreeDataList* +_gtk_tree_data_list_node_copy (GtkTreeDataList *list, + GType type) +{ + GtkTreeDataList *new_list; + + new_list = _gtk_tree_data_list_alloc (); + + switch (type) + { + case G_TYPE_UINT: + case G_TYPE_INT: + case G_TYPE_UCHAR: + case G_TYPE_CHAR: + case G_TYPE_BOOLEAN: + case G_TYPE_POINTER: + case G_TYPE_FLOAT: + new_list->data = list->data; + break; + case G_TYPE_STRING: + new_list->data.v_pointer = g_strdup (list->data.v_pointer); + break; + + default: + if (g_type_is_a (type, G_TYPE_OBJECT)) + { + new_list->data.v_pointer = list->data.v_pointer; + if (new_list->data.v_pointer) + g_object_ref (G_OBJECT (new_list->data.v_pointer)); + } + else if (g_type_is_a (type, G_TYPE_BOXED)) + { + if (list->data.v_pointer) + new_list->data.v_pointer = g_boxed_copy (type, list->data.v_pointer); + else + new_list->data.v_pointer = NULL; + } + else + g_warning ("Unsupported node type (%s) copied.", g_type_name (type)); + break; + } + + return new_list; +} diff --git a/gtk/gtktreedatalist.h b/gtk/gtktreedatalist.h index 1149fdad0..66fe37592 100644 --- a/gtk/gtktreedatalist.h +++ b/gtk/gtktreedatalist.h @@ -50,6 +50,8 @@ void _gtk_tree_data_list_node_to_value (GtkTreeDataList *list, void _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, GValue *value); +GtkTreeDataList *_gtk_tree_data_list_node_copy (GtkTreeDataList *list, + GType type); #endif /* __GTK_TREE_DATA_LIST_H__ */ diff --git a/gtk/gtktreednd.c b/gtk/gtktreednd.c new file mode 100644 index 000000000..f798022c2 --- /dev/null +++ b/gtk/gtktreednd.c @@ -0,0 +1,265 @@ +/* gtktreednd.c + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include "gtktreednd.h" + +GType +gtk_tree_drag_source_get_type (void) +{ + static GType our_type = 0; + + if (!our_type) + { + static const GTypeInfo our_info = + { + sizeof (GtkTreeDragSourceIface), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + our_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeDragSource", &our_info, 0); + } + + return our_type; +} + + +GType +gtk_tree_drag_dest_get_type (void) +{ + static GType our_type = 0; + + if (!our_type) + { + static const GTypeInfo our_info = + { + sizeof (GtkTreeDragDestIface), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + our_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeDragDest", &our_info, 0); + } + + return our_type; +} + + +/** + * gtk_tree_drag_source_drag_data_delete: + * @drag_source: a #GtkTreeDragSource + * @path: row that was being dragged + * + * Asks the #GtkTreeDragSource to delete the row at @path, because + * it was moved somewhere else via drag-and-drop. Returns %FALSE + * if the deletion fails because @path no longer exists, or for + * some model-specific reason. Should robustly handle a @path no + * longer found in the model! + * + * Return value: %TRUE if the row was successfully deleted + **/ +gboolean +gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path) +{ + GtkTreeDragSourceIface *iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (drag_source); + + g_return_val_if_fail (iface->drag_data_delete != NULL, FALSE); + g_return_val_if_fail (path != NULL, FALSE); + + return (* iface->drag_data_delete) (drag_source, path); +} + +/** + * gtk_tree_drag_source_drag_data_get: + * @drag_source: a #GtkTreeDragSource + * @path: row that was dragged + * @selection_data: a #GtkSelectionData to fill with data from the dragged row + * + * Asks the #GtkTreeDragSource to fill in @selection_data with a + * representation of the row at @path. @selection_data->target gives + * the required type of the data. Should robustly handle a @path no + * longer found in the model! + * + * Return value: %TRUE if data of the required type was provided + **/ +gboolean +gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data) +{ + GtkTreeDragSourceIface *iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (drag_source); + + g_return_val_if_fail (iface->drag_data_get != NULL, FALSE); + g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail (selection_data != NULL, FALSE); + + return (* iface->drag_data_get) (drag_source, path, selection_data); +} + +/** + * gtk_tree_drag_dest_drag_data_received: + * @drag_dest: a #GtkTreeDragDest + * @dest: row to drop in front of + * @selection_data: data to drop + * + * Asks the #GtkTreeDragDest to insert a row before the path @dest, + * deriving the contents of the row from @selection_data. If @dest is + * outside the tree so that inserting before it is impossible, %FALSE + * will be returned. Also, %FALSE may be returned if the new row is + * not created for some model-specific reason. Should robustly handle + * a @dest no longer found in the model! + * + * Return value: whether a new row was created before position @dest + **/ +gboolean +gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest, + GtkTreePath *dest, + GtkSelectionData *selection_data) +{ + GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE (drag_dest); + + g_return_val_if_fail (iface->drag_data_received != NULL, FALSE); + g_return_val_if_fail (dest != NULL, FALSE); + g_return_val_if_fail (selection_data != NULL, FALSE); + + return (* iface->drag_data_received) (drag_dest, dest, selection_data); +} + +typedef struct _TreeRowData TreeRowData; + +struct _TreeRowData +{ + GtkTreeModel *model; + gchar path[4]; +}; + +/** + * gtk_selection_data_set_tree_row: + * @selection_data: some #GtkSelectionData + * @tree_model: a #GtkTreeModel + * @path: a row in @tree_model + * + * Sets selection data of target type %GTK_TREE_MODEL_ROW. Normally used + * in a drag_data_get handler. + * + * Return value: %TRUE if the #GtkSelectionData had the proper target type to allow us to set a tree row + **/ +gboolean +gtk_selection_data_set_tree_row (GtkSelectionData *selection_data, + GtkTreeModel *tree_model, + GtkTreePath *path) +{ + TreeRowData *trd; + gchar *path_str; + gint len; + gint struct_size; + + g_return_val_if_fail (selection_data != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE); + g_return_val_if_fail (path != NULL, FALSE); + + if (selection_data->target != gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE)) + return FALSE; + + path_str = gtk_tree_path_to_string (path); + + len = strlen (path_str); + + /* the old allocate-end-of-struct-to-hold-string trick */ + struct_size = sizeof (TreeRowData) + len + 1 - + (sizeof (TreeRowData) - G_STRUCT_OFFSET (TreeRowData, path)); + + trd = g_malloc (struct_size); + + strcpy (trd->path, path_str); + + trd->model = tree_model; + + gtk_selection_data_set (selection_data, + gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE), + 8, /* bytes */ + (void*)trd, + struct_size); + + g_free (trd); + + return TRUE; +} + +/** + * gtk_selection_data_get_tree_row: + * @selection_data: a #GtkSelectionData + * @tree_model: a #GtkTreeModel + * @path: row in @tree_model + * + * Obtains a @tree_model and @path from selection data of target type + * %GTK_TREE_MODEL_ROW. Normally called from a drag_data_received handler. + * This function can only be used if @selection_data originates from the same + * process that's calling this function, because a pointer to the tree model + * is being passed around. If you aren't in the same process, then you'll + * get memory corruption. In the #GtkTreeDragDest drag_data_received handler, + * you can assume that selection data of type %GTK_TREE_MODEL_ROW is + * in from the current process. The returned path must be freed with + * gtk_tree_path_free(). + * + * Return value: %TRUE if @selection_data had target type %GTK_TREE_MODEL_ROW and + * is otherwise valid + **/ +gboolean +gtk_selection_data_get_tree_row (GtkSelectionData *selection_data, + GtkTreeModel **tree_model, + GtkTreePath **path) +{ + TreeRowData *trd; + + g_return_val_if_fail (selection_data != NULL, FALSE); + + if (tree_model) + *tree_model = NULL; + + if (path) + *path = NULL; + + if (selection_data->target != gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE)) + return FALSE; + + trd = (void*) selection_data->data; + + if (tree_model) + *tree_model = trd->model; + + if (path) + *path = gtk_tree_path_new_from_string (trd->path); + + return TRUE; +} diff --git a/gtk/gtktreednd.h b/gtk/gtktreednd.h new file mode 100644 index 000000000..1257ed25f --- /dev/null +++ b/gtk/gtktreednd.h @@ -0,0 +1,109 @@ +/* gtktreednd.h + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GTK_TREE_DND_H__ +#define __GTK_TREE_DND_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GTK_TYPE_TREE_DRAG_SOURCE (gtk_tree_drag_source_get_type ()) +#define GTK_TREE_DRAG_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_DRAG_SOURCE, GtkTreeDragSource)) +#define GTK_IS_TREE_DRAG_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_DRAG_SOURCE)) +#define GTK_TREE_DRAG_SOURCE_GET_IFACE(obj) ((GtkTreeDragSourceIface *)g_type_interface_peek (((GTypeInstance *)GTK_TREE_DRAG_SOURCE (obj))->g_class, GTK_TYPE_TREE_DRAG_SOURCE)) + +typedef struct _GtkTreeDragSource GtkTreeDragSource; /* Dummy typedef */ +typedef struct _GtkTreeDragSourceIface GtkTreeDragSourceIface; + +struct _GtkTreeDragSourceIface +{ + GTypeInterface g_iface; + + /* VTable - not signals */ + + gboolean (* drag_data_get) (GtkTreeDragSource *dragsource, + GtkTreePath *path, + GtkSelectionData *selection_data); + + gboolean (* drag_data_delete) (GtkTreeDragSource *dragsource, + GtkTreePath *path); +}; + +GType gtk_tree_drag_source_get_type (void) G_GNUC_CONST; + +/* Deletes the given row, or returns FALSE if it can't */ +gboolean gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path); + +/* Fills in selection_data with type selection_data->target based on + * the row denoted by path, returns TRUE if it does anything + */ +gboolean gtk_tree_drag_source_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data); + +#define GTK_TYPE_TREE_DRAG_DEST (gtk_tree_drag_dest_get_type ()) +#define GTK_TREE_DRAG_DEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_DRAG_DEST, GtkTreeDragDest)) +#define GTK_IS_TREE_DRAG_DEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_DRAG_DEST)) +#define GTK_TREE_DRAG_DEST_GET_IFACE(obj) ((GtkTreeDragDestIface *)g_type_interface_peek (((GTypeInstance *)GTK_TREE_DRAG_DEST (obj))->g_class, GTK_TYPE_TREE_DRAG_DEST)) + +typedef struct _GtkTreeDragDest GtkTreeDragDest; /* Dummy typedef */ +typedef struct _GtkTreeDragDestIface GtkTreeDragDestIface; + +struct _GtkTreeDragDestIface +{ + GTypeInterface g_iface; + + /* VTable - not signals */ + + gboolean (* drag_data_received) (GtkTreeDragDest *dragdest, + GtkTreePath *dest, + GtkSelectionData *selection_data); + +}; + +GType gtk_tree_drag_dest_get_type (void) G_GNUC_CONST; + +/* Inserts a row before dest which contains data in selection_data, + * or returns FALSE if it can't + */ +gboolean gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest *drag_dest, + GtkTreePath *dest, + GtkSelectionData *selection_data); + +/* The selection data would normally have target type GTK_TREE_MODEL_ROW in this + * case. If the target is wrong these functions return FALSE. + */ +gboolean gtk_selection_data_set_tree_row (GtkSelectionData *selection_data, + GtkTreeModel *tree_model, + GtkTreePath *path); +gboolean gtk_selection_data_get_tree_row (GtkSelectionData *selection_data, + GtkTreeModel **tree_model, + GtkTreePath **path); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_TREE_DND_H__ */ diff --git a/gtk/gtktreemodel.h b/gtk/gtktreemodel.h index 74fd34da7..b15b92b67 100644 --- a/gtk/gtktreemodel.h +++ b/gtk/gtktreemodel.h @@ -179,7 +179,7 @@ gboolean gtk_tree_model_iter_parent (GtkTreeModel *tree_model, void gtk_tree_model_ref_iter (GtkTreeModel *tree_model, GtkTreeIter *iter); void gtk_tree_model_unref_iter (GtkTreeModel *tree_model, - GtkTreeIter *iter); + GtkTreeIter *iter); #ifdef __cplusplus } diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 78d093c56..73d5a9fd3 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -20,6 +20,7 @@ #include "gtktreeview.h" #include "gtkrbtree.h" +#include "gtktreednd.h" #include "gtktreeprivate.h" #include "gtkcellrenderer.h" #include "gtksignal.h" @@ -35,9 +36,35 @@ #define TREE_VIEW_DRAG_WIDTH 6 #define TREE_VIEW_EXPANDER_WIDTH 14 #define TREE_VIEW_EXPANDER_HEIGHT 14 -#define TREE_VIEW_VERTICAL_SEPARATOR 2 + +/* The TREE_VIEW_VERTICAL_SEPARATOR is the space between rows. The + * GTK_RBNODE_GET_HEIGHT() value includes the separators; the offset + * of each row points to the center of the inter-row space. For an odd + * separator, the extra pixel by convention goes _below_ the row. So + * a node in the rbtree owns TREE_VIEW_VERTICAL_SEPARATOR/2 pixels + * above the row, and TREE_VIEW_VERTICAL_SEPARATOR/2 + + * TREE_VIEW_VERTICAL_SEPARATOR%2 pixels below the row. + */ + +/* Set to large number for debugging. Should normally be 2. */ +#define TREE_VIEW_VERTICAL_SEPARATOR 11 + #define TREE_VIEW_HORIZONTAL_SEPARATOR 0 +/* The "background" areas of all rows/cells add up to cover the entire tree. + * The background includes all inter-row and inter-cell spacing. + * The "cell" areas are the cell_area passed in to gtk_cell_renderer_render(), + * i.e. just the cells, no spacing. + */ + +#define BACKGROUND_FIRST_PIXEL(tree_view,tree,node) (_gtk_rbtree_node_find_offset ((tree), (node)) + TREE_VIEW_HEADER_HEIGHT ((tree_view))) +#define CELL_FIRST_PIXEL(tree_view,tree,node) (BACKGROUND_FIRST_PIXEL (tree_view,tree,node) + TREE_VIEW_VERTICAL_SEPARATOR/2) + +#define BACKGROUND_HEIGHT(node) (GTK_RBNODE_GET_HEIGHT (node)) +#define CELL_HEIGHT(node) (BACKGROUND_HEIGHT (node) - TREE_VIEW_VERTICAL_SEPARATOR); + +#define TREE_WINDOW_Y_TO_RBTREE_Y(tree_view,y) ((y) - TREE_VIEW_HEADER_HEIGHT (tree_view)) +#define RBTREE_Y_TO_TREE_WINDOW_Y(tree_view,y) ((y) + TREE_VIEW_HEADER_HEIGHT (tree_view)) typedef struct _GtkTreeViewChild GtkTreeViewChild; @@ -152,13 +179,16 @@ static void gtk_tree_view_queue_draw_node (GtkTreeView *tree_view, GtkRBTree *tree, GtkRBNode *node, GdkRectangle *clip_rect); +static void gtk_tree_view_queue_draw_path (GtkTreeView *tree_view, + GtkTreePath *path, + GdkRectangle *clip_rect); static void gtk_tree_view_draw_arrow (GtkTreeView *tree_view, GtkRBTree *tree, GtkRBNode *node, gint x, gint y); -static void gtk_tree_view_get_arrow_range (GtkTreeView *tree_view, - gint *x1, +static void gtk_tree_view_get_arrow_xrange (GtkTreeView *tree_view, + gint *x1, gint *x2); static gint gtk_tree_view_new_column_width (GtkTreeView *tree_view, gint i, @@ -821,9 +851,9 @@ gtk_tree_view_draw_node_focus_rect (GtkWidget *widget, widget->style->fg_gc[GTK_STATE_NORMAL], FALSE, 0, - _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view), + BACKGROUND_FIRST_PIXEL (tree_view, tree, node), bin_window_width - 2, - GTK_RBNODE_GET_HEIGHT (node)); + BACKGROUND_HEIGHT (node) - 1); } GdkPixmap* @@ -836,7 +866,6 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view, GtkCellRenderer *cell; gint i; gint cell_offset; - gint max_height; GList *list; GdkRectangle background_area; GtkWidget *widget; @@ -860,20 +889,18 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view, &iter, path)) return NULL; - - max_height = GTK_RBNODE_GET_HEIGHT (node); cell_offset = x; - background_area.y = y + TREE_VIEW_VERTICAL_SEPARATOR; - background_area.height = max_height - TREE_VIEW_VERTICAL_SEPARATOR; + background_area.y = y; + background_area.height = BACKGROUND_HEIGHT (node); gdk_drawable_get_size (tree_view->priv->bin_window, &bin_window_width, NULL); drawable = gdk_pixmap_new (tree_view->priv->bin_window, bin_window_width + 2, - max_height + 2, + background_area.height + 2, -1); gdk_draw_rectangle (drawable, @@ -881,14 +908,14 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view, TRUE, 0, 0, bin_window_width + 2, - max_height + 2); + background_area.height + 2); gdk_draw_rectangle (drawable, widget->style->black_gc, FALSE, 0, 0, bin_window_width + 1, - max_height + 1); + background_area.height + 1); for (i = 0, list = tree_view->priv->columns; i < tree_view->priv->n_columns; i++, list = list->next) { @@ -907,6 +934,9 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view, background_area.width = TREE_VIEW_COLUMN_WIDTH (column); cell_area = background_area; + + cell_area.y += TREE_VIEW_VERTICAL_SEPARATOR / 2; + cell_area.height -= TREE_VIEW_VERTICAL_SEPARATOR; if (i == tree_view->priv->expander_column && TREE_VIEW_DRAW_EXPANDERS(tree_view)) @@ -972,8 +1002,11 @@ gtk_tree_view_bin_expose (GtkWidget *widget, * height to find the right node. */ new_y = (event->area.yarea.y; + + /* y_offset is the */ + y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, - new_y - TREE_VIEW_HEADER_HEIGHT (tree_view), + TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y), &tree, &node) + new_y - event->area.y; if (node == NULL) @@ -1015,13 +1048,13 @@ gtk_tree_view_bin_expose (GtkWidget *widget, max_height = MAX (TREE_VIEW_EXPANDER_MIN_HEIGHT, GTK_RBNODE_GET_HEIGHT (node)); else */ - max_height = GTK_RBNODE_GET_HEIGHT (node); + max_height = BACKGROUND_HEIGHT (node); x_offset = -event->area.x; cell_offset = 0; highlight_x = 0; /* should match x coord of first cell */ - background_area.y = y_offset + event->area.y + TREE_VIEW_VERTICAL_SEPARATOR; + background_area.y = y_offset + event->area.y + TREE_VIEW_VERTICAL_SEPARATOR / 2; background_area.height = max_height - TREE_VIEW_VERTICAL_SEPARATOR; flags = 0; @@ -1236,11 +1269,11 @@ coords_are_over_arrow (GtkTreeView *tree_view, if ((node->flags & GTK_RBNODE_IS_PARENT) == 0) return FALSE; - arrow.y = _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view); + arrow.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node); - arrow.height = GTK_RBNODE_GET_HEIGHT (node); + arrow.height = BACKGROUND_HEIGHT (node); - gtk_tree_view_get_arrow_range (tree_view, &arrow.x, &x2); + gtk_tree_view_get_arrow_xrange (tree_view, &arrow.x, &x2); arrow.width = x2 - arrow.x; @@ -1256,21 +1289,10 @@ do_unprelight (GtkTreeView *tree_view, gint x, gint y) { - gint y1, y2; - if (tree_view->priv->prelight_node == NULL) return; - y1 = _gtk_rbtree_node_find_offset (tree_view->priv->prelight_tree, - tree_view->priv->prelight_node) + - TREE_VIEW_HEADER_HEIGHT (tree_view); - - y2 = y1 + GTK_RBNODE_GET_HEIGHT (tree_view->priv->prelight_node); - - if (tree_view->priv->prelight_node) - GTK_RBNODE_UNSET_FLAG (tree_view->priv->prelight_node, GTK_RBNODE_IS_PRELIT); - - /* FIXME queue draw on y1-y2 range */ + GTK_RBNODE_UNSET_FLAG (tree_view->priv->prelight_node, GTK_RBNODE_IS_PRELIT); if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT) && !coords_are_over_arrow (tree_view, @@ -1286,15 +1308,12 @@ do_unprelight (GtkTreeView *tree_view, tree_view->priv->prelight_tree, tree_view->priv->prelight_node, x, - y); + y); } tree_view->priv->prelight_node = NULL; tree_view->priv->prelight_tree = NULL; - - /* FIXME */ - gtk_widget_queue_draw (GTK_WIDGET (tree_view)); } static void @@ -1312,8 +1331,6 @@ do_prelight (GtkTreeView *tree_view, tree_view->priv->prelight_tree = tree; GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_PRELIT); - - gtk_widget_queue_draw (GTK_WIDGET (tree_view)); } static gboolean @@ -1324,6 +1341,8 @@ gtk_tree_view_motion (GtkWidget *widget, GtkRBTree *tree; GtkRBNode *node; gint new_y; + GtkRBTree *old_prelight_tree; + GtkRBNode *old_prelight_node; tree_view = (GtkTreeView *) widget; @@ -1357,11 +1376,15 @@ gtk_tree_view_motion (GtkWidget *widget, gtk_tree_view_maybe_begin_dragging_row (tree_view, event); + old_prelight_tree = tree_view->priv->prelight_tree; + old_prelight_node = tree_view->priv->prelight_node; + do_unprelight (tree_view, event->x, event->y); new_y = ((gint)event->yy; - _gtk_rbtree_find_offset (tree_view->priv->tree, new_y - TREE_VIEW_HEADER_HEIGHT (tree_view), + _gtk_rbtree_find_offset (tree_view->priv->tree, + TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y), &tree, &node); @@ -1376,6 +1399,21 @@ gtk_tree_view_motion (GtkWidget *widget, do_prelight (tree_view, tree, node, event->x, new_y); + if (old_prelight_node != tree_view->priv->prelight_node) + { + if (old_prelight_node) + gtk_tree_view_queue_draw_node (tree_view, + old_prelight_tree, + old_prelight_node, + NULL); + + if (tree_view->priv->prelight_node) + gtk_tree_view_queue_draw_node (tree_view, + tree_view->priv->prelight_tree, + tree_view->priv->prelight_node, + NULL); + } + return TRUE; } @@ -1411,7 +1449,7 @@ gtk_tree_view_enter_notify (GtkWidget *widget, new_y = ((gint)event->yy; _gtk_rbtree_find_offset (tree_view->priv->tree, - new_y - TREE_VIEW_HEADER_HEIGHT (tree_view), + TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y), &tree, &node); @@ -1420,6 +1458,12 @@ gtk_tree_view_enter_notify (GtkWidget *widget, do_prelight (tree_view, tree, node, event->x, new_y); + if (tree_view->priv->prelight_node) + gtk_tree_view_queue_draw_node (tree_view, + tree_view->priv->prelight_tree, + tree_view->priv->prelight_node, + NULL); + return TRUE; } @@ -1434,6 +1478,12 @@ gtk_tree_view_leave_notify (GtkWidget *widget, tree_view = GTK_TREE_VIEW (widget); + if (tree_view->priv->prelight_node) + gtk_tree_view_queue_draw_node (tree_view, + tree_view->priv->prelight_tree, + tree_view->priv->prelight_node, + NULL); + do_unprelight (tree_view, -1000, -1000); /* coords not possibly over an arrow */ return TRUE; @@ -1491,7 +1541,7 @@ gtk_tree_view_button_press (GtkWidget *widget, /* find the node that was clicked */ new_y = ((gint)event->yy; y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, - new_y - TREE_VIEW_HEADER_HEIGHT (tree_view), + TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y), &tree, &node) + new_y - (gint)event->y; @@ -2233,7 +2283,8 @@ gtk_tree_view_forall (GtkContainer *container, for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) { - column = tmp_list->data; + column = tmp_list->data; + if (column->button) (* callback) (column->button, callback_data); } @@ -2283,8 +2334,7 @@ gtk_tree_view_changed (GtkTreeModel *model, gtk_widget_queue_resize (GTK_WIDGET (data)); else { - /* FIXME: just redraw the node */ - gtk_widget_queue_draw (GTK_WIDGET (data)); + gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL); } } @@ -2849,7 +2899,7 @@ gtk_tree_view_create_buttons (GtkTreeView *tree_view) for (list = tree_view->priv->columns, i = 0; list; list = list->next, i++) { column = list->data; - + if (column->button != NULL) continue; @@ -3020,52 +3070,6 @@ _gtk_tree_view_find_node (GtkTreeView *tree_view, while (1); } -static void -gtk_tree_view_get_arrow_range (GtkTreeView *tree_view, - gint *x1, - gint *x2) -{ - gint x_offset = 0; - GList *list; - GtkTreeViewColumn *tmp_column = NULL; - gint total_width; - gint i; - - i = 0; - total_width = 0; - for (list = tree_view->priv->columns; list; list = list->next) - { - tmp_column = list->data; - - if (i == tree_view->priv->expander_column) - { - x_offset = total_width; - break; - } - - if (tmp_column->visible) - total_width += tmp_column->width; - - ++i; - } - - if (x1) - *x1 = x_offset; - - if (tmp_column && tmp_column->visible) - { - /* +1 because x2 isn't included in the range. */ - if (x2) - *x2 = x_offset + tree_view->priv->tab_offset + 1; - } - else - { - /* return an empty range, the expander column is hidden */ - if (x2) - *x2 = x_offset; - } -} - static void gtk_tree_view_queue_draw_node (GtkTreeView *tree_view, GtkRBTree *tree, @@ -3074,28 +3078,43 @@ gtk_tree_view_queue_draw_node (GtkTreeView *tree_view, { GdkRectangle rect; + if (!GTK_WIDGET_REALIZED (tree_view)) + return; + rect.x = 0; rect.width = tree_view->priv->width; - rect.y = _gtk_rbtree_node_find_offset (tree, node) + - TREE_VIEW_VERTICAL_SEPARATOR/2 + - TREE_VIEW_HEADER_HEIGHT (tree_view); - rect.height = GTK_RBNODE_GET_HEIGHT (node) + TREE_VIEW_VERTICAL_SEPARATOR; + + rect.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node); + rect.height = BACKGROUND_HEIGHT (node); + if (clip_rect) { GdkRectangle new_rect; - gdk_rectangle_intersect (clip_rect, &rect, &new_rect); - gtk_widget_queue_draw_area (GTK_WIDGET (tree_view), - new_rect.x, new_rect.y, - new_rect.width, new_rect.height); + + gdk_rectangle_intersect (clip_rect, &rect, &new_rect); + + gdk_window_invalidate_rect (tree_view->priv->bin_window, &new_rect, TRUE); } else { - gtk_widget_queue_draw_area (GTK_WIDGET (tree_view), - rect.x, rect.y, - rect.width, rect.height); + gdk_window_invalidate_rect (tree_view->priv->bin_window, &rect, TRUE); } } +static void +gtk_tree_view_queue_draw_path (GtkTreeView *tree_view, + GtkTreePath *path, + GdkRectangle *clip_rect) +{ + GtkRBTree *tree = NULL; + GtkRBNode *node = NULL; + + _gtk_tree_view_find_node (tree_view, path, &tree, &node); + + if (tree) + gtk_tree_view_queue_draw_node (tree_view, tree, node, clip_rect); +} + /* x and y are the mouse position */ static void @@ -3109,21 +3128,18 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view, GtkStateType state; GtkWidget *widget; gint x_offset = 0; - gint y_offset = 0; if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT)) return; widget = GTK_WIDGET (tree_view); - y_offset = _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view); - - gtk_tree_view_get_arrow_range (tree_view, &x_offset, NULL); + gtk_tree_view_get_arrow_xrange (tree_view, &x_offset, NULL); area.x = x_offset; - area.y = y_offset + TREE_VIEW_VERTICAL_SEPARATOR; + area.y = CELL_FIRST_PIXEL (tree_view, tree, node); area.width = tree_view->priv->tab_offset - 2; - area.height = GTK_RBNODE_GET_HEIGHT (node) - TREE_VIEW_VERTICAL_SEPARATOR; + area.height = CELL_HEIGHT (node); if (node == tree_view->priv->button_pressed_node) { @@ -3755,7 +3771,6 @@ gtk_tree_view_append_column (GtkTreeView *tree_view, g_return_val_if_fail (column->tree_view == NULL, -1); g_object_ref (G_OBJECT (column)); - gtk_object_sink (GTK_OBJECT (column)); tree_view->priv->columns = g_list_append (tree_view->priv->columns, column); column->tree_view = GTK_WIDGET (tree_view); @@ -3820,7 +3835,7 @@ gtk_tree_view_insert_column (GtkTreeView *tree_view, g_return_val_if_fail (column->tree_view == NULL, -1); g_object_ref (G_OBJECT (column)); - gtk_object_sink (GTK_OBJECT (column)); + tree_view->priv->columns = g_list_insert (tree_view->priv->columns, column, position); column->tree_view = GTK_WIDGET (tree_view); @@ -3965,7 +3980,7 @@ gtk_tree_view_scroll_to_cell (GtkTreeView *tree_view, return; } - gtk_tree_view_get_cell_rect (tree_view, path, column, &cell_rect); + gtk_tree_view_get_cell_area (tree_view, path, column, &cell_rect); gtk_tree_view_get_visible_rect (tree_view, &vis_rect); dest_x = vis_rect.x; @@ -3999,14 +4014,16 @@ gtk_tree_view_scroll_to_cell (GtkTreeView *tree_view, * @cell_x: A pointer where the X coordinate relative to the cell can be placed, or %NULL * @cell_y: A pointer where the Y coordinate relative to the cell can be placed, or %NULL * - * Finds the path at the point (@x, @y) relative to @window. If @window is - * NULL, then the point is found relative to the widget coordinates. This - * function is expected to be called after an event, with event->window being - * passed in as @window. It is primarily for things like popup menus. If @path - * is non-NULL, then it will be filled with the #GtkTreePath at that point. - * This path should be freed with #gtk_tree_path_free. If @column is non-NULL, - * then it will be filled with the column at that point. @cell_x and @cell_y return - * the coordinates relative to the cell. + * Finds the path at the point (@x, @y) relative to @window. If + * @window is NULL, then the point is found relative to the widget + * coordinates. This function is expected to be called after an + * event, with event->window being passed in as @window. It is + * primarily for things like popup menus. If @path is non-NULL, then + * it will be filled with the #GtkTreePath at that point. This path + * should be freed with #gtk_tree_path_free. If @column is non-NULL, + * then it will be filled with the column at that point. @cell_x and + * @cell_y return the coordinates relative to the cell background + * (i.e. the background_area passed to gtk_cell_renderer_render()). * * Return value: TRUE if a row exists at that coordinate. **/ @@ -4086,7 +4103,7 @@ gtk_tree_view_get_path_at_pos (GtkTreeView *tree_view, if (window) { y_offset = _gtk_rbtree_find_offset (tree_view->priv->tree, - y - TREE_VIEW_HEADER_HEIGHT (tree_view), + TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y), &tree, &node); } else @@ -4094,8 +4111,8 @@ gtk_tree_view_get_path_at_pos (GtkTreeView *tree_view, if (y < TREE_VIEW_HEADER_HEIGHT (tree_view)) return FALSE; - y_offset = _gtk_rbtree_find_offset (tree_view->priv->tree, y - TREE_VIEW_HEADER_HEIGHT (tree_view) + - tree_view->priv->vadjustment->value, + y_offset = _gtk_rbtree_find_offset (tree_view->priv->tree, + TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y + tree_view->priv->vadjustment->value), &tree, &node); } @@ -4111,28 +4128,182 @@ gtk_tree_view_get_path_at_pos (GtkTreeView *tree_view, return TRUE; } + +static void +gtk_tree_view_get_background_xrange (GtkTreeView *tree_view, + GtkRBTree *tree, + GtkTreeViewColumn *column, + gint *x1, + gint *x2) +{ + GtkTreeViewColumn *tmp_column = NULL; + gint total_width; + GList *list; + + if (x1) + *x1 = 0; + + if (x2) + *x2 = 0; + + total_width = 0; + for (list = tree_view->priv->columns; list; list = list->next) + { + tmp_column = list->data; + + if (tmp_column == column) + break; + + if (tmp_column->visible) + total_width += tmp_column->width; + } + + if (tmp_column != column) + { + g_warning (G_STRLOC": passed-in column isn't in the tree"); + return; + } + + if (x1) + *x1 = total_width; + + if (x2) + { + if (column->visible) + *x2 = total_width + column->width; + else + *x2 = total_width; /* width of 0 */ + } +} + +static void +gtk_tree_view_get_cell_xrange (GtkTreeView *tree_view, + GtkRBTree *tree, + GtkTreeViewColumn *column, + gint *x1, + gint *x2) +{ + GtkTreeViewColumn *tmp_column = NULL; + gint total_width; + GList *list; + gint i; + + if (x1) + *x1 = 0; + + if (x2) + *x2 = 0; + + i = 0; + total_width = 0; + for (list = tree_view->priv->columns; list; list = list->next) + { + tmp_column = list->data; + + if (tmp_column == column) + break; + + if (tmp_column->visible) + total_width += tmp_column->width; + + ++i; + } + + if (tmp_column != column) + { + g_warning (G_STRLOC": passed-in column isn't in the tree"); + return; + } + + /* Remember we're getting the cell range, i.e. the cell_area passed + * to the cell renderer. + */ + + if (i == tree_view->priv->expander_column) + total_width += tree_view->priv->tab_offset * _gtk_rbtree_get_depth (tree); + + if (x1) + *x1 = total_width; + + if (x2) + { + if (column->visible) + *x2 = total_width + column->width; + else + *x2 = total_width; /* width of 0 */ + } +} + +static void +gtk_tree_view_get_arrow_xrange (GtkTreeView *tree_view, + gint *x1, + gint *x2) +{ + gint x_offset = 0; + GList *list; + GtkTreeViewColumn *tmp_column = NULL; + gint total_width; + gint i; + + i = 0; + total_width = 0; + for (list = tree_view->priv->columns; list; list = list->next) + { + tmp_column = list->data; + + if (i == tree_view->priv->expander_column) + { + x_offset = total_width; + break; + } + + if (tmp_column->visible) + total_width += tmp_column->width; + + ++i; + } + + if (x1) + *x1 = x_offset; + + if (tmp_column && tmp_column->visible) + { + /* +1 because x2 isn't included in the range. */ + if (x2) + *x2 = x_offset + tree_view->priv->tab_offset + 1; + } + else + { + /* return an empty range, the expander column is hidden */ + if (x2) + *x2 = x_offset; + } +} + + /** - * gtk_tree_view_get_cell_rect: + * gtk_tree_view_get_cell_area: * @tree_view: a #GtkTreeView * @path: a #GtkTreePath for the row, or %NULL to get only horizontal coordinates * @column: a #GtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes * @rect: rectangle to fill with cell rect * - * Fills the bounding rectangle in tree window coordinates for the cell - * at the row specified by @path and the column specified by @column. - * If @path is %NULL, the y and height fields of the rectangle will be filled - * with 0. If @column is %NULL, the x and width fields will be filled with 0. + * Fills the bounding rectangle in tree window coordinates for the + * cell at the row specified by @path and the column specified by + * @column. If @path is %NULL, the y and height fields of the + * rectangle will be filled with 0. If @column is %NULL, the x and + * width fields will be filled with 0. The sum of all cell rects does + * not cover the entire tree; there are extra pixels in between rows, + * for example. The returned rectangle is equivalent to the @cell_area + * passed to gtk_cell_renderer_render(). * **/ void -gtk_tree_view_get_cell_rect (GtkTreeView *tree_view, +gtk_tree_view_get_cell_area (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, GdkRectangle *rect) { - GtkTreeViewColumn *tmp_column = NULL; - gint total_width; - GList *list; GtkRBTree *tree = NULL; GtkRBNode *node = NULL; @@ -4157,35 +4328,85 @@ gtk_tree_view_get_cell_rect (GtkTreeView *tree_view, return; } - rect->y = _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view); + /* Remember that the rbtree stores node height including the vertical + * separator, see comment at top of file. + */ + rect->y = CELL_FIRST_PIXEL (tree_view, tree, node); + + rect->height = CELL_HEIGHT (node); + } + + if (column) + { + gint x2 = 0; - rect->height = GTK_RBNODE_GET_HEIGHT (node); + gtk_tree_view_get_cell_xrange (tree_view, tree, column, &rect->x, &x2); + rect->width = x2 - rect->x; } +} + + +/** + * gtk_tree_view_get_background_area: + * @tree_view: a #GtkTreeView + * @path: a #GtkTreePath for the row, or %NULL to get only horizontal coordinates + * @column: a #GtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes + * @rect: rectangle to fill with cell background rect + * + * Fills the bounding rectangle in tree window coordinates for the + * cell at the row specified by @path and the column specified by + * @column. If @path is %NULL, the y and height fields of the + * rectangle will be filled with 0. If @column is %NULL, the x and + * width fields will be filled with 0. The returned rectangle is + * equivalent to the @background_area passed to + * gtk_cell_renderer_render(). These background areas tile to cover + * the entire tree window (except for the area used for header + * buttons). Contrast with the cell_area, returned by + * gtk_tree_view_get_cell_area(), which returns only the cell itself, + * excluding surrounding borders and the tree expander area. + * + **/ +void +gtk_tree_view_get_background_area (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + GdkRectangle *rect) +{ + GtkRBTree *tree = NULL; + GtkRBNode *node = NULL; + + g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); + g_return_if_fail (column == NULL || GTK_IS_TREE_VIEW_COLUMN (column)); + g_return_if_fail (rect != NULL); - if (column && column->visible) + rect->x = 0; + rect->y = 0; + rect->width = 0; + rect->height = 0; + + if (path) { - total_width = 0; - for (list = tree_view->priv->columns; list; list = list->next) - { - tmp_column = list->data; - - if (tmp_column == column) - { - rect->x = total_width; - break; - } - - if (tmp_column->visible) - total_width += tmp_column->width; - } + /* Get vertical coords */ - if (tmp_column != column) + _gtk_tree_view_find_node (tree_view, path, &tree, &node); + + if (tree == NULL) { - g_warning (G_STRLOC": passed-in column isn't in the tree"); + g_warning (G_STRLOC": no row corresponding to path"); return; } - - rect->width = column->width; + + rect->y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node); + + rect->height = BACKGROUND_HEIGHT (node); + } + + if (column) + { + gint x2 = 0; + + gtk_tree_view_get_background_xrange (tree_view, tree, column, &rect->x, &x2); + rect->width = x2 - rect->x; } } @@ -4458,8 +4679,7 @@ gtk_tree_view_widget_to_tree_coords (GtkTreeView *tree_view, if (ty) { - *ty = wy - TREE_VIEW_HEADER_HEIGHT (tree_view) + - tree_view->priv->vadjustment->value; + *ty = wy + tree_view->priv->vadjustment->value; } } @@ -4491,13 +4711,45 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view, if (wy) { - *wy = ty + TREE_VIEW_HEADER_HEIGHT (tree_view) - - tree_view->priv->vadjustment->value; + *wy = ty - tree_view->priv->vadjustment->value; } } /* Drag-and-drop */ +void +set_source_row (GdkDragContext *context, + GtkTreePath *source_row) +{ + g_object_set_data_full (G_OBJECT (context), + "gtk-tree-view-source-row", + source_row ? gtk_tree_path_copy (source_row) : NULL, + (GDestroyNotify) (source_row ? gtk_tree_path_free : NULL)); +} + +GtkTreePath* +get_source_row (GdkDragContext *context) +{ + return g_object_get_data (G_OBJECT (context), "gtk-tree-view-source-row"); +} + + +void +set_dest_row (GdkDragContext *context, + GtkTreePath *dest_row) +{ + g_object_set_data_full (G_OBJECT (context), + "gtk-tree-view-dest-row", + dest_row ? gtk_tree_path_copy (dest_row) : NULL, + (GDestroyNotify) (dest_row ? gtk_tree_path_free : NULL)); +} + +GtkTreePath* +get_dest_row (GdkDragContext *context) +{ + return g_object_get_data (G_OBJECT (context), "gtk-tree-view-dest-row"); +} + typedef struct _TreeViewDragInfo TreeViewDragInfo; struct _TreeViewDragInfo @@ -4506,7 +4758,6 @@ struct _TreeViewDragInfo GtkTargetList *source_target_list; GdkDragAction source_actions; GClosure *row_draggable_closure; - GtkTreePath *source_row; GtkTargetList *dest_target_list; GClosure *location_droppable_closure; @@ -4529,13 +4780,9 @@ clear_source_info (TreeViewDragInfo *di) if (di->row_draggable_closure) g_closure_unref (di->row_draggable_closure); - - if (di->source_row) - gtk_tree_path_free (di->source_row); di->source_target_list = NULL; di->row_draggable_closure = NULL; - di->source_row = NULL; } static void @@ -4766,7 +5013,6 @@ gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view) } } - void gtk_tree_view_set_drag_dest_row (GtkTreeView *tree_view, GtkTreePath *path, @@ -4778,21 +5024,42 @@ gtk_tree_view_set_drag_dest_row (GtkTreeView *tree_view, g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); + g_print ("drag dest row %p -> %p\n", tree_view->priv->drag_dest_row, path); + if (tree_view->priv->drag_dest_row) { - /* FIXME queue undraw on previous location */ + gtk_tree_view_queue_draw_path (tree_view, tree_view->priv->drag_dest_row, NULL); gtk_tree_path_free (tree_view->priv->drag_dest_row); } tree_view->priv->drag_dest_pos = pos; if (path) - tree_view->priv->drag_dest_row = gtk_tree_path_copy (path); + { + tree_view->priv->drag_dest_row = gtk_tree_path_copy (path); + gtk_tree_view_queue_draw_path (tree_view, tree_view->priv->drag_dest_row, NULL); + } else tree_view->priv->drag_dest_row = NULL; +} + +void +gtk_tree_view_get_drag_dest_row (GtkTreeView *tree_view, + GtkTreePath **path, + GtkTreeViewDropPosition *pos) +{ + g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); + + if (path) + { + if (tree_view->priv->drag_dest_row) + *path = gtk_tree_path_copy (tree_view->priv->drag_dest_row); + else + *path = NULL; + } - /* FIXME this is crap, queue draw only on the newly-highlighted row */ - gtk_widget_queue_draw (GTK_WIDGET (tree_view)); + if (pos) + *pos = tree_view->priv->drag_dest_pos; } gboolean @@ -4823,7 +5090,7 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, if (path) *path = NULL; - /* remember that drag_x and drag_y are in widget coords, convert to rbtree */ + /* remember that drag_x and drag_y are in widget coords, convert to tree window */ gtk_tree_view_widget_to_tree_coords (tree_view, drag_x, drag_y, &x, &y); @@ -4842,8 +5109,8 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, &cell_y)) return FALSE; - gtk_tree_view_get_cell_rect (tree_view, tmp_path, column, - &cell); + gtk_tree_view_get_background_area (tree_view, tmp_path, column, + &cell); offset_into_row = cell_y; @@ -4879,24 +5146,6 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, return TRUE; } -gboolean -gtk_selection_data_set_tree_row (GtkSelectionData *selection_data, - GtkTreeView *tree_view, - GtkTreePath *path) -{ - - return FALSE; -} - -gboolean -gtk_selection_data_get_tree_row (GtkSelectionData *selection_data, - GtkTreeView **tree_view, - GtkTreePath **path) -{ - return FALSE; -} - - static gboolean gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view, GdkEventMotion *event) @@ -4969,7 +5218,8 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view, gdk_pixmap_unref (row_pix); } - di->source_row = path; + set_source_row (context, path); + gtk_tree_path_free (path); return TRUE; } @@ -4998,38 +5248,99 @@ gtk_tree_view_drag_data_get (GtkWidget *widget, guint time) { GtkTreeView *tree_view; - + GtkTreeModel *model; + TreeViewDragInfo *di; + GtkTreePath *source_row; + tree_view = GTK_TREE_VIEW (widget); - if (selection_data->target == gdk_atom_intern ("GTK_TREE_VIEW_ROW", FALSE)) - { - TreeViewDragInfo *di; + model = gtk_tree_view_get_model (tree_view); - di = get_info (GTK_TREE_VIEW (widget)); + if (model == NULL) + return; - if (di == NULL) - { - /* There's a race where someone could have unset - * drag source before the data is requested - */ - return; - } - + di = get_info (GTK_TREE_VIEW (widget)); + + if (di == NULL) + return; + + source_row = get_source_row (context); + + if (source_row == NULL) + return; + + /* We can implement the GTK_TREE_MODEL_ROW target generically for + * any model; for DragSource models there are some other targets + * we also support. + */ + + if (GTK_IS_TREE_DRAG_SOURCE (model) && + gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model), + source_row, + selection_data)) + return; + + /* If drag_data_get does nothing, try providing row data. */ + if (selection_data->target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE)) + { gtk_selection_data_set_tree_row (selection_data, - GTK_TREE_VIEW (widget), - di->source_row); + model, + source_row); + } +} + + +static gboolean +check_model_dnd (GtkTreeModel *model, + GType required_iface, + const gchar *signal) +{ + if (model == NULL || !G_TYPE_CHECK_INSTANCE_TYPE ((model), required_iface)) + { + g_warning ("You must override the default '%s' handler " + "on GtkTreeView when using models that don't support " + "the %s interface. The simplest way to do this " + "is to connect to '%s' and call " + "gtk_signal_emit_stop_by_name() in your signal handler to prevent " + "the default handler from running. Look at the source code " + "for the default handler in gtktreeview.c to get an idea what " + "your handler should do. (gtktreeview.c is in the GTK source " + "code.)", + signal, g_type_name (required_iface), signal); + return FALSE; } + else + return TRUE; } static void gtk_tree_view_drag_data_delete (GtkWidget *widget, GdkDragContext *context) { - /* FIXME we need to delete the source_row if we're doing automagical - * reordering stuff. - */ -} + TreeViewDragInfo *di; + GtkTreeModel *model; + GtkTreeView *tree_view; + GtkTreePath *source_row; + + tree_view = GTK_TREE_VIEW (widget); + model = gtk_tree_view_get_model (tree_view); + + if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_SOURCE, "drag_data_delete")) + return; + + di = get_info (tree_view); + if (di == NULL) + return; + + source_row = get_source_row (context); + + + gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model), + source_row); + + set_source_row (context, NULL); +} static void remove_open_timeout (GtkTreeView *tree_view) @@ -5051,6 +5362,7 @@ gtk_tree_view_drag_leave (GtkWidget *widget, di = get_info (GTK_TREE_VIEW (widget)); /* unset any highlight row */ + g_print ("drag leave\n"); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), NULL, GTK_TREE_VIEW_DROP_BEFORE); @@ -5078,21 +5390,24 @@ open_row_timeout (gpointer data) return TRUE; } +/* Returns TRUE if event should not be propagated to parent widgets */ static gboolean -gtk_tree_view_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) +set_destination_row (GtkTreeView *tree_view, + GdkDragContext *context, + gint x, + gint y, + GdkDragAction *suggested_action) { GtkTreePath *path = NULL; - TreeViewDragInfo *di; GtkTreeViewDropPosition pos; - GtkTreeView *tree_view; + TreeViewDragInfo *di; + GtkWidget *widget; - tree_view = GTK_TREE_VIEW (widget); + *suggested_action = 0; - di = get_info (GTK_TREE_VIEW (widget)); + widget = GTK_WIDGET (tree_view); + + di = get_info (tree_view); if (di == NULL) { @@ -5100,6 +5415,7 @@ gtk_tree_view_drag_motion (GtkWidget *widget, * we return FALSE drag_leave isn't called */ + g_print ("no longer a drag dest\n"); gtk_tree_view_set_drag_dest_row (tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE); @@ -5110,7 +5426,12 @@ gtk_tree_view_drag_motion (GtkWidget *widget, return FALSE; /* no longer a drop site */ } - ensure_scroll_timeout (tree_view); + /* We don't take this target */ + if (gtk_drag_dest_find_target (widget, context, di->dest_target_list) == GDK_NONE) + { + g_print ("bad target, not accepting\n"); + return FALSE; + } if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, @@ -5119,9 +5440,8 @@ gtk_tree_view_drag_motion (GtkWidget *widget, { /* can't drop here */ remove_open_timeout (tree_view); - - gdk_drag_status (context, 0, time); + g_print ("no drag row here\n"); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), NULL, GTK_TREE_VIEW_DROP_BEFORE); @@ -5141,13 +5461,11 @@ gtk_tree_view_drag_motion (GtkWidget *widget, pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE))) remove_open_timeout (tree_view); - if (TRUE /* FIXME if the location droppable predicate */ && - gtk_drag_dest_find_target (widget, context, di->dest_target_list) != GDK_NONE) + if (TRUE /* FIXME if the location droppable predicate */) { GtkWidget *source_widget; - GdkDragAction suggested_action; - suggested_action = context->suggested_action; + *suggested_action = context->suggested_action; source_widget = gtk_drag_get_source_widget (context); @@ -5157,34 +5475,73 @@ gtk_tree_view_drag_motion (GtkWidget *widget, * pressed ctrl or alt to affect available actions */ if ((context->actions & GDK_ACTION_MOVE) != 0) - suggested_action = GDK_ACTION_MOVE; + *suggested_action = GDK_ACTION_MOVE; } - + + g_print ("setting drag dest row\n"); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), path, pos); - - if (tree_view->priv->open_dest_timeout == 0) - { - tree_view->priv->open_dest_timeout = - gtk_timeout_add (250, open_row_timeout, tree_view); - } - - gdk_drag_status (context, suggested_action, time); } else { /* can't drop here */ remove_open_timeout (tree_view); - gdk_drag_status (context, 0, time); - + g_print ("droppable predicate false\n"); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), NULL, GTK_TREE_VIEW_DROP_BEFORE); } - gtk_tree_path_free (path); + return TRUE; +} + +static gboolean +gtk_tree_view_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + GtkTreePath *path = NULL; + GtkTreeViewDropPosition pos; + GtkTreeView *tree_view; + GdkDragAction suggested_action = 0; + + tree_view = GTK_TREE_VIEW (widget); + + g_print ("motion\n"); + + if (!set_destination_row (tree_view, context, x, y, &suggested_action)) + return FALSE; + + ensure_scroll_timeout (tree_view); + gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos); + + if (path == NULL) + { + /* Can't drop here. */ + g_print ("not over a dest row\n"); + gdk_drag_status (context, 0, time); + } + else + { + if (tree_view->priv->open_dest_timeout == 0 && + (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER || + pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)) + { + tree_view->priv->open_dest_timeout = + gtk_timeout_add (250, open_row_timeout, tree_view); + } + + g_print ("status\n"); + gdk_drag_status (context, suggested_action, time); + } + + if (path) + gtk_tree_path_free (path); + return TRUE; } @@ -5195,22 +5552,59 @@ gtk_tree_view_drag_drop (GtkWidget *widget, gint y, guint time) { + GtkTreePath *path = NULL; + GtkTreeViewDropPosition pos; + GtkTreeView *tree_view; + GdkDragAction suggested_action = 0; GdkAtom target = GDK_NONE; TreeViewDragInfo *di; - GtkTreeView *tree_view; - + GtkTreeModel *model; + tree_view = GTK_TREE_VIEW (widget); + model = gtk_tree_view_get_model (tree_view); + + g_print ("drop\n"); + remove_scroll_timeout (GTK_TREE_VIEW (widget)); remove_open_timeout (GTK_TREE_VIEW (widget)); - + di = get_info (tree_view); - if (di && tree_view->priv->drag_dest_row && di->dest_target_list) - target = gtk_drag_dest_find_target (widget, context, di->dest_target_list); + if (di == NULL) + return FALSE; + + if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag_drop")) + return FALSE; + + if (!set_destination_row (tree_view, context, x, y, &suggested_action)) + return FALSE; + gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos); + + if (path != NULL && di->dest_target_list) + { + target = gtk_drag_dest_find_target (widget, context, di->dest_target_list); + + if (target != GDK_NONE) + { + g_print ("have target\n"); + + set_dest_row (context, path); + } + } + + if (path) + gtk_tree_path_free (path); + + /* Unset this thing */ + gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), + NULL, + GTK_TREE_VIEW_DROP_BEFORE); + if (target != GDK_NONE) { + g_print ("getting data\n"); gtk_drag_get_data (widget, context, target, time); return TRUE; } @@ -5226,21 +5620,48 @@ gtk_tree_view_drag_data_received (GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time) -{ +{ + TreeViewDragInfo *di; + gboolean accepted = FALSE; + GtkTreeModel *model; + GtkTreeView *tree_view; + GtkTreePath *dest_row; + + tree_view = GTK_TREE_VIEW (widget); + + model = gtk_tree_view_get_model (tree_view); + + if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag_data_received")) + return; + + g_print ("drag data received\n"); + + di = get_info (tree_view); + + if (di == NULL) + return; + + dest_row = get_dest_row (context); + + if (dest_row == NULL) + return; + if (selection_data->length >= 0) { - /* FIXME respond to contents of selection_data */ - + if (gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model), + dest_row, + selection_data)) + accepted = TRUE; + + + /* Don't clear drop_row, we may need it in drag_data_delete */ } - - gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), - NULL, - GTK_TREE_VIEW_DROP_BEFORE); gtk_drag_finish (context, - (selection_data->length >= 0), + accepted, (context->action == GDK_ACTION_MOVE), - time); + time); + g_print ("accepted: %d\n", accepted); } diff --git a/gtk/gtktreeview.h b/gtk/gtktreeview.h index d15109eff..22890ae66 100644 --- a/gtk/gtktreeview.h +++ b/gtk/gtktreeview.h @@ -125,7 +125,11 @@ gboolean gtk_tree_view_get_path_at_pos (GtkTreeView *tr GtkTreeViewColumn **column, gint *cell_x, gint *cell_y); -void gtk_tree_view_get_cell_rect (GtkTreeView *tree_view, +void gtk_tree_view_get_cell_area (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + GdkRectangle *rect); +void gtk_tree_view_get_background_area (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, GdkRectangle *rect); @@ -190,6 +194,9 @@ void gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view); void gtk_tree_view_set_drag_dest_row (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewDropPosition pos); +void gtk_tree_view_get_drag_dest_row (GtkTreeView *tree_view, + GtkTreePath **path, + GtkTreeViewDropPosition *pos); gboolean gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, gint drag_x, gint drag_y, @@ -198,16 +205,6 @@ gboolean gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_vi GdkPixmap* gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view, GtkTreePath *path); -/* The selection data would normally have target type GTK_TREE_VIEW_ROW in this - * case. If the target is wrong these functions return FALSE. - */ -gboolean gtk_selection_data_set_tree_row (GtkSelectionData *selection_data, - GtkTreeView *tree_view, - GtkTreePath *path); -gboolean gtk_selection_data_get_tree_row (GtkSelectionData *selection_data, - GtkTreeView **tree_view, - GtkTreePath **path); - #ifdef __cplusplus diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index 140bbb6a7..1d7dab0ee 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -212,6 +212,10 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class) static void gtk_tree_view_column_init (GtkTreeViewColumn *tree_column) { + /* FIXME remove on port to GtkObject */ + gtk_object_ref (GTK_OBJECT (tree_column)); + gtk_object_sink (GTK_OBJECT (tree_column)); + tree_column->button = NULL; tree_column->justification = GTK_JUSTIFY_LEFT; tree_column->width = 1; @@ -919,17 +923,18 @@ update_button_contents (GtkTreeViewColumn *tree_column) { if (tree_column->button) { - GtkWidget *current_child = GTK_BIN (GTK_BIN (tree_column->button)->child)->child; + GtkWidget *alignment = GTK_BIN (tree_column->button)->child; + GtkWidget *current_child = GTK_BIN (alignment)->child; if (tree_column->child) { if (current_child != tree_column->child) { - gtk_container_remove (GTK_CONTAINER (tree_column->button), + gtk_container_remove (GTK_CONTAINER (alignment), current_child); - gtk_container_add (GTK_CONTAINER (tree_column->button), - tree_column->child); + gtk_container_add (GTK_CONTAINER (alignment), + tree_column->child); } } else @@ -940,7 +945,7 @@ update_button_contents (GtkTreeViewColumn *tree_column) gtk_widget_show (current_child); - gtk_container_add (GTK_CONTAINER (tree_column->button), + gtk_container_add (GTK_CONTAINER (alignment), current_child); } diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 534c93736..acdaa65ed 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -2002,6 +2002,34 @@ create_get_image (void) /* * Label Demo */ +static void +sensitivity_toggled (GtkWidget *toggle, + GtkWidget *widget) +{ + gtk_widget_set_sensitive (widget, GTK_TOGGLE_BUTTON (toggle)->active); +} + +static GtkWidget* +create_sensitivity_control (GtkWidget *widget) +{ + GtkWidget *button; + GtkWidget *toplevel; + + button = gtk_toggle_button_new_with_label ("Sensitive"); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), + GTK_WIDGET_IS_SENSITIVE (widget)); + + gtk_signal_connect (GTK_OBJECT (button), + "toggled", + GTK_SIGNAL_FUNC (sensitivity_toggled), + widget); + + gtk_widget_show_all (button); + + return button; +} + void create_labels (void) { static GtkWidget *window = NULL; @@ -2009,7 +2037,8 @@ void create_labels (void) GtkWidget *vbox; GtkWidget *frame; GtkWidget *label; - + GtkWidget *button; + if (!window) { guint keyval; @@ -2020,9 +2049,20 @@ void create_labels (void) &window); gtk_window_set_title (GTK_WINDOW (window), "Label"); + vbox = gtk_vbox_new (FALSE, 5); + hbox = gtk_hbox_new (FALSE, 5); - gtk_container_add (GTK_CONTAINER (window), hbox); + gtk_container_add (GTK_CONTAINER (window), vbox); + + gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + button = create_sensitivity_control (hbox); + + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + + vbox = gtk_vbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (window), 5); @@ -2127,8 +2167,8 @@ void create_labels (void) gtk_container_add (GTK_CONTAINER (frame), label); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - } + if (!GTK_WIDGET_VISIBLE (window)) gtk_widget_show_all (window); else @@ -3274,6 +3314,14 @@ create_scrolled_windows (void) * GtkEntry */ +static void +entry_toggle_frame (GtkWidget *checkbutton, + GtkWidget *entry) +{ + gtk_entry_set_has_frame (GTK_ENTRY(entry), + GTK_TOGGLE_BUTTON(checkbutton)->active); +} + static void entry_toggle_editable (GtkWidget *checkbutton, GtkWidget *entry) @@ -3394,6 +3442,13 @@ create_entry (void) gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled", GTK_SIGNAL_FUNC(entry_toggle_invisible_char), entry); gtk_widget_show (invisible_char_check); + + editable_check = gtk_check_button_new_with_label("Has Frame"); + gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT(editable_check), "toggled", + GTK_SIGNAL_FUNC(entry_toggle_frame), entry); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(editable_check), TRUE); + gtk_widget_show (editable_check); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); diff --git a/tests/testgtk.c b/tests/testgtk.c index 534c93736..acdaa65ed 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -2002,6 +2002,34 @@ create_get_image (void) /* * Label Demo */ +static void +sensitivity_toggled (GtkWidget *toggle, + GtkWidget *widget) +{ + gtk_widget_set_sensitive (widget, GTK_TOGGLE_BUTTON (toggle)->active); +} + +static GtkWidget* +create_sensitivity_control (GtkWidget *widget) +{ + GtkWidget *button; + GtkWidget *toplevel; + + button = gtk_toggle_button_new_with_label ("Sensitive"); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), + GTK_WIDGET_IS_SENSITIVE (widget)); + + gtk_signal_connect (GTK_OBJECT (button), + "toggled", + GTK_SIGNAL_FUNC (sensitivity_toggled), + widget); + + gtk_widget_show_all (button); + + return button; +} + void create_labels (void) { static GtkWidget *window = NULL; @@ -2009,7 +2037,8 @@ void create_labels (void) GtkWidget *vbox; GtkWidget *frame; GtkWidget *label; - + GtkWidget *button; + if (!window) { guint keyval; @@ -2020,9 +2049,20 @@ void create_labels (void) &window); gtk_window_set_title (GTK_WINDOW (window), "Label"); + vbox = gtk_vbox_new (FALSE, 5); + hbox = gtk_hbox_new (FALSE, 5); - gtk_container_add (GTK_CONTAINER (window), hbox); + gtk_container_add (GTK_CONTAINER (window), vbox); + + gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + button = create_sensitivity_control (hbox); + + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + + vbox = gtk_vbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (window), 5); @@ -2127,8 +2167,8 @@ void create_labels (void) gtk_container_add (GTK_CONTAINER (frame), label); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - } + if (!GTK_WIDGET_VISIBLE (window)) gtk_widget_show_all (window); else @@ -3274,6 +3314,14 @@ create_scrolled_windows (void) * GtkEntry */ +static void +entry_toggle_frame (GtkWidget *checkbutton, + GtkWidget *entry) +{ + gtk_entry_set_has_frame (GTK_ENTRY(entry), + GTK_TOGGLE_BUTTON(checkbutton)->active); +} + static void entry_toggle_editable (GtkWidget *checkbutton, GtkWidget *entry) @@ -3394,6 +3442,13 @@ create_entry (void) gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled", GTK_SIGNAL_FUNC(entry_toggle_invisible_char), entry); gtk_widget_show (invisible_char_check); + + editable_check = gtk_check_button_new_with_label("Has Frame"); + gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT(editable_check), "toggled", + GTK_SIGNAL_FUNC(entry_toggle_frame), entry); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(editable_check), TRUE); + gtk_widget_show (editable_check); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); diff --git a/tests/testtreeview.c b/tests/testtreeview.c index 6181114d0..5ffcecb25 100644 --- a/tests/testtreeview.c +++ b/tests/testtreeview.c @@ -314,11 +314,11 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type) image = gtk_image_new_from_pixbuf (pixbuf); + g_object_unref (G_OBJECT (pixbuf)); + gtk_widget_show (image); gtk_tree_view_column_set_widget (col, image); - - g_object_unref (G_OBJECT (pixbuf)); g_object_unref (G_OBJECT (rend)); g_object_unref (G_OBJECT (col)); @@ -346,6 +346,98 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type) g_object_unref (G_OBJECT (rend)); g_object_unref (G_OBJECT (col)); +#if 0 + + rend = gtk_cell_renderer_text_new (); + + col = gtk_tree_view_column_new_with_attributes ("Column 5", + rend, + "text", 3, + NULL); + + setup_column (col); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col); + + g_object_unref (G_OBJECT (rend)); + g_object_unref (G_OBJECT (col)); + + + rend = gtk_cell_renderer_text_new (); + + col = gtk_tree_view_column_new_with_attributes ("Column 6", + rend, + "text", 4, + NULL); + + setup_column (col); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col); + + g_object_unref (G_OBJECT (rend)); + g_object_unref (G_OBJECT (col)); + + + rend = gtk_cell_renderer_text_new (); + + col = gtk_tree_view_column_new_with_attributes ("Column 7", + rend, + "text", 5, + NULL); + + setup_column (col); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col); + + g_object_unref (G_OBJECT (rend)); + g_object_unref (G_OBJECT (col)); + + rend = gtk_cell_renderer_text_new (); + + col = gtk_tree_view_column_new_with_attributes ("Column 8", + rend, + "text", 6, + NULL); + + setup_column (col); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col); + + g_object_unref (G_OBJECT (rend)); + g_object_unref (G_OBJECT (col)); + + + rend = gtk_cell_renderer_text_new (); + + col = gtk_tree_view_column_new_with_attributes ("Column 9", + rend, + "text", 7, + NULL); + + setup_column (col); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col); + + g_object_unref (G_OBJECT (rend)); + g_object_unref (G_OBJECT (col)); + + + rend = gtk_cell_renderer_text_new (); + + col = gtk_tree_view_column_new_with_attributes ("Column 10", + rend, + "text", 8, + NULL); + + setup_column (col); + + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col); + + g_object_unref (G_OBJECT (rend)); + g_object_unref (G_OBJECT (col)); + +#endif + gtk_tree_view_set_expander_column (tree_view, 1); /* FALL THRU */ @@ -544,12 +636,12 @@ columns_selected (GtkOptionMenu *om, gpointer data) enum { - TARGET_GTK_TREE_VIEW_ROW + TARGET_GTK_TREE_MODEL_ROW }; static GtkTargetEntry row_targets[] = { - { "GTK_TREE_VIEW_ROW", GTK_TARGET_SAME_APP, - TARGET_GTK_TREE_VIEW_ROW } + { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, + TARGET_GTK_TREE_MODEL_ROW } }; int