mirror of
https://github.com/morgan9e/dash-to-panel
synced 2026-04-15 00:34:05 +09:00
Animate app icons when urgent property is set
This commit is contained in:
@@ -110,12 +110,13 @@ var taskbarAppIcon = Utils.defineClass({
|
||||
Extends: AppDisplay.AppIcon,
|
||||
ParentConstrParams: [[0, 'app'], [2]],
|
||||
|
||||
_init: function(appInfo, panel, iconParams, previewMenu) {
|
||||
_init: function(appInfo, panel, iconParams, previewMenu, iconAnimator) {
|
||||
this.dtpPanel = panel;
|
||||
this._nWindows = 0;
|
||||
this.window = appInfo.window;
|
||||
this.isLauncher = appInfo.isLauncher;
|
||||
this._previewMenu = previewMenu;
|
||||
this.iconAnimator = iconAnimator;
|
||||
|
||||
this._timeoutsHandler = new Utils.TimeoutsHandler();
|
||||
|
||||
|
||||
@@ -104,6 +104,8 @@ var dtpPanelManager = Utils.defineClass({
|
||||
);
|
||||
|
||||
this._findPanelMenuButtons(p.panelBox).forEach(pmb => this._adjustPanelMenuButton(pmb, p.monitor, panelPosition));
|
||||
|
||||
p.taskbar.iconAnimator.start();
|
||||
});
|
||||
|
||||
//in 3.32, BoxPointer now inherits St.Widget
|
||||
@@ -278,6 +280,8 @@ var dtpPanelManager = Utils.defineClass({
|
||||
this.proximityManager.destroy();
|
||||
|
||||
this.allPanels.forEach(p => {
|
||||
p.taskbar.iconAnimator.pause();
|
||||
|
||||
this._findPanelMenuButtons(p.panelBox).forEach(pmb => {
|
||||
if (pmb.menu._boxPointer._dtpGetPreferredHeightId) {
|
||||
pmb.menu._boxPointer._container.disconnect(pmb.menu._boxPointer._dtpGetPreferredHeightId);
|
||||
@@ -605,6 +609,76 @@ var dtpPanelManager = Utils.defineClass({
|
||||
},
|
||||
});
|
||||
|
||||
// This class drives long-running icon animations, to keep them running in sync
|
||||
// with each other.
|
||||
var IconAnimator = Utils.defineClass({
|
||||
Name: 'DashToPanel.IconAnimator',
|
||||
|
||||
_init: function(actor) {
|
||||
this._count = 0;
|
||||
this._started = false;
|
||||
this._animations = {
|
||||
dance: [],
|
||||
};
|
||||
this._timeline = new Clutter.Timeline({
|
||||
duration: 3000,
|
||||
repeat_count: -1,
|
||||
});
|
||||
|
||||
/* Just use the construction property when no need to support 3.36 */
|
||||
if (this._timeline.set_actor)
|
||||
this._timeline.set_actor(actor);
|
||||
|
||||
this._timeline.connect('new-frame', () => {
|
||||
const progress = this._timeline.get_progress();
|
||||
const danceRotation = progress < 1/6 ? 15*Math.sin(progress*24*Math.PI) : 0;
|
||||
const dancers = this._animations.dance;
|
||||
for (let i = 0, iMax = dancers.length; i < iMax; i++) {
|
||||
dancers[i].rotation_angle_z = danceRotation;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this._timeline.stop();
|
||||
this._timeline = null;
|
||||
this._animations = null;
|
||||
},
|
||||
|
||||
pause: function() {
|
||||
if (this._started && this._count > 0) {
|
||||
this._timeline.stop();
|
||||
}
|
||||
this._started = false;
|
||||
},
|
||||
|
||||
start: function() {
|
||||
if (!this._started && this._count > 0) {
|
||||
this._timeline.start();
|
||||
}
|
||||
this._started = true;
|
||||
},
|
||||
|
||||
addAnimation: function(target, name) {
|
||||
this._animations[name].push(target);
|
||||
if (this._started && this._count === 0) {
|
||||
this._timeline.start();
|
||||
}
|
||||
this._count++;
|
||||
},
|
||||
|
||||
removeAnimation: function(target, name) {
|
||||
const index = this._animations[name].indexOf(target);
|
||||
if (index >= 0) {
|
||||
this._animations[name].splice(index, 1);
|
||||
this._count--;
|
||||
if (this._started && this._count === 0) {
|
||||
this._timeline.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function newViewSelectorAnimateIn(oldPage) {
|
||||
if (oldPage)
|
||||
oldPage.hide();
|
||||
@@ -842,4 +916,4 @@ function _newLookingGlassOpen() {
|
||||
|
||||
this._resize();
|
||||
this._oldOpen();
|
||||
}
|
||||
}
|
||||
|
||||
40
progress.js
40
progress.js
@@ -176,6 +176,7 @@ var AppProgress = Utils.defineClass({
|
||||
this._countVisible = false;
|
||||
this._progress = 0.0;
|
||||
this._progressVisible = false;
|
||||
this._urgent = false;
|
||||
this.update(properties);
|
||||
},
|
||||
|
||||
@@ -231,6 +232,17 @@ var AppProgress = Utils.defineClass({
|
||||
}
|
||||
},
|
||||
|
||||
urgent: function() {
|
||||
return this._urgent;
|
||||
},
|
||||
|
||||
setUrgent: function(urgent) {
|
||||
if (this._urgent != urgent) {
|
||||
this._urgent = urgent;
|
||||
this.emit('urgent-changed', this._urgent);
|
||||
}
|
||||
},
|
||||
|
||||
setDBusName: function(dbusName) {
|
||||
if (this._dbusName != dbusName) {
|
||||
let oldName = this._dbusName;
|
||||
@@ -246,6 +258,7 @@ var AppProgress = Utils.defineClass({
|
||||
this.setCountVisible(other.countVisible());
|
||||
this.setProgress(other.progress());
|
||||
this.setProgressVisible(other.progressVisible())
|
||||
this.setUrgent(other.urgent());
|
||||
} else {
|
||||
for (let property in other) {
|
||||
if (other.hasOwnProperty(property)) {
|
||||
@@ -257,6 +270,8 @@ var AppProgress = Utils.defineClass({
|
||||
this.setProgress(other[property].get_double());
|
||||
} else if (property == 'progress-visible') {
|
||||
this.setProgressVisible(Me.settings.get_boolean('progress-show-bar') && other[property].get_boolean());
|
||||
} else if (property == 'urgent') {
|
||||
this.setUrgent(other[property].get_boolean());
|
||||
} else {
|
||||
// Not implemented yet
|
||||
}
|
||||
@@ -513,6 +528,7 @@ var ProgressIndicator = Utils.defineClass({
|
||||
this.toggleNotificationBadge(false);
|
||||
this.setProgress(0);
|
||||
this.toggleProgressOverlay(false);
|
||||
this.setUrgent(false);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -547,6 +563,12 @@ var ProgressIndicator = Utils.defineClass({
|
||||
(appProgress, value) => {
|
||||
this.toggleProgressOverlay(value);
|
||||
}
|
||||
], [
|
||||
appProgress,
|
||||
'urgent-changed',
|
||||
(appProgress, value) => {
|
||||
this.setUrgent(value)
|
||||
}
|
||||
]);
|
||||
|
||||
this.setNotificationBadge(appProgress.count());
|
||||
@@ -554,5 +576,23 @@ var ProgressIndicator = Utils.defineClass({
|
||||
this.setProgress(appProgress.progress());
|
||||
this.toggleProgressOverlay(appProgress.progressVisible());
|
||||
|
||||
this._isUrgent = false;
|
||||
},
|
||||
|
||||
setUrgent(urgent) {
|
||||
const icon = this._source.icon._iconBin;
|
||||
if (urgent) {
|
||||
if (!this._isUrgent) {
|
||||
icon.set_pivot_point(0.5, 0.5);
|
||||
this._source.iconAnimator.addAnimation(icon, 'dance');
|
||||
this._isUrgent = true;
|
||||
}
|
||||
} else {
|
||||
if (this._isUrgent) {
|
||||
this._source.iconAnimator.removeAnimation(icon, 'dance');
|
||||
this._isUrgent = false;
|
||||
}
|
||||
icon.rotation_angle_z = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -46,6 +46,7 @@ const Workspace = imports.ui.workspace;
|
||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||
const AppIcons = Me.imports.appIcons;
|
||||
const Panel = Me.imports.panel;
|
||||
const PanelManager = Me.imports.panelManager;
|
||||
const Utils = Me.imports.utils;
|
||||
const WindowPreview = Me.imports.windowPreview;
|
||||
|
||||
@@ -241,6 +242,8 @@ var taskbar = Utils.defineClass({
|
||||
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
|
||||
this.iconAnimator = new PanelManager.IconAnimator(this.dtpPanel.panel.actor);
|
||||
|
||||
this._signalsHandler.add(
|
||||
[
|
||||
this.dtpPanel.panel.actor,
|
||||
@@ -351,6 +354,8 @@ var taskbar = Utils.defineClass({
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.iconAnimator.destroy();
|
||||
|
||||
this._signalsHandler.destroy();
|
||||
this._signalsHandler = 0;
|
||||
|
||||
@@ -549,7 +554,8 @@ var taskbar = Utils.defineClass({
|
||||
showLabel: false,
|
||||
isDraggable: !Me.settings.get_boolean('taskbar-locked'),
|
||||
},
|
||||
this.previewMenu
|
||||
this.previewMenu,
|
||||
this.iconAnimator
|
||||
);
|
||||
|
||||
if (appIcon._draggable) {
|
||||
|
||||
Reference in New Issue
Block a user