mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-06 16:50:11 +00:00
Added 'background_area' calculation to GtkCellAreaClass->foreach_alloc vfunc
This allows us to reduce code allocation code paths in subclasses, as a result GtkCellArea implements the ->render() vfunc and the subclass only decides the cell area and background area distributions in a single code path.
This commit is contained in:
parent
a47a557fc3
commit
34f4b5c190
@ -317,7 +317,7 @@
|
|||||||
* The #GtkCellArea introduces <emphasis>cell properties</emphasis> for #GtkCellRenderers in very
|
* The #GtkCellArea introduces <emphasis>cell properties</emphasis> for #GtkCellRenderers in very
|
||||||
* much the same way that #GtkContainer introduces <link linkend="child-properties">child properties</link>
|
* much the same way that #GtkContainer introduces <link linkend="child-properties">child properties</link>
|
||||||
* for #GtkWidgets. This provides some general interfaces for defining the relationship cell areas
|
* for #GtkWidgets. This provides some general interfaces for defining the relationship cell areas
|
||||||
* have with thier cells. For instance in a #GtkCellAreaBox a cell might "expand" and recieve extra
|
* have with their cells. For instance in a #GtkCellAreaBox a cell might "expand" and recieve extra
|
||||||
* space when the area is allocated more than it's full natural request, or a cell might be configured
|
* space when the area is allocated more than it's full natural request, or a cell might be configured
|
||||||
* to "align" with adjacent rows which were requested and rendered with the same #GtkCellAreaContext.
|
* to "align" with adjacent rows which were requested and rendered with the same #GtkCellAreaContext.
|
||||||
*
|
*
|
||||||
@ -371,6 +371,14 @@ static gint gtk_cell_area_real_event (GtkCellArea
|
|||||||
GdkEvent *event,
|
GdkEvent *event,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GtkCellRendererState flags);
|
GtkCellRendererState flags);
|
||||||
|
static void gtk_cell_area_real_render (GtkCellArea *area,
|
||||||
|
GtkCellAreaContext *context,
|
||||||
|
GtkWidget *widget,
|
||||||
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
gboolean paint_focus);
|
||||||
static void gtk_cell_area_real_apply_attributes (GtkCellArea *area,
|
static void gtk_cell_area_real_apply_attributes (GtkCellArea *area,
|
||||||
GtkTreeModel *tree_model,
|
GtkTreeModel *tree_model,
|
||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
@ -430,6 +438,18 @@ typedef struct {
|
|||||||
GdkRectangle allocation;
|
GdkRectangle allocation;
|
||||||
} RendererAllocationData;
|
} RendererAllocationData;
|
||||||
|
|
||||||
|
/* Used in foreach loop to render cells */
|
||||||
|
typedef struct {
|
||||||
|
GtkCellArea *area;
|
||||||
|
GtkWidget *widget;
|
||||||
|
cairo_t *cr;
|
||||||
|
GdkRectangle focus_rect;
|
||||||
|
GtkCellRendererState render_flags;
|
||||||
|
guint paint_focus : 1;
|
||||||
|
guint focus_all : 1;
|
||||||
|
guint first_focus : 1;
|
||||||
|
} CellRenderData;
|
||||||
|
|
||||||
/* Used in foreach loop to get a cell by position */
|
/* Used in foreach loop to get a cell by position */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gint x;
|
gint x;
|
||||||
@ -587,7 +607,7 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
|
|||||||
class->remove = NULL;
|
class->remove = NULL;
|
||||||
class->foreach = NULL;
|
class->foreach = NULL;
|
||||||
class->event = gtk_cell_area_real_event;
|
class->event = gtk_cell_area_real_event;
|
||||||
class->render = NULL;
|
class->render = gtk_cell_area_real_render;
|
||||||
class->apply_attributes = gtk_cell_area_real_apply_attributes;
|
class->apply_attributes = gtk_cell_area_real_apply_attributes;
|
||||||
|
|
||||||
/* geometry */
|
/* geometry */
|
||||||
@ -1005,6 +1025,103 @@ gtk_cell_area_real_event (GtkCellArea *area,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
render_cell (GtkCellRenderer *renderer,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *cell_background,
|
||||||
|
CellRenderData *data)
|
||||||
|
{
|
||||||
|
GtkCellRenderer *focus_cell;
|
||||||
|
GtkCellRendererState flags;
|
||||||
|
GdkRectangle inner_area;
|
||||||
|
|
||||||
|
focus_cell = gtk_cell_area_get_focus_cell (data->area);
|
||||||
|
flags = data->render_flags;
|
||||||
|
|
||||||
|
gtk_cell_area_inner_cell_area (data->area, data->widget, cell_area, &inner_area);
|
||||||
|
|
||||||
|
if ((flags & GTK_CELL_RENDERER_FOCUSED) &&
|
||||||
|
(data->focus_all ||
|
||||||
|
(focus_cell &&
|
||||||
|
(renderer == focus_cell ||
|
||||||
|
gtk_cell_area_is_focus_sibling (data->area, focus_cell, renderer)))))
|
||||||
|
{
|
||||||
|
GdkRectangle cell_focus;
|
||||||
|
|
||||||
|
gtk_cell_renderer_get_aligned_area (renderer, data->widget, flags, &inner_area, &cell_focus);
|
||||||
|
|
||||||
|
if (data->first_focus)
|
||||||
|
{
|
||||||
|
data->first_focus = FALSE;
|
||||||
|
data->focus_rect = cell_focus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gdk_rectangle_union (&data->focus_rect, &cell_focus, &data->focus_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
flags &= ~GTK_CELL_RENDERER_FOCUSED;
|
||||||
|
|
||||||
|
gtk_cell_renderer_render (renderer, data->cr, data->widget,
|
||||||
|
cell_background, &inner_area, flags);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_cell_area_real_render (GtkCellArea *area,
|
||||||
|
GtkCellAreaContext *context,
|
||||||
|
GtkWidget *widget,
|
||||||
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
gboolean paint_focus)
|
||||||
|
{
|
||||||
|
CellRenderData render_data =
|
||||||
|
{
|
||||||
|
area,
|
||||||
|
widget,
|
||||||
|
cr,
|
||||||
|
{ 0, },
|
||||||
|
flags,
|
||||||
|
paint_focus,
|
||||||
|
FALSE, TRUE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Make sure we dont paint a focus rectangle while there
|
||||||
|
* is an editable widget in play
|
||||||
|
*/
|
||||||
|
if (gtk_cell_area_get_edited_cell (area))
|
||||||
|
render_data.paint_focus = FALSE;
|
||||||
|
|
||||||
|
/* If no cell can activate but the caller wants focus painted,
|
||||||
|
* then we paint focus around all cells */
|
||||||
|
if ((flags & GTK_CELL_RENDERER_FOCUSED) != 0 && paint_focus &&
|
||||||
|
!gtk_cell_area_is_activatable (area))
|
||||||
|
render_data.focus_all = TRUE;
|
||||||
|
|
||||||
|
gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area,
|
||||||
|
(GtkCellAllocCallback)render_cell, &render_data);
|
||||||
|
|
||||||
|
if (render_data.paint_focus &&
|
||||||
|
render_data.focus_rect.width != 0 &&
|
||||||
|
render_data.focus_rect.height != 0)
|
||||||
|
{
|
||||||
|
GtkStateType renderer_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 (widget), cr,
|
||||||
|
renderer_state, widget,
|
||||||
|
gtk_cell_area_get_style_detail (area),
|
||||||
|
render_data.focus_rect.x, render_data.focus_rect.y,
|
||||||
|
render_data.focus_rect.width, render_data.focus_rect.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_cell_attributes (GtkCellRenderer *renderer,
|
apply_cell_attributes (GtkCellRenderer *renderer,
|
||||||
CellInfo *info,
|
CellInfo *info,
|
||||||
@ -1476,6 +1593,7 @@ gtk_cell_area_foreach (GtkCellArea *area,
|
|||||||
* @context: the #GtkCellAreaContext for this row of data.
|
* @context: the #GtkCellAreaContext for this row of data.
|
||||||
* @widget: the #GtkWidget that @area is rendering to
|
* @widget: the #GtkWidget that @area is rendering to
|
||||||
* @cell_area: the @widget relative coordinates and size for @area
|
* @cell_area: the @widget relative coordinates and size for @area
|
||||||
|
* @background_area: the @widget relative coordinates of the background area
|
||||||
* @callback: the #GtkCellAllocCallback to call
|
* @callback: the #GtkCellAllocCallback to call
|
||||||
* @callback_data: user provided data pointer
|
* @callback_data: user provided data pointer
|
||||||
*
|
*
|
||||||
@ -1489,6 +1607,7 @@ gtk_cell_area_foreach_alloc (GtkCellArea *area,
|
|||||||
GtkCellAreaContext *context,
|
GtkCellAreaContext *context,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
GtkCellAllocCallback callback,
|
GtkCellAllocCallback callback,
|
||||||
gpointer callback_data)
|
gpointer callback_data)
|
||||||
{
|
{
|
||||||
@ -1503,7 +1622,7 @@ gtk_cell_area_foreach_alloc (GtkCellArea *area,
|
|||||||
class = GTK_CELL_AREA_GET_CLASS (area);
|
class = GTK_CELL_AREA_GET_CLASS (area);
|
||||||
|
|
||||||
if (class->foreach_alloc)
|
if (class->foreach_alloc)
|
||||||
class->foreach_alloc (area, context, widget, cell_area, callback, callback_data);
|
class->foreach_alloc (area, context, widget, cell_area, background_area, callback, callback_data);
|
||||||
else
|
else
|
||||||
g_warning ("GtkCellAreaClass::foreach_alloc not implemented for `%s'",
|
g_warning ("GtkCellAreaClass::foreach_alloc not implemented for `%s'",
|
||||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||||
@ -1647,6 +1766,7 @@ gtk_cell_area_get_style_detail (GtkCellArea *area)
|
|||||||
static gboolean
|
static gboolean
|
||||||
get_cell_allocation (GtkCellRenderer *renderer,
|
get_cell_allocation (GtkCellRenderer *renderer,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *cell_background,
|
||||||
RendererAllocationData *data)
|
RendererAllocationData *data)
|
||||||
{
|
{
|
||||||
if (data->renderer == renderer)
|
if (data->renderer == renderer)
|
||||||
@ -1687,7 +1807,7 @@ gtk_cell_area_get_cell_allocation (GtkCellArea *area,
|
|||||||
g_return_if_fail (cell_area != NULL);
|
g_return_if_fail (cell_area != NULL);
|
||||||
g_return_if_fail (allocation != NULL);
|
g_return_if_fail (allocation != NULL);
|
||||||
|
|
||||||
gtk_cell_area_foreach_alloc (area, context, widget, cell_area,
|
gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area,
|
||||||
(GtkCellAllocCallback)get_cell_allocation, &data);
|
(GtkCellAllocCallback)get_cell_allocation, &data);
|
||||||
|
|
||||||
*allocation = data.allocation;
|
*allocation = data.allocation;
|
||||||
@ -1696,6 +1816,7 @@ gtk_cell_area_get_cell_allocation (GtkCellArea *area,
|
|||||||
static gboolean
|
static gboolean
|
||||||
get_cell_by_position (GtkCellRenderer *renderer,
|
get_cell_by_position (GtkCellRenderer *renderer,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *cell_background,
|
||||||
CellByPositionData *data)
|
CellByPositionData *data)
|
||||||
{
|
{
|
||||||
if (data->x >= cell_area->x && data->x < cell_area->x + cell_area->width &&
|
if (data->x >= cell_area->x && data->x < cell_area->x + cell_area->width &&
|
||||||
@ -1723,7 +1844,7 @@ get_cell_by_position (GtkCellRenderer *renderer,
|
|||||||
* Gets the #GtkCellRenderer at @x and @y coordinates inside @area and optionally
|
* Gets the #GtkCellRenderer at @x and @y coordinates inside @area and optionally
|
||||||
* returns the full cell allocation for it inside @cell_area.
|
* returns the full cell allocation for it inside @cell_area.
|
||||||
*
|
*
|
||||||
* Returns: the #GtkCellRenderer at @x and @y.
|
* Returns value: the #GtkCellRenderer at @x and @y.
|
||||||
*
|
*
|
||||||
* Since: 3.0
|
* Since: 3.0
|
||||||
*/
|
*/
|
||||||
@ -1745,7 +1866,7 @@ gtk_cell_area_get_cell_at_position (GtkCellArea *area,
|
|||||||
g_return_val_if_fail (x >= cell_area->x && x <= cell_area->x + cell_area->width, NULL);
|
g_return_val_if_fail (x >= cell_area->x && x <= cell_area->x + cell_area->width, NULL);
|
||||||
g_return_val_if_fail (y >= cell_area->y && y <= cell_area->y + cell_area->height, NULL);
|
g_return_val_if_fail (y >= cell_area->y && y <= cell_area->y + cell_area->height, NULL);
|
||||||
|
|
||||||
gtk_cell_area_foreach_alloc (area, context, widget, cell_area,
|
gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area,
|
||||||
(GtkCellAllocCallback)get_cell_by_position, &data);
|
(GtkCellAllocCallback)get_cell_by_position, &data);
|
||||||
|
|
||||||
if (alloc_area)
|
if (alloc_area)
|
||||||
@ -1754,7 +1875,6 @@ gtk_cell_area_get_cell_at_position (GtkCellArea *area,
|
|||||||
return data.renderer;
|
return data.renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* API: Geometry *
|
* API: Geometry *
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
@ -76,6 +76,8 @@ typedef gboolean (*GtkCellCallback) (GtkCellRenderer *renderer,
|
|||||||
* GtkCellAllocCallback:
|
* GtkCellAllocCallback:
|
||||||
* @renderer: the cell renderer to operate on
|
* @renderer: the cell renderer to operate on
|
||||||
* @cell_area: the area allocated to @renderer inside the rectangle provided to gtk_cell_area_foreach_alloc().
|
* @cell_area: the area allocated to @renderer inside the rectangle provided to gtk_cell_area_foreach_alloc().
|
||||||
|
* @cell_background: the background area for @renderer inside the background
|
||||||
|
* area provided to gtk_cell_area_foreach_alloc().
|
||||||
* @data: user-supplied data
|
* @data: user-supplied data
|
||||||
*
|
*
|
||||||
* The type of the callback functions used for iterating over
|
* The type of the callback functions used for iterating over
|
||||||
@ -86,6 +88,7 @@ typedef gboolean (*GtkCellCallback) (GtkCellRenderer *renderer,
|
|||||||
*/
|
*/
|
||||||
typedef gboolean (*GtkCellAllocCallback) (GtkCellRenderer *renderer,
|
typedef gboolean (*GtkCellAllocCallback) (GtkCellRenderer *renderer,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *cell_background,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
|
||||||
@ -174,6 +177,7 @@ struct _GtkCellAreaClass
|
|||||||
GtkCellAreaContext *context,
|
GtkCellAreaContext *context,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
GtkCellAllocCallback callback,
|
GtkCellAllocCallback callback,
|
||||||
gpointer callback_data);
|
gpointer callback_data);
|
||||||
gint (* event) (GtkCellArea *area,
|
gint (* event) (GtkCellArea *area,
|
||||||
@ -273,6 +277,7 @@ void gtk_cell_area_foreach_alloc (GtkCellArea
|
|||||||
GtkCellAreaContext *context,
|
GtkCellAreaContext *context,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
GtkCellAllocCallback callback,
|
GtkCellAllocCallback callback,
|
||||||
gpointer callback_data);
|
gpointer callback_data);
|
||||||
gint gtk_cell_area_event (GtkCellArea *area,
|
gint gtk_cell_area_event (GtkCellArea *area,
|
||||||
@ -308,7 +313,6 @@ GtkCellRenderer *gtk_cell_area_get_cell_at_position (GtkCellArea
|
|||||||
gint y,
|
gint y,
|
||||||
GdkRectangle *alloc_area);
|
GdkRectangle *alloc_area);
|
||||||
|
|
||||||
|
|
||||||
/* Geometry */
|
/* Geometry */
|
||||||
GtkCellAreaContext *gtk_cell_area_create_context (GtkCellArea *area);
|
GtkCellAreaContext *gtk_cell_area_create_context (GtkCellArea *area);
|
||||||
GtkSizeRequestMode gtk_cell_area_get_request_mode (GtkCellArea *area);
|
GtkSizeRequestMode gtk_cell_area_get_request_mode (GtkCellArea *area);
|
||||||
|
@ -78,16 +78,9 @@ static void gtk_cell_area_box_foreach_alloc (GtkCellArea
|
|||||||
GtkCellAreaContext *context,
|
GtkCellAreaContext *context,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
GtkCellAllocCallback callback,
|
GtkCellAllocCallback callback,
|
||||||
gpointer callback_data);
|
gpointer callback_data);
|
||||||
static void gtk_cell_area_box_render (GtkCellArea *area,
|
|
||||||
GtkCellAreaContext *context,
|
|
||||||
GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
const GdkRectangle *background_area,
|
|
||||||
const GdkRectangle *cell_area,
|
|
||||||
GtkCellRendererState flags,
|
|
||||||
gboolean paint_focus);
|
|
||||||
static void gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
static void gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -262,7 +255,6 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
|
|||||||
area_class->remove = gtk_cell_area_box_remove;
|
area_class->remove = gtk_cell_area_box_remove;
|
||||||
area_class->foreach = gtk_cell_area_box_foreach;
|
area_class->foreach = gtk_cell_area_box_foreach;
|
||||||
area_class->foreach_alloc = gtk_cell_area_box_foreach_alloc;
|
area_class->foreach_alloc = gtk_cell_area_box_foreach_alloc;
|
||||||
area_class->render = gtk_cell_area_box_render;
|
|
||||||
area_class->set_cell_property = gtk_cell_area_box_set_cell_property;
|
area_class->set_cell_property = gtk_cell_area_box_set_cell_property;
|
||||||
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
|
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
|
||||||
|
|
||||||
@ -1040,6 +1032,7 @@ gtk_cell_area_box_foreach_alloc (GtkCellArea *area,
|
|||||||
GtkCellAreaContext *context,
|
GtkCellAreaContext *context,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
GtkCellAllocCallback callback,
|
GtkCellAllocCallback callback,
|
||||||
gpointer callback_data)
|
gpointer callback_data)
|
||||||
{
|
{
|
||||||
@ -1047,80 +1040,13 @@ gtk_cell_area_box_foreach_alloc (GtkCellArea *area,
|
|||||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||||
GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
|
GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
|
||||||
GSList *allocated_cells, *l;
|
GSList *allocated_cells, *l;
|
||||||
GdkRectangle allocation;
|
GdkRectangle cell_alloc, cell_background;
|
||||||
|
|
||||||
allocation = *cell_area;
|
|
||||||
|
|
||||||
/* Get a list of cells with allocation sizes decided regardless
|
|
||||||
* of alignments and pack order etc. */
|
|
||||||
allocated_cells = get_allocated_cells (box, box_context, widget,
|
|
||||||
cell_area->width, cell_area->height);
|
|
||||||
|
|
||||||
for (l = allocated_cells; l; l = l->next)
|
|
||||||
{
|
|
||||||
AllocatedCell *cell = l->data;
|
|
||||||
|
|
||||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
{
|
|
||||||
allocation.x = cell_area->x + cell->position;
|
|
||||||
allocation.width = cell->size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
allocation.y = cell_area->y + cell->position;
|
|
||||||
allocation.height = cell->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback (cell->renderer, &allocation, callback_data))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL);
|
|
||||||
g_slist_free (allocated_cells);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_cell_area_box_render (GtkCellArea *area,
|
|
||||||
GtkCellAreaContext *context,
|
|
||||||
GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
const GdkRectangle *background_area,
|
|
||||||
const GdkRectangle *cell_area,
|
|
||||||
GtkCellRendererState flags,
|
|
||||||
gboolean paint_focus)
|
|
||||||
{
|
|
||||||
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
|
|
||||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
|
||||||
GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
|
|
||||||
GSList *allocated_cells, *l;
|
|
||||||
GdkRectangle cell_background, inner_area;
|
|
||||||
GtkCellRenderer *focus_cell = NULL;
|
|
||||||
GdkRectangle focus_rect = { 0, };
|
|
||||||
gboolean first_focus_cell = TRUE;
|
|
||||||
gboolean focus_all = FALSE;
|
|
||||||
gboolean rtl;
|
gboolean rtl;
|
||||||
|
|
||||||
rtl = (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
rtl = (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||||
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
||||||
|
|
||||||
/* Make sure we dont paint a focus rectangle while there
|
cell_alloc = *cell_area;
|
||||||
* is an editable widget in play
|
|
||||||
*/
|
|
||||||
if (gtk_cell_area_get_edited_cell (area))
|
|
||||||
paint_focus = FALSE;
|
|
||||||
|
|
||||||
if (flags & GTK_CELL_RENDERER_FOCUSED)
|
|
||||||
{
|
|
||||||
focus_cell = gtk_cell_area_get_focus_cell (area);
|
|
||||||
flags &= ~GTK_CELL_RENDERER_FOCUSED;
|
|
||||||
|
|
||||||
/* If no cell can activate but the caller wants focus painted,
|
|
||||||
* then we paint focus around all cells */
|
|
||||||
if (paint_focus && !gtk_cell_area_is_activatable (area))
|
|
||||||
focus_all = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell_background = *cell_area;
|
|
||||||
|
|
||||||
/* Get a list of cells with allocation sizes decided regardless
|
/* Get a list of cells with allocation sizes decided regardless
|
||||||
* of alignments and pack order etc. */
|
* of alignments and pack order etc. */
|
||||||
@ -1130,28 +1056,26 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
for (l = allocated_cells; l; l = l->next)
|
for (l = allocated_cells; l; l = l->next)
|
||||||
{
|
{
|
||||||
AllocatedCell *cell = l->data;
|
AllocatedCell *cell = l->data;
|
||||||
GtkCellRendererState cell_fields = 0;
|
|
||||||
GdkRectangle render_background;
|
|
||||||
|
|
||||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
{
|
{
|
||||||
cell_background.x = cell_area->x + cell->position;
|
cell_alloc.x = cell_area->x + cell->position;
|
||||||
cell_background.width = cell->size;
|
cell_alloc.width = cell->size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell_background.y = cell_area->y + cell->position;
|
cell_alloc.y = cell_area->y + cell->position;
|
||||||
cell_background.height = cell->size;
|
cell_alloc.height = cell->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop rendering cells if they flow out of the render area,
|
/* Stop iterating over cells if they flow out of the render area,
|
||||||
* this can happen because the render area can actually be
|
* this can happen because the render area can actually be
|
||||||
* smaller than the requested area (treeview columns can
|
* smaller than the requested area (treeview columns can
|
||||||
* be user resizable and can be resized to be smaller than
|
* be user resizable and can be resized to be smaller than
|
||||||
* the actual requested area). */
|
* the actual requested area). */
|
||||||
if (cell_background.x > cell_area->x + cell_area->width ||
|
if (cell_alloc.x > cell_area->x + cell_area->width ||
|
||||||
cell_background.x + cell_background.width < cell_area->x ||
|
cell_alloc.x + cell_alloc.width < cell_area->x ||
|
||||||
cell_background.y > cell_area->y + cell_area->height)
|
cell_alloc.y > cell_area->y + cell_area->height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Special case for the last cell (or first cell in rtl)... let the last cell consume
|
/* Special case for the last cell (or first cell in rtl)... let the last cell consume
|
||||||
@ -1164,13 +1088,13 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
if (rtl)
|
if (rtl)
|
||||||
{
|
{
|
||||||
/* Fill the leading space for the first cell in the area (still last in the list) */
|
/* Fill the leading space for the first cell in the area (still last in the list) */
|
||||||
cell_background.width = (cell_background.x - cell_area->x) + cell_background.width;
|
cell_alloc.width = (cell_alloc.x - cell_area->x) + cell_alloc.width;
|
||||||
cell_background.x = cell_area->x;
|
cell_alloc.x = cell_area->x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell_background.width = cell_area->x + cell_area->width - cell_background.x;
|
cell_alloc.width = cell_area->x + cell_area->width - cell_alloc.x;
|
||||||
cell_background.height = cell_area->y + cell_area->height - cell_background.y;
|
cell_alloc.height = cell_area->y + cell_area->height - cell_alloc.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1179,97 +1103,51 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
* so that the underlying renderer has a chance to deal with it (for instance
|
* so that the underlying renderer has a chance to deal with it (for instance
|
||||||
* text renderers get a chance to ellipsize).
|
* text renderers get a chance to ellipsize).
|
||||||
*/
|
*/
|
||||||
if (cell_background.x + cell_background.width > cell_area->x + cell_area->width)
|
if (cell_alloc.x + cell_alloc.width > cell_area->x + cell_area->width)
|
||||||
cell_background.width = cell_area->x + cell_area->width - cell_background.x;
|
cell_alloc.width = cell_area->x + cell_area->width - cell_alloc.x;
|
||||||
|
|
||||||
if (cell_background.y + cell_background.height > cell_area->y + cell_area->height)
|
if (cell_alloc.y + cell_alloc.height > cell_area->y + cell_area->height)
|
||||||
cell_background.height = cell_area->y + cell_area->height - cell_background.y;
|
cell_alloc.height = cell_area->y + cell_area->height - cell_alloc.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove margins from the background area to produce the cell area
|
/* Add portions of the background_area to the cell_alloc
|
||||||
*/
|
* to create the cell_background */
|
||||||
gtk_cell_area_inner_cell_area (area, widget, &cell_background, &inner_area);
|
cell_background = cell_alloc;
|
||||||
|
|
||||||
/* Add portions of the background_area to the cell_background
|
|
||||||
* to create the render_background */
|
|
||||||
render_background = cell_background;
|
|
||||||
|
|
||||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
{
|
{
|
||||||
if (l == allocated_cells)
|
if (l == allocated_cells)
|
||||||
{
|
{
|
||||||
render_background.width += render_background.x - background_area->x;
|
cell_background.width += cell_background.x - background_area->x;
|
||||||
render_background.x = background_area->x;
|
cell_background.x = background_area->x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l->next == NULL)
|
if (l->next == NULL)
|
||||||
render_background.width =
|
cell_background.width =
|
||||||
background_area->width - (render_background.x - background_area->x);
|
background_area->width - (cell_background.x - background_area->x);
|
||||||
|
|
||||||
render_background.y = background_area->y;
|
cell_background.y = background_area->y;
|
||||||
render_background.height = background_area->height;
|
cell_background.height = background_area->height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (l == allocated_cells)
|
if (l == allocated_cells)
|
||||||
{
|
{
|
||||||
render_background.height += render_background.y - background_area->y;
|
cell_background.height += cell_background.y - background_area->y;
|
||||||
render_background.y = background_area->y;
|
cell_background.y = background_area->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l->next == NULL)
|
if (l->next == NULL)
|
||||||
render_background.height =
|
cell_background.height =
|
||||||
background_area->height - (render_background.y - background_area->y);
|
background_area->height - (cell_background.y - background_area->y);
|
||||||
|
|
||||||
render_background.x = background_area->x;
|
cell_background.x = background_area->x;
|
||||||
render_background.width = background_area->width;
|
cell_background.width = background_area->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focus_all ||
|
if (callback (cell->renderer, &cell_alloc, &cell_background, callback_data))
|
||||||
(focus_cell &&
|
break;
|
||||||
(cell->renderer == focus_cell ||
|
|
||||||
gtk_cell_area_is_focus_sibling (area, focus_cell, cell->renderer))))
|
|
||||||
{
|
|
||||||
cell_fields |= GTK_CELL_RENDERER_FOCUSED;
|
|
||||||
|
|
||||||
if (paint_focus)
|
|
||||||
{
|
|
||||||
GdkRectangle cell_focus;
|
|
||||||
|
|
||||||
gtk_cell_renderer_get_aligned_area (cell->renderer, widget, flags, &inner_area, &cell_focus);
|
|
||||||
|
|
||||||
/* Accumulate the focus rectangle for all focus siblings */
|
|
||||||
if (first_focus_cell)
|
|
||||||
{
|
|
||||||
focus_rect = cell_focus;
|
|
||||||
first_focus_cell = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
gdk_rectangle_union (&focus_rect, &cell_focus, &focus_rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have to do some per-cell considerations for the 'flags'
|
|
||||||
* for focus handling */
|
|
||||||
gtk_cell_renderer_render (cell->renderer, cr, widget,
|
|
||||||
&render_background, &inner_area,
|
|
||||||
flags | cell_fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paint_focus && focus_rect.width != 0 && focus_rect.height != 0)
|
|
||||||
{
|
|
||||||
GtkStateType renderer_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 (widget), cr,
|
|
||||||
renderer_state, widget,
|
|
||||||
gtk_cell_area_get_style_detail (area),
|
|
||||||
focus_rect.x, focus_rect.y,
|
|
||||||
focus_rect.width, focus_rect.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL);
|
g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL);
|
||||||
g_slist_free (allocated_cells);
|
g_slist_free (allocated_cells);
|
||||||
|
Loading…
Reference in New Issue
Block a user