File indexing completed on 2024-11-10 04:57:03

0001 /*
0002     This file is part of the KDE project.
0003 
0004     SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
0005     SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 "use strict";
0011 
0012 var morphingEffect = {
0013     duration: animationTime(150),
0014     loadConfig: function () {
0015         morphingEffect.duration = animationTime(150);
0016     },
0017 
0018     handleFrameGeometryAboutToChange: function (window) {
0019         var couldRetarget = false;
0020         if (window.fadeAnimation) {
0021             couldRetarget = retarget(window.fadeAnimation[0], 1.0, morphingEffect.duration);
0022         }
0023 
0024         if (!couldRetarget) {
0025             window.fadeAnimation = animate({
0026                 window: window,
0027                 duration: morphingEffect.duration,
0028                 curve: QEasingCurve.InOutCubic,
0029                 animations: [{
0030                     type: Effect.CrossFadePrevious,
0031                     to: 1.0,
0032                     from: 0.0
0033                 }]
0034             });
0035         }
0036     },
0037     handleFrameGeometryChanged: function (window, oldGeometry) {
0038         var newGeometry = window.geometry;
0039 
0040         //only do the transition for near enough tooltips,
0041         //don't cross the whole screen: ugly
0042         var distance = Math.abs(oldGeometry.x - newGeometry.x) + Math.abs(oldGeometry.y - newGeometry.y);
0043 
0044         if (distance > (newGeometry.width + newGeometry.height) * 2) {
0045             if (window.moveAnimation) {
0046                 delete window.moveAnimation;
0047             }
0048             if (window.fadeAnimation) {
0049                 delete window.fadeAnimation;
0050             }
0051 
0052             return;
0053         }
0054 
0055         //don't resize it "too much", set as four times
0056         if ((newGeometry.width / oldGeometry.width) > 4 ||
0057             (oldGeometry.width / newGeometry.width) > 4 ||
0058             (newGeometry.height / oldGeometry.height) > 4 ||
0059             (oldGeometry.height / newGeometry.height) > 4) {
0060             return;
0061         }
0062 
0063         window.setData(Effect.WindowForceBackgroundContrastRole, true);
0064         window.setData(Effect.WindowForceBlurRole, true);
0065 
0066         var couldRetarget = false;
0067 
0068         if (window.moveAnimation) {
0069             if (window.moveAnimation[0]) {
0070                 couldRetarget = retarget(window.moveAnimation[0], {
0071                         value1: newGeometry.width,
0072                         value2: newGeometry.height
0073                     }, morphingEffect.duration);
0074             }
0075             if (couldRetarget && window.moveAnimation[1]) {
0076                 couldRetarget = retarget(window.moveAnimation[1], {
0077                         value1: newGeometry.x + newGeometry.width/2,
0078                         value2: newGeometry.y + newGeometry.height / 2
0079                     }, morphingEffect.duration);
0080             }
0081             if (!couldRetarget) {
0082                 cancel(window.moveAnimation[0]);
0083             }
0084 
0085         }
0086 
0087         if (!couldRetarget) {
0088             window.moveAnimation = animate({
0089                 window: window,
0090                 duration: morphingEffect.duration,
0091                 curve: QEasingCurve.InOutCubic,
0092                 animations: [{
0093                     type: Effect.Size,
0094                     to: {
0095                         value1: newGeometry.width,
0096                         value2: newGeometry.height
0097                     },
0098                     from: {
0099                         value1: oldGeometry.width,
0100                         value2: oldGeometry.height
0101                     }
0102                 }, {
0103                     type: Effect.Position,
0104                     to: {
0105                         value1: newGeometry.x + newGeometry.width / 2,
0106                         value2: newGeometry.y + newGeometry.height / 2
0107                     },
0108                     from: {
0109                         value1: oldGeometry.x + oldGeometry.width / 2,
0110                         value2: oldGeometry.y + oldGeometry.height / 2
0111                     }
0112                 }]
0113             });
0114 
0115         }
0116     },
0117 
0118     manage: function (window) {
0119         //only tooltips and notifications
0120         if (!window.tooltip && !window.notification && !window.criticalNotification) {
0121             return;
0122         }
0123 
0124         window.windowFrameGeometryAboutToChange.connect(morphingEffect.handleFrameGeometryAboutToChange);
0125         window.windowFrameGeometryChanged.connect(morphingEffect.handleFrameGeometryChanged);
0126     },
0127 
0128     init: function () {
0129         effect.configChanged.connect(morphingEffect.loadConfig);
0130         effects.windowAdded.connect(morphingEffect.manage);
0131 
0132         for (const window of effects.stackingOrder) {
0133             morphingEffect.manage(window);
0134         }
0135     }
0136 };
0137 morphingEffect.init();