- if (list->next)
- {
- real_background_area.width = info->real_width + depth;
- }
- else
- {
- /* fill the rest of background for the last cell */
- real_background_area.width = background_area->x + background_area->width - real_background_area.x;
- }
-
- rtl_cell_area = real_cell_area;
- rtl_background_area = real_background_area;
-
- if (rtl)
- {
- rtl_cell_area.x = cell_area->x + cell_area->width - (real_cell_area.x - cell_area->x) - real_cell_area.width;
- rtl_background_area.x = background_area->x + background_area->width - (real_background_area.x - background_area->x) - real_background_area.width;
- }
-
- /* RENDER */
- if (action == CELL_ACTION_RENDER)
- {
- gtk_cell_renderer_render_cairo (info->cell,
- cr,
- tree_column->tree_view,
- &rtl_background_area,
- &rtl_cell_area,
- flags);
- }
- /* FOCUS */
- else if (action == CELL_ACTION_FOCUS)
- {
- gint x_offset, y_offset;
- GtkRequisition min_size;
-
- gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
- tree_column->tree_view,
- &min_size, NULL);
-
- _gtk_cell_renderer_calc_offset (info->cell, &rtl_cell_area,
- gtk_widget_get_direction (tree_column->tree_view),
- min_size.width, min_size.height,
- &x_offset, &y_offset);
-
- if (special_cells > 1)
- {
- if (info->has_focus)
- {
- min_x = rtl_cell_area.x + x_offset;
- max_x = min_x + min_size.width;
- min_y = rtl_cell_area.y + y_offset;
- max_y = min_y + min_size.height;
- }
- }
- else
- {
- if (min_x > (rtl_cell_area.x + x_offset))
- min_x = rtl_cell_area.x + x_offset;
- if (max_x < rtl_cell_area.x + x_offset + min_size.width)
- max_x = rtl_cell_area.x + x_offset + min_size.width;
- if (min_y > (rtl_cell_area.y + y_offset))
- min_y = rtl_cell_area.y + y_offset;
- if (max_y < rtl_cell_area.y + y_offset + min_size.height)
- max_y = rtl_cell_area.y + y_offset + min_size.height;
- }
- }
- /* EVENT */
- 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 (rtl_cell_area.x <= ((GdkEventButton *)event)->x &&
- rtl_cell_area.x + rtl_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 (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,
- &rtl_background_area,
- &rtl_cell_area,
- flags))
- {
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
- 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,
- &rtl_background_area,
- &rtl_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);
-
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
-
- return TRUE;
- }
- }
- }
- }
-
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
-
- real_cell_area.x += (real_cell_area.width + 2 * focus_line_width + tree_column->spacing);
- real_background_area.x += real_background_area.width + tree_column->spacing;
-
- /* Only needed for first cell */
- depth = 0;
- }
-
- /* iterate list for PACK_END cells */
- for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
- {
- GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
-
- if (info->pack == GTK_PACK_START)
- continue;
-
- if (!gtk_cell_renderer_get_visible(info->cell))
- continue;
-
- if ((info->has_focus || special_cells == 1) && cursor_row)
- flags |= GTK_CELL_RENDERER_FOCUSED;
- else
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
-
- info->real_width = info->requested_width + (info->expand?extra_space:0);
-
- /* We constrain ourselves to only the width available */
- if (real_cell_area.x - focus_line_width + info->real_width > cell_area->x + cell_area->width)
- {
- info->real_width = cell_area->x + cell_area->width - real_cell_area.x;
- }
-
- if (real_cell_area.x > cell_area->x + cell_area->width)
- break;
-
- real_cell_area.width = info->real_width;
- real_cell_area.width -= 2 * focus_line_width;
- real_background_area.width = info->real_width + depth;
-
- rtl_cell_area = real_cell_area;
- rtl_background_area = real_background_area;
- if (rtl)
- {
- rtl_cell_area.x = cell_area->x + cell_area->width - (real_cell_area.x - cell_area->x) - real_cell_area.width;
- rtl_background_area.x = background_area->x + background_area->width - (real_background_area.x - background_area->x) - real_background_area.width;
- }
-
- /* RENDER */
- if (action == CELL_ACTION_RENDER)
- {
- gtk_cell_renderer_render_cairo (info->cell,
- cr,
- tree_column->tree_view,
- &rtl_background_area,
- &rtl_cell_area,
- flags);
- }
- /* FOCUS */
- else if (action == CELL_ACTION_FOCUS)
- {
- gint x_offset, y_offset;
- GtkRequisition min_size;
-
- gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
- tree_column->tree_view,
- &min_size, NULL);
-
- _gtk_cell_renderer_calc_offset (info->cell, &rtl_cell_area,
- gtk_widget_get_direction (tree_column->tree_view),
- min_size.width, min_size.height,
- &x_offset, &y_offset);
-
- if (special_cells > 1)
- {
- if (info->has_focus)
- {
- min_x = rtl_cell_area.x + x_offset;
- max_x = min_x + min_size.width;
- min_y = rtl_cell_area.y + y_offset;
- max_y = min_y + min_size.height;
- }
- }
- else
- {
- if (min_x > (rtl_cell_area.x + x_offset))
- min_x = rtl_cell_area.x + x_offset;
- if (max_x < rtl_cell_area.x + x_offset + min_size.width)
- max_x = rtl_cell_area.x + x_offset + min_size.width;
- if (min_y > (rtl_cell_area.y + y_offset))
- min_y = rtl_cell_area.y + y_offset;
- if (max_y < rtl_cell_area.y + y_offset + min_size.height)
- max_y = rtl_cell_area.y + y_offset + min_size.height;
- }
- }
- /* EVENT */
- 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 (rtl_cell_area.x <= ((GdkEventButton *)event)->x &&
- rtl_cell_area.x + rtl_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 (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,
- &rtl_background_area,
- &rtl_cell_area,
- flags))
- {
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
- 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,
- &rtl_background_area,
- &rtl_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);
-
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
- return TRUE;
- }
- }
- }
- }
-
- flags &= ~GTK_CELL_RENDERER_FOCUSED;
-
- real_cell_area.x += (real_cell_area.width + 2 * focus_line_width + tree_column->spacing);
- real_background_area.x += (real_background_area.width + tree_column->spacing);
-
- /* Only needed for first cell */
- depth = 0;
- }
-
- /* fill focus_rectangle when required */
- if (action == CELL_ACTION_FOCUS)
- {
- if (min_x >= max_x || min_y >= max_y)
- {
- *focus_rectangle = *cell_area;
- /* don't change the focus_rectangle, just draw it nicely inside
- * the cell area */
- }
- else
- {
- focus_rectangle->x = min_x - focus_line_width;
- focus_rectangle->y = min_y - focus_line_width;
- focus_rectangle->width = (max_x - min_x) + 2 * focus_line_width;
- focus_rectangle->height = (max_y - min_y) + 2 * focus_line_width;
- }
- }
-
- return FALSE;
-}
-
-/**
- * gtk_tree_view_column_cell_render:
- * @tree_column: A #GtkTreeViewColumn.
- * @cr: cairo context to draw to
- * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
- * @cell_area: area normally rendered by a cell renderer
- * @flags: flags that affect rendering
- *
- * Renders the cell contained by #tree_column. This is used primarily by the
- * #GtkTreeView.
- **/
-void
-_gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
- cairo_t *cr,
- const GdkRectangle *background_area,
- const GdkRectangle *cell_area,
- guint flags)
-{
- g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
- g_return_if_fail (cr != NULL);
- g_return_if_fail (background_area != NULL);
- g_return_if_fail (cell_area != NULL);
-
- cairo_save (cr);
-
- gtk_tree_view_column_cell_process_action (tree_column,
- cr,
- background_area,
- cell_area,
- flags,
- CELL_ACTION_RENDER,
- NULL, NULL, NULL, NULL);
-
- cairo_restore (cr);
-}
-
-gboolean
-_gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
- GtkCellEditable **editable_widget,
- GdkEvent *event,
- gchar *path_string,
- const GdkRectangle *background_area,
- const GdkRectangle *cell_area,
- guint flags)
-{
- g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
-
- return gtk_tree_view_column_cell_process_action (tree_column,
- NULL,
- background_area,
- cell_area,
- flags,
- CELL_ACTION_EVENT,
- NULL,
- editable_widget,
- event,
- path_string);
-}
-
-void
-_gtk_tree_view_column_get_focus_area (GtkTreeViewColumn *tree_column,
- const GdkRectangle *background_area,
- const GdkRectangle *cell_area,
- GdkRectangle *focus_area)
-{
- gtk_tree_view_column_cell_process_action (tree_column,
- NULL,
- background_area,
- cell_area,
- 0,
- CELL_ACTION_FOCUS,
- focus_area,
- NULL, NULL, NULL);
-}
-
-
-/* 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,
- gboolean left,
- gboolean right)
-{
- gint count;
- gboolean rtl;
-
- count = _gtk_tree_view_column_count_special_cells (tree_column);
- rtl = gtk_widget_get_direction (GTK_WIDGET (tree_column->tree_view)) == GTK_TEXT_DIR_RTL;
-
- /* 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)
- {
- 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;
-
- if (rtl)
- {
- prev = gtk_tree_view_column_cell_next (tree_column, list);
- next = gtk_tree_view_column_cell_prev (tree_column, list);
- }
- else
- {
- 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 last cell */
- if (rtl)
- info = gtk_tree_view_column_cell_first (tree_column)->data;
- else
- 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 */
- if (rtl)
- info = gtk_tree_view_column_cell_last (tree_column)->data;
- else
- 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;
- }
-
- list = NULL;
- if (rtl)
- {
- if (direction > 0)
- list = gtk_tree_view_column_cell_last (tree_column);
- else if (direction < 0)
- list = gtk_tree_view_column_cell_first (tree_column);
- }
- else
- {
- if (direction > 0)
- list = gtk_tree_view_column_cell_first (tree_column);
- else if (direction < 0)
- list = gtk_tree_view_column_cell_last (tree_column);
- }
-
- if (list)
- ((GtkTreeViewColumnCellInfo *) list->data)->has_focus = TRUE;
- }
-
- return TRUE;
-}
-
-void
-_gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column,
- cairo_t *cr,
- const GdkRectangle *background_area,
- const GdkRectangle *cell_area,
- guint flags)
-{
- gint focus_line_width;
- GtkStateType cell_state;
-
- g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
- g_return_if_fail (cr != NULL);
-
- gtk_widget_style_get (GTK_WIDGET (tree_column->tree_view),
- "focus-line-width", &focus_line_width, NULL);
- if (tree_column->editable_widget)
- {
- /* This function is only called on the editable row when editing.
- */
-#if 0
- gtk_paint_focus (tree_column->tree_view->style,
- window,
- gtk_widget_get_state (tree_column->tree_view),
- NULL,
- tree_column->tree_view,
- "treeview",
- cell_area->x - focus_line_width,
- cell_area->y - focus_line_width,
- cell_area->width + 2 * focus_line_width,
- cell_area->height + 2 * focus_line_width);
-#endif
- }
- else
- {
- GdkRectangle focus_rectangle;
- gtk_tree_view_column_cell_process_action (tree_column,
- cr,
- background_area,
- cell_area,
- flags,
- CELL_ACTION_FOCUS,
- &focus_rectangle,
- NULL, NULL, NULL);
-
- cell_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));
- gtk_paint_focus (gtk_widget_get_style (tree_column->tree_view),
- cr,
- cell_state,
- tree_column->tree_view,
- "treeview",
- focus_rectangle.x,
- focus_rectangle.y,
- focus_rectangle.width,
- focus_rectangle.height);
- }
-}
-
-/**
- * gtk_tree_view_column_cell_is_visible:
- * @tree_column: A #GtkTreeViewColumn
- *
- * Returns %TRUE if any of the cells packed into the @tree_column are visible.
- * For this to be meaningful, you must first initialize the cells with
- * gtk_tree_view_column_cell_set_cell_data()
- *
- * Return value: %TRUE, if any of the cells packed into the @tree_column are currently visible
- **/
-gboolean
-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;
-
- if (gtk_cell_renderer_get_visible (info->cell))
- return TRUE;
- }
-
- return FALSE;
-}