ScreenShield: rework the arrow in the lock screen
User testing has shown that it is not discoverable that the whole lock screen can be dragged. A new mockup includes more arrows and a short animation every 4 seconds. https://bugzilla.gnome.org/show_bug.cgi?id=682285
This commit is contained in:
parent
eb351b1882
commit
1a6d74fcb2
@ -2204,10 +2204,15 @@ StButton.popup-menu-item:insensitive {
|
|||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lockScreenGroup .arrow {
|
.screen-shield-arrows {
|
||||||
color: #333333;
|
padding-bottom: 3em;
|
||||||
width: 100px;
|
}
|
||||||
height: 50px;
|
|
||||||
|
.screen-shield-arrows > StDrawingArea {
|
||||||
|
color: white;
|
||||||
|
width: 80px;
|
||||||
|
height: 48px;
|
||||||
|
-arrow-thickness: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.screen-shield-clock {
|
.screen-shield-clock {
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Cairo = imports.cairo;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
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 TweenerEquations = imports.tweener.equations;
|
||||||
|
|
||||||
const GnomeSession = imports.misc.gnomeSession;
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
@ -25,6 +28,11 @@ const CURTAIN_SLIDE_TIME = 0.5;
|
|||||||
// the slide up automatically
|
// the slide up automatically
|
||||||
const ARROW_DRAG_TRESHOLD = 0.1;
|
const ARROW_DRAG_TRESHOLD = 0.1;
|
||||||
|
|
||||||
|
// Parameters for the arrow animation
|
||||||
|
const N_ARROWS = 3;
|
||||||
|
const ARROW_ANIMATION_TIME = 0.6;
|
||||||
|
const ARROW_ANIMATION_PEAK_OPACITY = 0.4;
|
||||||
|
|
||||||
// The distance in px that the lock screen will move to when pressing
|
// The distance in px that the lock screen will move to when pressing
|
||||||
// a key that has no effect in the lock screen (bumping it)
|
// a key that has no effect in the lock screen (bumping it)
|
||||||
const BUMP_SIZE = 25;
|
const BUMP_SIZE = 25;
|
||||||
@ -300,19 +308,21 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._lockScreenGroup.add_actor(this._background);
|
this._lockScreenGroup.add_actor(this._background);
|
||||||
this._lockScreenGroup.add_actor(this._lockScreenContents);
|
this._lockScreenGroup.add_actor(this._lockScreenContents);
|
||||||
|
|
||||||
// FIXME: build the rest of the lock screen here
|
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
|
||||||
|
vertical: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
// HACK: without these, ClutterBinLayout
|
||||||
|
// ignores alignment properties on the actor
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true });
|
||||||
|
|
||||||
this._arrow = new St.DrawingArea({ style_class: 'arrow',
|
for (let i = 0; i < N_ARROWS; i++) {
|
||||||
reactive: true,
|
let arrow = new St.DrawingArea({ opacity: 0 });
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
arrow.connect('repaint', Lang.bind(this, this._drawArrow));
|
||||||
y_align: Clutter.ActorAlign.END,
|
this._arrowContainer.add_actor(arrow);
|
||||||
// HACK: without these, ClutterBinLayout
|
}
|
||||||
// ignores alignment properties on the actor
|
this._lockScreenContents.add_actor(this._arrowContainer);
|
||||||
x_expand: true,
|
|
||||||
y_expand: true
|
|
||||||
});
|
|
||||||
this._arrow.connect('repaint', Lang.bind(this, this._drawArrow));
|
|
||||||
this._lockScreenContents.add_actor(this._arrow);
|
|
||||||
|
|
||||||
let dragArea = new Clutter.Rect({ origin: new Clutter.Point({ x: 0, y: -global.screen_height, }),
|
let dragArea = new Clutter.Rect({ origin: new Clutter.Point({ x: 0, y: -global.screen_height, }),
|
||||||
size: new Clutter.Size({ width: global.screen_width,
|
size: new Clutter.Size({ width: global.screen_width,
|
||||||
@ -374,17 +384,43 @@ const ScreenShield = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_drawArrow: function() {
|
_drawArrow: function(arrow) {
|
||||||
let cr = this._arrow.get_context();
|
let cr = arrow.get_context();
|
||||||
let [w, h] = this._arrow.get_surface_size();
|
let [w, h] = arrow.get_surface_size();
|
||||||
let node = this._arrow.get_theme_node();
|
let node = arrow.get_theme_node();
|
||||||
|
let thickness = node.get_length('-arrow-thickness');
|
||||||
|
|
||||||
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
|
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
|
||||||
|
|
||||||
cr.moveTo(0, h);
|
cr.setLineCap(Cairo.LineCap.ROUND);
|
||||||
cr.lineTo(w/2, 0);
|
cr.setLineWidth(thickness);
|
||||||
cr.lineTo(w, h);
|
|
||||||
cr.fill();
|
cr.moveTo(thickness / 2, h - thickness / 2);
|
||||||
|
cr.lineTo(w/2, thickness);
|
||||||
|
cr.lineTo(w - thickness / 2, h - thickness / 2);
|
||||||
|
cr.stroke();
|
||||||
|
},
|
||||||
|
|
||||||
|
_animateArrows: function() {
|
||||||
|
let arrows = this._arrowContainer.get_children();
|
||||||
|
let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1);
|
||||||
|
let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY;
|
||||||
|
for (let i = 0; i < arrows.length; i++) {
|
||||||
|
arrows.opacity = 0;
|
||||||
|
Tweener.addTween(arrows[i],
|
||||||
|
{ opacity: 0,
|
||||||
|
delay: unitaryDelay * (N_ARROWS - (i + 1)),
|
||||||
|
time: ARROW_ANIMATION_TIME,
|
||||||
|
transition: function(t, b, c, d) {
|
||||||
|
if (t < d/2)
|
||||||
|
return TweenerEquations.easeOutQuad(t, 0, maxOpacity, d/2);
|
||||||
|
else
|
||||||
|
return TweenerEquations.easeInQuad(t - d/2, maxOpacity, -maxOpacity, d/2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragBegin: function() {
|
_onDragBegin: function() {
|
||||||
@ -575,6 +611,11 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_lockScreenShown: function() {
|
_lockScreenShown: function() {
|
||||||
|
if (this._arrowAnimationId)
|
||||||
|
Mainloop.source_remove(this._arrowAnimationId);
|
||||||
|
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
|
||||||
|
this._animateArrows();
|
||||||
|
|
||||||
this._lockScreenState = MessageTray.State.SHOWN;
|
this._lockScreenState = MessageTray.State.SHOWN;
|
||||||
this._lockScreenGroup.fixed_position_set = false;
|
this._lockScreenGroup.fixed_position_set = false;
|
||||||
|
|
||||||
@ -616,6 +657,11 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
this._lockScreenContentsBox.destroy();
|
this._lockScreenContentsBox.destroy();
|
||||||
|
|
||||||
|
if (this._arrowAnimationId) {
|
||||||
|
Mainloop.source_remove(this._arrowAnimationId);
|
||||||
|
this._arrowAnimationId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
this._hasLockScreen = false;
|
this._hasLockScreen = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user