forked from AuroraMiddleware/gtk
GtkCellArea now paints focus on cells
Added concept of "Focus Siblings" to GtkCellArea so that some static text/icon may be included in the focus/click area of an activatable or editable cell, implemented focus drawing as well, updated testcellarea to reflect the changes.
This commit is contained in:
parent
524110f902
commit
f330b40521
@ -97,6 +97,13 @@ static void gtk_cell_area_reorder (GtkCellLayout
|
|||||||
gint position);
|
gint position);
|
||||||
static GList *gtk_cell_area_get_cells (GtkCellLayout *cell_layout);
|
static GList *gtk_cell_area_get_cells (GtkCellLayout *cell_layout);
|
||||||
|
|
||||||
|
|
||||||
|
/* Used in forall loop to check if a child renderer is present */
|
||||||
|
typedef struct {
|
||||||
|
GtkCellRenderer *renderer;
|
||||||
|
gboolean has_renderer;
|
||||||
|
} HasRendererCheck;
|
||||||
|
|
||||||
/* Attribute/Cell metadata */
|
/* Attribute/Cell metadata */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const gchar *attribute;
|
const gchar *attribute;
|
||||||
@ -154,6 +161,9 @@ struct _GtkCellAreaPrivate
|
|||||||
*/
|
*/
|
||||||
GHashTable *cell_info;
|
GHashTable *cell_info;
|
||||||
|
|
||||||
|
/* Tracking which cells are focus siblings of focusable cells */
|
||||||
|
GHashTable *focus_siblings;
|
||||||
|
|
||||||
/* The cell border decides how much space to reserve
|
/* The cell border decides how much space to reserve
|
||||||
* around each cell for the background_area
|
* around each cell for the background_area
|
||||||
*/
|
*/
|
||||||
@ -222,6 +232,11 @@ gtk_cell_area_init (GtkCellArea *area)
|
|||||||
NULL,
|
NULL,
|
||||||
(GDestroyNotify)cell_info_free);
|
(GDestroyNotify)cell_info_free);
|
||||||
|
|
||||||
|
priv->focus_siblings = g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify)g_list_free);
|
||||||
|
|
||||||
priv->cell_border.left = 0;
|
priv->cell_border.left = 0;
|
||||||
priv->cell_border.right = 0;
|
priv->cell_border.right = 0;
|
||||||
priv->cell_border.top = 0;
|
priv->cell_border.top = 0;
|
||||||
@ -470,9 +485,10 @@ gtk_cell_area_finalize (GObject *object)
|
|||||||
GtkCellAreaPrivate *priv = area->priv;
|
GtkCellAreaPrivate *priv = area->priv;
|
||||||
|
|
||||||
/* All cell renderers should already be removed at this point,
|
/* All cell renderers should already be removed at this point,
|
||||||
* just kill our hash table here.
|
* just kill our (empty) hash tables here.
|
||||||
*/
|
*/
|
||||||
g_hash_table_destroy (priv->cell_info);
|
g_hash_table_destroy (priv->cell_info);
|
||||||
|
g_hash_table_destroy (priv->focus_siblings);
|
||||||
|
|
||||||
g_free (priv->current_path);
|
g_free (priv->current_path);
|
||||||
|
|
||||||
@ -858,6 +874,7 @@ gtk_cell_area_remove (GtkCellArea *area,
|
|||||||
{
|
{
|
||||||
GtkCellAreaClass *class;
|
GtkCellAreaClass *class;
|
||||||
GtkCellAreaPrivate *priv;
|
GtkCellAreaPrivate *priv;
|
||||||
|
GList *renderers, *l;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||||
@ -868,6 +885,25 @@ gtk_cell_area_remove (GtkCellArea *area,
|
|||||||
/* Remove any custom attributes and custom cell data func here first */
|
/* Remove any custom attributes and custom cell data func here first */
|
||||||
g_hash_table_remove (priv->cell_info, renderer);
|
g_hash_table_remove (priv->cell_info, renderer);
|
||||||
|
|
||||||
|
/* Remove focus siblings of this renderer */
|
||||||
|
g_hash_table_remove (priv->focus_siblings, renderer);
|
||||||
|
|
||||||
|
/* Remove this renderer from any focus renderer's sibling list */
|
||||||
|
renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area));
|
||||||
|
|
||||||
|
for (l = renderers; l; l = l->next)
|
||||||
|
{
|
||||||
|
GtkCellRenderer *focus_renderer = l->data;
|
||||||
|
|
||||||
|
if (gtk_cell_area_is_focus_sibling (area, focus_renderer, renderer))
|
||||||
|
{
|
||||||
|
gtk_cell_area_remove_focus_sibling (area, focus_renderer, renderer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (renderers);
|
||||||
|
|
||||||
if (class->remove)
|
if (class->remove)
|
||||||
class->remove (area, renderer);
|
class->remove (area, renderer);
|
||||||
else
|
else
|
||||||
@ -875,6 +911,28 @@ gtk_cell_area_remove (GtkCellArea *area,
|
|||||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_has_renderer (GtkCellRenderer *renderer,
|
||||||
|
HasRendererCheck *check)
|
||||||
|
{
|
||||||
|
if (renderer == check->renderer)
|
||||||
|
check->has_renderer = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gtk_cell_area_has_renderer (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer)
|
||||||
|
{
|
||||||
|
HasRendererCheck check = { renderer, FALSE };
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), FALSE);
|
||||||
|
|
||||||
|
gtk_cell_area_forall (area, (GtkCellCallback)get_has_renderer, &check);
|
||||||
|
|
||||||
|
return check.has_renderer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_cell_area_forall
|
* gtk_cell_area_forall
|
||||||
* @area: a #GtkCellArea
|
* @area: a #GtkCellArea
|
||||||
@ -972,8 +1030,10 @@ gtk_cell_area_render (GtkCellArea *area,
|
|||||||
GtkCellAreaIter *iter,
|
GtkCellAreaIter *iter,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GtkCellRendererState flags)
|
GtkCellRendererState flags,
|
||||||
|
gboolean paint_focus)
|
||||||
{
|
{
|
||||||
GtkCellAreaClass *class;
|
GtkCellAreaClass *class;
|
||||||
|
|
||||||
@ -981,12 +1041,13 @@ gtk_cell_area_render (GtkCellArea *area,
|
|||||||
g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
|
g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
|
||||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||||
g_return_if_fail (cr != NULL);
|
g_return_if_fail (cr != NULL);
|
||||||
|
g_return_if_fail (background_area != NULL);
|
||||||
g_return_if_fail (cell_area != NULL);
|
g_return_if_fail (cell_area != NULL);
|
||||||
|
|
||||||
class = GTK_CELL_AREA_GET_CLASS (area);
|
class = GTK_CELL_AREA_GET_CLASS (area);
|
||||||
|
|
||||||
if (class->render)
|
if (class->render)
|
||||||
class->render (area, iter, widget, cr, cell_area, flags);
|
class->render (area, iter, widget, cr, background_area, cell_area, flags, paint_focus);
|
||||||
else
|
else
|
||||||
g_warning ("GtkCellAreaClass::render not implemented for `%s'",
|
g_warning ("GtkCellAreaClass::render not implemented for `%s'",
|
||||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||||
@ -1136,6 +1197,7 @@ gtk_cell_area_attribute_connect (GtkCellArea *area,
|
|||||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||||
g_return_if_fail (attribute != NULL);
|
g_return_if_fail (attribute != NULL);
|
||||||
|
g_return_if_fail (gtk_cell_area_has_renderer (area, renderer));
|
||||||
|
|
||||||
priv = area->priv;
|
priv = area->priv;
|
||||||
info = g_hash_table_lookup (priv->cell_info, renderer);
|
info = g_hash_table_lookup (priv->cell_info, renderer);
|
||||||
@ -1202,6 +1264,7 @@ gtk_cell_area_attribute_disconnect (GtkCellArea *area,
|
|||||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||||
g_return_if_fail (attribute != NULL);
|
g_return_if_fail (attribute != NULL);
|
||||||
|
g_return_if_fail (gtk_cell_area_has_renderer (area, renderer));
|
||||||
|
|
||||||
priv = area->priv;
|
priv = area->priv;
|
||||||
info = g_hash_table_lookup (priv->cell_info, renderer);
|
info = g_hash_table_lookup (priv->cell_info, renderer);
|
||||||
@ -1821,6 +1884,110 @@ gtk_cell_area_get_focus_cell (GtkCellArea *area)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* API: Focus Siblings *
|
||||||
|
*************************************************************/
|
||||||
|
void
|
||||||
|
gtk_cell_area_add_focus_sibling (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer,
|
||||||
|
GtkCellRenderer *sibling)
|
||||||
|
{
|
||||||
|
GtkCellAreaPrivate *priv;
|
||||||
|
GList *siblings;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||||
|
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||||
|
g_return_if_fail (GTK_IS_CELL_RENDERER (sibling));
|
||||||
|
g_return_if_fail (renderer != sibling);
|
||||||
|
g_return_if_fail (gtk_cell_area_has_renderer (area, renderer));
|
||||||
|
g_return_if_fail (gtk_cell_area_has_renderer (area, sibling));
|
||||||
|
g_return_if_fail (!gtk_cell_area_is_focus_sibling (area, renderer, sibling));
|
||||||
|
|
||||||
|
/* XXX We should also check that sibling is not in any other renderer's sibling
|
||||||
|
* list already, a renderer can be sibling of only one focusable renderer
|
||||||
|
* at a time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
priv = area->priv;
|
||||||
|
|
||||||
|
siblings = g_hash_table_lookup (priv->focus_siblings, renderer);
|
||||||
|
|
||||||
|
if (siblings)
|
||||||
|
siblings = g_list_append (siblings, sibling);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
siblings = g_list_append (siblings, sibling);
|
||||||
|
g_hash_table_insert (priv->focus_siblings, renderer, siblings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_cell_area_remove_focus_sibling (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer,
|
||||||
|
GtkCellRenderer *sibling)
|
||||||
|
{
|
||||||
|
GtkCellAreaPrivate *priv;
|
||||||
|
GList *siblings;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||||
|
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||||
|
g_return_if_fail (GTK_IS_CELL_RENDERER (sibling));
|
||||||
|
g_return_if_fail (gtk_cell_area_is_focus_sibling (area, renderer, sibling));
|
||||||
|
|
||||||
|
priv = area->priv;
|
||||||
|
|
||||||
|
siblings = g_hash_table_lookup (priv->focus_siblings, renderer);
|
||||||
|
|
||||||
|
siblings = g_list_copy (siblings);
|
||||||
|
siblings = g_list_remove (siblings, sibling);
|
||||||
|
|
||||||
|
if (!siblings)
|
||||||
|
g_hash_table_remove (priv->focus_siblings, renderer);
|
||||||
|
else
|
||||||
|
g_hash_table_insert (priv->focus_siblings, renderer, siblings);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gtk_cell_area_is_focus_sibling (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer,
|
||||||
|
GtkCellRenderer *sibling)
|
||||||
|
{
|
||||||
|
GtkCellAreaPrivate *priv;
|
||||||
|
GList *siblings, *l;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), FALSE);
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_RENDERER (sibling), FALSE);
|
||||||
|
|
||||||
|
priv = area->priv;
|
||||||
|
|
||||||
|
siblings = g_hash_table_lookup (priv->focus_siblings, renderer);
|
||||||
|
|
||||||
|
for (l = siblings; l; l = l->next)
|
||||||
|
{
|
||||||
|
GtkCellRenderer *a_sibling = l->data;
|
||||||
|
|
||||||
|
if (a_sibling == sibling)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GList *
|
||||||
|
gtk_cell_area_get_focus_siblings (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer)
|
||||||
|
{
|
||||||
|
GtkCellAreaPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
|
||||||
|
g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), NULL);
|
||||||
|
|
||||||
|
priv = area->priv;
|
||||||
|
|
||||||
|
return g_hash_table_lookup (priv->focus_siblings, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* API: Cell Activation/Editing *
|
* API: Cell Activation/Editing *
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
@ -95,8 +95,10 @@ struct _GtkCellAreaClass
|
|||||||
GtkCellAreaIter *iter,
|
GtkCellAreaIter *iter,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GtkCellRendererState flags);
|
GtkCellRendererState flags,
|
||||||
|
gboolean paint_focus);
|
||||||
|
|
||||||
/* Geometry */
|
/* Geometry */
|
||||||
GtkCellAreaIter *(* create_iter) (GtkCellArea *area);
|
GtkCellAreaIter *(* create_iter) (GtkCellArea *area);
|
||||||
@ -165,6 +167,8 @@ void gtk_cell_area_add (GtkCellArea
|
|||||||
GtkCellRenderer *renderer);
|
GtkCellRenderer *renderer);
|
||||||
void gtk_cell_area_remove (GtkCellArea *area,
|
void gtk_cell_area_remove (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer);
|
GtkCellRenderer *renderer);
|
||||||
|
gboolean gtk_cell_area_has_renderer (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer);
|
||||||
void gtk_cell_area_forall (GtkCellArea *area,
|
void gtk_cell_area_forall (GtkCellArea *area,
|
||||||
GtkCellCallback callback,
|
GtkCellCallback callback,
|
||||||
gpointer callback_data);
|
gpointer callback_data);
|
||||||
@ -184,8 +188,10 @@ void gtk_cell_area_render (GtkCellArea
|
|||||||
GtkCellAreaIter *iter,
|
GtkCellAreaIter *iter,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GtkCellRendererState flags);
|
GtkCellRendererState flags,
|
||||||
|
gboolean paint_focus);
|
||||||
|
|
||||||
/* Geometry */
|
/* Geometry */
|
||||||
GtkCellAreaIter *gtk_cell_area_create_iter (GtkCellArea *area);
|
GtkCellAreaIter *gtk_cell_area_create_iter (GtkCellArea *area);
|
||||||
@ -283,6 +289,21 @@ void gtk_cell_area_set_focus_cell (GtkCellArea
|
|||||||
GtkCellRenderer *renderer);
|
GtkCellRenderer *renderer);
|
||||||
GtkCellRenderer *gtk_cell_area_get_focus_cell (GtkCellArea *area);
|
GtkCellRenderer *gtk_cell_area_get_focus_cell (GtkCellArea *area);
|
||||||
|
|
||||||
|
|
||||||
|
/* Focus siblings */
|
||||||
|
void gtk_cell_area_add_focus_sibling (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer,
|
||||||
|
GtkCellRenderer *sibling);
|
||||||
|
void gtk_cell_area_remove_focus_sibling (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer,
|
||||||
|
GtkCellRenderer *sibling);
|
||||||
|
gboolean gtk_cell_area_is_focus_sibling (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer,
|
||||||
|
GtkCellRenderer *sibling);
|
||||||
|
G_CONST_RETURN GList *gtk_cell_area_get_focus_siblings (GtkCellArea *area,
|
||||||
|
GtkCellRenderer *renderer);
|
||||||
|
|
||||||
|
|
||||||
/* Cell Activation/Editing */
|
/* Cell Activation/Editing */
|
||||||
void gtk_cell_area_set_edited_cell (GtkCellArea *area,
|
void gtk_cell_area_set_edited_cell (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer);
|
GtkCellRenderer *renderer);
|
||||||
|
@ -66,8 +66,10 @@ static void gtk_cell_area_box_render (GtkCellArea
|
|||||||
GtkCellAreaIter *iter,
|
GtkCellAreaIter *iter,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GtkCellRendererState flags);
|
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,
|
||||||
@ -900,15 +902,19 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
GtkCellAreaIter *iter,
|
GtkCellAreaIter *iter,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
|
const GdkRectangle *background_area,
|
||||||
const GdkRectangle *cell_area,
|
const GdkRectangle *cell_area,
|
||||||
GtkCellRendererState flags)
|
GtkCellRendererState flags,
|
||||||
|
gboolean paint_focus)
|
||||||
{
|
{
|
||||||
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
|
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
|
||||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||||
GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
|
GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
|
||||||
GSList *allocated_cells, *l;
|
GSList *allocated_cells, *l;
|
||||||
GdkRectangle background_area, inner_area;
|
GdkRectangle cell_background, inner_area;
|
||||||
GtkCellRenderer *focus_cell = NULL;
|
GtkCellRenderer *focus_cell = NULL;
|
||||||
|
GdkRectangle focus_rect = { 0, };
|
||||||
|
gboolean first_focus_cell = TRUE;
|
||||||
|
|
||||||
if (flags & GTK_CELL_RENDERER_FOCUSED)
|
if (flags & GTK_CELL_RENDERER_FOCUSED)
|
||||||
{
|
{
|
||||||
@ -916,7 +922,7 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
flags &= ~GTK_CELL_RENDERER_FOCUSED;
|
flags &= ~GTK_CELL_RENDERER_FOCUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
background_area = *cell_area;
|
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. */
|
||||||
@ -929,29 +935,95 @@ gtk_cell_area_box_render (GtkCellArea *area,
|
|||||||
|
|
||||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
{
|
{
|
||||||
background_area.x = cell_area->x + cell->position;
|
cell_background.x = cell_area->x + cell->position;
|
||||||
background_area.width = cell->size;
|
cell_background.width = cell->size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
background_area.y = cell_area->y + cell->position;
|
cell_background.y = cell_area->y + cell->position;
|
||||||
background_area.height = cell->size;
|
cell_background.height = cell->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->renderer == focus_cell)
|
|
||||||
cell_fields |= GTK_CELL_RENDERER_FOCUSED;
|
|
||||||
|
|
||||||
/* Remove margins from the background area to produce the cell area
|
/* Remove margins from the background area to produce the cell area
|
||||||
*/
|
*/
|
||||||
gtk_cell_area_inner_cell_area (area, &background_area, &inner_area);
|
gtk_cell_area_inner_cell_area (area, &cell_background, &inner_area);
|
||||||
|
|
||||||
|
if (focus_cell &&
|
||||||
|
(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;
|
||||||
|
gint opposite_size, x_offset, y_offset;
|
||||||
|
|
||||||
|
cell_focus = inner_area;
|
||||||
|
|
||||||
|
/* Trim up the focus size */
|
||||||
|
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
{
|
||||||
|
gtk_cell_renderer_get_preferred_height_for_width (cell->renderer, widget,
|
||||||
|
cell_focus.width,
|
||||||
|
NULL, &opposite_size);
|
||||||
|
|
||||||
|
cell_focus.height = MIN (opposite_size, cell_focus.height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_cell_renderer_get_preferred_width_for_height (cell->renderer, widget,
|
||||||
|
cell_focus.height,
|
||||||
|
NULL, &opposite_size);
|
||||||
|
|
||||||
|
cell_focus.width = MIN (opposite_size, cell_focus.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offset the cell position */
|
||||||
|
_gtk_cell_renderer_calc_offset (cell->renderer, &inner_area, GTK_TEXT_DIR_LTR,
|
||||||
|
cell_focus.width, cell_focus.height,
|
||||||
|
&x_offset, &y_offset);
|
||||||
|
|
||||||
|
cell_focus.x += x_offset;
|
||||||
|
cell_focus.y += y_offset;
|
||||||
|
|
||||||
|
/* 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'
|
/* We have to do some per-cell considerations for the 'flags'
|
||||||
* for focus handling */
|
* for focus handling */
|
||||||
gtk_cell_renderer_render (cell->renderer, cr, widget,
|
gtk_cell_renderer_render (cell->renderer, cr, widget,
|
||||||
&background_area, &inner_area,
|
&cell_background, &inner_area,
|
||||||
flags | cell_fields);
|
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,
|
||||||
|
/* XXX This hint should be a property on GtkCellArea I suppose */
|
||||||
|
"treeview",
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,9 @@ cell_area_scaffold_draw (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
|
gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
|
||||||
gtk_cell_area_render (priv->area, priv->iter, widget, cr, &render_area, flags);
|
gtk_cell_area_render (priv->area, priv->iter, widget, cr,
|
||||||
|
&render_area, &render_area, flags,
|
||||||
|
(have_focus && i == priv->focus_row));
|
||||||
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
{
|
{
|
||||||
@ -726,13 +728,11 @@ cell_area_scaffold_focus (GtkWidget *widget,
|
|||||||
/* If focus stays in the area we dont need to do any more */
|
/* If focus stays in the area we dont need to do any more */
|
||||||
if (gtk_cell_area_focus (priv->area, direction))
|
if (gtk_cell_area_focus (priv->area, direction))
|
||||||
{
|
{
|
||||||
GtkCellRenderer *renderer = gtk_cell_area_get_focus_cell (priv->area);
|
|
||||||
|
|
||||||
priv->focus_row = focus_row;
|
priv->focus_row = focus_row;
|
||||||
|
|
||||||
g_print ("focusing in direction %s: focus set on a %s in row %d\n",
|
/* XXX A smarter implementation would only invalidate the rectangles where
|
||||||
DIRECTION_STR (direction), G_OBJECT_TYPE_NAME (renderer), priv->focus_row);
|
* focus was removed from and new focus was placed */
|
||||||
|
gtk_widget_queue_draw (widget);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -802,8 +802,9 @@ cell_area_scaffold_focus (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("focus leaving with no cells in focus (direction %s, focus_row %d)\n",
|
/* XXX A smarter implementation would only invalidate the rectangles where
|
||||||
DIRECTION_STR (direction), priv->focus_row);
|
* focus was removed from and new focus was placed */
|
||||||
|
gtk_widget_queue_draw (widget);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +246,8 @@ simple_cell_area (void)
|
|||||||
/*******************************************************
|
/*******************************************************
|
||||||
* Focus Test *
|
* Focus Test *
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
static GtkCellRenderer *focus_renderer, *sibling_renderer;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FOCUS_COLUMN_NAME,
|
FOCUS_COLUMN_NAME,
|
||||||
FOCUS_COLUMN_CHECK,
|
FOCUS_COLUMN_CHECK,
|
||||||
@ -328,7 +330,7 @@ focus_scaffold (void)
|
|||||||
gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_NAME);
|
gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_NAME);
|
||||||
|
|
||||||
/* Catch signal ... */
|
/* Catch signal ... */
|
||||||
renderer = gtk_cell_renderer_toggle_new ();
|
focus_renderer = renderer = gtk_cell_renderer_toggle_new ();
|
||||||
g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
|
g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "active", FOCUS_COLUMN_CHECK);
|
gtk_cell_area_attribute_connect (area, renderer, "active", FOCUS_COLUMN_CHECK);
|
||||||
@ -336,7 +338,7 @@ focus_scaffold (void)
|
|||||||
g_signal_connect (G_OBJECT (renderer), "toggled",
|
g_signal_connect (G_OBJECT (renderer), "toggled",
|
||||||
G_CALLBACK (cell_toggled), scaffold);
|
G_CALLBACK (cell_toggled), scaffold);
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new ();
|
sibling_renderer = renderer = gtk_cell_renderer_text_new ();
|
||||||
g_object_set (G_OBJECT (renderer),
|
g_object_set (G_OBJECT (renderer),
|
||||||
"wrap-mode", PANGO_WRAP_WORD,
|
"wrap-mode", PANGO_WRAP_WORD,
|
||||||
"wrap-width", 150,
|
"wrap-width", 150,
|
||||||
@ -347,6 +349,21 @@ focus_scaffold (void)
|
|||||||
return scaffold;
|
return scaffold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
focus_sibling_toggled (GtkToggleButton *toggle,
|
||||||
|
CellAreaScaffold *scaffold)
|
||||||
|
{
|
||||||
|
GtkCellArea *area = cell_area_scaffold_get_area (scaffold);
|
||||||
|
gboolean active = gtk_toggle_button_get_active (toggle);
|
||||||
|
|
||||||
|
if (active)
|
||||||
|
gtk_cell_area_add_focus_sibling (area, focus_renderer, sibling_renderer);
|
||||||
|
else
|
||||||
|
gtk_cell_area_remove_focus_sibling (area, focus_renderer, sibling_renderer);
|
||||||
|
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (scaffold));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
focus_cell_area (void)
|
focus_cell_area (void)
|
||||||
@ -375,10 +392,13 @@ focus_cell_area (void)
|
|||||||
gtk_widget_show (vbox);
|
gtk_widget_show (vbox);
|
||||||
gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
|
gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
|
||||||
|
|
||||||
widget = gtk_check_button_new_with_label ("check button");
|
widget = gtk_check_button_new_with_label ("Focus Sibling");
|
||||||
gtk_widget_show (widget);
|
gtk_widget_show (widget);
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (widget), "toggled",
|
||||||
|
G_CALLBACK (focus_sibling_toggled), scaffold);
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (window), hbox);
|
gtk_container_add (GTK_CONTAINER (window), hbox);
|
||||||
|
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
|
Loading…
Reference in New Issue
Block a user