forked from AuroraMiddleware/gtk
Added gtk_cell_renderer_get_aligned_area() and class vfunc.
Since a cell renderer might use more space than the natural size when recieving expand space it's impossible to know how much space is actually used to render content. Adding this virtual method to allow text renderers to implement it, the base default method uses height-for-width apis and aligns the cell assuming the renderer uses a fixed size. This commit removes the similar code from gtkcellarea and subclasses.
This commit is contained in:
parent
5f7787ab2e
commit
2dd2c7ce05
@ -2575,7 +2575,7 @@ gtk_cell_area_activate_cell (GtkCellArea *area,
|
|||||||
gtk_cell_area_set_edited_cell (area, renderer);
|
gtk_cell_area_set_edited_cell (area, renderer);
|
||||||
gtk_cell_area_set_edit_widget (area, editable_widget);
|
gtk_cell_area_set_edit_widget (area, editable_widget);
|
||||||
|
|
||||||
gtk_cell_area_aligned_cell_area (area, widget, renderer, &inner_area, &edit_area);
|
gtk_cell_renderer_get_aligned_area (renderer, widget, flags, &inner_area, &edit_area);
|
||||||
|
|
||||||
/* Signal that editing started so that callers can get
|
/* Signal that editing started so that callers can get
|
||||||
* a handle on the editable_widget */
|
* a handle on the editable_widget */
|
||||||
@ -2672,55 +2672,6 @@ gtk_cell_area_inner_cell_area (GtkCellArea *area,
|
|||||||
inner_area->height -= focus_line_width * 2;
|
inner_area->height -= focus_line_width * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
gtk_cell_area_aligned_cell_area (GtkCellArea *area,
|
|
||||||
GtkWidget *widget,
|
|
||||||
GtkCellRenderer *renderer,
|
|
||||||
const GdkRectangle *cell_area,
|
|
||||||
GdkRectangle *aligned_area)
|
|
||||||
{
|
|
||||||
GtkCellAreaPrivate *priv;
|
|
||||||
gint opposite_size, x_offset, y_offset;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
|
||||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
|
||||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
||||||
g_return_if_fail (cell_area != NULL);
|
|
||||||
g_return_if_fail (aligned_area != NULL);
|
|
||||||
|
|
||||||
priv = area->priv;
|
|
||||||
|
|
||||||
*aligned_area = *cell_area;
|
|
||||||
|
|
||||||
/* Trim up the aligned size */
|
|
||||||
if (gtk_cell_renderer_get_request_mode (renderer) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
|
||||||
{
|
|
||||||
gtk_cell_renderer_get_preferred_height_for_width (renderer, widget,
|
|
||||||
aligned_area->width,
|
|
||||||
NULL, &opposite_size);
|
|
||||||
|
|
||||||
aligned_area->height = MIN (opposite_size, aligned_area->height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gtk_cell_renderer_get_preferred_width_for_height (renderer, widget,
|
|
||||||
aligned_area->height,
|
|
||||||
NULL, &opposite_size);
|
|
||||||
|
|
||||||
aligned_area->width = MIN (opposite_size, aligned_area->width);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* offset the cell position */
|
|
||||||
_gtk_cell_renderer_calc_offset (renderer, cell_area,
|
|
||||||
gtk_widget_get_direction (widget),
|
|
||||||
aligned_area->width,
|
|
||||||
aligned_area->height,
|
|
||||||
&x_offset, &y_offset);
|
|
||||||
|
|
||||||
aligned_area->x += x_offset;
|
|
||||||
aligned_area->y += y_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gtk_cell_area_request_renderer (GtkCellArea *area,
|
gtk_cell_area_request_renderer (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
|
@ -333,14 +333,6 @@ void gtk_cell_area_inner_cell_area (GtkCellArea
|
|||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GdkRectangle *inner_area);
|
GdkRectangle *inner_area);
|
||||||
|
|
||||||
/* Aligns a cell renderer into cell_area by requesting it's size ... used for focus and cell edit areas */
|
|
||||||
void gtk_cell_area_aligned_cell_area (GtkCellArea *area,
|
|
||||||
GtkWidget *widget,
|
|
||||||
GtkCellRenderer *renderer,
|
|
||||||
const GdkRectangle *cell_area,
|
|
||||||
GdkRectangle *aligned_area);
|
|
||||||
|
|
||||||
|
|
||||||
/* Request the size of a cell while respecting the cell margins (requests are margin inclusive) */
|
/* Request the size of a cell while respecting the cell margins (requests are margin inclusive) */
|
||||||
void gtk_cell_area_request_renderer (GtkCellArea *area,
|
void gtk_cell_area_request_renderer (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
|
@ -1094,7 +1094,7 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
{
|
{
|
||||||
GdkRectangle cell_focus;
|
GdkRectangle cell_focus;
|
||||||
|
|
||||||
gtk_cell_area_aligned_cell_area (area, widget, cell->renderer, &inner_area, &cell_focus);
|
gtk_cell_renderer_get_aligned_area (cell->renderer, widget, flags, &inner_area, &cell_focus);
|
||||||
|
|
||||||
/* Accumulate the focus rectangle for all focus siblings */
|
/* Accumulate the focus rectangle for all focus siblings */
|
||||||
if (first_focus_cell)
|
if (first_focus_cell)
|
||||||
|
@ -97,7 +97,11 @@ static void gtk_cell_renderer_real_get_preferred_width_for_height(GtkCellRendere
|
|||||||
gint height,
|
gint height,
|
||||||
gint *minimum_width,
|
gint *minimum_width,
|
||||||
gint *natural_width);
|
gint *natural_width);
|
||||||
|
static void gtk_cell_renderer_real_get_aligned_area (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area);
|
||||||
|
|
||||||
|
|
||||||
struct _GtkCellRendererPrivate
|
struct _GtkCellRendererPrivate
|
||||||
@ -192,6 +196,7 @@ gtk_cell_renderer_class_init (GtkCellRendererClass *class)
|
|||||||
class->get_preferred_height = gtk_cell_renderer_real_get_preferred_height;
|
class->get_preferred_height = gtk_cell_renderer_real_get_preferred_height;
|
||||||
class->get_preferred_width_for_height = gtk_cell_renderer_real_get_preferred_width_for_height;
|
class->get_preferred_width_for_height = gtk_cell_renderer_real_get_preferred_width_for_height;
|
||||||
class->get_preferred_height_for_width = gtk_cell_renderer_real_get_preferred_height_for_width;
|
class->get_preferred_height_for_width = gtk_cell_renderer_real_get_preferred_height_for_width;
|
||||||
|
class->get_aligned_area = gtk_cell_renderer_real_get_aligned_area;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkCellRenderer::editing-canceled:
|
* GtkCellRenderer::editing-canceled:
|
||||||
@ -1236,6 +1241,67 @@ gtk_cell_renderer_real_get_preferred_width_for_height (GtkCellRenderer *cell,
|
|||||||
gtk_cell_renderer_get_preferred_width (cell, widget, minimum_width, natural_width);
|
gtk_cell_renderer_get_preferred_width (cell, widget, minimum_width, natural_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Default implementation assumes that a cell renderer will never use more
|
||||||
|
* space than it's natural size (this is fine for toggles and pixbufs etc
|
||||||
|
* but needs to be overridden from wrapping/ellipsizing text renderers) */
|
||||||
|
static void
|
||||||
|
gtk_cell_renderer_real_get_aligned_area (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area)
|
||||||
|
{
|
||||||
|
gint opposite_size, x_offset, y_offset;
|
||||||
|
gint natural_size;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||||
|
g_return_if_fail (cell_area != NULL);
|
||||||
|
g_return_if_fail (aligned_area != NULL);
|
||||||
|
|
||||||
|
*aligned_area = *cell_area;
|
||||||
|
|
||||||
|
/* Trim up the aligned size */
|
||||||
|
if (gtk_cell_renderer_get_request_mode (cell) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||||
|
{
|
||||||
|
gtk_cell_renderer_get_preferred_width (cell, widget,
|
||||||
|
NULL, &natural_size);
|
||||||
|
|
||||||
|
aligned_area->width = MIN (aligned_area->width, natural_size);
|
||||||
|
|
||||||
|
gtk_cell_renderer_get_preferred_height_for_width (cell, widget,
|
||||||
|
aligned_area->width,
|
||||||
|
NULL, &opposite_size);
|
||||||
|
|
||||||
|
aligned_area->height = MIN (opposite_size, aligned_area->height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_cell_renderer_get_preferred_height (cell, widget,
|
||||||
|
NULL, &natural_size);
|
||||||
|
|
||||||
|
aligned_area->height = MIN (aligned_area->width, natural_size);
|
||||||
|
|
||||||
|
gtk_cell_renderer_get_preferred_width_for_height (cell, widget,
|
||||||
|
aligned_area->height,
|
||||||
|
NULL, &opposite_size);
|
||||||
|
|
||||||
|
aligned_area->width = MIN (opposite_size, aligned_area->width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offset the cell position */
|
||||||
|
_gtk_cell_renderer_calc_offset (cell, cell_area,
|
||||||
|
gtk_widget_get_direction (widget),
|
||||||
|
aligned_area->width,
|
||||||
|
aligned_area->height,
|
||||||
|
&x_offset, &y_offset);
|
||||||
|
|
||||||
|
aligned_area->x += x_offset;
|
||||||
|
aligned_area->y += y_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* An internal convenience function for some containers to peek at the
|
/* An internal convenience function for some containers to peek at the
|
||||||
* cell alignment in a target allocation (used to draw focus and align
|
* cell alignment in a target allocation (used to draw focus and align
|
||||||
* cells in the icon view).
|
* cells in the icon view).
|
||||||
@ -1561,3 +1627,35 @@ gtk_cell_renderer_get_preferred_size (GtkCellRenderer *cell,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_cell_renderer_get_aligned_area:
|
||||||
|
* @cell: a #GtkCellRenderer instance
|
||||||
|
* @widget: the #GtkWidget this cell will be rendering to
|
||||||
|
* @flags: render flags
|
||||||
|
* @cell_area: cell area which would be passed to gtk_cell_renderer_render()
|
||||||
|
* @aligned_area: the return location for the space inside @cell_area that
|
||||||
|
* would acually be used to render.
|
||||||
|
*
|
||||||
|
* Gets the aligned area used by @cell inside @cell_area. Used for finding
|
||||||
|
* the appropriate edit and focus rectangle.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gtk_cell_renderer_get_aligned_area (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area)
|
||||||
|
{
|
||||||
|
GtkCellRendererClass *klass;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||||
|
g_return_if_fail (cell_area != NULL);
|
||||||
|
g_return_if_fail (aligned_area != NULL);
|
||||||
|
|
||||||
|
klass = GTK_CELL_RENDERER_GET_CLASS (cell);
|
||||||
|
klass->get_aligned_area (cell, widget, flags, cell_area, aligned_area);
|
||||||
|
}
|
||||||
|
@ -111,6 +111,11 @@ struct _GtkCellRendererClass
|
|||||||
gint height,
|
gint height,
|
||||||
gint *minimum_width,
|
gint *minimum_width,
|
||||||
gint *natural_width);
|
gint *natural_width);
|
||||||
|
void (* get_aligned_area) (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area);
|
||||||
void (* get_size) (GtkCellRenderer *cell,
|
void (* get_size) (GtkCellRenderer *cell,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
@ -177,6 +182,12 @@ void gtk_cell_renderer_get_preferred_size (GtkCellRend
|
|||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
GtkRequisition *minimum_size,
|
GtkRequisition *minimum_size,
|
||||||
GtkRequisition *natural_size);
|
GtkRequisition *natural_size);
|
||||||
|
void gtk_cell_renderer_get_aligned_area (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area);
|
||||||
|
|
||||||
#ifndef GTK_DISABLE_DEPRECATED
|
#ifndef GTK_DISABLE_DEPRECATED
|
||||||
void gtk_cell_renderer_get_size (GtkCellRenderer *cell,
|
void gtk_cell_renderer_get_size (GtkCellRenderer *cell,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
|
@ -84,6 +84,13 @@ static void gtk_cell_renderer_text_get_preferred_height_for_width (GtkCell
|
|||||||
gint width,
|
gint width,
|
||||||
gint *minimum_height,
|
gint *minimum_height,
|
||||||
gint *natural_height);
|
gint *natural_height);
|
||||||
|
static void gtk_cell_renderer_text_get_aligned_area (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EDITED,
|
EDITED,
|
||||||
@ -240,6 +247,7 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
|
|||||||
cell_class->get_preferred_width = gtk_cell_renderer_text_get_preferred_width;
|
cell_class->get_preferred_width = gtk_cell_renderer_text_get_preferred_width;
|
||||||
cell_class->get_preferred_height = gtk_cell_renderer_text_get_preferred_height;
|
cell_class->get_preferred_height = gtk_cell_renderer_text_get_preferred_height;
|
||||||
cell_class->get_preferred_height_for_width = gtk_cell_renderer_text_get_preferred_height_for_width;
|
cell_class->get_preferred_height_for_width = gtk_cell_renderer_text_get_preferred_height_for_width;
|
||||||
|
cell_class->get_aligned_area = gtk_cell_renderer_text_get_aligned_area;
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_TEXT,
|
PROP_TEXT,
|
||||||
@ -1731,30 +1739,8 @@ get_size (GtkCellRenderer *cell,
|
|||||||
if (height)
|
if (height)
|
||||||
*height = ypad * 2 + rect.height;
|
*height = ypad * 2 + rect.height;
|
||||||
|
|
||||||
/* The minimum size for ellipsized labels is ~ 3 chars */
|
|
||||||
if (width)
|
if (width)
|
||||||
{
|
*width = xpad * 2 + rect.x + rect.width;
|
||||||
if (priv->ellipsize || priv->width_chars > 0)
|
|
||||||
{
|
|
||||||
PangoContext *context;
|
|
||||||
PangoFontMetrics *metrics;
|
|
||||||
gint char_width;
|
|
||||||
|
|
||||||
context = pango_layout_get_context (layout);
|
|
||||||
metrics = pango_context_get_metrics (context,
|
|
||||||
gtk_widget_get_style (widget)->font_desc,
|
|
||||||
pango_context_get_language (context));
|
|
||||||
|
|
||||||
char_width = pango_font_metrics_get_approximate_char_width (metrics);
|
|
||||||
pango_font_metrics_unref (metrics);
|
|
||||||
|
|
||||||
*width = xpad * 2 + (PANGO_PIXELS (char_width) * MAX (priv->width_chars, 3));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*width = xpad * 2 + rect.x + rect.width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell_area)
|
if (cell_area)
|
||||||
{
|
{
|
||||||
@ -2250,3 +2236,24 @@ gtk_cell_renderer_text_get_preferred_height (GtkCellRenderer *cell,
|
|||||||
minimum_size, natural_size);
|
minimum_size, natural_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_cell_renderer_text_get_aligned_area (GtkCellRenderer *cell,
|
||||||
|
GtkWidget *widget,
|
||||||
|
GtkCellRendererState flags,
|
||||||
|
const GdkRectangle *cell_area,
|
||||||
|
GdkRectangle *aligned_area)
|
||||||
|
{
|
||||||
|
GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
|
||||||
|
PangoLayout *layout;
|
||||||
|
gint x_offset = 0;
|
||||||
|
gint y_offset = 0;
|
||||||
|
|
||||||
|
layout = get_layout (celltext, widget, cell_area, flags);
|
||||||
|
get_size (cell, widget, cell_area, layout, &x_offset, &y_offset,
|
||||||
|
&aligned_area->width, &aligned_area->height);
|
||||||
|
|
||||||
|
aligned_area->x = cell_area->x + x_offset;
|
||||||
|
aligned_area->y = cell_area->y + y_offset;
|
||||||
|
|
||||||
|
g_object_unref (layout);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user