|
1 | | -// |
2 | | -// Copyright (C) 2014 Tom Beckmann |
3 | | -// |
4 | | -// This program is free software: you can redistribute it and/or modify |
5 | | -// it under the terms of the GNU General Public License as published by |
6 | | -// the Free Software Foundation, either version 3 of the License, or |
7 | | -// (at your option) any later version. |
8 | | -// |
9 | | -// This program is distributed in the hope that it will be useful, |
10 | | -// but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | -// GNU General Public License for more details. |
13 | | -// |
14 | | -// You should have received a copy of the GNU General Public License |
15 | | -// along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | | -// |
17 | | - |
18 | | -namespace Gala { |
| 1 | +/* |
| 2 | + * SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | + * SPDX-FileCopyrightText: 2014 Tom Beckmann |
| 4 | + * 2025 elementary, Inc. (https://elementary.io) |
| 5 | + */ |
| 6 | + |
| 7 | +/** |
| 8 | + * Private class which is basically just a container for the actual |
| 9 | + * icon and takes care of blending the same icon in different sizes |
| 10 | + * over each other and various animations related to the icons |
| 11 | + */ |
| 12 | +public class Gala.WindowIconActor : Clutter.Actor { |
| 13 | + public Meta.Window window { get; construct; } |
| 14 | + |
| 15 | + private float cur_icon_scale = 1.0f; |
| 16 | + private float desired_icon_scale = 1.0f; |
| 17 | + |
| 18 | + private int _icon_size; |
19 | 19 | /** |
20 | | - * Private class which is basically just a container for the actual |
21 | | - * icon and takes care of blending the same icon in different sizes |
22 | | - * over each other and various animations related to the icons |
| 20 | + * The icon size of the WindowIcon. Once set the new icon will be |
| 21 | + * faded over the old one and the actor animates to the new size. |
23 | 22 | */ |
24 | | - public class WindowIconActor : Clutter.Actor { |
25 | | - public Meta.Window window { get; construct; } |
26 | | - |
27 | | - private float cur_icon_scale = 1.0f; |
28 | | - private float desired_icon_scale = 1.0f; |
29 | | - |
30 | | - private int _icon_size; |
31 | | - /** |
32 | | - * The icon size of the WindowIcon. Once set the new icon will be |
33 | | - * faded over the old one and the actor animates to the new size. |
34 | | - */ |
35 | | - public int icon_size { |
36 | | - get { |
37 | | - return _icon_size; |
| 23 | + public int icon_size { |
| 24 | + get { |
| 25 | + return _icon_size; |
| 26 | + } |
| 27 | + private set { |
| 28 | + if (value == _icon_size && cur_icon_scale == desired_icon_scale) { |
| 29 | + return; |
38 | 30 | } |
39 | | - private set { |
40 | | - if (value == _icon_size && cur_icon_scale == desired_icon_scale) { |
41 | | - return; |
42 | | - } |
43 | 31 |
|
44 | | - _icon_size = value; |
45 | | - cur_icon_scale = desired_icon_scale; |
| 32 | + _icon_size = value; |
| 33 | + cur_icon_scale = desired_icon_scale; |
46 | 34 |
|
47 | | - var scaled_size = InternalUtils.scale_to_int (_icon_size, cur_icon_scale); |
48 | | - set_size (scaled_size, scaled_size); |
| 35 | + var scaled_size = InternalUtils.scale_to_int (_icon_size, cur_icon_scale); |
| 36 | + set_size (scaled_size, scaled_size); |
49 | 37 |
|
50 | | - fade_new_icon (); |
51 | | - } |
| 38 | + fade_new_icon (); |
52 | 39 | } |
| 40 | + } |
53 | 41 |
|
54 | | - private bool _temporary; |
55 | | - /** |
56 | | - * Mark the WindowIcon as temporary. Only effect of this is that a pulse |
57 | | - * animation will be played on the actor. Used while DnDing window thumbs |
58 | | - * over the group. |
59 | | - */ |
60 | | - public bool temporary { |
61 | | - get { |
62 | | - return _temporary; |
63 | | - } |
64 | | - set { |
65 | | - if (_temporary && !value) { |
66 | | - remove_transition ("pulse"); |
67 | | - } else if (!_temporary && value && AnimationsSettings.get_enable_animations ()) { |
68 | | - var transition = new Clutter.TransitionGroup () { |
69 | | - duration = 800, |
70 | | - auto_reverse = true, |
71 | | - repeat_count = -1, |
72 | | - progress_mode = Clutter.AnimationMode.LINEAR |
73 | | - }; |
74 | | - |
75 | | - var opacity_transition = new Clutter.PropertyTransition ("opacity"); |
76 | | - opacity_transition.set_from_value (100); |
77 | | - opacity_transition.set_to_value (255); |
78 | | - opacity_transition.auto_reverse = true; |
79 | | - |
80 | | - var scale_x_transition = new Clutter.PropertyTransition ("scale-x"); |
81 | | - scale_x_transition.set_from_value (0.8); |
82 | | - scale_x_transition.set_to_value (1.1); |
83 | | - scale_x_transition.auto_reverse = true; |
84 | | - |
85 | | - var scale_y_transition = new Clutter.PropertyTransition ("scale-y"); |
86 | | - scale_y_transition.set_from_value (0.8); |
87 | | - scale_y_transition.set_to_value (1.1); |
88 | | - scale_y_transition.auto_reverse = true; |
89 | | - |
90 | | - transition.add_transition (opacity_transition); |
91 | | - transition.add_transition (scale_x_transition); |
92 | | - transition.add_transition (scale_y_transition); |
93 | | - |
94 | | - add_transition ("pulse", transition); |
95 | | - } |
96 | | - |
97 | | - _temporary = value; |
| 42 | + private bool _temporary; |
| 43 | + /** |
| 44 | + * Mark the WindowIcon as temporary. Only effect of this is that a pulse |
| 45 | + * animation will be played on the actor. Used while DnDing window thumbs |
| 46 | + * over the group. |
| 47 | + */ |
| 48 | + public bool temporary { |
| 49 | + get { |
| 50 | + return _temporary; |
| 51 | + } |
| 52 | + set { |
| 53 | + if (_temporary && !value) { |
| 54 | + remove_transition ("pulse"); |
| 55 | + } else if (!_temporary && value && AnimationsSettings.get_enable_animations ()) { |
| 56 | + var transition = new Clutter.TransitionGroup () { |
| 57 | + duration = 800, |
| 58 | + auto_reverse = true, |
| 59 | + repeat_count = -1, |
| 60 | + progress_mode = Clutter.AnimationMode.LINEAR |
| 61 | + }; |
| 62 | + |
| 63 | + var opacity_transition = new Clutter.PropertyTransition ("opacity"); |
| 64 | + opacity_transition.set_from_value (100); |
| 65 | + opacity_transition.set_to_value (255); |
| 66 | + opacity_transition.auto_reverse = true; |
| 67 | + |
| 68 | + var scale_x_transition = new Clutter.PropertyTransition ("scale-x"); |
| 69 | + scale_x_transition.set_from_value (0.8); |
| 70 | + scale_x_transition.set_to_value (1.1); |
| 71 | + scale_x_transition.auto_reverse = true; |
| 72 | + |
| 73 | + var scale_y_transition = new Clutter.PropertyTransition ("scale-y"); |
| 74 | + scale_y_transition.set_from_value (0.8); |
| 75 | + scale_y_transition.set_to_value (1.1); |
| 76 | + scale_y_transition.auto_reverse = true; |
| 77 | + |
| 78 | + transition.add_transition (opacity_transition); |
| 79 | + transition.add_transition (scale_x_transition); |
| 80 | + transition.add_transition (scale_y_transition); |
| 81 | + |
| 82 | + add_transition ("pulse", transition); |
98 | 83 | } |
| 84 | + |
| 85 | + _temporary = value; |
99 | 86 | } |
| 87 | + } |
100 | 88 |
|
101 | | - private WindowIcon? icon = null; |
102 | | - private WindowIcon? old_icon = null; |
| 89 | + private WindowIcon? icon = null; |
| 90 | + private WindowIcon? old_icon = null; |
103 | 91 |
|
104 | | - public WindowIconActor (Meta.Window window) { |
105 | | - Object (window: window); |
106 | | - } |
| 92 | + public WindowIconActor (Meta.Window window) { |
| 93 | + Object (window: window); |
| 94 | + } |
107 | 95 |
|
108 | | - construct { |
109 | | - set_pivot_point (0.5f, 0.5f); |
| 96 | + construct { |
| 97 | + set_pivot_point (0.5f, 0.5f); |
110 | 98 |
|
111 | | - window.notify["on-all-workspaces"].connect (on_all_workspaces_changed); |
112 | | - } |
| 99 | + window.notify["on-all-workspaces"].connect (on_all_workspaces_changed); |
| 100 | + } |
113 | 101 |
|
114 | | - ~WindowIconActor () { |
115 | | - window.notify["on-all-workspaces"].disconnect (on_all_workspaces_changed); |
116 | | - } |
| 102 | + ~WindowIconActor () { |
| 103 | + window.notify["on-all-workspaces"].disconnect (on_all_workspaces_changed); |
| 104 | + } |
117 | 105 |
|
118 | | - private void on_all_workspaces_changed () { |
119 | | - // we don't display windows that are on all workspaces |
120 | | - if (window.on_all_workspaces) |
121 | | - destroy (); |
122 | | - } |
| 106 | + private void on_all_workspaces_changed () { |
| 107 | + // we don't display windows that are on all workspaces |
| 108 | + if (window.on_all_workspaces) |
| 109 | + destroy (); |
| 110 | + } |
123 | 111 |
|
124 | | - /** |
125 | | - * Shortcut to set both position and size of the icon |
126 | | - * |
127 | | - * @param x The x coordinate to which to animate to |
128 | | - * @param y The y coordinate to which to animate to |
129 | | - * @param size The size to which to animate to and display the icon in |
130 | | - */ |
131 | | - public void place (float x, float y, int size, float scale) { |
132 | | - desired_icon_scale = scale; |
133 | | - set_position (x, y); |
134 | | - icon_size = size; |
135 | | - } |
| 112 | + /** |
| 113 | + * Shortcut to set both position and size of the icon |
| 114 | + * |
| 115 | + * @param x The x coordinate to which to animate to |
| 116 | + * @param y The y coordinate to which to animate to |
| 117 | + * @param size The size to which to animate to and display the icon in |
| 118 | + */ |
| 119 | + public void place (float x, float y, int size, float scale) { |
| 120 | + desired_icon_scale = scale; |
| 121 | + set_position (x, y); |
| 122 | + icon_size = size; |
| 123 | + } |
136 | 124 |
|
137 | | - /** |
138 | | - * Fades out the old icon and fades in the new icon |
139 | | - */ |
140 | | - private void fade_new_icon () { |
141 | | - var new_icon = new WindowIcon (window, icon_size, (int)Math.round (cur_icon_scale)); |
142 | | - new_icon.add_constraint (new Clutter.BindConstraint (this, Clutter.BindCoordinate.SIZE, 0)); |
143 | | - new_icon.opacity = 0; |
| 125 | + /** |
| 126 | + * Fades out the old icon and fades in the new icon |
| 127 | + */ |
| 128 | + private void fade_new_icon () { |
| 129 | + var new_icon = new WindowIcon (window, icon_size, (int)Math.round (cur_icon_scale)); |
| 130 | + new_icon.add_constraint (new Clutter.BindConstraint (this, Clutter.BindCoordinate.SIZE, 0)); |
| 131 | + new_icon.opacity = 0; |
144 | 132 |
|
145 | | - add_child (new_icon); |
| 133 | + add_child (new_icon); |
146 | 134 |
|
147 | | - new_icon.save_easing_state (); |
148 | | - new_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); |
149 | | - new_icon.set_easing_duration (AnimationsSettings.get_animation_duration (500)); |
150 | | - new_icon.restore_easing_state (); |
| 135 | + new_icon.save_easing_state (); |
| 136 | + new_icon.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); |
| 137 | + new_icon.set_easing_duration (AnimationsSettings.get_animation_duration (500)); |
| 138 | + new_icon.restore_easing_state (); |
151 | 139 |
|
152 | | - if (icon == null) { |
153 | | - icon = new_icon; |
154 | | - } else { |
155 | | - old_icon = icon; |
156 | | - } |
| 140 | + if (icon == null) { |
| 141 | + icon = new_icon; |
| 142 | + } else { |
| 143 | + old_icon = icon; |
| 144 | + } |
| 145 | + |
| 146 | + new_icon.opacity = 255; |
157 | 147 |
|
158 | | - new_icon.opacity = 255; |
159 | | - |
160 | | - if (old_icon != null) { |
161 | | - old_icon.opacity = 0; |
162 | | - var transition = old_icon.get_transition ("opacity"); |
163 | | - if (transition != null) { |
164 | | - transition.completed.connect (() => { |
165 | | - old_icon.destroy (); |
166 | | - old_icon = null; |
167 | | - }); |
168 | | - } else { |
| 148 | + if (old_icon != null) { |
| 149 | + old_icon.opacity = 0; |
| 150 | + var transition = old_icon.get_transition ("opacity"); |
| 151 | + if (transition != null) { |
| 152 | + transition.completed.connect (() => { |
169 | 153 | old_icon.destroy (); |
170 | 154 | old_icon = null; |
171 | | - } |
| 155 | + }); |
| 156 | + } else { |
| 157 | + old_icon.destroy (); |
| 158 | + old_icon = null; |
172 | 159 | } |
173 | | - |
174 | | - icon = new_icon; |
175 | 160 | } |
| 161 | + |
| 162 | + icon = new_icon; |
176 | 163 | } |
177 | 164 | } |
0 commit comments