2013-06-18 07:35:41 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
2013-11-28 19:45:39 -05:00
|
|
|
const GLib = imports.gi.GLib;
|
2018-11-28 10:41:09 -05:00
|
|
|
const Gio = imports.gi.Gio;
|
2013-06-18 07:35:41 -04:00
|
|
|
const Lang = imports.lang;
|
|
|
|
const Mainloop = imports.mainloop;
|
|
|
|
const St = imports.gi.St;
|
|
|
|
const Signals = imports.signals;
|
|
|
|
const Atk = imports.gi.Atk;
|
|
|
|
|
2018-11-28 11:34:48 -05:00
|
|
|
const Tweener = imports.ui.tweener;
|
|
|
|
|
2017-07-18 13:47:27 -04:00
|
|
|
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
2018-11-28 11:34:48 -05:00
|
|
|
var SPINNER_ANIMATION_TIME = 0.3;
|
|
|
|
var SPINNER_ANIMATION_DELAY = 1.0;
|
2013-06-18 07:35:41 -04:00
|
|
|
|
2017-07-18 13:41:25 -04:00
|
|
|
var Animation = new Lang.Class({
|
2013-06-18 07:35:41 -04:00
|
|
|
Name: 'Animation',
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_init(file, width, height, speed) {
|
2013-06-18 07:35:41 -04:00
|
|
|
this.actor = new St.Bin();
|
2017-12-01 19:27:35 -05:00
|
|
|
this.actor.connect('destroy', this._onDestroy.bind(this));
|
2013-06-18 07:35:41 -04:00
|
|
|
this._speed = speed;
|
|
|
|
|
|
|
|
this._isLoaded = false;
|
|
|
|
this._isPlaying = false;
|
|
|
|
this._timeoutId = 0;
|
|
|
|
this._frame = 0;
|
2014-03-22 22:20:50 -04:00
|
|
|
|
|
|
|
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
2014-09-18 20:04:00 -04:00
|
|
|
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
|
2017-12-01 19:27:35 -05:00
|
|
|
this._animationsLoaded.bind(this));
|
2013-06-18 07:35:41 -04:00
|
|
|
this.actor.set_child(this._animations);
|
|
|
|
},
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
play() {
|
2013-06-18 07:35:41 -04:00
|
|
|
if (this._isLoaded && this._timeoutId == 0) {
|
|
|
|
if (this._frame == 0)
|
|
|
|
this._showFrame(0);
|
|
|
|
|
2017-12-01 19:27:35 -05:00
|
|
|
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, this._update.bind(this));
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._update');
|
2013-06-18 07:35:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
this._isPlaying = true;
|
|
|
|
},
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
stop() {
|
2013-06-18 07:35:41 -04:00
|
|
|
if (this._timeoutId > 0) {
|
|
|
|
Mainloop.source_remove(this._timeoutId);
|
|
|
|
this._timeoutId = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._isPlaying = false;
|
|
|
|
},
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_showFrame(frame) {
|
2013-06-18 07:35:41 -04:00
|
|
|
let oldFrameActor = this._animations.get_child_at_index(this._frame);
|
|
|
|
if (oldFrameActor)
|
|
|
|
oldFrameActor.hide();
|
|
|
|
|
|
|
|
this._frame = (frame % this._animations.get_n_children());
|
|
|
|
|
|
|
|
let newFrameActor = this._animations.get_child_at_index(this._frame);
|
|
|
|
if (newFrameActor)
|
|
|
|
newFrameActor.show();
|
|
|
|
},
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_update() {
|
2013-06-18 07:35:41 -04:00
|
|
|
this._showFrame(this._frame + 1);
|
2013-11-28 19:45:39 -05:00
|
|
|
return GLib.SOURCE_CONTINUE;
|
2013-06-18 07:35:41 -04:00
|
|
|
},
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_animationsLoaded() {
|
2016-11-21 12:09:42 -05:00
|
|
|
this._isLoaded = this._animations.get_n_children() > 0;
|
2013-06-18 07:35:41 -04:00
|
|
|
|
|
|
|
if (this._isPlaying)
|
|
|
|
this.play();
|
|
|
|
},
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onDestroy() {
|
2013-06-18 07:35:41 -04:00
|
|
|
this.stop();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-07-18 13:41:25 -04:00
|
|
|
var AnimatedIcon = new Lang.Class({
|
2013-06-18 07:35:41 -04:00
|
|
|
Name: 'AnimatedIcon',
|
|
|
|
Extends: Animation,
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_init(file, size) {
|
2014-09-18 20:04:00 -04:00
|
|
|
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
2013-06-18 07:35:41 -04:00
|
|
|
}
|
|
|
|
});
|
2018-11-28 10:41:09 -05:00
|
|
|
|
|
|
|
var Spinner = new Lang.Class({
|
|
|
|
Name: 'Spinner',
|
|
|
|
Extends: AnimatedIcon,
|
|
|
|
|
2018-11-28 11:34:48 -05:00
|
|
|
_init(size, animate=false) {
|
2018-11-28 10:41:09 -05:00
|
|
|
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
|
|
|
|
this.parent(file, size);
|
2018-11-28 11:34:48 -05:00
|
|
|
|
|
|
|
this.actor.opacity = 0;
|
|
|
|
this._animate = animate;
|
|
|
|
},
|
|
|
|
|
|
|
|
play() {
|
|
|
|
Tweener.removeTweens(this.actor);
|
|
|
|
|
|
|
|
if (this._animate) {
|
|
|
|
this.parent();
|
|
|
|
Tweener.addTween(this.actor, {
|
|
|
|
opacity: 255,
|
|
|
|
delay: SPINNER_ANIMATION_DELAY,
|
|
|
|
time: SPINNER_ANIMATION_TIME,
|
|
|
|
transition: 'linear'
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.actor.opacity = 255;
|
|
|
|
this.parent();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
stop() {
|
|
|
|
Tweener.removeTweens(this.actor);
|
|
|
|
|
|
|
|
if (this._animate) {
|
|
|
|
Tweener.addTween(this.actor, {
|
|
|
|
opacity: 0,
|
|
|
|
time: SPINNER_ANIMATION_TIME,
|
|
|
|
transition: 'linear',
|
|
|
|
onComplete: () => {
|
|
|
|
this.stop(false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.actor.opacity = 0;
|
|
|
|
this.parent();
|
|
|
|
}
|
2018-11-28 10:41:09 -05:00
|
|
|
}
|
|
|
|
});
|