mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -05:00
clutter: Split pick and paint
Add the corresponding clutter_actor_pick() and clutter_actor_continue_pick() as public APIs, and use them in pick overrides and ClutterEffect. https://gitlab.gnome.org/GNOME/mutter/merge_requests/865
This commit is contained in:
parent
98892391d7
commit
179d5ba6a6
@ -2373,7 +2373,7 @@ clutter_actor_real_pick (ClutterActor *self)
|
||||
for (iter = self->priv->first_child;
|
||||
iter != NULL;
|
||||
iter = iter->priv->next_sibling)
|
||||
clutter_actor_paint (iter);
|
||||
clutter_actor_pick (iter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4215,6 +4215,149 @@ clutter_actor_continue_paint (ClutterActor *self)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_pick:
|
||||
* @actor: A #ClutterActor
|
||||
*
|
||||
* Asks @actor to perform a pick.
|
||||
*/
|
||||
void
|
||||
clutter_actor_pick (ClutterActor *actor)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterActorBox clip;
|
||||
gboolean clip_set = FALSE;
|
||||
|
||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (actor))
|
||||
return;
|
||||
|
||||
priv = actor->priv;
|
||||
|
||||
/* if we aren't paintable (not in a toplevel with all
|
||||
* parents paintable) then do nothing.
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (actor))
|
||||
return;
|
||||
|
||||
clutter_actor_ensure_resource_scale (actor);
|
||||
|
||||
/* mark that we are in the paint process */
|
||||
CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
if (priv->enable_model_view_transform)
|
||||
{
|
||||
CoglMatrix matrix;
|
||||
|
||||
cogl_get_modelview_matrix (&matrix);
|
||||
_clutter_actor_apply_modelview_transform (actor, &matrix);
|
||||
cogl_set_modelview_matrix (&matrix);
|
||||
}
|
||||
|
||||
if (priv->has_clip)
|
||||
{
|
||||
clip.x1 = priv->clip.origin.x;
|
||||
clip.y1 = priv->clip.origin.y;
|
||||
clip.x2 = priv->clip.origin.x + priv->clip.size.width;
|
||||
clip.y2 = priv->clip.origin.y + priv->clip.size.height;
|
||||
clip_set = TRUE;
|
||||
}
|
||||
else if (priv->clip_to_allocation)
|
||||
{
|
||||
clip.x1 = 0.f;
|
||||
clip.y1 = 0.f;
|
||||
clip.x2 = priv->allocation.x2 - priv->allocation.x1;
|
||||
clip.y2 = priv->allocation.y2 - priv->allocation.y1;
|
||||
clip_set = TRUE;
|
||||
}
|
||||
|
||||
if (clip_set)
|
||||
clip_set = _clutter_actor_push_pick_clip (actor, &clip);
|
||||
|
||||
priv->next_effect_to_paint = NULL;
|
||||
if (priv->effects)
|
||||
{
|
||||
priv->next_effect_to_paint =
|
||||
_clutter_meta_group_peek_metas (priv->effects);
|
||||
}
|
||||
|
||||
clutter_actor_continue_pick (actor);
|
||||
|
||||
if (clip_set)
|
||||
_clutter_actor_pop_pick_clip (actor);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
|
||||
/* paint sequence complete */
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_continue_pick:
|
||||
* @actor: A #ClutterActor
|
||||
*
|
||||
* Run the next stage of the pick sequence. This function should only
|
||||
* be called within the implementation of the ‘pick’ virtual of a
|
||||
* #ClutterEffect. It will cause the run method of the next effect to
|
||||
* be applied, or it will pick the actual actor if the current effect
|
||||
* is the last effect in the chain.
|
||||
*/
|
||||
void
|
||||
clutter_actor_continue_pick (ClutterActor *actor)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
g_return_if_fail (CLUTTER_ACTOR_IN_PICK (actor));
|
||||
|
||||
priv = actor->priv;
|
||||
|
||||
/* Skip any effects that are disabled */
|
||||
while (priv->next_effect_to_paint &&
|
||||
!clutter_actor_meta_get_enabled (priv->next_effect_to_paint->data))
|
||||
priv->next_effect_to_paint = priv->next_effect_to_paint->next;
|
||||
|
||||
/* If this has come from the last effect then we'll just pick the
|
||||
* actual actor.
|
||||
*/
|
||||
if (priv->next_effect_to_paint == NULL)
|
||||
{
|
||||
/* The actor will log a silhouette of itself to the stage pick log.
|
||||
*
|
||||
* XXX:2.0 - Call the pick() virtual directly
|
||||
*/
|
||||
if (g_signal_has_handler_pending (actor, actor_signals[PICK],
|
||||
0, TRUE))
|
||||
g_signal_emit (actor, actor_signals[PICK], 0);
|
||||
else
|
||||
CLUTTER_ACTOR_GET_CLASS (actor)->pick (actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterEffect *old_current_effect;
|
||||
ClutterEffectPaintFlags run_flags = 0;
|
||||
|
||||
/* Cache the current effect so that we can put it back before
|
||||
* returning.
|
||||
*/
|
||||
old_current_effect = priv->current_effect;
|
||||
|
||||
priv->current_effect = priv->next_effect_to_paint->data;
|
||||
priv->next_effect_to_paint = priv->next_effect_to_paint->next;
|
||||
|
||||
/* We can't determine when an actor has been modified since
|
||||
* its last pick so lets just assume it has always been
|
||||
* modified.
|
||||
*/
|
||||
run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY;
|
||||
_clutter_effect_pick (priv->current_effect, run_flags);
|
||||
|
||||
priv->current_effect = old_current_effect;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_actor_stop_transitions (ClutterActor *self)
|
||||
{
|
||||
|
@ -353,6 +353,10 @@ void clutter_actor_paint
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_continue_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_pick (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_continue_pick (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_redraw (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_redraw_with_clip (ClutterActor *self,
|
||||
|
@ -223,7 +223,7 @@ clutter_effect_real_pick (ClutterEffect *effect,
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (actor_meta);
|
||||
clutter_actor_continue_paint (actor);
|
||||
clutter_actor_continue_pick (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -67,6 +67,7 @@ typedef struct _ClutterVertex4 ClutterVertex4;
|
||||
#define CLUTTER_ACTOR_IN_DESTRUCTION(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_DESTRUCTION) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_REPARENT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_REPARENT) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_PAINT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PAINT) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_PICK(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PICK) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_RELAYOUT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_RELAYOUT) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_PREF_WIDTH(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_WIDTH) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_PREF_HEIGHT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_HEIGHT) != FALSE)
|
||||
@ -104,9 +105,10 @@ typedef enum
|
||||
|
||||
/* Used to avoid recursion */
|
||||
CLUTTER_IN_PAINT = 1 << 5,
|
||||
CLUTTER_IN_PICK = 1 << 6,
|
||||
|
||||
/* Used to avoid recursion */
|
||||
CLUTTER_IN_RELAYOUT = 1 << 6,
|
||||
CLUTTER_IN_RELAYOUT = 1 << 7,
|
||||
} ClutterPrivateFlags;
|
||||
|
||||
/*
|
||||
|
@ -168,7 +168,7 @@ meta_surface_actor_pick (ClutterActor *actor)
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
clutter_actor_paint (child);
|
||||
clutter_actor_pick (child);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
Loading…
Reference in New Issue
Block a user