diff --git a/ChangeLog b/ChangeLog index e8914e6f81..90915b7314 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +Sun May 5 16:42:32 2002 Kristian Rietveld + + The "big treeview focus patch". Fixes several issues and adds some + goodies. Related bugs: #73676, #73734, #78660. + + * gtk/gtktreeview.h: add gtk_tree_view_set_cursor_on_cell + + * gtk/gtktreeview.c (gtk_tree_view_button_press): focus on a cell + if applicable, + (gtk_tree_view_bin_expose): set_cell_data before iterating columns, + add support for row-spanning focus rectangles, + (gtk_tree_view_has_special_cell): new function, + (gtk_tree_view_move_cursor_left_right): add support for multiple + focusable cells in one column, + (gtk_tree_view_set_cursor): call _set_cursor_on_cell now, + (gtk_tree_view_set_cursor_on_cell): copy of _set_cursor, extended + with focus_cell parameter, + (gtk_tree_view_search_iter): removed unused column variable, + (gtk_tree_view_start_editing): add neighbor size code to allow + for multiple editable cells in one column. + + * gtk/gtktreeviewcolumn.c (_GtkTreeViewColumnCellInfo): add + in_editing_mode field, + (gtk_tree_view_column_get_edited_cell): new function, removed + _get_editable_cell, + (_gtk_tree_view_column_get_cell_at_pos): new function, + (gtk_tree_view_column_pack_end): s/g_new/g_new0/ ..., + (gtk_tree_view_column_cell_process_action): loads of changes to get + it right and to allow for multiple special cells, etc, + (gtk_tree_view_column_cell_first): new function, + (gtk_tree_view_column_cell_last): ditto, + (gtk_tree_view_column_cell_next): ditto, + (gtk_tree_view_column_cell_prev): ditto, + (gtk_tree_view_column_cell_focus): add left and right parameters, + allow for multiple special cells, + (gtk_tree_view_column_cell_is_visible): add assertion, + (gtk_tree_view_column_focus_cell): new function, + (gtk_tree_view_column_stop_editing): unset in_editing_mode flag, + (_gtk_tree_view_column_get_neighbor_sizes): iterate through cells + correctly + + * gtk/gtktreeviewcolumn.h: add gtk_tree_view_column_focus_cell + + * gtk/gtktreeprivate.h: s/_get_editable_cell/_get_edited_cell/, add + _gtk_tree_view_column_get_cell_at_pos, add new parameters to + _gtk_tree_view_column_cell_focus. + + * tests/testtreeedit.c: add some cells in order to test new code. + Sun May 5 02:22:59 2002 Soeren Sandmann * tests/test-images/*: image files for testing pixbuf loaders diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index e8914e6f81..90915b7314 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,52 @@ +Sun May 5 16:42:32 2002 Kristian Rietveld + + The "big treeview focus patch". Fixes several issues and adds some + goodies. Related bugs: #73676, #73734, #78660. + + * gtk/gtktreeview.h: add gtk_tree_view_set_cursor_on_cell + + * gtk/gtktreeview.c (gtk_tree_view_button_press): focus on a cell + if applicable, + (gtk_tree_view_bin_expose): set_cell_data before iterating columns, + add support for row-spanning focus rectangles, + (gtk_tree_view_has_special_cell): new function, + (gtk_tree_view_move_cursor_left_right): add support for multiple + focusable cells in one column, + (gtk_tree_view_set_cursor): call _set_cursor_on_cell now, + (gtk_tree_view_set_cursor_on_cell): copy of _set_cursor, extended + with focus_cell parameter, + (gtk_tree_view_search_iter): removed unused column variable, + (gtk_tree_view_start_editing): add neighbor size code to allow + for multiple editable cells in one column. + + * gtk/gtktreeviewcolumn.c (_GtkTreeViewColumnCellInfo): add + in_editing_mode field, + (gtk_tree_view_column_get_edited_cell): new function, removed + _get_editable_cell, + (_gtk_tree_view_column_get_cell_at_pos): new function, + (gtk_tree_view_column_pack_end): s/g_new/g_new0/ ..., + (gtk_tree_view_column_cell_process_action): loads of changes to get + it right and to allow for multiple special cells, etc, + (gtk_tree_view_column_cell_first): new function, + (gtk_tree_view_column_cell_last): ditto, + (gtk_tree_view_column_cell_next): ditto, + (gtk_tree_view_column_cell_prev): ditto, + (gtk_tree_view_column_cell_focus): add left and right parameters, + allow for multiple special cells, + (gtk_tree_view_column_cell_is_visible): add assertion, + (gtk_tree_view_column_focus_cell): new function, + (gtk_tree_view_column_stop_editing): unset in_editing_mode flag, + (_gtk_tree_view_column_get_neighbor_sizes): iterate through cells + correctly + + * gtk/gtktreeviewcolumn.h: add gtk_tree_view_column_focus_cell + + * gtk/gtktreeprivate.h: s/_get_editable_cell/_get_edited_cell/, add + _gtk_tree_view_column_get_cell_at_pos, add new parameters to + _gtk_tree_view_column_cell_focus. + + * tests/testtreeedit.c: add some cells in order to test new code. + Sun May 5 02:22:59 2002 Soeren Sandmann * tests/test-images/*: image files for testing pixbuf loaders diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index e8914e6f81..90915b7314 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,52 @@ +Sun May 5 16:42:32 2002 Kristian Rietveld + + The "big treeview focus patch". Fixes several issues and adds some + goodies. Related bugs: #73676, #73734, #78660. + + * gtk/gtktreeview.h: add gtk_tree_view_set_cursor_on_cell + + * gtk/gtktreeview.c (gtk_tree_view_button_press): focus on a cell + if applicable, + (gtk_tree_view_bin_expose): set_cell_data before iterating columns, + add support for row-spanning focus rectangles, + (gtk_tree_view_has_special_cell): new function, + (gtk_tree_view_move_cursor_left_right): add support for multiple + focusable cells in one column, + (gtk_tree_view_set_cursor): call _set_cursor_on_cell now, + (gtk_tree_view_set_cursor_on_cell): copy of _set_cursor, extended + with focus_cell parameter, + (gtk_tree_view_search_iter): removed unused column variable, + (gtk_tree_view_start_editing): add neighbor size code to allow + for multiple editable cells in one column. + + * gtk/gtktreeviewcolumn.c (_GtkTreeViewColumnCellInfo): add + in_editing_mode field, + (gtk_tree_view_column_get_edited_cell): new function, removed + _get_editable_cell, + (_gtk_tree_view_column_get_cell_at_pos): new function, + (gtk_tree_view_column_pack_end): s/g_new/g_new0/ ..., + (gtk_tree_view_column_cell_process_action): loads of changes to get + it right and to allow for multiple special cells, etc, + (gtk_tree_view_column_cell_first): new function, + (gtk_tree_view_column_cell_last): ditto, + (gtk_tree_view_column_cell_next): ditto, + (gtk_tree_view_column_cell_prev): ditto, + (gtk_tree_view_column_cell_focus): add left and right parameters, + allow for multiple special cells, + (gtk_tree_view_column_cell_is_visible): add assertion, + (gtk_tree_view_column_focus_cell): new function, + (gtk_tree_view_column_stop_editing): unset in_editing_mode flag, + (_gtk_tree_view_column_get_neighbor_sizes): iterate through cells + correctly + + * gtk/gtktreeviewcolumn.h: add gtk_tree_view_column_focus_cell + + * gtk/gtktreeprivate.h: s/_get_editable_cell/_get_edited_cell/, add + _gtk_tree_view_column_get_cell_at_pos, add new parameters to + _gtk_tree_view_column_cell_focus. + + * tests/testtreeedit.c: add some cells in order to test new code. + Sun May 5 02:22:59 2002 Soeren Sandmann * tests/test-images/*: image files for testing pixbuf loaders diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index e8914e6f81..90915b7314 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,52 @@ +Sun May 5 16:42:32 2002 Kristian Rietveld + + The "big treeview focus patch". Fixes several issues and adds some + goodies. Related bugs: #73676, #73734, #78660. + + * gtk/gtktreeview.h: add gtk_tree_view_set_cursor_on_cell + + * gtk/gtktreeview.c (gtk_tree_view_button_press): focus on a cell + if applicable, + (gtk_tree_view_bin_expose): set_cell_data before iterating columns, + add support for row-spanning focus rectangles, + (gtk_tree_view_has_special_cell): new function, + (gtk_tree_view_move_cursor_left_right): add support for multiple + focusable cells in one column, + (gtk_tree_view_set_cursor): call _set_cursor_on_cell now, + (gtk_tree_view_set_cursor_on_cell): copy of _set_cursor, extended + with focus_cell parameter, + (gtk_tree_view_search_iter): removed unused column variable, + (gtk_tree_view_start_editing): add neighbor size code to allow + for multiple editable cells in one column. + + * gtk/gtktreeviewcolumn.c (_GtkTreeViewColumnCellInfo): add + in_editing_mode field, + (gtk_tree_view_column_get_edited_cell): new function, removed + _get_editable_cell, + (_gtk_tree_view_column_get_cell_at_pos): new function, + (gtk_tree_view_column_pack_end): s/g_new/g_new0/ ..., + (gtk_tree_view_column_cell_process_action): loads of changes to get + it right and to allow for multiple special cells, etc, + (gtk_tree_view_column_cell_first): new function, + (gtk_tree_view_column_cell_last): ditto, + (gtk_tree_view_column_cell_next): ditto, + (gtk_tree_view_column_cell_prev): ditto, + (gtk_tree_view_column_cell_focus): add left and right parameters, + allow for multiple special cells, + (gtk_tree_view_column_cell_is_visible): add assertion, + (gtk_tree_view_column_focus_cell): new function, + (gtk_tree_view_column_stop_editing): unset in_editing_mode flag, + (_gtk_tree_view_column_get_neighbor_sizes): iterate through cells + correctly + + * gtk/gtktreeviewcolumn.h: add gtk_tree_view_column_focus_cell + + * gtk/gtktreeprivate.h: s/_get_editable_cell/_get_edited_cell/, add + _gtk_tree_view_column_get_cell_at_pos, add new parameters to + _gtk_tree_view_column_cell_focus. + + * tests/testtreeedit.c: add some cells in order to test new code. + Sun May 5 02:22:59 2002 Soeren Sandmann * tests/test-images/*: image files for testing pixbuf loaders diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index e8914e6f81..90915b7314 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,52 @@ +Sun May 5 16:42:32 2002 Kristian Rietveld + + The "big treeview focus patch". Fixes several issues and adds some + goodies. Related bugs: #73676, #73734, #78660. + + * gtk/gtktreeview.h: add gtk_tree_view_set_cursor_on_cell + + * gtk/gtktreeview.c (gtk_tree_view_button_press): focus on a cell + if applicable, + (gtk_tree_view_bin_expose): set_cell_data before iterating columns, + add support for row-spanning focus rectangles, + (gtk_tree_view_has_special_cell): new function, + (gtk_tree_view_move_cursor_left_right): add support for multiple + focusable cells in one column, + (gtk_tree_view_set_cursor): call _set_cursor_on_cell now, + (gtk_tree_view_set_cursor_on_cell): copy of _set_cursor, extended + with focus_cell parameter, + (gtk_tree_view_search_iter): removed unused column variable, + (gtk_tree_view_start_editing): add neighbor size code to allow + for multiple editable cells in one column. + + * gtk/gtktreeviewcolumn.c (_GtkTreeViewColumnCellInfo): add + in_editing_mode field, + (gtk_tree_view_column_get_edited_cell): new function, removed + _get_editable_cell, + (_gtk_tree_view_column_get_cell_at_pos): new function, + (gtk_tree_view_column_pack_end): s/g_new/g_new0/ ..., + (gtk_tree_view_column_cell_process_action): loads of changes to get + it right and to allow for multiple special cells, etc, + (gtk_tree_view_column_cell_first): new function, + (gtk_tree_view_column_cell_last): ditto, + (gtk_tree_view_column_cell_next): ditto, + (gtk_tree_view_column_cell_prev): ditto, + (gtk_tree_view_column_cell_focus): add left and right parameters, + allow for multiple special cells, + (gtk_tree_view_column_cell_is_visible): add assertion, + (gtk_tree_view_column_focus_cell): new function, + (gtk_tree_view_column_stop_editing): unset in_editing_mode flag, + (_gtk_tree_view_column_get_neighbor_sizes): iterate through cells + correctly + + * gtk/gtktreeviewcolumn.h: add gtk_tree_view_column_focus_cell + + * gtk/gtktreeprivate.h: s/_get_editable_cell/_get_edited_cell/, add + _gtk_tree_view_column_get_cell_at_pos, add new parameters to + _gtk_tree_view_column_cell_focus. + + * tests/testtreeedit.c: add some cells in order to test new code. + Sun May 5 02:22:59 2002 Soeren Sandmann * tests/test-images/*: image files for testing pixbuf loaders diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index e8914e6f81..90915b7314 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,52 @@ +Sun May 5 16:42:32 2002 Kristian Rietveld + + The "big treeview focus patch". Fixes several issues and adds some + goodies. Related bugs: #73676, #73734, #78660. + + * gtk/gtktreeview.h: add gtk_tree_view_set_cursor_on_cell + + * gtk/gtktreeview.c (gtk_tree_view_button_press): focus on a cell + if applicable, + (gtk_tree_view_bin_expose): set_cell_data before iterating columns, + add support for row-spanning focus rectangles, + (gtk_tree_view_has_special_cell): new function, + (gtk_tree_view_move_cursor_left_right): add support for multiple + focusable cells in one column, + (gtk_tree_view_set_cursor): call _set_cursor_on_cell now, + (gtk_tree_view_set_cursor_on_cell): copy of _set_cursor, extended + with focus_cell parameter, + (gtk_tree_view_search_iter): removed unused column variable, + (gtk_tree_view_start_editing): add neighbor size code to allow + for multiple editable cells in one column. + + * gtk/gtktreeviewcolumn.c (_GtkTreeViewColumnCellInfo): add + in_editing_mode field, + (gtk_tree_view_column_get_edited_cell): new function, removed + _get_editable_cell, + (_gtk_tree_view_column_get_cell_at_pos): new function, + (gtk_tree_view_column_pack_end): s/g_new/g_new0/ ..., + (gtk_tree_view_column_cell_process_action): loads of changes to get + it right and to allow for multiple special cells, etc, + (gtk_tree_view_column_cell_first): new function, + (gtk_tree_view_column_cell_last): ditto, + (gtk_tree_view_column_cell_next): ditto, + (gtk_tree_view_column_cell_prev): ditto, + (gtk_tree_view_column_cell_focus): add left and right parameters, + allow for multiple special cells, + (gtk_tree_view_column_cell_is_visible): add assertion, + (gtk_tree_view_column_focus_cell): new function, + (gtk_tree_view_column_stop_editing): unset in_editing_mode flag, + (_gtk_tree_view_column_get_neighbor_sizes): iterate through cells + correctly + + * gtk/gtktreeviewcolumn.h: add gtk_tree_view_column_focus_cell + + * gtk/gtktreeprivate.h: s/_get_editable_cell/_get_edited_cell/, add + _gtk_tree_view_column_get_cell_at_pos, add new parameters to + _gtk_tree_view_column_cell_focus. + + * tests/testtreeedit.c: add some cells in order to test new code. + Sun May 5 02:22:59 2002 Soeren Sandmann * tests/test-images/*: image files for testing pixbuf loaders diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h index 8abd5657b3..5f01013197 100644 --- a/gtk/gtktreeprivate.h +++ b/gtk/gtktreeprivate.h @@ -316,8 +316,10 @@ void _gtk_tree_view_column_autosize (GtkTreeView *tre GtkTreeViewColumn *column); gboolean _gtk_tree_view_column_has_editable_cell (GtkTreeViewColumn *column); -GtkCellRenderer *_gtk_tree_view_column_get_editable_cell (GtkTreeViewColumn *column); +GtkCellRenderer *_gtk_tree_view_column_get_edited_cell (GtkTreeViewColumn *column); gint _gtk_tree_view_column_count_special_cells (GtkTreeViewColumn *column); +GtkCellRenderer *_gtk_tree_view_column_get_cell_at_pos (GtkTreeViewColumn *column, + gint x); GtkTreeSelection* _gtk_tree_selection_new (void); GtkTreeSelection* _gtk_tree_selection_new_with_tree_view (GtkTreeView *tree_view); @@ -331,7 +333,9 @@ void _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column, GdkRectangle *expose_area, guint flags); gboolean _gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column, - gint direction); + gint direction, + gboolean left, + gboolean right); void _gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column, GdkWindow *window, GdkRectangle *background_area, diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 4e6cfd482c..e1bcaa31d6 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -347,6 +347,7 @@ static void gtk_tree_view_real_set_cursor (GtkTreeView GtkTreePath *path, gboolean clear_and_select, gboolean clamp_node); +static gboolean gtk_tree_view_has_special_cell (GtkTreeView *tree_view); /* interactive search */ static void gtk_tree_view_search_dialog_destroy (GtkWidget *search_dialog, @@ -1709,6 +1710,7 @@ gtk_tree_view_button_press (GtkWidget *widget, gint dval; gint pre_val, aft_val; GtkTreeViewColumn *column = NULL; + GtkCellRenderer *focus_cell = NULL; gint column_handled_click = FALSE; gboolean emit_row_activated = FALSE; @@ -1829,7 +1831,7 @@ gtk_tree_view_button_press (GtkWidget *widget, GdkRectangle area; area = cell_area; - _gtk_tree_view_column_get_neighbor_sizes (column, _gtk_tree_view_column_get_editable_cell (column), &left, &right); + _gtk_tree_view_column_get_neighbor_sizes (column, _gtk_tree_view_column_get_edited_cell (column), &left, &right); area.x += left; area.width -= right + left; @@ -1857,6 +1859,10 @@ gtk_tree_view_button_press (GtkWidget *widget, pre_val = tree_view->priv->vadjustment->value; tree_view->priv->focus_column = column; + focus_cell = _gtk_tree_view_column_get_cell_at_pos (column, event->x - background_area.x); + if (focus_cell) + gtk_tree_view_column_focus_cell (column, focus_cell); + if (event->state & GDK_CONTROL_MASK) { gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE); @@ -2727,7 +2733,9 @@ gtk_tree_view_bin_expose (GtkWidget *widget, GList *last_column; gint vertical_separator; gint horizontal_separator; + gint focus_line_width; gboolean allow_rules; + gboolean has_special_cell; g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); @@ -2737,6 +2745,7 @@ gtk_tree_view_bin_expose (GtkWidget *widget, "horizontal_separator", &horizontal_separator, "vertical_separator", &vertical_separator, "allow_rules", &allow_rules, + "focus-line-width", &focus_line_width, NULL); if (tree_view->priv->tree == NULL) @@ -2822,6 +2831,18 @@ gtk_tree_view_bin_expose (GtkWidget *widget, parity = _gtk_rbtree_node_find_parity (tree, node); + for (list = tree_view->priv->columns; list; list = list->next) + { + GtkTreeViewColumn *column = list->data; + gtk_tree_view_column_cell_set_cell_data (column, + tree_view->priv->model, + &iter, + GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT), + node->children?TRUE:FALSE); + } + + has_special_cell = gtk_tree_view_has_special_cell (tree_view); + for (list = tree_view->priv->columns; list; list = list->next) { GtkTreeViewColumn *column = list->data; @@ -2843,13 +2864,6 @@ gtk_tree_view_bin_expose (GtkWidget *widget, else flags &= ~GTK_CELL_RENDERER_SORTED; - gtk_tree_view_column_cell_set_cell_data (column, - tree_view->priv->model, - &iter, - GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT), - node->children?TRUE:FALSE); - - background_area.x = cell_offset; background_area.width = column->width; @@ -2954,7 +2968,7 @@ gtk_tree_view_bin_expose (GtkWidget *widget, &event->area, flags); } - if (node == cursor && + if (node == cursor && has_special_cell && ((column == tree_view->priv->focus_column && GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS) && GTK_WIDGET_HAS_FOCUS (widget)) || @@ -3027,6 +3041,35 @@ gtk_tree_view_bin_expose (GtkWidget *widget, } } + /* draw the big row-spanning focus rectangle, if needed */ + if (!has_special_cell && node == cursor && + GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS) && + GTK_WIDGET_HAS_FOCUS (widget)) + { + gint width; + GtkStateType focus_rect_state; + + focus_rect_state = + flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED : + (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT : + (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE : + GTK_STATE_NORMAL)); + + gdk_drawable_get_size (tree_view->priv->bin_window, + &width, NULL); + gtk_paint_focus (widget->style, + tree_view->priv->bin_window, + focus_rect_state, + NULL, + widget, + "treeview", + 0, + BACKGROUND_FIRST_PIXEL (tree_view, tree, node), + width, + MAX (BACKGROUND_HEIGHT (node), + tree_view->priv->expander_size)); + } + y_offset += max_height; if (node->children) { @@ -5192,6 +5235,25 @@ gtk_tree_view_forall (GtkContainer *container, } } +/* Returns TRUE if the treeview contains no "special" (editable or activatable) + * cells. If so we draw one big row-spanning focus rectangle. + */ +static gboolean +gtk_tree_view_has_special_cell (GtkTreeView *tree_view) +{ + GList *list; + + for (list = tree_view->priv->columns; list; list = list->next) + { + if (!((GtkTreeViewColumn *)list->data)->visible) + continue; + if (_gtk_tree_view_column_count_special_cells (list->data)) + return TRUE; + } + + return FALSE; +} + /* Returns TRUE if the focus is within the headers, after the focus operation is * done */ @@ -7076,7 +7138,9 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view, &iter, GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT), cursor_node->children?TRUE:FALSE); - if (_gtk_tree_view_column_cell_focus (column, count)) + if (_gtk_tree_view_column_cell_focus (column, count, + list->prev?TRUE:FALSE, + list->next?TRUE:FALSE)) { tree_view->priv->focus_column = column; found_column = TRUE; @@ -7091,10 +7155,11 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view, if (found_column) { - _gtk_tree_view_queue_draw_node (tree_view, - cursor_tree, - cursor_node, - NULL); + if (!gtk_tree_view_has_special_cell (tree_view)) + _gtk_tree_view_queue_draw_node (tree_view, + cursor_tree, + cursor_node, + NULL); g_signal_emit (G_OBJECT (tree_view), tree_view_signals[CURSOR_CHANGED], 0); } gtk_tree_view_clamp_column_visible (tree_view, tree_view->priv->focus_column); @@ -9246,11 +9311,47 @@ gtk_tree_view_set_cursor (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *focus_column, gboolean start_editing) +{ + gtk_tree_view_set_cursor_on_cell (tree_view, path, focus_column, + NULL, start_editing); +} + +/** + * gtk_tree_view_set_cursor_on_cell: + * @tree_view: A #GtkTreeView + * @path: A #GtkTreePath + * @focus_column: A #GtkTreeViewColumn, or %NULL + * @focus_cell: A #GtkCellRenderer, or %NULL + * @start_editing: %TRUE if the specified cell should start being edited. + * + * Sets the current keyboard focus to be at @path, and selects it. This is + * useful when you want to focus the user's attention on a particular row. If + * @focus_column is not %NULL, then focus is given to the column specified by + * it. If @focus_column and @focus_cell are not %NULL, and @focus_column + * contains 2 or more editable or activatable cells, then focus is given to + * the cell specified by @focus_cell. Additionally, if @focus_column is + * specified, and @start_editing is %TRUE, then editing should be started in + * the specified cell. This function is often followed by + * @gtk_widget_grab_focus (@tree_view) in order to give keyboard focus to the + * widget. Please note that editing can only happen when the widget is + * realized. + **/ +void +gtk_tree_view_set_cursor_on_cell (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *focus_column, + GtkCellRenderer *focus_cell, + gboolean start_editing) { g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); g_return_if_fail (path != NULL); if (focus_column) g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (focus_column)); + if (focus_cell) + { + g_return_if_fail (focus_column); + g_return_if_fail (GTK_IS_CELL_RENDERER (focus_cell)); + } gtk_tree_view_real_set_cursor (tree_view, path, TRUE, TRUE); @@ -9267,12 +9368,13 @@ gtk_tree_view_set_cursor (GtkTreeView *tree_view, } g_return_if_fail (column_in_tree); tree_view->priv->focus_column = focus_column; + if (focus_cell) + gtk_tree_view_column_focus_cell (focus_column, focus_cell); if (start_editing) gtk_tree_view_start_editing (tree_view, path); } } - /** * gtk_tree_view_get_bin_window: * @tree_view: A #GtkTreeView @@ -10418,8 +10520,6 @@ gtk_tree_view_search_iter (GtkTreeModel *model, GtkTreePath *path; GtkTreeView *tree_view = gtk_tree_selection_get_tree_view (selection); - GtkTreeViewColumn *column = - gtk_tree_view_get_column (tree_view, tree_view->priv->search_column); path = gtk_tree_model_get_path (model, iter); _gtk_tree_view_find_node (tree_view, path, &tree, &node); @@ -10634,11 +10734,22 @@ gtk_tree_view_start_editing (GtkTreeView *tree_view, retval = TRUE; if (editable_widget != NULL) { + gint left, right; + GdkRectangle area; + GtkCellRenderer *cell; + + area = cell_area; + cell = _gtk_tree_view_column_get_edited_cell (tree_view->priv->focus_column); + _gtk_tree_view_column_get_neighbor_sizes (tree_view->priv->focus_column, cell, &left, &right); + + area.x += left; + area.width -= right + left; + gtk_tree_view_real_start_editing (tree_view, tree_view->priv->focus_column, cursor_path, editable_widget, - &cell_area, + &area, NULL, flags); } diff --git a/gtk/gtktreeview.h b/gtk/gtktreeview.h index 69ef93b954..750aa1c39e 100644 --- a/gtk/gtktreeview.h +++ b/gtk/gtktreeview.h @@ -218,6 +218,11 @@ void gtk_tree_view_set_cursor (GtkTreeView GtkTreePath *path, GtkTreeViewColumn *focus_column, gboolean start_editing); +void gtk_tree_view_set_cursor_on_cell (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *focus_column, + GtkCellRenderer *focus_cell, + gboolean start_editing); void gtk_tree_view_get_cursor (GtkTreeView *tree_view, GtkTreePath **path, GtkTreeViewColumn **focus_column); diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index eb2cc21a9d..7f76fc6cf7 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -68,6 +68,7 @@ struct _GtkTreeViewColumnCellInfo guint expand : 1; guint pack : 1; guint has_focus : 1; + guint in_editing_mode : 1; }; /* Type methods */ @@ -113,6 +114,13 @@ static void gtk_tree_view_column_set_attributesv (GtkTreeViewColum static GtkTreeViewColumnCellInfo *gtk_tree_view_column_get_cell_info (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell_renderer); +/* cell list manipulation */ +static GList *gtk_tree_view_column_cell_first (GtkTreeViewColumn *tree_column); +static GList *gtk_tree_view_column_cell_last (GtkTreeViewColumn *tree_column); +static GList *gtk_tree_view_column_cell_next (GtkTreeViewColumn *tree_column, + GList *current); +static GList *gtk_tree_view_column_cell_prev (GtkTreeViewColumn *tree_column, + GList *current); static GtkObjectClass *parent_class = NULL; @@ -1054,14 +1062,14 @@ _gtk_tree_view_column_has_editable_cell (GtkTreeViewColumn *column) return FALSE; } +/* gets cell being edited */ GtkCellRenderer * -_gtk_tree_view_column_get_editable_cell (GtkTreeViewColumn *column) +_gtk_tree_view_column_get_edited_cell (GtkTreeViewColumn *column) { GList *list; for (list = column->cell_list; list; list = list->next) - if (((GtkTreeViewColumnCellInfo *)list->data)->cell->mode == - GTK_CELL_RENDERER_MODE_EDITABLE) + if (((GtkTreeViewColumnCellInfo *)list->data)->in_editing_mode) return ((GtkTreeViewColumnCellInfo *)list->data)->cell; return NULL; @@ -1085,6 +1093,25 @@ _gtk_tree_view_column_count_special_cells (GtkTreeViewColumn *column) return i; } +GtkCellRenderer * +_gtk_tree_view_column_get_cell_at_pos (GtkTreeViewColumn *column, + gint x) +{ + GList *list; + gint current_x = 0; + + list = gtk_tree_view_column_cell_first (column); + for (; list; list = gtk_tree_view_column_cell_next (column, list)) + { + GtkTreeViewColumnCellInfo *cellinfo = list->data; + if (current_x <= x && x <= current_x + cellinfo->real_width) + return cellinfo->cell; + current_x += cellinfo->real_width; + } + + return NULL; +} + /* Public Functions */ @@ -1222,7 +1249,7 @@ gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column, g_object_ref (G_OBJECT (cell)); gtk_object_sink (GTK_OBJECT (cell)); - cell_info = g_new (GtkTreeViewColumnCellInfo, 1); + cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1); cell_info->cell = cell; cell_info->expand = expand ? TRUE : FALSE; cell_info->pack = GTK_PACK_END; @@ -2351,23 +2378,53 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, gint min_x, min_y, max_x, max_y; gint focus_line_width; gint dx; + gint special_cells; min_x = G_MAXINT; min_y = G_MAXINT; max_x = 0; max_y = 0; - real_cell_area = *cell_area; - real_background_area = *background_area; - dx = real_cell_area.x - real_background_area.x; + special_cells = _gtk_tree_view_column_count_special_cells (tree_column); + + if (special_cells > 1 && action == CELL_ACTION_FOCUS) + { + GtkTreeViewColumnCellInfo *info = NULL; + gboolean found_has_focus = FALSE; + + /* one should have focus */ + for (list = tree_column->cell_list; list; list = list->next) + { + info = list->data; + if (info && info->has_focus) + { + found_has_focus = TRUE; + break; + } + } + + if (!found_has_focus) + { + /* give the first one focus */ + info = gtk_tree_view_column_cell_first (tree_column)->data; + info->has_focus = TRUE; + } + } gtk_widget_style_get (GTK_WIDGET (tree_column->tree_view), "focus-line-width", &focus_line_width, NULL); - /* Find out how my extra space we have to allocate */ + + real_cell_area = *cell_area; + real_background_area = *background_area; + dx = real_cell_area.x - real_background_area.x - focus_line_width; + + real_cell_area.x += focus_line_width; + + /* Find out how many extra space we have to allocate */ for (list = tree_column->cell_list; list; list = list->next) { - GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data; + GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data; if (! info->cell->visible) continue; @@ -2377,10 +2434,13 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, full_requested_width += info->requested_width; } - extra_space = cell_area->width - full_requested_width; + extra_space = background_area->width - full_requested_width; if (extra_space < 0) extra_space = 0; + else if (extra_space > 0 && expand_cell_count > 0) + extra_space /= expand_cell_count; + /* iterate list for GTK_PACK_START cells */ for (list = tree_column->cell_list; list; list = list->next) { GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data; @@ -2391,15 +2451,12 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, if (! info->cell->visible) continue; - real_cell_area.width = info->requested_width + + real_background_area.width = info->requested_width + (info->expand?extra_space:0); - info->real_width = real_cell_area.width; - real_cell_area.x += focus_line_width; + info->real_width = real_background_area.width; - real_background_area.width = real_cell_area.width; - real_background_area.x += focus_line_width; - if (!list->prev) - real_background_area.width += dx; + real_cell_area.width = real_background_area.width; + real_cell_area.width -= 2 * focus_line_width; if (action == CELL_ACTION_RENDER) { @@ -2421,14 +2478,27 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, &x_offset, &y_offset, &width, &height); - if (min_x > (real_cell_area.x + x_offset)) - min_x = real_cell_area.x + x_offset; - if (max_x < real_cell_area.x + x_offset + width) - max_x = real_cell_area.x + x_offset + width; - if (min_y > (real_cell_area.y + y_offset)) - min_y = real_cell_area.y + y_offset; - if (max_y < real_cell_area.y + y_offset + height) - max_y = real_cell_area.y + y_offset + height; + if (special_cells > 1) + { + if (info->has_focus) + { + min_x = real_cell_area.x + x_offset; + max_x = min_x + width; + min_y = real_cell_area.y + y_offset; + max_y = min_y + height; + } + } + else + { + if (min_x > (real_cell_area.x + x_offset)) + min_x = real_cell_area.x + x_offset; + if (max_x < real_cell_area.x + x_offset + width) + max_x = real_cell_area.x + x_offset + width; + if (min_y > (real_cell_area.y + y_offset)) + min_y = real_cell_area.y + y_offset; + if (max_y < real_cell_area.y + y_offset + height) + max_y = real_cell_area.y + y_offset + height; + } } else if (action == CELL_ACTION_EVENT) { @@ -2436,9 +2506,9 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, if (event) { - if (_gtk_tree_view_column_count_special_cells (tree_column) == 1) + if (special_cells == 1) { - /* only 1 activatably cell -> whole column can activate */ + /* only 1 activatable cell -> whole column can activate */ if (cell_area->x <= ((GdkEventButton *)event)->x && cell_area->x + cell_area->width > ((GdkEventButton *)event)->x) try_event = TRUE; @@ -2450,11 +2520,11 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, */ try_event = TRUE; } - else /* if (info->has_focus)*/ - /* FIXME 73676: allow focusing individual cells */ - { - try_event = TRUE; - } + else if (special_cells > 1 && info->has_focus) + try_event = TRUE; + else if (special_cells == 1) + try_event = TRUE; + if (try_event) { gboolean visible, mode; @@ -2488,15 +2558,20 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, if (*editable_widget != NULL) { g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE); + info->in_editing_mode = TRUE; + gtk_tree_view_column_focus_cell (tree_column, info->cell); return TRUE; } } } } - real_cell_area.x += (info->requested_width + tree_column->spacing); - real_background_area.x += (info->requested_width + tree_column->spacing); + + real_cell_area.x += (info->real_width + tree_column->spacing); + real_background_area.x += (info->real_width + tree_column->spacing); } + + /* iterate list for PACK_END cells */ for (list = g_list_last (tree_column->cell_list); list; list = list->prev) { GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data; @@ -2507,10 +2582,13 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, if (! info->cell->visible) continue; - real_cell_area.width = info->requested_width + + real_background_area.width = info->requested_width + (info->expand?extra_space:0); - info->real_width = real_cell_area.width; - real_background_area.width = real_background_area.width; + info->real_width = real_background_area.width; + + real_cell_area.width = real_background_area.width; + real_cell_area.width -= 2 * focus_line_width; + if (action == CELL_ACTION_RENDER) { gtk_cell_renderer_render (info->cell, @@ -2531,19 +2609,100 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column, &x_offset, &y_offset, &width, &height); - if (min_x > (real_cell_area.x + x_offset)) - min_x = real_cell_area.x + x_offset; - if (max_x < real_cell_area.x + x_offset + width) - max_x = real_cell_area.x + x_offset + width; - if (min_y > (real_cell_area.y + y_offset)) - min_y = real_cell_area.y + y_offset; - if (max_y < real_cell_area.y + y_offset + height) - max_y = real_cell_area.y + y_offset + height; + if (special_cells > 1) + { + if (info->has_focus) + { + min_x = real_cell_area.x + x_offset; + max_x = min_x + width; + min_y = real_cell_area.y + y_offset; + max_y = min_y + height; + } + } + else + { + if (min_x > (real_cell_area.x + x_offset)) + min_x = real_cell_area.x + x_offset; + if (max_x < real_cell_area.x + x_offset + width) + max_x = real_cell_area.x + x_offset + width; + if (min_y > (real_cell_area.y + y_offset)) + min_y = real_cell_area.y + y_offset; + if (max_y < real_cell_area.y + y_offset + height) + max_y = real_cell_area.y + y_offset + height; + } } - real_cell_area.x += (info->requested_width + tree_column->spacing); - real_background_area.x += (info->requested_width + tree_column->spacing); + else if (action == CELL_ACTION_EVENT) + { + gboolean try_event = FALSE; + + if (event) + { + if (special_cells == 1) + { + /* only 1 activatable cell -> whole column can activate */ + if (cell_area->x <= ((GdkEventButton *)event)->x && + cell_area->x + cell_area->width > ((GdkEventButton *)event)->x) + try_event = TRUE; + } + else if (real_cell_area.x <= ((GdkEventButton *)event)->x && + real_cell_area.x + real_cell_area.width > ((GdkEventButton *)event)->x) + /* only activate cell if the user clicked on an individual + * cell + */ + try_event = TRUE; + } + else if (special_cells > 1 && info->has_focus) + try_event = TRUE; + else if (special_cells == 1) + try_event = TRUE; + + if (try_event) + { + gboolean visible, mode; + + g_object_get (G_OBJECT (info->cell), + "visible", &visible, + "mode", &mode, + NULL); + if (visible && mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE) + { + if (gtk_cell_renderer_activate (info->cell, + event, + tree_column->tree_view, + path_string, + background_area, + cell_area, + flags)) + return TRUE; + } + else if (visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE) + { + *editable_widget = + gtk_cell_renderer_start_editing (info->cell, + event, + tree_column->tree_view, + path_string, + background_area, + cell_area, + flags); + + if (*editable_widget != NULL) + { + g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE); + info->in_editing_mode = TRUE; + gtk_tree_view_column_focus_cell (tree_column, info->cell); + + return TRUE; + } + } + } + } + + real_cell_area.x += (info->real_width + tree_column->spacing); + real_background_area.x += (info->real_width + tree_column->spacing); } + /* fill focus_rectangle when required */ if (action == CELL_ACTION_FOCUS) { if (min_x >= max_x || min_y >= max_y) @@ -2622,14 +2781,218 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column, path_string); } +/* cell list manipulation */ +static GList * +gtk_tree_view_column_cell_first (GtkTreeViewColumn *tree_column) +{ + GList *list = tree_column->cell_list; + + /* first GTK_PACK_START cell we find */ + for ( ; list; list = list->next) + { + GtkTreeViewColumnCellInfo *info = list->data; + if (info->pack == GTK_PACK_START) + return list; + } + + /* hmm, else the *last* GTK_PACK_END cell */ + list = g_list_last (tree_column->cell_list); + + for ( ; list; list = list->prev) + { + GtkTreeViewColumnCellInfo *info = list->data; + if (info->pack == GTK_PACK_END) + return list; + } + + return NULL; +} + +static GList * +gtk_tree_view_column_cell_last (GtkTreeViewColumn *tree_column) +{ + GList *list = tree_column->cell_list; + + /* *first* GTK_PACK_END cell we find */ + for ( ; list ; list = list->next) + { + GtkTreeViewColumnCellInfo *info = list->data; + if (info->pack == GTK_PACK_END) + return list; + } + + /* hmm, else the last GTK_PACK_START cell */ + list = g_list_last (tree_column->cell_list); + + for ( ; list; list = list->prev) + { + GtkTreeViewColumnCellInfo *info = list->data; + if (info->pack == GTK_PACK_START) + return list; + } + + return NULL; +} + +static GList * +gtk_tree_view_column_cell_next (GtkTreeViewColumn *tree_column, + GList *current) +{ + GList *list; + GtkTreeViewColumnCellInfo *info = current->data; + + if (info->pack == GTK_PACK_START) + { + for (list = current->next; list; list = list->next) + { + GtkTreeViewColumnCellInfo *inf = list->data; + if (inf->pack == GTK_PACK_START) + return list; + } + + /* out of GTK_PACK_START cells, get *last* GTK_PACK_END one */ + list = g_list_last (tree_column->cell_list); + for (; list; list = list->prev) + { + GtkTreeViewColumnCellInfo *inf = list->data; + if (inf->pack == GTK_PACK_END) + return list; + } + } + + for (list = current->prev; list; list = list->prev) + { + GtkTreeViewColumnCellInfo *inf = list->data; + if (inf->pack == GTK_PACK_END) + return list; + } + + return NULL; +} + +static GList * +gtk_tree_view_column_cell_prev (GtkTreeViewColumn *tree_column, + GList *current) +{ + GList *list; + GtkTreeViewColumnCellInfo *info = current->data; + + if (info->pack == GTK_PACK_END) + { + for (list = current->next; list; list = list->next) + { + GtkTreeViewColumnCellInfo *inf = list->data; + if (inf->pack == GTK_PACK_END) + return list; + } + + /* out of GTK_PACK_END, get last GTK_PACK_START one */ + list = g_list_last (tree_column->cell_list); + for ( ; list; list = list->prev) + { + GtkTreeViewColumnCellInfo *inf = list->data; + if (inf->pack == GTK_PACK_START) + return list; + } + } + + for (list = current->prev; list; list = list->prev) + { + GtkTreeViewColumnCellInfo *inf = list->data; + if (inf->pack == GTK_PACK_START) + return list; + } + + return NULL; +} gboolean _gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column, - gint direction) + gint direction, + gboolean left, + gboolean right) { - /* FIXME 73676: allow focusing individual cells */ + gint count; + + count = _gtk_tree_view_column_count_special_cells (tree_column); + + /* if we are the current focus column and have multiple editable cells, + * try to select the next one, else move the focus to the next column + */ if (GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column == tree_column) - return FALSE; + { + if (count > 1) + { + GList *next, *prev; + GList *list = tree_column->cell_list; + GtkTreeViewColumnCellInfo *info = NULL; + + /* find current focussed cell */ + for ( ; list; list = list->next) + { + info = list->data; + if (info->has_focus) + break; + } + + /* not a focussed cell in the focus column? */ + if (!list || !info || !info->has_focus) + return FALSE; + + next = gtk_tree_view_column_cell_next (tree_column, list); + prev = gtk_tree_view_column_cell_prev (tree_column, list); + + info->has_focus = FALSE; + if (direction > 0 && next) + { + info = next->data; + info->has_focus = TRUE; + return TRUE; + } + else if (direction > 0 && !next && !right) + { + /* keep focus on latest cell */ + info = gtk_tree_view_column_cell_last (tree_column)->data; + info->has_focus = TRUE; + return TRUE; + } + else if (direction < 0 && prev) + { + info = prev->data; + info->has_focus = TRUE; + return TRUE; + } + else if (direction < 0 && !prev && !left) + { + /* keep focus on first cell */ + info = gtk_tree_view_column_cell_first (tree_column)->data; + info->has_focus = TRUE; + return TRUE; + } + } + return FALSE; + } + + /* we get focus, if we have multiple editable cells, give the correct one + * focus + */ + if (count > 1) + { + GList *list = tree_column->cell_list; + + /* clear focus first */ + for ( ; list ; list = list->next) + { + GtkTreeViewColumnCellInfo *info = list->data; + if (info->has_focus) + info->has_focus = FALSE; + } + + if (direction > 0) + ((GtkTreeViewColumnCellInfo *)gtk_tree_view_column_cell_first (tree_column)->data)->has_focus = TRUE; + else if (direction < 0) + ((GtkTreeViewColumnCellInfo *)gtk_tree_view_column_cell_last (tree_column)->data)->has_focus = TRUE; + } return TRUE; } @@ -2708,6 +3071,8 @@ gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column) { GList *list; + g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE); + for (list = tree_column->cell_list; list; list = list->next) { GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data; @@ -2719,6 +3084,53 @@ gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column) return FALSE; } +/** + * gtk_tree_view_column_focus_cell: + * @tree_view: A #GtkTreeView + * @cell: A #GtkCellRenderer + * + * Sets the current keyboard focus to be at @cell, if the column contains + * 2 or more editable and activatable cells. + **/ +void +gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell) +{ + GList *list; + gboolean found_cell = FALSE; + + g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column)); + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + if (_gtk_tree_view_column_count_special_cells (tree_column) < 2) + return; + + for (list = tree_column->cell_list; list; list = list->next) + { + GtkTreeViewColumnCellInfo *info = list->data; + + if (info->cell == cell) + { + info->has_focus = TRUE; + found_cell = TRUE; + break; + } + } + + if (found_cell) + { + for (list = tree_column->cell_list; list; list = list->next) + { + GtkTreeViewColumnCellInfo *info = list->data; + + if (info->cell != cell) + info->has_focus = FALSE; + } + + /* FIXME: redraw? */ + } +} + void _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column, gboolean install_handler) @@ -2759,9 +3171,13 @@ _gtk_tree_view_column_start_editing (GtkTreeViewColumn *tree_column, void _gtk_tree_view_column_stop_editing (GtkTreeViewColumn *tree_column) { + GList *list; + g_return_if_fail (tree_column->editable_widget != NULL); tree_column->editable_widget = NULL; + for (list = tree_column->cell_list; list; list = list->next) + ((GtkTreeViewColumnCellInfo *)list->data)->in_editing_mode = FALSE; } void @@ -2775,8 +3191,9 @@ _gtk_tree_view_column_get_neighbor_sizes (GtkTreeViewColumn *column, if (left) { *left = 0; + list = gtk_tree_view_column_cell_first (column); - for (list = column->cell_list; list; list = list->next) + for (; list; list = gtk_tree_view_column_cell_next (column, list)) { GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data; @@ -2790,9 +3207,12 @@ _gtk_tree_view_column_get_neighbor_sizes (GtkTreeViewColumn *column, if (right) { - *right = 0; + GList *next; - for (list = column->cell_list; list; list = list->next) + *right = 0; + list = gtk_tree_view_column_cell_first (column); + + for (; list; list = gtk_tree_view_column_cell_next (column, list)) { GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data; @@ -2802,10 +3222,11 @@ _gtk_tree_view_column_get_neighbor_sizes (GtkTreeViewColumn *column, } /* skip cell */ - if (list && list->next) + next = gtk_tree_view_column_cell_next (column, list); + if (list && next) { - list = list->next; - for ( ; list; list = list->next) + list = next; + for ( ; list; list = gtk_tree_view_column_cell_next (column, list)) { GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data; diff --git a/gtk/gtktreeviewcolumn.h b/gtk/gtktreeviewcolumn.h index fd1f48c2bb..22d20ef704 100644 --- a/gtk/gtktreeviewcolumn.h +++ b/gtk/gtktreeviewcolumn.h @@ -217,6 +217,8 @@ void gtk_tree_view_column_cell_get_size (GtkTreeViewCol gint *width, gint *height); gboolean gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column); +void gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell); #ifdef __cplusplus } diff --git a/tests/testtreeedit.c b/tests/testtreeedit.c index 9163fd2c9b..2b8f114ccc 100644 --- a/tests/testtreeedit.c +++ b/tests/testtreeedit.c @@ -8,6 +8,7 @@ typedef struct { enum { STRING_COLUMN, IS_EDITABLE_COLUMN, + PIXBUF_COLUMN, NUM_COLUMNS }; @@ -24,21 +25,29 @@ static ListEntry model_strings[] = static GtkTreeModel * create_model (void) { - GtkListStore *model; + GtkTreeStore *model; GtkTreeIter iter; gint i; + GdkPixbuf *foo; + GtkWidget *blah; + + blah = gtk_window_new (GTK_WINDOW_TOPLEVEL); + foo = gtk_widget_render_icon (blah, GTK_STOCK_NEW, GTK_ICON_SIZE_MENU, NULL); + gtk_widget_destroy (blah); - model = gtk_list_store_new (NUM_COLUMNS, + model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING, - G_TYPE_BOOLEAN); + G_TYPE_BOOLEAN, + GDK_TYPE_PIXBUF); for (i = 0; model_strings[i].string != NULL; i++) { - gtk_list_store_append (model, &iter); + gtk_tree_store_append (model, &iter, NULL); - gtk_list_store_set (model, &iter, + gtk_tree_store_set (model, &iter, STRING_COLUMN, model_strings[i].string, IS_EDITABLE_COLUMN, model_strings[i].is_editable, + PIXBUF_COLUMN, foo, -1); } @@ -59,7 +68,7 @@ toggled (GtkCellRendererToggle *cell, gtk_tree_model_get (model, &iter, IS_EDITABLE_COLUMN, &value, -1); value = !value; - gtk_list_store_set (GTK_LIST_STORE (model), &iter, IS_EDITABLE_COLUMN, value, -1); + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, IS_EDITABLE_COLUMN, value, -1); gtk_tree_path_free (path); } @@ -75,7 +84,7 @@ edited (GtkCellRendererText *cell, GtkTreePath *path = gtk_tree_path_new_from_string (path_string); gtk_tree_model_get_iter (model, &iter, path); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, STRING_COLUMN, new_text, -1); + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, STRING_COLUMN, new_text, -1); gtk_tree_path_free (path); } @@ -102,6 +111,7 @@ main (gint argc, gchar **argv) GtkWidget *tree_view; GtkTreeModel *tree_model; GtkCellRenderer *renderer; + GtkTreeViewColumn *column; gtk_init (&argc, &argv); @@ -118,18 +128,39 @@ main (gint argc, gchar **argv) tree_view = gtk_tree_view_new_with_model (tree_model); g_signal_connect (tree_view, "button_press_event", G_CALLBACK (button_press_event), NULL); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), TRUE); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, "String"); + + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, + "pixbuf", PIXBUF_COLUMN, NULL); renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view), - -1, "String", - renderer, - "text", STRING_COLUMN, - "editable", IS_EDITABLE_COLUMN, - NULL); - + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, + "text", STRING_COLUMN, + "editable", IS_EDITABLE_COLUMN, + NULL); g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (edited), tree_model); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, + "text", STRING_COLUMN, + "editable", IS_EDITABLE_COLUMN, + NULL); + g_signal_connect (G_OBJECT (renderer), "edited", + G_CALLBACK (edited), tree_model); + + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, + "pixbuf", PIXBUF_COLUMN, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + renderer = gtk_cell_renderer_toggle_new (); g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (toggled), tree_model); @@ -145,7 +176,7 @@ main (gint argc, gchar **argv) gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view); gtk_window_set_default_size (GTK_WINDOW (window), - 650, 400); + 800, 175); gtk_widget_show_all (window); gtk_main ();