js: Drop tweener.js
We're using clutter's animation framework now, so lets drop the old tweener support layer. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1200
This commit is contained in:
parent
ff4c5270d3
commit
b3b91f1699
@ -102,7 +102,6 @@
|
||||
<file>ui/swipeTracker.js</file>
|
||||
<file>ui/switcherPopup.js</file>
|
||||
<file>ui/switchMonitor.js</file>
|
||||
<file>ui/tweener.js</file>
|
||||
<file>ui/unlockDialog.js</file>
|
||||
<file>ui/userWidget.js</file>
|
||||
<file>ui/viewSelector.js</file>
|
||||
|
@ -638,7 +638,7 @@ var AllView = GObject.registerClass({
|
||||
|
||||
this._grid.currentPage = pageNumber;
|
||||
|
||||
// Tween the change between pages.
|
||||
// Animate the change between pages.
|
||||
this._adjustment.ease(this._grid.getPageY(this._grid.currentPage), {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
duration: animate ? PAGE_SWITCH_TIME : 0,
|
||||
|
@ -356,9 +356,7 @@ function init() {
|
||||
|
||||
// OK, now things are initialized enough that we can import shell JS
|
||||
const Format = imports.format;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
Tweener.init();
|
||||
String.prototype.format = Format.format;
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,7 @@ var ScreenShield = class {
|
||||
this._lockDialogGroup.remove_all_transitions();
|
||||
|
||||
if (animate) {
|
||||
// Tween the lock screen out of screen
|
||||
// Animate the lock screen out of screen
|
||||
// if velocity is not specified (i.e. we come here from pressing ESC),
|
||||
// use the same speed regardless of original position
|
||||
// if velocity is specified, it's in pixels per milliseconds
|
||||
|
228
js/ui/tweener.js
228
js/ui/tweener.js
@ -1,228 +0,0 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported init, addCaller, addTween, getTweenCount, removeTweens,
|
||||
pauseTweens, resumeTweens, registerSpecialProperty,
|
||||
registerSpecialPropertyModifier, registerSpecialPropertySplitter */
|
||||
|
||||
const { Clutter, GLib, Shell } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const Tweener = imports.tweener.tweener;
|
||||
|
||||
const { adjustAnimationTime } = imports.ui.environment;
|
||||
|
||||
// This is a wrapper around imports.tweener.tweener that adds a bit of
|
||||
// Clutter integration. If the tweening target is a Clutter.Actor, then
|
||||
// the tweenings will automatically be removed if the actor is destroyed.
|
||||
|
||||
// ActionScript Tweener methods that imports.tweener.tweener doesn't
|
||||
// currently implement: getTweens, getVersion, registerTransition,
|
||||
// setTimeScale, updateTime.
|
||||
|
||||
// imports.tweener.tweener methods that we don't re-export:
|
||||
// pauseAllTweens, removeAllTweens, resumeAllTweens. (It would be hard
|
||||
// to clean up properly after removeAllTweens, and also, any code that
|
||||
// calls any of these is almost certainly wrong anyway, because they
|
||||
// affect the entire application.)
|
||||
|
||||
// Called from Main.start
|
||||
function init() {
|
||||
Tweener.setFrameTicker(new ClutterFrameTicker());
|
||||
}
|
||||
|
||||
|
||||
function addCaller(target, tweeningParameters) {
|
||||
_wrapTweening(target, tweeningParameters);
|
||||
Tweener.addCaller(target, tweeningParameters);
|
||||
}
|
||||
|
||||
function addTween(target, tweeningParameters) {
|
||||
_wrapTweening(target, tweeningParameters);
|
||||
Tweener.addTween(target, tweeningParameters);
|
||||
}
|
||||
|
||||
function _wrapTweening(target, tweeningParameters) {
|
||||
let state = _getTweenState(target);
|
||||
|
||||
if (!state.destroyedId) {
|
||||
if (target instanceof Clutter.Actor) {
|
||||
state.actor = target;
|
||||
state.destroyedId = target.connect('destroy', _actorDestroyed);
|
||||
} else if (target.actor && target.actor instanceof Clutter.Actor) {
|
||||
state.actor = target.actor;
|
||||
state.destroyedId = target.actor.connect('destroy', () => _actorDestroyed(target));
|
||||
}
|
||||
}
|
||||
|
||||
let { time, delay } = tweeningParameters;
|
||||
if (!isNaN(time))
|
||||
tweeningParameters['time'] = adjustAnimationTime(1000 * time) / 1000;
|
||||
if (!isNaN(delay))
|
||||
tweeningParameters['delay'] = adjustAnimationTime(1000 * delay) / 1000;
|
||||
|
||||
_addHandler(target, tweeningParameters, 'onComplete', _tweenCompleted);
|
||||
}
|
||||
|
||||
function _getTweenState(target) {
|
||||
// If we were paranoid, we could keep a plist mapping targets to
|
||||
// states... but we're not that paranoid.
|
||||
if (!target.__ShellTweenerState)
|
||||
target.__ShellTweenerState = {};
|
||||
return target.__ShellTweenerState;
|
||||
}
|
||||
|
||||
function _resetTweenState(target) {
|
||||
let state = target.__ShellTweenerState;
|
||||
|
||||
if (state) {
|
||||
if (state.destroyedId)
|
||||
state.actor.disconnect(state.destroyedId);
|
||||
}
|
||||
|
||||
target.__ShellTweenerState = {};
|
||||
}
|
||||
|
||||
function _addHandler(target, params, name, handler) {
|
||||
if (params[name]) {
|
||||
let oldHandler = params[name];
|
||||
let oldScope = params[`${name}Scope`];
|
||||
let oldParams = params[`${name}Params`];
|
||||
let eventScope = oldScope ? oldScope : target;
|
||||
|
||||
params[name] = () => {
|
||||
oldHandler.apply(eventScope, oldParams);
|
||||
handler(target);
|
||||
};
|
||||
} else {
|
||||
params[name] = () => handler(target);
|
||||
}
|
||||
}
|
||||
|
||||
function _actorDestroyed(target) {
|
||||
_resetTweenState(target);
|
||||
Tweener.removeTweens(target);
|
||||
}
|
||||
|
||||
function _tweenCompleted(target) {
|
||||
if (!isTweening(target))
|
||||
_resetTweenState(target);
|
||||
}
|
||||
|
||||
function getTweenCount(scope) {
|
||||
return Tweener.getTweenCount(scope);
|
||||
}
|
||||
|
||||
// imports.tweener.tweener doesn't provide this method (which exists
|
||||
// in the ActionScript version) but it's easy to implement.
|
||||
function isTweening(scope) {
|
||||
return Tweener.getTweenCount(scope) != 0;
|
||||
}
|
||||
|
||||
function removeTweens(...args) {
|
||||
if (Tweener.removeTweens(args)) {
|
||||
let [scope] = args;
|
||||
// If we just removed the last active tween, clean up
|
||||
if (Tweener.getTweenCount(scope) == 0)
|
||||
_tweenCompleted(scope);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function pauseTweens(...args) {
|
||||
return Tweener.pauseTweens(...args);
|
||||
}
|
||||
|
||||
function resumeTweens(...args) {
|
||||
return Tweener.resumeTweens(...args);
|
||||
}
|
||||
|
||||
|
||||
function registerSpecialProperty(...args) {
|
||||
Tweener.registerSpecialProperty(...args);
|
||||
}
|
||||
|
||||
function registerSpecialPropertyModifier(name, modifyFunction, getFunction) {
|
||||
Tweener.registerSpecialPropertyModifier(name, modifyFunction, getFunction);
|
||||
}
|
||||
|
||||
function registerSpecialPropertySplitter(name, splitFunction, parameters) {
|
||||
Tweener.registerSpecialPropertySplitter(name, splitFunction, parameters);
|
||||
}
|
||||
|
||||
|
||||
// The 'FrameTicker' object is an object used to feed new frames to
|
||||
// Tweener so it can update values and redraw. The default frame
|
||||
// ticker for Tweener just uses a simple timeout at a fixed frame rate
|
||||
// and has no idea of "catching up" by dropping frames.
|
||||
//
|
||||
// We substitute it with custom frame ticker here that connects
|
||||
// Tweener to a Clutter.TimeLine. Now, Clutter.Timeline itself isn't a
|
||||
// whole lot more sophisticated than a simple timeout at a fixed frame
|
||||
// rate, but at least it knows how to drop frames. (See
|
||||
// HippoAnimationManager for a more sophisticated view of continuous
|
||||
// time updates; even better is to pay attention to the vertical
|
||||
// vblank and sync to that when possible.)
|
||||
//
|
||||
var ClutterFrameTicker = class {
|
||||
constructor() {
|
||||
// We don't have a finite duration; tweener will tell us to stop
|
||||
// when we need to stop, so use 1000 seconds as "infinity", and
|
||||
// set the timeline to loop. Doing this means we have to track
|
||||
// time ourselves, since clutter timeline's time will cycle
|
||||
// instead of strictly increase.
|
||||
this._timeline = new Clutter.Timeline({ duration: 1000 * 1000 });
|
||||
this._timeline.set_loop(true);
|
||||
this._startTime = -1;
|
||||
this._currentTime = -1;
|
||||
|
||||
this._timeline.connect('new-frame', () => {
|
||||
this._onNewFrame();
|
||||
});
|
||||
|
||||
let perfLog = Shell.PerfLog.get_default();
|
||||
perfLog.define_event("tweener.framePrepareStart",
|
||||
"Start of a new animation frame",
|
||||
"");
|
||||
perfLog.define_event("tweener.framePrepareDone",
|
||||
"Finished preparing frame",
|
||||
"");
|
||||
}
|
||||
|
||||
get FRAME_RATE() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
_onNewFrame() {
|
||||
// If there is a lot of setup to start the animation, then
|
||||
// first frame number we get from clutter might be a long ways
|
||||
// into the animation (or the animation might even be done).
|
||||
// That looks bad, so we always start at the first frame of the
|
||||
// animation then only do frame dropping from there.
|
||||
if (this._startTime < 0)
|
||||
this._startTime = GLib.get_monotonic_time() / 1000.0;
|
||||
|
||||
// currentTime is in milliseconds
|
||||
let perfLog = Shell.PerfLog.get_default();
|
||||
this._currentTime = GLib.get_monotonic_time() / 1000.0 - this._startTime;
|
||||
perfLog.event("tweener.framePrepareStart");
|
||||
this.emit('prepare-frame');
|
||||
perfLog.event("tweener.framePrepareDone");
|
||||
}
|
||||
|
||||
getTime() {
|
||||
return this._currentTime;
|
||||
}
|
||||
|
||||
start() {
|
||||
this._timeline.start();
|
||||
global.begin_work();
|
||||
}
|
||||
|
||||
stop() {
|
||||
this._timeline.stop();
|
||||
this._startTime = -1;
|
||||
this._currentTime = -1;
|
||||
global.end_work();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ClutterFrameTicker.prototype);
|
@ -1599,10 +1599,8 @@ shell_global_end_work (ShellGlobal *global)
|
||||
* Idle means here no animations, no redrawing, and no ongoing background
|
||||
* work. Since there is currently no way to hook into the Clutter master
|
||||
* clock and know when is running, the implementation here is somewhat
|
||||
* approximation. Animations done through the shell's Tweener module will
|
||||
* be handled properly, but other animations may be detected as terminating
|
||||
* early if they can be drawn fast enough so that the event loop goes idle
|
||||
* between frames.
|
||||
* approximation. Animations may be detected as terminating early if they
|
||||
* can be drawn fast enough so that the event loop goes idle between frames.
|
||||
*
|
||||
* The intent of this function is for performance measurement runs
|
||||
* where a number of actions should be run serially and each action is
|
||||
|
Loading…
Reference in New Issue
Block a user