Lightbox: complete radial effect for modal dialogs

Rework the radial effect to use similar code to MetaBackground,
and adjust parameters to make it more noticeable.

https://bugzilla.gnome.org/show_bug.cgi?id=725830
This commit is contained in:
Giovanni Campagna 2014-03-06 16:17:36 +01:00
parent 821768a414
commit fc4bc5277a
4 changed files with 123 additions and 46 deletions

View File

@ -11,30 +11,60 @@ const Params = imports.misc.params;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const DEFAULT_FADE_FACTOR = 0.4; const DEFAULT_FADE_FACTOR = 0.4;
const VIGNETTE_BRIGHTNESS = 0.8;
const VIGNETTE_SHARPNESS = 0.7;
const GLSL_DIM_EFFECT_DECLARATIONS = '\ const VIGNETTE_DECLARATIONS = '\
float compute_dim_factor (const vec2 coords) {\ uniform float brightness;\n\
vec2 dist = coords - vec2(0.5, 0.5); \ uniform float vignette_sharpness;\n';
float elipse_radius = 0.5; \
/* interpolate darkening value, based on distance from screen center */ \ const VIGNETTE_CODE = '\
float val = min(length(dist), elipse_radius); \ cogl_color_out.a = cogl_color_in.a;\n\
return mix(0.3, 1.0, val / elipse_radius) * 0.4; \ cogl_color_out.rgb = vec3(0.0, 0.0, 0.0);\n\
}'; vec2 position = cogl_tex_coord_in[0].xy - 0.5;\n\
const GLSL_DIM_EFFECT_CODE = '\ float t = length(2.0 * position);\n\
float a = compute_dim_factor (cogl_tex_coord0_in.xy);\ t = clamp(t, 0.0, 1.0);\n\
cogl_color_out = vec4(0, 0, 0, cogl_color_in.a * a);' float pixel_brightness = mix(1.0, 1.0 - vignette_sharpness, t);\n\
; cogl_color_out.a = cogl_color_out.a * (1 - pixel_brightness * brightness);';
const RadialShaderQuad = new Lang.Class({ const RadialShaderQuad = new Lang.Class({
Name: 'RadialShaderQuad', Name: 'RadialShaderQuad',
Extends: Shell.GLSLQuad, Extends: Shell.GLSLQuad,
_init: function(params) {
this.parent(params);
this._brightnessLocation = this.get_uniform_location('brightness');
this._sharpnessLocation = this.get_uniform_location('vignette_sharpness');
this.brightness = 1.0;
this.vignetteSharpness = 0.0;
},
vfunc_build_pipeline: function() { vfunc_build_pipeline: function() {
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
GLSL_DIM_EFFECT_DECLARATIONS, VIGNETTE_DECLARATIONS, VIGNETTE_CODE, true);
GLSL_DIM_EFFECT_CODE,
true);
}, },
get brightness() {
return this._brightness;
},
set brightness(v) {
this._brightness = v;
this.set_uniform_float(this._brightnessLocation,
1, [this._brightness]);
},
get vignetteSharpness() {
return this._sharpness;
},
set vignetteSharpness(v) {
this._sharpness = v;
this.set_uniform_float(this._sharpnessLocation,
1, [this._sharpness]);
}
}); });
/** /**
@ -75,6 +105,7 @@ const Lightbox = new Lang.Class({
this._container = container; this._container = container;
this._children = container.get_children(); this._children = container.get_children();
this._fadeFactor = params.fadeFactor; this._fadeFactor = params.fadeFactor;
this._radialEffect = params.radialEffect;
if (params.radialEffect) if (params.radialEffect)
this.actor = new RadialShaderQuad({ x: 0, this.actor = new RadialShaderQuad({ x: 0,
y: 0, y: 0,
@ -82,6 +113,7 @@ const Lightbox = new Lang.Class({
else else
this.actor = new St.Bin({ x: 0, this.actor = new St.Bin({ x: 0,
y: 0, y: 0,
opacity: 0,
style_class: 'lightbox', style_class: 'lightbox',
reactive: params.inhibitEvents }); reactive: params.inhibitEvents });
@ -133,9 +165,18 @@ const Lightbox = new Lang.Class({
fadeInTime = fadeInTime || 0; fadeInTime = fadeInTime || 0;
Tweener.removeTweens(this.actor); Tweener.removeTweens(this.actor);
if (fadeInTime != 0) { if (this._radialEffect) {
this.shown = false; Tweener.addTween(this.actor,
this.actor.opacity = 0; { brightness: VIGNETTE_BRIGHTNESS,
vignetteSharpness: VIGNETTE_SHARPNESS,
time: fadeInTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.shown = true;
this.emit('shown');
})
});
} else {
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ opacity: 255 * this._fadeFactor, { opacity: 255 * this._fadeFactor,
time: fadeInTime, time: fadeInTime,
@ -145,11 +186,8 @@ const Lightbox = new Lang.Class({
this.emit('shown'); this.emit('shown');
}) })
}); });
} else {
this.actor.opacity = 255 * this._fadeFactor;
this.shown = true;
this.emit('shown');
} }
this.actor.show(); this.actor.show();
}, },
@ -158,7 +196,18 @@ const Lightbox = new Lang.Class({
this.shown = false; this.shown = false;
Tweener.removeTweens(this.actor); Tweener.removeTweens(this.actor);
if (fadeOutTime != 0) { if (this._radialEffect) {
Tweener.addTween(this.actor,
{ brightness: 1.0,
vignetteSharpness: 0.0,
opacity: 0,
time: fadeOutTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.actor.hide();
})
});
} else {
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ opacity: 0, { opacity: 0,
time: fadeOutTime, time: fadeOutTime,
@ -167,8 +216,6 @@ const Lightbox = new Lang.Class({
this.actor.hide(); this.actor.hide();
}) })
}); });
} else {
this.actor.hide();
} }
}, },

View File

@ -14,6 +14,7 @@ const Gdk = imports.gi.Gdk;
const Background = imports.ui.background; const Background = imports.ui.background;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const LayoutManager = imports.ui.layout; const LayoutManager = imports.ui.layout;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
const OverviewControls = imports.ui.overviewControls; const OverviewControls = imports.ui.overviewControls;
@ -196,11 +197,7 @@ const Overview = new Lang.Class({
Tweener.addTween(background, Tweener.addTween(background,
{ brightness: 1.0, { brightness: 1.0,
time: SHADE_ANIMATION_TIME, vignetteSharpness: 0.0,
transition: 'easeOutQuad'
});
Tweener.addTween(background,
{ vignetteSharpness: 0.0,
time: SHADE_ANIMATION_TIME, time: SHADE_ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
@ -213,12 +210,8 @@ const Overview = new Lang.Class({
let background = backgrounds[i]._delegate; let background = backgrounds[i]._delegate;
Tweener.addTween(background, Tweener.addTween(background,
{ brightness: 0.8, { brightness: Lightbox.VIGNETTE_BRIGHTNESS,
time: SHADE_ANIMATION_TIME, vignetteSharpness: Lightbox.VIGNETTE_SHARPNESS,
transition: 'easeOutQuad'
});
Tweener.addTween(background,
{ vignetteSharpness: 0.7,
time: SHADE_ANIMATION_TIME, time: SHADE_ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });

View File

@ -24,7 +24,6 @@ G_DEFINE_TYPE (ShellGLSLQuad, shell_glsl_quad, CLUTTER_TYPE_ACTOR);
struct _ShellGLSLQuadPrivate struct _ShellGLSLQuadPrivate
{ {
CoglPipeline *pipeline; CoglPipeline *pipeline;
CoglTexture2D *texture;
}; };
static void static void
@ -40,9 +39,10 @@ shell_glsl_quad_paint (ClutterActor *actor)
paint_opacity = clutter_actor_get_paint_opacity (actor); paint_opacity = clutter_actor_get_paint_opacity (actor);
clutter_actor_get_allocation_box (actor, &box); clutter_actor_get_allocation_box (actor, &box);
/* semi-transparent black */
cogl_pipeline_set_color4ub (priv->pipeline, cogl_pipeline_set_color4ub (priv->pipeline,
0, 0, 0, paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity); paint_opacity);
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
priv->pipeline, priv->pipeline,
@ -105,7 +105,6 @@ shell_glsl_quad_dispose (GObject *gobject)
priv = self->priv; priv = self->priv;
g_clear_pointer (&priv->pipeline, cogl_object_unref); g_clear_pointer (&priv->pipeline, cogl_object_unref);
g_clear_pointer (&priv->texture, cogl_object_unref);
G_OBJECT_CLASS (shell_glsl_quad_parent_class)->dispose (gobject); G_OBJECT_CLASS (shell_glsl_quad_parent_class)->dispose (gobject);
} }
@ -123,7 +122,6 @@ shell_glsl_quad_constructed (GObject *object)
ShellGLSLQuadClass *klass; ShellGLSLQuadClass *klass;
CoglContext *ctx = CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ()); clutter_backend_get_cogl_context (clutter_get_default_backend ());
static const uint8_t tex_data[] = { 0, 0, 0, 0 };
G_OBJECT_CLASS (shell_glsl_quad_parent_class)->constructed (object); G_OBJECT_CLASS (shell_glsl_quad_parent_class)->constructed (object);
@ -144,11 +142,7 @@ shell_glsl_quad_constructed (GObject *object)
self->priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); self->priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
self->priv->texture = cogl_texture_2d_new_from_data (ctx, 1, 1, cogl_pipeline_set_layer_null_texture (self->priv->pipeline, 0, COGL_TEXTURE_TYPE_2D);
COGL_PIXEL_FORMAT_RGBA_8888,
0, tex_data, NULL);
cogl_pipeline_set_layer_texture (self->priv->pipeline, 0,
COGL_TEXTURE (self->priv->texture));
} }
static void static void
@ -164,3 +158,38 @@ shell_glsl_quad_class_init (ShellGLSLQuadClass *klass)
g_type_class_add_private (klass, sizeof (ShellGLSLQuadPrivate)); g_type_class_add_private (klass, sizeof (ShellGLSLQuadPrivate));
} }
/**
* shell_glsl_quad_get_uniform_location:
* @quad: a #ShellGLSLQuad
* @name: the uniform name
*
* Returns: the location of the uniform named @name, that can be
* passed to shell_glsl_quad_set_uniform_float().
*/
int
shell_glsl_quad_get_uniform_location (ShellGLSLQuad *quad,
const char *name)
{
return cogl_pipeline_get_uniform_location (quad->priv->pipeline, name);
}
/**
* shell_glsl_quad_set_uniform_float:
* @quad: a #ShellGLSLQuad
* @uniform: the uniform location (as returned by shell_glsl_quad_get_uniform_location())
* @n_components: the number of components in the uniform (eg. 3 for a vec3)
* @total_count: the total number of floats in @value
* @value: (array length=total_count): the array of floats to set @uniform
*/
void
shell_glsl_quad_set_uniform_float (ShellGLSLQuad *quad,
int uniform,
int n_components,
int total_count,
const float *value)
{
cogl_pipeline_set_uniform_float (quad->priv->pipeline, uniform,
n_components, total_count / n_components,
value);
}

View File

@ -61,4 +61,12 @@ void shell_glsl_quad_add_glsl_snippet (ShellGLSLQuad *quad,
const char *code, const char *code,
gboolean is_replace); gboolean is_replace);
int shell_glsl_quad_get_uniform_location (ShellGLSLQuad *quad,
const char *name);
void shell_glsl_quad_set_uniform_float (ShellGLSLQuad *quad,
int uniform,
int n_components,
int total_count,
const float *value);
#endif /* __SHELL_GLSL_QUAD_H__ */ #endif /* __SHELL_GLSL_QUAD_H__ */