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();