File indexing completed on 2024-06-30 05:25:44

0001 /*
0002     This file is part of the KDE project.
0003 
0004     SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 "use strict";
0010 
0011 class MaximizeEffect {
0012     constructor() {
0013         effect.configChanged.connect(this.loadConfig.bind(this));
0014         effect.animationEnded.connect(this.restoreForceBlurState.bind(this));
0015 
0016         effects.windowAdded.connect(this.manage.bind(this));
0017         for (const window of effects.stackingOrder) {
0018             this.manage(window);
0019         }
0020 
0021         this.loadConfig();
0022     }
0023 
0024     loadConfig() {
0025         this.duration = animationTime(250);
0026     }
0027 
0028     manage(window) {
0029         window.windowFrameGeometryChanged.connect(this.onWindowFrameGeometryChanged.bind(this));
0030         window.windowMaximizedStateChanged.connect(this.onWindowMaximizedStateChanged.bind(this));
0031         window.windowMaximizedStateAboutToChange.connect(this.onWindowMaximizedStateAboutToChange.bind(this));
0032     }
0033 
0034     onWindowMaximizedStateAboutToChange(window) {
0035         if (!window.visible) {
0036             return;
0037         }
0038 
0039         window.oldGeometry = Object.assign({}, window.geometry);
0040 
0041         if (window.maximizeAnimation1) {
0042             cancel(window.maximizeAnimation1);
0043             delete window.maximizeAnimation1;
0044         }
0045         let couldRetarget = false;
0046         if (window.maximizeAnimation2) {
0047             couldRetarget = retarget(window.maximizeAnimation2, 1.0, this.duration);
0048         }
0049         if (!couldRetarget) {
0050             window.maximizeAnimation2 = animate({
0051                 window: window,
0052                 duration: this.duration,
0053                 animations: [{
0054                     type: Effect.CrossFadePrevious,
0055                     to: 1.0,
0056                     from: 0.0,
0057                     curve: QEasingCurve.OutCubic
0058                 }]
0059             });
0060         }
0061     }
0062 
0063     onWindowMaximizedStateChanged(window) {
0064         if (!window.visible || !window.oldGeometry) {
0065             return;
0066         }
0067         window.setData(Effect.WindowForceBlurRole, true);
0068         const oldGeometry = window.oldGeometry;
0069         const newGeometry = window.geometry;
0070         window.maximizeAnimation1 = animate({
0071             window: window,
0072             duration: this.duration,
0073             animations: [{
0074                 type: Effect.Size,
0075                 to: {
0076                     value1: newGeometry.width,
0077                     value2: newGeometry.height
0078                 },
0079                 from: {
0080                     value1: oldGeometry.width,
0081                     value2: oldGeometry.height
0082                 },
0083                 curve: QEasingCurve.OutCubic
0084             }, {
0085                 type: Effect.Translation,
0086                 to: {
0087                     value1: 0,
0088                     value2: 0
0089                 },
0090                 from: {
0091                     value1: oldGeometry.x - newGeometry.x - (newGeometry.width / 2 - oldGeometry.width / 2),
0092                     value2: oldGeometry.y - newGeometry.y - (newGeometry.height / 2 - oldGeometry.height / 2)
0093                 },
0094                 curve: QEasingCurve.OutCubic
0095             }]
0096         });
0097     }
0098 
0099     restoreForceBlurState(window) {
0100         window.setData(Effect.WindowForceBlurRole, null);
0101     }
0102 
0103     onWindowFrameGeometryChanged(window, oldGeometry) {
0104         if (!window.maximizeAnimation1 ||
0105             // Check only dimension changes.
0106             (window.geometry.width == oldGeometry.width && window.geometry.height == oldGeometry.height) ||
0107             // Check only if last dimension isn't equal to dimension from which effect was started (window.oldGeometry).
0108             (window.oldGeometry.width == oldGeometry.width && window.oldGeometry.height == oldGeometry.height)
0109         ) {
0110             return;
0111         }
0112 
0113         // Cancel animation if window got resized halfway through it.
0114         cancel(window.maximizeAnimation1);
0115         delete window.maximizeAnimation1;
0116 
0117         if (window.maximizeAnimation2) {
0118             cancel(window.maximizeAnimation2);
0119             delete window.maximizeAnimation2;
0120         }
0121     }
0122 }
0123 
0124 new MaximizeEffect();