Add a radial background shade for modal dialogs
Use a new ShellGLSLQuad actor class to build a RadialEffect that can be enabled on Lightboxes to achieve a radial effect similar to the overview one. Then enable it for modal dialogs. https://bugzilla.gnome.org/show_bug.cgi?id=669798
This commit is contained in:
parent
5413010c60
commit
7e9ecf4eb2
@ -5,12 +5,38 @@ const Lang = imports.lang;
|
|||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const Params = imports.misc.params;
|
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 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 RadialShaderQuad = new Lang.Class({
|
||||||
|
Name: 'RadialShaderQuad',
|
||||||
|
Extends: Shell.GLSLQuad,
|
||||||
|
|
||||||
|
vfunc_build_pipeline: function() {
|
||||||
|
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
|
||||||
|
GLSL_DIM_EFFECT_DECLARATIONS,
|
||||||
|
GLSL_DIM_EFFECT_CODE,
|
||||||
|
true);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lightbox:
|
* Lightbox:
|
||||||
* @container: parent Clutter.Container
|
* @container: parent Clutter.Container
|
||||||
@ -43,15 +69,21 @@ const Lightbox = new Lang.Class({
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
fadeFactor: DEFAULT_FADE_FACTOR,
|
fadeFactor: DEFAULT_FADE_FACTOR,
|
||||||
|
radialEffect: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
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.actor = new St.Bin({ x: 0,
|
if (params.radialEffect)
|
||||||
y: 0,
|
this.actor = new RadialShaderQuad({ x: 0,
|
||||||
style_class: 'lightbox',
|
y: 0,
|
||||||
reactive: params.inhibitEvents });
|
reactive: params.inhibitEvents });
|
||||||
|
else
|
||||||
|
this.actor = new St.Bin({ x: 0,
|
||||||
|
y: 0,
|
||||||
|
style_class: 'lightbox',
|
||||||
|
reactive: params.inhibitEvents });
|
||||||
|
|
||||||
container.add_actor(this.actor);
|
container.add_actor(this.actor);
|
||||||
this.actor.raise_top();
|
this.actor.raise_top();
|
||||||
|
@ -89,7 +89,8 @@ const ModalDialog = new Lang.Class({
|
|||||||
|
|
||||||
if (!this._shellReactive) {
|
if (!this._shellReactive) {
|
||||||
this._lightbox = new Lightbox.Lightbox(this._group,
|
this._lightbox = new Lightbox.Lightbox(this._group,
|
||||||
{ inhibitEvents: true });
|
{ inhibitEvents: true,
|
||||||
|
radialEffect: true });
|
||||||
this._lightbox.highlight(this._backgroundBin);
|
this._lightbox.highlight(this._backgroundBin);
|
||||||
|
|
||||||
this._eventBlocker = new Clutter.Actor({ reactive: true });
|
this._eventBlocker = new Clutter.Actor({ reactive: true });
|
||||||
|
@ -92,6 +92,7 @@ shell_public_headers_h = \
|
|||||||
shell-app-usage.h \
|
shell-app-usage.h \
|
||||||
shell-embedded-window.h \
|
shell-embedded-window.h \
|
||||||
shell-generic-container.h \
|
shell-generic-container.h \
|
||||||
|
shell-glsl-quad.h \
|
||||||
shell-gtk-embed.h \
|
shell-gtk-embed.h \
|
||||||
shell-global.h \
|
shell-global.h \
|
||||||
shell-invert-lightness-effect.h \
|
shell-invert-lightness-effect.h \
|
||||||
@ -128,6 +129,7 @@ libgnome_shell_base_la_SOURCES = \
|
|||||||
shell-embedded-window-private.h \
|
shell-embedded-window-private.h \
|
||||||
shell-embedded-window.c \
|
shell-embedded-window.c \
|
||||||
shell-generic-container.c \
|
shell-generic-container.c \
|
||||||
|
shell-glsl-quad.c \
|
||||||
shell-invert-lightness-effect.c \
|
shell-invert-lightness-effect.c \
|
||||||
shell-keyring-prompt.h \
|
shell-keyring-prompt.h \
|
||||||
shell-keyring-prompt.c \
|
shell-keyring-prompt.c \
|
||||||
|
166
src/shell-glsl-quad.c
Normal file
166
src/shell-glsl-quad.c
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:shell-glsl-quad
|
||||||
|
* @short_description: Draw a rectangle using GLSL
|
||||||
|
*
|
||||||
|
* A #ShellGLSLQuad draws one single rectangle, sized to the allocation
|
||||||
|
* box, but allows running custom GLSL to the vertex and fragment
|
||||||
|
* stages of the graphic pipeline.
|
||||||
|
*
|
||||||
|
* To ease writing the shader, a single texture layer is also used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||||
|
#define COGL_ENABLE_EXPERIMENTAL_API
|
||||||
|
|
||||||
|
#include <cogl/cogl.h>
|
||||||
|
#include "shell-glsl-quad.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ShellGLSLQuad, shell_glsl_quad, CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
|
struct _ShellGLSLQuadPrivate
|
||||||
|
{
|
||||||
|
CoglPipeline *pipeline;
|
||||||
|
CoglTexture2D *texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_glsl_quad_paint (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ShellGLSLQuad *self = SHELL_GLSL_QUAD (actor);
|
||||||
|
ShellGLSLQuadPrivate *priv;
|
||||||
|
guint8 paint_opacity;
|
||||||
|
ClutterActorBox box;
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
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);
|
||||||
|
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
|
||||||
|
priv->pipeline,
|
||||||
|
box.x1, box.y1,
|
||||||
|
box.x2, box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_glsl_quad_add_glsl_snippet:
|
||||||
|
* @quad: a #ShellGLSLQuad
|
||||||
|
* @hook: where to insert the code
|
||||||
|
* @declarations: GLSL declarations
|
||||||
|
* @code: GLSL code
|
||||||
|
* @is_replace: wheter Cogl code should be replaced by the custom shader
|
||||||
|
*
|
||||||
|
* Adds a GLSL snippet to the pipeline used for drawing the actor texture.
|
||||||
|
* See #CoglSnippet for details.
|
||||||
|
*
|
||||||
|
* This is only valid inside the a call to the build_pipeline() virtual
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shell_glsl_quad_add_glsl_snippet (ShellGLSLQuad *quad,
|
||||||
|
ShellSnippetHook hook,
|
||||||
|
const char *declarations,
|
||||||
|
const char *code,
|
||||||
|
gboolean is_replace)
|
||||||
|
{
|
||||||
|
ShellGLSLQuadClass *klass = SHELL_GLSL_QUAD_GET_CLASS (quad);
|
||||||
|
CoglSnippet *snippet;
|
||||||
|
|
||||||
|
g_return_if_fail (klass->base_pipeline != NULL);
|
||||||
|
|
||||||
|
if (is_replace)
|
||||||
|
{
|
||||||
|
snippet = cogl_snippet_new (hook, declarations, NULL);
|
||||||
|
cogl_snippet_set_replace (snippet, code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snippet = cogl_snippet_new (hook, declarations, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hook == SHELL_SNIPPET_HOOK_VERTEX ||
|
||||||
|
hook == SHELL_SNIPPET_HOOK_FRAGMENT)
|
||||||
|
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||||
|
else
|
||||||
|
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
|
||||||
|
|
||||||
|
cogl_object_unref (snippet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_glsl_quad_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
ShellGLSLQuad *self = SHELL_GLSL_QUAD (gobject);
|
||||||
|
ShellGLSLQuadPrivate *priv;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_glsl_quad_init (ShellGLSLQuad *quad)
|
||||||
|
{
|
||||||
|
quad->priv = G_TYPE_INSTANCE_GET_PRIVATE (quad, SHELL_TYPE_GLSL_QUAD, ShellGLSLQuadPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_glsl_quad_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
ShellGLSLQuad *self;
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Note that, differently from ClutterBlurEffect, we are calling
|
||||||
|
this inside constructed, not init, so klass points to the most-derived
|
||||||
|
GTypeClass, not ShellGLSLQuadClass.
|
||||||
|
*/
|
||||||
|
klass = SHELL_GLSL_QUAD_GET_CLASS (object);
|
||||||
|
self = SHELL_GLSL_QUAD (object);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||||
|
{
|
||||||
|
klass->base_pipeline = cogl_pipeline_new (ctx);
|
||||||
|
|
||||||
|
if (klass->build_pipeline != NULL)
|
||||||
|
klass->build_pipeline (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_glsl_quad_class_init (ShellGLSLQuadClass *klass)
|
||||||
|
{
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->constructed = shell_glsl_quad_constructed;
|
||||||
|
gobject_class->dispose = shell_glsl_quad_dispose;
|
||||||
|
|
||||||
|
actor_class->paint = shell_glsl_quad_paint;
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ShellGLSLQuadPrivate));
|
||||||
|
}
|
64
src/shell-glsl-quad.h
Normal file
64
src/shell-glsl-quad.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
#ifndef __SHELL_GLSL_QUAD_H__
|
||||||
|
#define __SHELL_GLSL_QUAD_H__
|
||||||
|
|
||||||
|
#include "st.h"
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShellSnippetHook:
|
||||||
|
* Temporary hack to work around Cogl not exporting CoglSnippetHook in
|
||||||
|
* the 1.0 API. Don't use.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/* Per pipeline vertex hooks */
|
||||||
|
SHELL_SNIPPET_HOOK_VERTEX = 0,
|
||||||
|
SHELL_SNIPPET_HOOK_VERTEX_TRANSFORM,
|
||||||
|
|
||||||
|
/* Per pipeline fragment hooks */
|
||||||
|
SHELL_SNIPPET_HOOK_FRAGMENT = 2048,
|
||||||
|
|
||||||
|
/* Per layer vertex hooks */
|
||||||
|
SHELL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM = 4096,
|
||||||
|
|
||||||
|
/* Per layer fragment hooks */
|
||||||
|
SHELL_SNIPPET_HOOK_LAYER_FRAGMENT = 6144,
|
||||||
|
SHELL_SNIPPET_HOOK_TEXTURE_LOOKUP
|
||||||
|
} ShellSnippetHook;
|
||||||
|
|
||||||
|
#define SHELL_TYPE_GLSL_QUAD (shell_glsl_quad_get_type ())
|
||||||
|
#define SHELL_GLSL_QUAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_GLSL_QUAD, ShellGLSLQuad))
|
||||||
|
#define SHELL_GLSL_QUAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_GLSL_QUAD, ShellGLSLQuadClass))
|
||||||
|
#define SHELL_IS_GLSL_QUAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_GLSL_QUAD))
|
||||||
|
#define SHELL_IS_GLSL_QUAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_GLSL_QUAD))
|
||||||
|
#define SHELL_GLSL_QUAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_GLSL_QUAD, ShellGLSLQuadClass))
|
||||||
|
|
||||||
|
typedef struct _ShellGLSLQuad ShellGLSLQuad;
|
||||||
|
typedef struct _ShellGLSLQuadClass ShellGLSLQuadClass;
|
||||||
|
typedef struct _ShellGLSLQuadPrivate ShellGLSLQuadPrivate;
|
||||||
|
|
||||||
|
struct _ShellGLSLQuad
|
||||||
|
{
|
||||||
|
ClutterActor parent;
|
||||||
|
|
||||||
|
ShellGLSLQuadPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ShellGLSLQuadClass
|
||||||
|
{
|
||||||
|
ClutterActorClass parent_class;
|
||||||
|
|
||||||
|
CoglPipeline *base_pipeline;
|
||||||
|
|
||||||
|
void (*build_pipeline) (ShellGLSLQuad *effect);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType shell_glsl_quad_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
void shell_glsl_quad_add_glsl_snippet (ShellGLSLQuad *quad,
|
||||||
|
ShellSnippetHook hook,
|
||||||
|
const char *declarations,
|
||||||
|
const char *code,
|
||||||
|
gboolean is_replace);
|
||||||
|
|
||||||
|
#endif /* __SHELL_GLSL_QUAD_H__ */
|
Loading…
x
Reference in New Issue
Block a user