From aa6b63373e0fdf99fd1a84988f589780c537c4d0 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 18 Jun 2013 07:35:41 -0400 Subject: [PATCH] ui: move AnimatedIcon out of panel.js The class is generally useful, so it only makes sense in panel.js for historical reasons. Because other parts of the code are using it, though, problems are cropping up that require a workaround like: placeSpinner: function(...) { /* This is here because of recursive imports */ const Panel = imports.ui.panel; Panel.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); ... } This commit moves AnimatedIcon to its own file so we can drop that workaround. https://bugzilla.gnome.org/show_bug.cgi?id=702818 --- js/Makefile.am | 1 + js/ui/animation.js | 84 ++++++++++++++++++++++++++++++++++++++++++++ js/ui/modalDialog.js | 5 ++- js/ui/panel.js | 79 ++--------------------------------------- 4 files changed, 89 insertions(+), 80 deletions(-) create mode 100644 js/ui/animation.js diff --git a/js/Makefile.am b/js/Makefile.am index 7920dff1e..4216df8de 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -37,6 +37,7 @@ nobase_dist_js_DATA = \ misc/util.js \ perf/core.js \ ui/altTab.js \ + ui/animation.js \ ui/appDisplay.js \ ui/appFavorites.js \ ui/backgroundMenu.js \ diff --git a/js/ui/animation.js b/js/ui/animation.js new file mode 100644 index 000000000..fb72e74e0 --- /dev/null +++ b/js/ui/animation.js @@ -0,0 +1,84 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +const Lang = imports.lang; +const Mainloop = imports.mainloop; +const St = imports.gi.St; +const Signals = imports.signals; +const Atk = imports.gi.Atk; + +const ANIMATED_ICON_UPDATE_TIMEOUT = 100; + +const Animation = new Lang.Class({ + Name: 'Animation', + + _init: function(filename, width, height, speed) { + this.actor = new St.Bin(); + this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); + this._speed = speed; + + this._isLoaded = false; + this._isPlaying = false; + this._timeoutId = 0; + this._frame = 0; + this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height, + Lang.bind(this, this._animationsLoaded)); + this.actor.set_child(this._animations); + }, + + play: function() { + if (this._isLoaded && this._timeoutId == 0) { + if (this._frame == 0) + this._showFrame(0); + + this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update)); + } + + this._isPlaying = true; + }, + + stop: function() { + if (this._timeoutId > 0) { + Mainloop.source_remove(this._timeoutId); + this._timeoutId = 0; + } + + this._isPlaying = false; + }, + + _showFrame: function(frame) { + 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(); + }, + + _update: function() { + this._showFrame(this._frame + 1); + return true; + }, + + _animationsLoaded: function() { + this._isLoaded = true; + + if (this._isPlaying) + this.play(); + }, + + _onDestroy: function() { + this.stop(); + } +}); + +const AnimatedIcon = new Lang.Class({ + Name: 'AnimatedIcon', + Extends: Animation, + + _init: function(filename, size) { + this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT); + } +}); diff --git a/js/ui/modalDialog.js b/js/ui/modalDialog.js index f770faf6a..8af40131c 100644 --- a/js/ui/modalDialog.js +++ b/js/ui/modalDialog.js @@ -14,6 +14,7 @@ const Atk = imports.gi.Atk; const Params = imports.misc.params; +const Animation = imports.ui.animation; const Layout = imports.ui.layout; const Lightbox = imports.ui.lightbox; const Main = imports.ui.main; @@ -187,10 +188,8 @@ const ModalDialog = new Lang.Class({ }, placeSpinner: function(layoutInfo) { - /* This is here because of recursive imports */ - const Panel = imports.ui.panel; let spinnerIcon = global.datadir + '/theme/process-working.svg'; - this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); + this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); this._workSpinner.actor.opacity = 0; this._workSpinner.actor.show(); diff --git a/js/ui/panel.js b/js/ui/panel.js index ded8ceea2..729a57409 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -15,6 +15,7 @@ const Signals = imports.signals; const Atk = imports.gi.Atk; +const Animation = imports.ui.animation; const Config = imports.misc.config; const CtrlAltTab = imports.ui.ctrlAltTab; const DND = imports.ui.dnd; @@ -29,7 +30,6 @@ const PANEL_ICON_SIZE = 24; const BUTTON_DND_ACTIVATION_TIMEOUT = 250; -const ANIMATED_ICON_UPDATE_TIMEOUT = 100; const SPINNER_ANIMATION_TIME = 0.2; // To make sure the panel corners blend nicely with the panel, @@ -75,81 +75,6 @@ function _unpremultiply(color) { blue: blue, alpha: color.alpha }); }; -const Animation = new Lang.Class({ - Name: 'Animation', - - _init: function(filename, width, height, speed) { - this.actor = new St.Bin(); - this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); - this._speed = speed; - - this._isLoaded = false; - this._isPlaying = false; - this._timeoutId = 0; - this._frame = 0; - this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height, - Lang.bind(this, this._animationsLoaded)); - this.actor.set_child(this._animations); - }, - - play: function() { - if (this._isLoaded && this._timeoutId == 0) { - if (this._frame == 0) - this._showFrame(0); - - this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update)); - } - - this._isPlaying = true; - }, - - stop: function() { - if (this._timeoutId > 0) { - Mainloop.source_remove(this._timeoutId); - this._timeoutId = 0; - } - - this._isPlaying = false; - }, - - _showFrame: function(frame) { - 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(); - }, - - _update: function() { - this._showFrame(this._frame + 1); - return true; - }, - - _animationsLoaded: function() { - this._isLoaded = true; - - if (this._isPlaying) - this.play(); - }, - - _onDestroy: function() { - this.stop(); - } -}); - -const AnimatedIcon = new Lang.Class({ - Name: 'AnimatedIcon', - Extends: Animation, - - _init: function(filename, size) { - this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT); - } -}); - const TextShadower = new Lang.Class({ Name: 'TextShadower', @@ -360,7 +285,7 @@ const AppMenuButton = new Lang.Class({ if (!success || this._spinnerIcon == icon) return; this._spinnerIcon = icon; - this._spinner = new AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE); + this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE); this._container.add_actor(this._spinner.actor); this._spinner.actor.hide(); this._spinner.actor.lower_bottom();