From fc4bc5277a686cedab7dad248ed33c34ab78011c Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 6 Mar 2014 16:17:36 +0100 Subject: [PATCH] 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 --- js/ui/lightbox.js | 97 ++++++++++++++++++++++++++++++++----------- js/ui/overview.js | 15 ++----- src/shell-glsl-quad.c | 49 +++++++++++++++++----- src/shell-glsl-quad.h | 8 ++++ 4 files changed, 123 insertions(+), 46 deletions(-) diff --git a/js/ui/lightbox.js b/js/ui/lightbox.js index e8d391f95..4b07debad 100644 --- a/js/ui/lightbox.js +++ b/js/ui/lightbox.js @@ -11,30 +11,60 @@ const Params = imports.misc.params; const Tweener = imports.ui.tweener; const DEFAULT_FADE_FACTOR = 0.4; +const VIGNETTE_BRIGHTNESS = 0.8; +const VIGNETTE_SHARPNESS = 0.7; -const GLSL_DIM_EFFECT_DECLARATIONS = '\ -float compute_dim_factor (const vec2 coords) {\ - vec2 dist = coords - vec2(0.5, 0.5); \ - float elipse_radius = 0.5; \ - /* interpolate darkening value, based on distance from screen center */ \ - float val = min(length(dist), elipse_radius); \ - return mix(0.3, 1.0, val / elipse_radius) * 0.4; \ -}'; -const GLSL_DIM_EFFECT_CODE = '\ - float a = compute_dim_factor (cogl_tex_coord0_in.xy);\ - cogl_color_out = vec4(0, 0, 0, cogl_color_in.a * a);' -; +const VIGNETTE_DECLARATIONS = '\ +uniform float brightness;\n\ +uniform float vignette_sharpness;\n'; + +const VIGNETTE_CODE = '\ +cogl_color_out.a = cogl_color_in.a;\n\ +cogl_color_out.rgb = vec3(0.0, 0.0, 0.0);\n\ +vec2 position = cogl_tex_coord_in[0].xy - 0.5;\n\ +float t = length(2.0 * position);\n\ +t = clamp(t, 0.0, 1.0);\n\ +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({ Name: 'RadialShaderQuad', 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() { this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, - GLSL_DIM_EFFECT_DECLARATIONS, - GLSL_DIM_EFFECT_CODE, - true); + VIGNETTE_DECLARATIONS, VIGNETTE_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._children = container.get_children(); this._fadeFactor = params.fadeFactor; + this._radialEffect = params.radialEffect; if (params.radialEffect) this.actor = new RadialShaderQuad({ x: 0, y: 0, @@ -82,6 +113,7 @@ const Lightbox = new Lang.Class({ else this.actor = new St.Bin({ x: 0, y: 0, + opacity: 0, style_class: 'lightbox', reactive: params.inhibitEvents }); @@ -133,9 +165,18 @@ const Lightbox = new Lang.Class({ fadeInTime = fadeInTime || 0; Tweener.removeTweens(this.actor); - if (fadeInTime != 0) { - this.shown = false; - this.actor.opacity = 0; + if (this._radialEffect) { + Tweener.addTween(this.actor, + { 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, { opacity: 255 * this._fadeFactor, time: fadeInTime, @@ -145,11 +186,8 @@ const Lightbox = new Lang.Class({ this.emit('shown'); }) }); - } else { - this.actor.opacity = 255 * this._fadeFactor; - this.shown = true; - this.emit('shown'); } + this.actor.show(); }, @@ -158,7 +196,18 @@ const Lightbox = new Lang.Class({ this.shown = false; 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, { opacity: 0, time: fadeOutTime, @@ -167,8 +216,6 @@ const Lightbox = new Lang.Class({ this.actor.hide(); }) }); - } else { - this.actor.hide(); } }, diff --git a/js/ui/overview.js b/js/ui/overview.js index db52c5450..a60a966af 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -14,6 +14,7 @@ const Gdk = imports.gi.Gdk; const Background = imports.ui.background; const DND = imports.ui.dnd; const LayoutManager = imports.ui.layout; +const Lightbox = imports.ui.lightbox; const Main = imports.ui.main; const MessageTray = imports.ui.messageTray; const OverviewControls = imports.ui.overviewControls; @@ -196,11 +197,7 @@ const Overview = new Lang.Class({ Tweener.addTween(background, { brightness: 1.0, - time: SHADE_ANIMATION_TIME, - transition: 'easeOutQuad' - }); - Tweener.addTween(background, - { vignetteSharpness: 0.0, + vignetteSharpness: 0.0, time: SHADE_ANIMATION_TIME, transition: 'easeOutQuad' }); @@ -213,12 +210,8 @@ const Overview = new Lang.Class({ let background = backgrounds[i]._delegate; Tweener.addTween(background, - { brightness: 0.8, - time: SHADE_ANIMATION_TIME, - transition: 'easeOutQuad' - }); - Tweener.addTween(background, - { vignetteSharpness: 0.7, + { brightness: Lightbox.VIGNETTE_BRIGHTNESS, + vignetteSharpness: Lightbox.VIGNETTE_SHARPNESS, time: SHADE_ANIMATION_TIME, transition: 'easeOutQuad' }); diff --git a/src/shell-glsl-quad.c b/src/shell-glsl-quad.c index 5e3ce1835..22edc9238 100644 --- a/src/shell-glsl-quad.c +++ b/src/shell-glsl-quad.c @@ -24,7 +24,6 @@ G_DEFINE_TYPE (ShellGLSLQuad, shell_glsl_quad, CLUTTER_TYPE_ACTOR); struct _ShellGLSLQuadPrivate { CoglPipeline *pipeline; - CoglTexture2D *texture; }; static void @@ -40,9 +39,10 @@ shell_glsl_quad_paint (ClutterActor *actor) paint_opacity = clutter_actor_get_paint_opacity (actor); clutter_actor_get_allocation_box (actor, &box); - /* semi-transparent black */ cogl_pipeline_set_color4ub (priv->pipeline, - 0, 0, 0, + paint_opacity, + paint_opacity, + paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), priv->pipeline, @@ -105,7 +105,6 @@ shell_glsl_quad_dispose (GObject *gobject) priv = self->priv; 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); } @@ -123,7 +122,6 @@ shell_glsl_quad_constructed (GObject *object) ShellGLSLQuadClass *klass; CoglContext *ctx = 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); @@ -144,11 +142,7 @@ shell_glsl_quad_constructed (GObject *object) self->priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); - self->priv->texture = cogl_texture_2d_new_from_data (ctx, 1, 1, - COGL_PIXEL_FORMAT_RGBA_8888, - 0, tex_data, NULL); - cogl_pipeline_set_layer_texture (self->priv->pipeline, 0, - COGL_TEXTURE (self->priv->texture)); + cogl_pipeline_set_layer_null_texture (self->priv->pipeline, 0, COGL_TEXTURE_TYPE_2D); } static void @@ -164,3 +158,38 @@ shell_glsl_quad_class_init (ShellGLSLQuadClass *klass) 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); +} diff --git a/src/shell-glsl-quad.h b/src/shell-glsl-quad.h index 04a93629d..f2b19bcd2 100644 --- a/src/shell-glsl-quad.h +++ b/src/shell-glsl-quad.h @@ -61,4 +61,12 @@ void shell_glsl_quad_add_glsl_snippet (ShellGLSLQuad *quad, const char *code, 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__ */