Compare commits
10 Commits
wip/css-tr
...
cellarea-s
Author | SHA1 | Date | |
---|---|---|---|
|
1914b0ce9e | ||
|
f1bf62c1b0 | ||
|
42a6a49281 | ||
|
5827f8d21f | ||
|
7742259a1c | ||
|
d306a6216b | ||
|
cc8463c665 | ||
|
8b2dce540a | ||
|
7e6cd377f9 | ||
|
95118d235b |
@@ -11,11 +11,11 @@
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkTreeModel *model = NULL;
|
||||
static guint timeout = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gboolean fixed;
|
||||
const gboolean active;
|
||||
const guint number;
|
||||
const gchar *severity;
|
||||
const gchar *description;
|
||||
@@ -28,7 +28,6 @@ enum
|
||||
COLUMN_NUMBER,
|
||||
COLUMN_SEVERITY,
|
||||
COLUMN_DESCRIPTION,
|
||||
COLUMN_PULSE,
|
||||
COLUMN_ICON,
|
||||
COLUMN_ACTIVE,
|
||||
COLUMN_SENSITIVE,
|
||||
@@ -37,49 +36,22 @@ enum
|
||||
|
||||
static Bug data[] =
|
||||
{
|
||||
{ FALSE, 60482, "Normal", "scrollable notebooks and hidden tabs" },
|
||||
{ FALSE, 60620, "Critical", "gdk_window_clear_area (gdkwindow-win32.c) is not thread-safe" },
|
||||
{ FALSE, 50214, "Major", "Xft support does not clean up correctly" },
|
||||
{ TRUE, 52877, "Major", "GtkFileSelection needs a refresh method. " },
|
||||
{ FALSE, 56070, "Normal", "Can't click button after setting in sensitive" },
|
||||
{ TRUE, 56355, "Normal", "GtkLabel - Not all changes propagate correctly" },
|
||||
{ FALSE, 50055, "Normal", "Rework width/height computations for TreeView" },
|
||||
{ FALSE, 58278, "Normal", "gtk_dialog_set_response_sensitive () doesn't work" },
|
||||
{ FALSE, 55767, "Normal", "Getters for all setters" },
|
||||
{ FALSE, 56925, "Normal", "Gtkcalender size" },
|
||||
{ FALSE, 56221, "Normal", "Selectable label needs right-click copy menu" },
|
||||
{ TRUE, 50939, "Normal", "Add shift clicking to GtkTextView" },
|
||||
{ FALSE, 6112, "Enhancement","netscape-like collapsable toolbars" },
|
||||
{ FALSE, 1, "Normal", "First bug :=)" },
|
||||
{ FALSE, TRUE, 60482, "Normal", "scrollable notebooks and hidden tabs" },
|
||||
{ FALSE, FALSE, 60620, "Critical", "gdk_window_clear_area (gdkwindow-win32.c) is not thread-safe" },
|
||||
{ FALSE, FALSE, 50214, "Major", "Xft support does not clean up correctly" },
|
||||
{ TRUE, FALSE, 52877, "Major", "GtkFileSelection needs a refresh method. " },
|
||||
{ FALSE, TRUE, 56070, "Normal", "Can't click button after setting in sensitive" },
|
||||
{ TRUE, FALSE, 56355, "Normal", "GtkLabel - Not all changes propagate correctly" },
|
||||
{ FALSE, FALSE, 50055, "Normal", "Rework width/height computations for TreeView" },
|
||||
{ FALSE, TRUE, 58278, "Normal", "gtk_dialog_set_response_sensitive () doesn't work" },
|
||||
{ FALSE, FALSE, 55767, "Normal", "Getters for all setters" },
|
||||
{ FALSE, TRUE, 56925, "Normal", "Gtkcalender size" },
|
||||
{ FALSE, TRUE, 56221, "Normal", "Selectable label needs right-click copy menu" },
|
||||
{ TRUE, FALSE, 50939, "Normal", "Add shift clicking to GtkTextView" },
|
||||
{ FALSE, FALSE, 6112, "Enhancement","netscape-like collapsable toolbars" },
|
||||
{ FALSE, FALSE, 1, "Normal", "First bug :=)" },
|
||||
};
|
||||
|
||||
static gboolean
|
||||
spinner_timeout (gpointer data)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
guint pulse;
|
||||
|
||||
if (model == NULL)
|
||||
return FALSE;
|
||||
|
||||
gtk_tree_model_get_iter_first (model, &iter);
|
||||
gtk_tree_model_get (model, &iter,
|
||||
COLUMN_PULSE, &pulse,
|
||||
-1);
|
||||
if (pulse == G_MAXUINT)
|
||||
pulse = 0;
|
||||
else
|
||||
pulse++;
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (model),
|
||||
&iter,
|
||||
COLUMN_PULSE, pulse,
|
||||
COLUMN_ACTIVE, TRUE,
|
||||
-1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkTreeModel *
|
||||
create_model (void)
|
||||
{
|
||||
@@ -93,7 +65,6 @@ create_model (void)
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_BOOLEAN,
|
||||
G_TYPE_BOOLEAN);
|
||||
@@ -118,9 +89,8 @@ create_model (void)
|
||||
COLUMN_NUMBER, data[i].number,
|
||||
COLUMN_SEVERITY, data[i].severity,
|
||||
COLUMN_DESCRIPTION, data[i].description,
|
||||
COLUMN_PULSE, 0,
|
||||
COLUMN_ICON, icon_name,
|
||||
COLUMN_ACTIVE, FALSE,
|
||||
COLUMN_ACTIVE, data[i].active,
|
||||
COLUMN_SENSITIVE, sensitive,
|
||||
-1);
|
||||
}
|
||||
@@ -209,12 +179,10 @@ add_columns (GtkTreeView *treeview)
|
||||
renderer = gtk_cell_renderer_spinner_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("Spinning",
|
||||
renderer,
|
||||
"pulse",
|
||||
COLUMN_PULSE,
|
||||
"active",
|
||||
COLUMN_ACTIVE,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_PULSE);
|
||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_ACTIVE);
|
||||
gtk_tree_view_append_column (treeview, column);
|
||||
|
||||
/* column for symbolic icon */
|
||||
@@ -238,11 +206,7 @@ window_closed (GtkWidget *widget,
|
||||
{
|
||||
model = NULL;
|
||||
window = NULL;
|
||||
if (timeout != 0)
|
||||
{
|
||||
g_source_remove (timeout);
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -303,22 +267,11 @@ do_list_store (GtkWidget *do_widget)
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
{
|
||||
gtk_widget_show_all (window);
|
||||
if (timeout == 0) {
|
||||
/* FIXME this should use the animation-duration instead */
|
||||
timeout = g_timeout_add (80, spinner_timeout, NULL);
|
||||
}
|
||||
}
|
||||
gtk_widget_show_all (window);
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
if (timeout != 0)
|
||||
{
|
||||
g_source_remove (timeout);
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return window;
|
||||
|
@@ -4475,6 +4475,8 @@ gtk_cell_area_activate_cell
|
||||
gtk_cell_area_stop_editing
|
||||
gtk_cell_area_inner_cell_area
|
||||
gtk_cell_area_request_renderer
|
||||
gtk_cell_area_set_animation_id
|
||||
gtk_cell_area_forget_animation_id
|
||||
<SUBSECTION Standard>
|
||||
GTK_CELL_AREA
|
||||
GTK_IS_CELL_AREA
|
||||
@@ -4566,6 +4568,7 @@ gtk_cell_renderer_set_alignment
|
||||
gtk_cell_renderer_get_padding
|
||||
gtk_cell_renderer_set_padding
|
||||
gtk_cell_renderer_get_state
|
||||
gtk_cell_renderer_apply_style
|
||||
gtk_cell_renderer_is_activatable
|
||||
|
||||
<SUBSECTION Width-for-height>
|
||||
|
@@ -365,6 +365,7 @@
|
||||
#include "gtkcellarea.h"
|
||||
#include "gtkcellareacontext.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkanimationdescription.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
#include <gobject/gvaluecollector.h>
|
||||
@@ -531,6 +532,17 @@ typedef struct {
|
||||
GtkCellLayout *proxy;
|
||||
} CellInfo;
|
||||
|
||||
typedef struct {
|
||||
GtkCellRenderer *renderer;
|
||||
gpointer anim_id;
|
||||
guint rendered : 1;
|
||||
} AnimationKey;
|
||||
|
||||
typedef struct {
|
||||
GtkStyleContext *context;
|
||||
gpointer anim_id;
|
||||
} ForgetAnimationData;
|
||||
|
||||
static CellInfo *cell_info_new (GtkCellLayoutDataFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
@@ -542,6 +554,11 @@ static void cell_attribute_free (CellAttribute *attribute);
|
||||
static gint cell_attribute_find (CellAttribute *cell_attribute,
|
||||
const gchar *attribute);
|
||||
|
||||
static void animation_key_free (AnimationKey *key);
|
||||
static guint animation_key_hash (gconstpointer p);
|
||||
static gboolean animation_key_equal (gconstpointer p1,
|
||||
gconstpointer p2);
|
||||
|
||||
/* Internal functions/signal emissions */
|
||||
static void gtk_cell_area_add_editable (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
@@ -591,6 +608,10 @@ struct _GtkCellAreaPrivate
|
||||
|
||||
/* Tracking which cells are focus siblings of focusable cells */
|
||||
GHashTable *focus_siblings;
|
||||
|
||||
/* GtkStateFlags tracking for transitions */
|
||||
gpointer parent_anim_id;
|
||||
GHashTable *cell_states;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -643,6 +664,10 @@ gtk_cell_area_init (GtkCellArea *area)
|
||||
NULL,
|
||||
(GDestroyNotify)g_list_free);
|
||||
|
||||
priv->cell_states = g_hash_table_new_full (animation_key_hash,
|
||||
animation_key_equal,
|
||||
(GDestroyNotify) animation_key_free,
|
||||
NULL);
|
||||
priv->focus_cell = NULL;
|
||||
priv->edited_cell = NULL;
|
||||
priv->edit_widget = NULL;
|
||||
@@ -933,6 +958,7 @@ gtk_cell_area_finalize (GObject *object)
|
||||
*/
|
||||
g_hash_table_destroy (priv->cell_info);
|
||||
g_hash_table_destroy (priv->focus_siblings);
|
||||
g_hash_table_destroy (priv->cell_states);
|
||||
|
||||
g_free (priv->current_path);
|
||||
|
||||
@@ -1124,6 +1150,192 @@ gtk_cell_area_real_event (GtkCellArea *area,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static AnimationKey *
|
||||
animation_key_new (GtkCellRenderer *renderer,
|
||||
gpointer anim_id)
|
||||
{
|
||||
AnimationKey *key;
|
||||
|
||||
key = g_slice_new (AnimationKey);
|
||||
key->renderer = renderer;
|
||||
key->anim_id = anim_id;
|
||||
key->rendered = FALSE;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void
|
||||
animation_key_free (AnimationKey *key)
|
||||
{
|
||||
g_slice_free (AnimationKey, key);
|
||||
}
|
||||
|
||||
static guint
|
||||
animation_key_hash (gconstpointer p)
|
||||
{
|
||||
const AnimationKey *key = p;
|
||||
guint h;
|
||||
|
||||
h = GPOINTER_TO_UINT (key->anim_id) < 16;
|
||||
h |= GPOINTER_TO_UINT (key->renderer) & 0xFFFF;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
animation_key_equal (gconstpointer p1,
|
||||
gconstpointer p2)
|
||||
{
|
||||
const AnimationKey *key1, *key2;
|
||||
|
||||
key1 = p1;
|
||||
key2 = p2;
|
||||
|
||||
return (key1->renderer == key2->renderer &&
|
||||
key1->anim_id == key2->anim_id);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_cell_area_set_state (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
gpointer anim_id,
|
||||
GtkStateFlags flags)
|
||||
{
|
||||
GtkCellAreaPrivate *priv;
|
||||
AnimationKey *key;
|
||||
|
||||
priv = area->priv;
|
||||
key = animation_key_new (renderer, anim_id);
|
||||
|
||||
g_hash_table_insert (priv->cell_states, key, GUINT_TO_POINTER (flags));
|
||||
}
|
||||
|
||||
static AnimationKey *
|
||||
_gtk_cell_area_lookup_state (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
gpointer anim_id,
|
||||
GtkStateFlags *flags)
|
||||
{
|
||||
GtkCellAreaPrivate *priv;
|
||||
gpointer orig_key, value;
|
||||
AnimationKey key;
|
||||
|
||||
priv = area->priv;
|
||||
|
||||
key.renderer = renderer;
|
||||
key.anim_id = anim_id;
|
||||
|
||||
if (!g_hash_table_lookup_extended (priv->cell_states, &key, &orig_key, &value))
|
||||
return NULL;
|
||||
|
||||
if (flags)
|
||||
*flags = GPOINTER_TO_UINT (value);
|
||||
|
||||
return orig_key;
|
||||
}
|
||||
|
||||
static AnimationKey *
|
||||
apply_renderer_transition (GtkCellArea *area,
|
||||
GdkWindow *window,
|
||||
GtkWidget *widget,
|
||||
GtkCellRendererState cell_state,
|
||||
GtkCellRenderer *renderer)
|
||||
{
|
||||
GtkCellAreaPrivate *priv;
|
||||
GtkStateFlags state, old_state, flag;
|
||||
GtkStyleContext *style_context;
|
||||
AnimationKey *anim_key;
|
||||
gboolean is_cached;
|
||||
|
||||
priv = area->priv;
|
||||
|
||||
if (!priv->parent_anim_id)
|
||||
return NULL;
|
||||
|
||||
state = gtk_cell_renderer_get_state (renderer, widget, cell_state);
|
||||
anim_key = _gtk_cell_area_lookup_state (area, renderer, priv->parent_anim_id, &old_state);
|
||||
is_cached = (anim_key != NULL);
|
||||
|
||||
if (is_cached && state == old_state)
|
||||
return anim_key;
|
||||
else
|
||||
{
|
||||
_gtk_cell_area_set_state (area, renderer, priv->parent_anim_id, state);
|
||||
|
||||
/* Fetch the just created anim ID if needed */
|
||||
if (!anim_key)
|
||||
anim_key = _gtk_cell_area_lookup_state (area, renderer, priv->parent_anim_id, NULL);
|
||||
}
|
||||
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
flag = GTK_STATE_FLAG_FOCUSED;
|
||||
|
||||
while (flag)
|
||||
{
|
||||
GtkAnimationDescription *animation_desc;
|
||||
|
||||
if (is_cached && ((state & flag) == (old_state & flag)))
|
||||
{
|
||||
/* Flag didn't change since it was last cached */
|
||||
flag >>= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
gtk_style_context_get (style_context, flag,
|
||||
"transition", &animation_desc,
|
||||
NULL);
|
||||
|
||||
if (animation_desc)
|
||||
{
|
||||
/* Only notify state transition on changes over previously cached
|
||||
* states (Which means a viewable renderer has changed) and those
|
||||
* with a looping animation.
|
||||
*/
|
||||
if (is_cached ||
|
||||
((state & flag) != 0 &&
|
||||
_gtk_animation_description_get_loop (animation_desc)))
|
||||
{
|
||||
GtkStateType anim_state;
|
||||
|
||||
switch (flag)
|
||||
{
|
||||
case GTK_STATE_FLAG_ACTIVE:
|
||||
anim_state = GTK_STATE_ACTIVE;
|
||||
break;
|
||||
case GTK_STATE_FLAG_PRELIGHT:
|
||||
anim_state = GTK_STATE_PRELIGHT;
|
||||
break;
|
||||
case GTK_STATE_FLAG_SELECTED:
|
||||
anim_state = GTK_STATE_SELECTED;
|
||||
break;
|
||||
case GTK_STATE_FLAG_INSENSITIVE:
|
||||
anim_state = GTK_STATE_INSENSITIVE;
|
||||
break;
|
||||
case GTK_STATE_FLAG_INCONSISTENT:
|
||||
anim_state = GTK_STATE_INCONSISTENT;
|
||||
break;
|
||||
case GTK_STATE_FLAG_FOCUSED:
|
||||
anim_state = GTK_STATE_FOCUSED;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_style_context_notify_state_change (style_context, window,
|
||||
anim_key, anim_state,
|
||||
(state & flag) != 0);
|
||||
}
|
||||
|
||||
_gtk_animation_description_unref (animation_desc);
|
||||
}
|
||||
|
||||
flag >>= 1;
|
||||
}
|
||||
|
||||
return anim_key;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
render_cell (GtkCellRenderer *renderer,
|
||||
const GdkRectangle *cell_area,
|
||||
@@ -1133,10 +1345,33 @@ render_cell (GtkCellRenderer *renderer,
|
||||
GtkCellRenderer *focus_cell;
|
||||
GtkCellRendererState flags;
|
||||
GdkRectangle inner_area;
|
||||
GtkStyleContext *style_context;
|
||||
GdkEventExpose *expose;
|
||||
AnimationKey *anim_key = NULL;
|
||||
|
||||
focus_cell = gtk_cell_area_get_focus_cell (data->area);
|
||||
flags = data->render_flags;
|
||||
|
||||
expose = _gtk_cairo_get_event (data->cr);
|
||||
style_context = gtk_widget_get_style_context (data->widget);
|
||||
|
||||
gtk_style_context_save (style_context);
|
||||
gtk_cell_renderer_apply_style (renderer, style_context);
|
||||
|
||||
if (expose)
|
||||
anim_key = apply_renderer_transition (data->area, expose->window, data->widget,
|
||||
flags, renderer);
|
||||
|
||||
if (anim_key)
|
||||
{
|
||||
/* Mark this animation as rendered, this is so we can keep
|
||||
* track after rendering of stale states, due to removed or
|
||||
* hidden cell renderers.
|
||||
*/
|
||||
anim_key->rendered = TRUE;
|
||||
gtk_style_context_push_animatable_region (style_context, anim_key);
|
||||
}
|
||||
|
||||
gtk_cell_area_inner_cell_area (data->area, data->widget, cell_area, &inner_area);
|
||||
|
||||
if ((flags & GTK_CELL_RENDERER_FOCUSED) &&
|
||||
@@ -1174,9 +1409,46 @@ render_cell (GtkCellRenderer *renderer,
|
||||
gtk_cell_renderer_render (renderer, data->cr, data->widget,
|
||||
cell_background, &inner_area, flags);
|
||||
|
||||
if (anim_key)
|
||||
gtk_style_context_pop_animatable_region (style_context);
|
||||
|
||||
gtk_style_context_restore (style_context);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
maybe_dispose_animation_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
AnimationKey *anim_key = key;
|
||||
CellRenderData *render_data = user_data;
|
||||
GtkCellAreaPrivate *priv = render_data->area->priv;
|
||||
|
||||
if (anim_key->anim_id != priv->parent_anim_id)
|
||||
return FALSE;
|
||||
|
||||
/* Stop tracking all animations that weren't rendered
|
||||
* this time, this usually means the cell renderer has
|
||||
* been hidden or removed.
|
||||
*/
|
||||
if (!anim_key->rendered)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (render_data->widget);
|
||||
gtk_style_context_cancel_animations (context, anim_key);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim_key->rendered = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_area_real_render (GtkCellArea *area,
|
||||
GtkCellAreaContext *context,
|
||||
@@ -1187,6 +1459,8 @@ gtk_cell_area_real_render (GtkCellArea *area,
|
||||
GtkCellRendererState flags,
|
||||
gboolean paint_focus)
|
||||
{
|
||||
GtkCellAreaPrivate *priv;
|
||||
GtkStyleContext *style_context;
|
||||
CellRenderData render_data =
|
||||
{
|
||||
area,
|
||||
@@ -1210,9 +1484,17 @@ gtk_cell_area_real_render (GtkCellArea *area,
|
||||
!gtk_cell_area_is_activatable (area))
|
||||
render_data.focus_all = TRUE;
|
||||
|
||||
priv = area->priv;
|
||||
style_context = gtk_widget_get_style_context (widget);
|
||||
|
||||
if (priv->parent_anim_id)
|
||||
gtk_style_context_push_animatable_region (style_context, priv->parent_anim_id);
|
||||
|
||||
gtk_cell_area_foreach_alloc (area, context, widget, cell_area, background_area,
|
||||
(GtkCellAllocCallback)render_cell, &render_data);
|
||||
|
||||
g_hash_table_foreach_remove (priv->cell_states, maybe_dispose_animation_foreach, &render_data);
|
||||
|
||||
if (render_data.paint_focus &&
|
||||
render_data.focus_rect.width != 0 &&
|
||||
render_data.focus_rect.height != 0)
|
||||
@@ -1238,6 +1520,9 @@ gtk_cell_area_real_render (GtkCellArea *area,
|
||||
gtk_style_context_restore (style_context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (priv->parent_anim_id)
|
||||
gtk_style_context_pop_animatable_region (style_context);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3660,3 +3945,85 @@ _gtk_cell_area_set_cell_data_func_with_proxy (GtkCellArea *area,
|
||||
g_hash_table_insert (priv->cell_info, cell, info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_area_set_animation_id:
|
||||
* @area: a #GtkCellArea
|
||||
* @anim_id: identifier for the animatable region, or %NULL.
|
||||
* See gtk_style_context_notify_state_change().
|
||||
*
|
||||
* Sets the identifier for the animatable region affecting the
|
||||
* subsequent gtk_cell_area_render() call. @area will compose
|
||||
* internal identificators for each contained cell renderer
|
||||
* using this information.
|
||||
*
|
||||
* Widgets caring about state transitions in #GtkCellArea
|
||||
* managed rendering should set a different animation
|
||||
* identificator for each row rendered.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
void
|
||||
gtk_cell_area_set_animation_id (GtkCellArea *area,
|
||||
gpointer anim_id)
|
||||
{
|
||||
GtkCellAreaPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
|
||||
priv = area->priv;
|
||||
priv->parent_anim_id = anim_id;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
forget_animation_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
AnimationKey *anim_key = key;
|
||||
ForgetAnimationData *data = user_data;
|
||||
|
||||
if (!data->anim_id ||
|
||||
anim_key->anim_id == data->anim_id)
|
||||
{
|
||||
gtk_style_context_cancel_animations (data->context,
|
||||
anim_key->anim_id);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_area_forget_animation_id:
|
||||
* @area: a #GtkCellArea
|
||||
* @widget: the renderer #GtkWidget
|
||||
* @anim_id: identifier for the animatable region, or %NULL.
|
||||
*
|
||||
* Drops any cached data on an animatable region identifier
|
||||
* passed through gtk_cell_area_set_animation_id(), and
|
||||
* cancels any ongoing animation there. A %NULL @anim_id
|
||||
* will drop every cached state.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
void
|
||||
gtk_cell_area_forget_animation_id (GtkCellArea *area,
|
||||
GtkWidget *widget,
|
||||
gpointer anim_id)
|
||||
{
|
||||
GtkCellAreaPrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
ForgetAnimationData data;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
priv = area->priv;
|
||||
data.context = gtk_widget_get_style_context (widget);
|
||||
data.anim_id = anim_id;
|
||||
|
||||
g_hash_table_foreach_remove (priv->cell_states,
|
||||
forget_animation_foreach,
|
||||
&data);
|
||||
}
|
||||
|
@@ -370,6 +370,14 @@ void gtk_cell_area_attribute_disconnect (GtkCellArea
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *attribute);
|
||||
|
||||
/* State tracking */
|
||||
void gtk_cell_area_set_animation_id (GtkCellArea *area,
|
||||
gpointer anim_id);
|
||||
|
||||
void gtk_cell_area_forget_animation_id (GtkCellArea *area,
|
||||
GtkWidget *widget,
|
||||
gpointer anim_id);
|
||||
|
||||
/* Cell Properties */
|
||||
void gtk_cell_area_class_install_cell_property (GtkCellAreaClass *aclass,
|
||||
guint property_id,
|
||||
|
@@ -104,6 +104,7 @@ static void gtk_cell_renderer_real_get_aligned_area (GtkCellRendere
|
||||
GtkCellRendererState flags,
|
||||
const GdkRectangle *cell_area,
|
||||
GdkRectangle *aligned_area);
|
||||
static GtkStateFlags gtk_cell_renderer_real_get_current_state (GtkCellRenderer *cell);
|
||||
|
||||
|
||||
struct _GtkCellRendererPrivate
|
||||
@@ -200,6 +201,7 @@ gtk_cell_renderer_class_init (GtkCellRendererClass *class)
|
||||
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_aligned_area = gtk_cell_renderer_real_get_aligned_area;
|
||||
class->get_current_state = gtk_cell_renderer_real_get_current_state;
|
||||
|
||||
/**
|
||||
* GtkCellRenderer::editing-canceled:
|
||||
@@ -1324,6 +1326,11 @@ gtk_cell_renderer_real_get_aligned_area (GtkCellRenderer *cell,
|
||||
aligned_area->y += y_offset;
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_cell_renderer_real_get_current_state (GtkCellRenderer *cell)
|
||||
{
|
||||
return GTK_STATE_FLAG_NORMAL;
|
||||
}
|
||||
|
||||
/* An internal convenience function for some containers to peek at the
|
||||
* cell alignment in a target allocation (used to draw focus and align
|
||||
@@ -1700,13 +1707,19 @@ gtk_cell_renderer_get_state (GtkCellRenderer *cell,
|
||||
g_return_val_if_fail (!cell || GTK_IS_CELL_RENDERER (cell), 0);
|
||||
g_return_val_if_fail (!widget || GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
if ((widget && !gtk_widget_is_sensitive (widget)) ||
|
||||
(cell && !gtk_cell_renderer_get_sensitive (cell)) ||
|
||||
(cell_state & GTK_CELL_RENDERER_INSENSITIVE) != 0)
|
||||
if (cell)
|
||||
{
|
||||
state |= GTK_STATE_FLAG_INSENSITIVE;
|
||||
state = GTK_CELL_RENDERER_GET_CLASS (cell)->get_current_state (cell);
|
||||
|
||||
if (!gtk_cell_renderer_get_sensitive (cell))
|
||||
state |= GTK_STATE_FLAG_INSENSITIVE;
|
||||
}
|
||||
else
|
||||
|
||||
if ((widget && !gtk_widget_is_sensitive (widget)) ||
|
||||
(cell_state & GTK_CELL_RENDERER_INSENSITIVE) != 0)
|
||||
state |= GTK_STATE_FLAG_INSENSITIVE;
|
||||
|
||||
if ((state & GTK_STATE_FLAG_INSENSITIVE) == 0)
|
||||
{
|
||||
if ((widget && gtk_widget_has_focus (widget)) &&
|
||||
(cell_state & GTK_CELL_RENDERER_FOCUSED) != 0)
|
||||
@@ -1721,3 +1734,25 @@ gtk_cell_renderer_get_state (GtkCellRenderer *cell,
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_renderer_apply_style:
|
||||
* @cell: a #GtkCellRenderer
|
||||
* @style_context: a #GtkStyleContext
|
||||
*
|
||||
* Applies into @style_context the style properties affecting
|
||||
* @cell. This should be called between a
|
||||
* gtk_style_context_save()/gtk_style_context_restore() pair.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
void
|
||||
gtk_cell_renderer_apply_style (GtkCellRenderer *cell,
|
||||
GtkStyleContext *style_context)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (style_context));
|
||||
|
||||
if (GTK_CELL_RENDERER_GET_CLASS (cell)->apply_style)
|
||||
GTK_CELL_RENDERER_GET_CLASS (cell)->apply_style (cell, style_context);
|
||||
}
|
||||
|
@@ -150,11 +150,13 @@ struct _GtkCellRendererClass
|
||||
GtkCellEditable *editable,
|
||||
const gchar *path);
|
||||
|
||||
GtkStateFlags (* get_current_state) (GtkCellRenderer *cell);
|
||||
void (* apply_style) (GtkCellRenderer *cell,
|
||||
GtkStyleContext *style_context);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
};
|
||||
|
||||
GType gtk_cell_renderer_get_type (void) G_GNUC_CONST;
|
||||
@@ -265,6 +267,8 @@ void _gtk_cell_renderer_calc_offset (GtkCellRenderer *cell,
|
||||
GtkStateFlags gtk_cell_renderer_get_state (GtkCellRenderer *cell,
|
||||
GtkWidget *widget,
|
||||
GtkCellRendererState cell_state);
|
||||
void gtk_cell_renderer_apply_style (GtkCellRenderer *cell,
|
||||
GtkStyleContext *style_context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -92,6 +92,10 @@ static void gtk_cell_renderer_spinner_render (GtkCellRenderer *cell,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags);
|
||||
static GtkStateFlags gtk_cell_renderer_spinner_get_current_state (GtkCellRenderer *cell);
|
||||
static void gtk_cell_renderer_spinner_apply_style (GtkCellRenderer *cell,
|
||||
GtkStyleContext *context);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkCellRendererSpinner, gtk_cell_renderer_spinner, GTK_TYPE_CELL_RENDERER)
|
||||
|
||||
@@ -106,6 +110,8 @@ gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
|
||||
|
||||
cell_class->get_size = gtk_cell_renderer_spinner_get_size;
|
||||
cell_class->render = gtk_cell_renderer_spinner_render;
|
||||
cell_class->get_current_state = gtk_cell_renderer_spinner_get_current_state;
|
||||
cell_class->apply_style = gtk_cell_renderer_spinner_apply_style;
|
||||
|
||||
/* GtkCellRendererSpinner:active:
|
||||
*
|
||||
@@ -130,6 +136,9 @@ gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
|
||||
* consisting of 12 frames, in 750 milliseconds.
|
||||
*
|
||||
* Since: 2.20
|
||||
*
|
||||
* Deprecated: 3.2. The ::active property is sufficient, animation
|
||||
* details are handled by theming.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PULSE,
|
||||
@@ -325,7 +334,8 @@ gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
|
||||
{
|
||||
GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
|
||||
GtkCellRendererSpinnerPrivate *priv = cell->priv;
|
||||
GtkStateType state;
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GdkRectangle pix_rect;
|
||||
GdkRectangle draw_rect;
|
||||
gint xpad, ypad;
|
||||
@@ -349,38 +359,45 @@ gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
|
||||
if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect))
|
||||
return;
|
||||
|
||||
state = GTK_STATE_NORMAL;
|
||||
if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE ||
|
||||
!gtk_cell_renderer_get_sensitive (cellr))
|
||||
{
|
||||
state = GTK_STATE_INSENSITIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
|
||||
{
|
||||
if (gtk_widget_has_focus (widget))
|
||||
state = GTK_STATE_SELECTED;
|
||||
else
|
||||
state = GTK_STATE_ACTIVE;
|
||||
}
|
||||
else
|
||||
state = GTK_STATE_PRELIGHT;
|
||||
}
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_cell_renderer_apply_style (cellr, context);
|
||||
|
||||
state = gtk_cell_renderer_get_state (cellr, widget, flags);
|
||||
gtk_style_context_set_state (context, state);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
gdk_cairo_rectangle (cr, cell_area);
|
||||
cairo_clip (cr);
|
||||
|
||||
gtk_paint_spinner (gtk_widget_get_style (widget),
|
||||
cr,
|
||||
state,
|
||||
widget,
|
||||
"cell",
|
||||
priv->pulse,
|
||||
draw_rect.x, draw_rect.y,
|
||||
draw_rect.width, draw_rect.height);
|
||||
gtk_render_activity (context, cr,
|
||||
draw_rect.x,
|
||||
draw_rect.y,
|
||||
draw_rect.width,
|
||||
draw_rect.height);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_cell_renderer_spinner_get_current_state (GtkCellRenderer *cellr)
|
||||
{
|
||||
GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
|
||||
GtkCellRendererSpinnerPrivate *priv = cell->priv;
|
||||
GtkStateFlags state = 0;
|
||||
|
||||
if (priv->active)
|
||||
state |= GTK_STATE_FLAG_ACTIVE;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_spinner_apply_style (GtkCellRenderer *cell,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SPINNER);
|
||||
}
|
||||
|
@@ -67,6 +67,10 @@ static gboolean gtk_cell_renderer_toggle_activate (GtkCellRenderer *
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags);
|
||||
|
||||
static GtkStateFlags gtk_cell_renderer_toggle_get_current_state (GtkCellRenderer *cell);
|
||||
static void gtk_cell_renderer_toggle_apply_style (GtkCellRenderer *cell,
|
||||
GtkStyleContext *context);
|
||||
|
||||
|
||||
enum {
|
||||
TOGGLED,
|
||||
@@ -133,7 +137,9 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
|
||||
cell_class->get_size = gtk_cell_renderer_toggle_get_size;
|
||||
cell_class->render = gtk_cell_renderer_toggle_render;
|
||||
cell_class->activate = gtk_cell_renderer_toggle_activate;
|
||||
|
||||
cell_class->get_current_state = gtk_cell_renderer_toggle_get_current_state;
|
||||
cell_class->apply_style = gtk_cell_renderer_toggle_apply_style;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ACTIVE,
|
||||
g_param_spec_boolean ("active",
|
||||
@@ -423,6 +429,36 @@ gtk_cell_renderer_toggle_activate (GtkCellRenderer *cell,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_cell_renderer_toggle_get_current_state (GtkCellRenderer *cell)
|
||||
{
|
||||
GtkCellRendererTogglePrivate *priv;
|
||||
GtkStateFlags state = 0;
|
||||
|
||||
priv = GTK_CELL_RENDERER_TOGGLE (cell)->priv;
|
||||
|
||||
if (priv->inconsistent)
|
||||
state |= GTK_STATE_FLAG_INCONSISTENT;
|
||||
else if (priv->active)
|
||||
state |= GTK_STATE_FLAG_ACTIVE;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_toggle_apply_style (GtkCellRenderer *cell,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
GtkCellRendererTogglePrivate *priv;
|
||||
|
||||
priv = GTK_CELL_RENDERER_TOGGLE (cell)->priv;
|
||||
|
||||
if (priv->radio)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RADIO);
|
||||
else
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_CHECK);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_renderer_toggle_set_radio:
|
||||
* @toggle: a #GtkCellRendererToggle
|
||||
|
@@ -2962,11 +2962,14 @@ gtk_icon_view_paint_item (GtkIconView *icon_view,
|
||||
cell_area.width = item->cell_area.width;
|
||||
cell_area.height = item->cell_area.height;
|
||||
|
||||
gtk_cell_area_set_animation_id (priv->cell_area, item);
|
||||
|
||||
context = g_ptr_array_index (priv->row_contexts, item->row);
|
||||
gtk_cell_area_render (priv->cell_area, context,
|
||||
widget, cr, &cell_area, &cell_area, flags,
|
||||
draw_focus);
|
||||
|
||||
gtk_cell_area_set_animation_id (priv->cell_area, NULL);
|
||||
gtk_style_context_restore (style_context);
|
||||
}
|
||||
|
||||
@@ -3355,7 +3358,11 @@ gtk_icon_view_row_deleted (GtkTreeModel *model,
|
||||
item = list->data;
|
||||
|
||||
if (icon_view->priv->cell_area)
|
||||
gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);
|
||||
{
|
||||
gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);
|
||||
gtk_cell_area_forget_animation_id (icon_view->priv->cell_area,
|
||||
GTK_WIDGET (data), item);
|
||||
}
|
||||
|
||||
if (item == icon_view->priv->anchor_item)
|
||||
icon_view->priv->anchor_item = NULL;
|
||||
|
@@ -3155,6 +3155,7 @@ _gtk_style_context_coalesce_animation_areas (GtkStyleContext *context,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
gboolean validate = TRUE;
|
||||
GSList *l;
|
||||
|
||||
priv = context->priv;
|
||||
@@ -3167,7 +3168,6 @@ _gtk_style_context_coalesce_animation_areas (GtkStyleContext *context,
|
||||
while (l)
|
||||
{
|
||||
AnimationInfo *info;
|
||||
gint rel_x, rel_y;
|
||||
GSList *cur;
|
||||
guint i;
|
||||
|
||||
@@ -3179,34 +3179,31 @@ _gtk_style_context_coalesce_animation_areas (GtkStyleContext *context,
|
||||
continue;
|
||||
|
||||
if (info->rectangles->len == 0)
|
||||
continue;
|
||||
{
|
||||
validate = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
info->invalidation_region = cairo_region_create ();
|
||||
_gtk_widget_get_translation_to_window (widget, info->window, &rel_x, &rel_y);
|
||||
|
||||
for (i = 0; i < info->rectangles->len; i++)
|
||||
{
|
||||
cairo_rectangle_int_t *rect;
|
||||
|
||||
rect = &g_array_index (info->rectangles, cairo_rectangle_int_t, i);
|
||||
|
||||
/* These are widget relative coordinates,
|
||||
* so have them inverted to be window relative
|
||||
*/
|
||||
rect->x -= rel_x;
|
||||
rect->y -= rel_y;
|
||||
|
||||
cairo_region_union_rectangle (info->invalidation_region, rect);
|
||||
}
|
||||
|
||||
g_array_remove_range (info->rectangles, 0, info->rectangles->len);
|
||||
}
|
||||
|
||||
priv->animations_invalidated = FALSE;
|
||||
if (validate)
|
||||
priv->animations_invalidated = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
store_animation_region (GtkStyleContext *context,
|
||||
cairo_t *cr,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble width,
|
||||
@@ -3236,6 +3233,12 @@ store_animation_region (GtkStyleContext *context,
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
/* store device coordinates so the coordinates
|
||||
* can be used right away in window invalidation
|
||||
*/
|
||||
cairo_user_to_device (cr, &x, &y);
|
||||
cairo_user_to_device_distance (cr, &width, &height);
|
||||
|
||||
rect.x = (gint) x;
|
||||
rect.y = (gint) y;
|
||||
rect.width = (gint) width;
|
||||
@@ -3711,7 +3714,7 @@ gtk_render_check (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_check (priv->theming_engine, cr,
|
||||
@@ -3762,7 +3765,7 @@ gtk_render_option (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_option (priv->theming_engine, cr,
|
||||
@@ -3811,7 +3814,7 @@ gtk_render_arrow (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, size, size);
|
||||
store_animation_region (context, cr, x, y, size, size);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_arrow (priv->theming_engine, cr,
|
||||
@@ -3863,7 +3866,7 @@ gtk_render_background (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_background (priv->theming_engine, cr, x, y, width, height);
|
||||
@@ -3916,7 +3919,7 @@ gtk_render_frame (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_frame (priv->theming_engine, cr, x, y, width, height);
|
||||
@@ -3966,7 +3969,7 @@ gtk_render_expander (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_expander (priv->theming_engine, cr, x, y, width, height);
|
||||
@@ -4013,7 +4016,7 @@ gtk_render_focus (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_focus (priv->theming_engine, cr, x, y, width, height);
|
||||
@@ -4055,7 +4058,7 @@ gtk_render_layout (GtkStyleContext *context,
|
||||
|
||||
pango_layout_get_extents (layout, &extents, NULL);
|
||||
|
||||
store_animation_region (context,
|
||||
store_animation_region (context, cr,
|
||||
x + extents.x,
|
||||
y + extents.y,
|
||||
extents.width,
|
||||
@@ -4149,7 +4152,7 @@ gtk_render_slider (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_slider (priv->theming_engine, cr, x, y, width, height, orientation);
|
||||
@@ -4214,7 +4217,7 @@ gtk_render_frame_gap (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_frame_gap (priv->theming_engine, cr,
|
||||
@@ -4268,7 +4271,7 @@ gtk_render_extension (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_extension (priv->theming_engine, cr, x, y, width, height, gap_side);
|
||||
@@ -4318,7 +4321,7 @@ gtk_render_handle (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_handle (priv->theming_engine, cr, x, y, width, height);
|
||||
@@ -4363,7 +4366,7 @@ gtk_render_activity (GtkStyleContext *context,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
store_animation_region (context, x, y, width, height);
|
||||
store_animation_region (context, cr, x, y, width, height);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_activity (priv->theming_engine, cr, x, y, width, height);
|
||||
|
@@ -133,11 +133,15 @@ gboolean _gtk_tree_view_column_is_blank_at_pos (GtkTreeViewColumn *co
|
||||
gint y);
|
||||
|
||||
void _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
gboolean draw_focus);
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
gboolean draw_focus,
|
||||
gpointer anim_id);
|
||||
void _gtk_tree_view_column_cancel_animations (GtkTreeViewColumn *tree_column,
|
||||
gpointer anim_id);
|
||||
|
||||
void _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
|
||||
gboolean install_handler);
|
||||
gboolean _gtk_tree_view_column_cell_get_dirty (GtkTreeViewColumn *tree_column);
|
||||
|
@@ -298,6 +298,7 @@ struct _GtkTreeViewPrivate
|
||||
|
||||
/* Scroll position state keeping */
|
||||
GtkTreeRowReference *top_row;
|
||||
GtkTreeRowReference *bottom_row;
|
||||
gint top_row_dy;
|
||||
/* dy == y pos of top_row + top_row_dy */
|
||||
/* we cache it for simplicity of the code */
|
||||
@@ -721,6 +722,9 @@ static void gtk_tree_view_set_top_row (GtkTreeView *tree_view,
|
||||
gint offset);
|
||||
static void gtk_tree_view_dy_to_top_row (GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view);
|
||||
static GtkTreePath * gtk_tree_view_get_bottom_row (GtkTreeView *tree_view,
|
||||
GtkTreePath *top_row);
|
||||
|
||||
static void invalidate_empty_focus (GtkTreeView *tree_view);
|
||||
|
||||
/* Internal functions */
|
||||
@@ -883,6 +887,10 @@ static GtkTreeViewColumn *gtk_tree_view_get_drop_column (GtkTreeView *tree
|
||||
GtkTreeViewColumn *column,
|
||||
gint drop_position);
|
||||
|
||||
static void gtk_tree_view_cancel_row_animations (GtkTreeView *tree_view,
|
||||
GtkTreePath *top_row,
|
||||
GtkTreePath *bottom_row);
|
||||
|
||||
/* GtkBuildable */
|
||||
static void gtk_tree_view_buildable_add_child (GtkBuildable *tree_view,
|
||||
GtkBuilder *builder,
|
||||
@@ -2815,6 +2823,26 @@ gtk_tree_view_size_allocate (GtkWidget *widget,
|
||||
tree_view->priv->prev_width_before_expander = width_before_expander;
|
||||
}
|
||||
}
|
||||
|
||||
if (tree_view->priv->top_row &&
|
||||
tree_view->priv->bottom_row)
|
||||
{
|
||||
GtkTreePath *top_path, *bottom_path;
|
||||
|
||||
|
||||
top_path = gtk_tree_row_reference_get_path (tree_view->priv->top_row);
|
||||
bottom_path = gtk_tree_view_get_bottom_row (tree_view, top_path);
|
||||
|
||||
gtk_tree_view_cancel_row_animations (tree_view, top_path, bottom_path);
|
||||
|
||||
gtk_tree_path_free (top_path);
|
||||
|
||||
/* Update bottom row */
|
||||
gtk_tree_row_reference_free (tree_view->priv->bottom_row);
|
||||
tree_view->priv->bottom_row = gtk_tree_row_reference_new (tree_view->priv->model,
|
||||
bottom_path);
|
||||
gtk_tree_path_free (bottom_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* Grabs the focus and unsets the GTK_TREE_VIEW_DRAW_KEYFOCUS flag */
|
||||
@@ -5036,7 +5064,8 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
flags,
|
||||
draw_focus);
|
||||
draw_focus,
|
||||
node);
|
||||
if (gtk_tree_view_draw_expanders (tree_view)
|
||||
&& (node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
|
||||
{
|
||||
@@ -5075,7 +5104,8 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
flags,
|
||||
draw_focus);
|
||||
draw_focus,
|
||||
node);
|
||||
}
|
||||
|
||||
if (draw_hgrid_lines)
|
||||
@@ -6856,13 +6886,195 @@ install_scroll_sync_handler (GtkTreeView *tree_view)
|
||||
}
|
||||
}
|
||||
|
||||
/* Gets the bottom row for a given top_row, taking
|
||||
* into account current treeview allocation.
|
||||
*/
|
||||
static GtkTreePath *
|
||||
gtk_tree_view_get_bottom_row (GtkTreeView *tree_view,
|
||||
GtkTreePath *top_row)
|
||||
{
|
||||
GtkRBTree *tree, *bottom_row_tree;
|
||||
GtkRBNode *node, *bottom_row_node;
|
||||
gint y;
|
||||
|
||||
if (!top_row)
|
||||
return NULL;
|
||||
|
||||
_gtk_tree_view_find_node (tree_view, top_row, &tree, &node);
|
||||
|
||||
if (!tree)
|
||||
return NULL;
|
||||
|
||||
y = _gtk_rbtree_node_find_offset (tree, node);
|
||||
y += gtk_adjustment_get_page_size (tree_view->priv->vadjustment);
|
||||
y = CLAMP (y,
|
||||
(gint) gtk_adjustment_get_lower (tree_view->priv->vadjustment),
|
||||
(gint) gtk_adjustment_get_upper (tree_view->priv->vadjustment));
|
||||
|
||||
if (y >= tree_view->priv->height)
|
||||
y = tree_view->priv->height - 1;
|
||||
|
||||
_gtk_rbtree_find_offset (tree_view->priv->tree, y,
|
||||
&bottom_row_tree,
|
||||
&bottom_row_node);
|
||||
|
||||
if (!bottom_row_tree)
|
||||
return NULL;
|
||||
|
||||
return _gtk_tree_view_find_path (tree_view,
|
||||
bottom_row_tree,
|
||||
bottom_row_node);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_cancel_row_range (GtkTreeView *tree_view,
|
||||
GtkTreePath *from,
|
||||
GtkTreePath *to)
|
||||
{
|
||||
GtkRBNode *from_node, *to_node;
|
||||
GtkRBTree *tree;
|
||||
|
||||
if (gtk_tree_path_compare (from, to) > 0)
|
||||
{
|
||||
GtkTreePath *tmp;
|
||||
|
||||
tmp = from;
|
||||
from = to;
|
||||
to = tmp;
|
||||
}
|
||||
|
||||
_gtk_tree_view_find_node (tree_view, to, &tree, &to_node);
|
||||
_gtk_tree_view_find_node (tree_view, from, &tree, &from_node);
|
||||
|
||||
if (!from_node || !to_node)
|
||||
return;
|
||||
|
||||
while (from_node)
|
||||
{
|
||||
GList *columns;
|
||||
|
||||
for (columns = tree_view->priv->columns; columns; columns = columns->next)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
column = columns->data;
|
||||
_gtk_tree_view_column_cancel_animations (column, from_node);
|
||||
}
|
||||
|
||||
if (from_node != to_node)
|
||||
_gtk_rbtree_next_full (tree, from_node, &tree, &from_node);
|
||||
else
|
||||
from_node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_cancel_row_animations (GtkTreeView *tree_view,
|
||||
GtkTreePath *top_row,
|
||||
GtkTreePath *bottom_row)
|
||||
{
|
||||
GtkTreePath *old_top_row, *old_bottom_row;
|
||||
GtkTreePath *start_path = NULL;
|
||||
GtkRBNode *node;
|
||||
GtkRBTree *tree;
|
||||
|
||||
if (!tree_view->priv->top_row &&
|
||||
!tree_view->priv->bottom_row)
|
||||
return;
|
||||
|
||||
old_top_row = gtk_tree_row_reference_get_path (tree_view->priv->top_row);
|
||||
old_bottom_row = gtk_tree_row_reference_get_path (tree_view->priv->bottom_row);
|
||||
|
||||
if (gtk_tree_path_compare (old_top_row, top_row) < 0)
|
||||
{
|
||||
/* If the top row moved downwards, cancel all running animations
|
||||
* from the new top row upwards, or optionally cancel all previous
|
||||
* view contents if it's been scrolled to a completely disconnected
|
||||
* place.
|
||||
*/
|
||||
if (gtk_tree_path_compare (top_row, old_bottom_row) < 0)
|
||||
{
|
||||
/* Top row is in the viewable range,
|
||||
* start from the one right above it
|
||||
*/
|
||||
_gtk_tree_view_find_node (tree_view, top_row, &tree, &node);
|
||||
|
||||
if (tree)
|
||||
{
|
||||
_gtk_rbtree_prev_full (tree, node, &tree, &node);
|
||||
|
||||
if (tree)
|
||||
start_path = _gtk_tree_view_find_path (tree_view, tree, node);
|
||||
}
|
||||
}
|
||||
else
|
||||
start_path = gtk_tree_path_copy (old_bottom_row);
|
||||
|
||||
if (start_path)
|
||||
{
|
||||
gtk_tree_view_cancel_row_range (tree_view, start_path, old_top_row);
|
||||
gtk_tree_path_free (start_path);
|
||||
start_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_tree_path_compare (old_bottom_row, bottom_row) > 0)
|
||||
{
|
||||
/* If the bottom row moved upwards, cancel all running
|
||||
* animations from the bottom row downwards, handling
|
||||
* also jumps through the view.
|
||||
*/
|
||||
if (gtk_tree_path_compare (bottom_row, old_top_row) > 0)
|
||||
{
|
||||
/* Bottom row is in the viewable range,
|
||||
* start from the one right above it
|
||||
*/
|
||||
_gtk_tree_view_find_node (tree_view, bottom_row, &tree, &node);
|
||||
|
||||
if (tree)
|
||||
{
|
||||
_gtk_rbtree_next_full (tree, node, &tree, &node);
|
||||
|
||||
if (tree)
|
||||
start_path = _gtk_tree_view_find_path (tree_view, tree, node);
|
||||
}
|
||||
}
|
||||
else
|
||||
start_path = gtk_tree_path_copy (old_top_row);
|
||||
|
||||
if (start_path)
|
||||
{
|
||||
gtk_tree_view_cancel_row_range (tree_view, start_path, old_bottom_row);
|
||||
gtk_tree_path_free (start_path);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_tree_path_free (old_top_row);
|
||||
gtk_tree_path_free (old_bottom_row);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_set_top_row (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
gint offset)
|
||||
{
|
||||
GtkTreePath *bottom_path = NULL;
|
||||
|
||||
if (path)
|
||||
bottom_path = gtk_tree_view_get_bottom_row (tree_view, path);
|
||||
|
||||
if (tree_view->priv->top_row &&
|
||||
tree_view->priv->bottom_row)
|
||||
gtk_tree_view_cancel_row_animations (tree_view, path, bottom_path);
|
||||
|
||||
gtk_tree_row_reference_free (tree_view->priv->top_row);
|
||||
|
||||
if (tree_view->priv->bottom_row)
|
||||
{
|
||||
gtk_tree_row_reference_free (tree_view->priv->bottom_row);
|
||||
tree_view->priv->bottom_row = NULL;
|
||||
}
|
||||
|
||||
if (!path)
|
||||
{
|
||||
tree_view->priv->top_row = NULL;
|
||||
@@ -6872,6 +7084,9 @@ gtk_tree_view_set_top_row (GtkTreeView *tree_view,
|
||||
{
|
||||
tree_view->priv->top_row = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), tree_view->priv->model, path);
|
||||
tree_view->priv->top_row_dy = offset;
|
||||
|
||||
if (bottom_path)
|
||||
tree_view->priv->bottom_row = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), tree_view->priv->model, bottom_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8972,6 +9187,29 @@ check_selection_helper (GtkRBTree *tree,
|
||||
_gtk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, check_selection_helper, data);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_row_animation_helper (GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeView *tree_view = user_data;
|
||||
GList *columns;
|
||||
|
||||
for (columns = tree_view->priv->columns;
|
||||
columns;
|
||||
columns = columns->next)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
column = columns->data;
|
||||
_gtk_tree_view_column_cancel_animations (column, node);
|
||||
}
|
||||
|
||||
if (node->children)
|
||||
_gtk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER,
|
||||
cancel_row_animation_helper, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_row_deleted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
@@ -8994,6 +9232,10 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
|
||||
if (tree == NULL)
|
||||
return;
|
||||
|
||||
_gtk_rbtree_traverse (tree, node, G_POST_ORDER,
|
||||
cancel_row_animation_helper,
|
||||
tree_view);
|
||||
|
||||
/* check if the selection has been changed */
|
||||
_gtk_rbtree_traverse (tree, node, G_POST_ORDER,
|
||||
check_selection_helper, &selection_changed);
|
||||
@@ -11315,6 +11557,8 @@ void
|
||||
gtk_tree_view_set_model (GtkTreeView *tree_view,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
GList *columns;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
|
||||
g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
|
||||
|
||||
@@ -11327,6 +11571,15 @@ gtk_tree_view_set_model (GtkTreeView *tree_view,
|
||||
tree_view->priv->scroll_to_path = NULL;
|
||||
}
|
||||
|
||||
/* Have all columns cancel every animation */
|
||||
for (columns = tree_view->priv->columns; columns; columns = columns->next)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
column = columns->data;
|
||||
_gtk_tree_view_column_cancel_animations (column, NULL);
|
||||
}
|
||||
|
||||
if (tree_view->priv->model)
|
||||
{
|
||||
GList *tmplist = tree_view->priv->columns;
|
||||
@@ -12852,6 +13105,8 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
|
||||
tree_view->priv->last_button_x = -1;
|
||||
tree_view->priv->last_button_y = -1;
|
||||
|
||||
_gtk_rbtree_traverse (node->children, node->children->root, G_PRE_ORDER, cancel_row_animation_helper, tree_view);
|
||||
|
||||
if (gtk_tree_view_unref_and_check_selection_tree (tree_view, node->children))
|
||||
{
|
||||
_gtk_rbtree_remove (node->children);
|
||||
@@ -14591,7 +14846,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
|
||||
cr,
|
||||
&background_area,
|
||||
&cell_area,
|
||||
0, FALSE);
|
||||
0, FALSE, NULL);
|
||||
}
|
||||
cell_offset += gtk_tree_view_column_get_width (column);
|
||||
}
|
||||
|
@@ -2891,11 +2891,12 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
|
||||
**/
|
||||
void
|
||||
_gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
gboolean draw_focus)
|
||||
cairo_t *cr,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
guint flags,
|
||||
gboolean draw_focus,
|
||||
gpointer anim_id)
|
||||
{
|
||||
GtkTreeViewColumnPrivate *priv;
|
||||
|
||||
@@ -2907,15 +2908,32 @@ _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
|
||||
priv = tree_column->priv;
|
||||
|
||||
cairo_save (cr);
|
||||
gtk_cell_area_set_animation_id (priv->cell_area, anim_id);
|
||||
|
||||
gtk_cell_area_render (priv->cell_area, priv->cell_area_context,
|
||||
priv->tree_view, cr,
|
||||
background_area, cell_area, flags,
|
||||
draw_focus);
|
||||
|
||||
gtk_cell_area_set_animation_id (priv->cell_area, NULL);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_tree_view_column_cancel_animations (GtkTreeViewColumn *tree_column,
|
||||
gpointer anim_id)
|
||||
{
|
||||
GtkTreeViewColumnPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
|
||||
priv = tree_column->priv;
|
||||
|
||||
gtk_cell_area_forget_animation_id (priv->cell_area,
|
||||
priv->tree_view,
|
||||
anim_id);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
|
||||
GdkEvent *event,
|
||||
|
Reference in New Issue
Block a user