The "big treeview focus patch". Fixes several issues and adds some

Sun May  5 16:42:32 2002  Kristian Rietveld  <kris@gtk.org>

        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.
This commit is contained in:
Kristian Rietveld 2002-05-05 14:54:00 +00:00 committed by Kristian Rietveld
parent d269c210c5
commit acce60b799
12 changed files with 960 additions and 92 deletions

View File

@ -1,3 +1,52 @@
Sun May 5 16:42:32 2002 Kristian Rietveld <kris@gtk.org>
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 <sandmann@daimi.au.dk>
* tests/test-images/*: image files for testing pixbuf loaders

View File

@ -1,3 +1,52 @@
Sun May 5 16:42:32 2002 Kristian Rietveld <kris@gtk.org>
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 <sandmann@daimi.au.dk>
* tests/test-images/*: image files for testing pixbuf loaders

View File

@ -1,3 +1,52 @@
Sun May 5 16:42:32 2002 Kristian Rietveld <kris@gtk.org>
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 <sandmann@daimi.au.dk>
* tests/test-images/*: image files for testing pixbuf loaders

View File

@ -1,3 +1,52 @@
Sun May 5 16:42:32 2002 Kristian Rietveld <kris@gtk.org>
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 <sandmann@daimi.au.dk>
* tests/test-images/*: image files for testing pixbuf loaders

View File

@ -1,3 +1,52 @@
Sun May 5 16:42:32 2002 Kristian Rietveld <kris@gtk.org>
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 <sandmann@daimi.au.dk>
* tests/test-images/*: image files for testing pixbuf loaders

View File

@ -1,3 +1,52 @@
Sun May 5 16:42:32 2002 Kristian Rietveld <kris@gtk.org>
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 <sandmann@daimi.au.dk>
* tests/test-images/*: image files for testing pixbuf loaders

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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
}

View File

@ -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 ();