1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//! Layers an application paints into a component's frame.
//!
//! A component owns its structure; what fills the space behind and in front
//! of that structure is the application's business. This is the slot for it:
//! one element under the content, one over it, both clipped to the frame's
//! own shape, neither taking any part in layout.
//!
//! # What can go in one
//!
//! Anything that is an element. A `div` with a patterned background, an
//! `img` — including an animated GIF or WebP — a `canvas` painting arbitrary
//! geometry, or a webview. This crate ships no effects of its own: a shake, a
//! ripple, a halftone field are an application's expression, not a library's.
//!
//! # Corners
//!
//! A layer that paints all the way to the edge has to carry the frame's
//! radius itself, because GPUI cannot clip a subtree to a rounded rectangle -
//! its `ContentMask` is a `Bounds`, so `overflow_hidden` clips to the box and
//! never to a corner. [`frame_radius`] is that radius. A layer that does not
//! reach the corners - scattered dots, a ring in the middle - needs nothing.
//!
//! # Example
//!
//! ```
//! use gpui_ai::prelude::{Decoration, decoration};
//! use gpui::{App, div, prelude::*};
//!
//! # fn example(cx: &App) -> Decoration {
//! Decoration::behind(div().size_full().rounded(decoration::frame_radius(cx)))
//! .and_above(div().size_full())
//! # }
//! ```
//!
//! # Motion
//!
//! [`animated`] drives a decoration from a looping 0…1 and stops it when the
//! frame it sits in scrolls out of view or the reader has asked for less
//! motion. A decoration that animates on its own clock would keep a scrolled
//! away panel paying for itself forever.
use crateVisibleAnimationExt as _;
use ;
use ActiveTheme as _;
use Duration;
/// The layers an application paints into one component's frame.
///
/// Both slots are optional and independent. A decoration never affects the
/// component's size: the frame measures its content, and these are painted
/// into the space that measurement produced.
/// The corner radius a decoration must carry to reach a component's edge.
///
/// Every framed component in this library rounds its frame by the theme's
/// large radius, so a layer that paints to the edge rounds itself by this and
/// lands on the frame exactly. It follows the active theme, including a custom
/// JSON one, which is why it is a call rather than a constant.
///
/// It exists because the alternative does not: GPUI's `ContentMask` is a
/// `Bounds`, so nothing here can clip a layer to a rounded shape on the
/// caller's behalf. Per-element radii on a `div` background or an `img` are
/// resolved in the shader and do work - and note that `ObjectFit::Cover` hands
/// a sprite bounds larger than the element, which puts those radii on corners
/// that are off screen. A covered photograph has to be cropped to the frame,
/// not fitted into it.
/// Places one layer over the component's own background, clipped to its box.
///
/// Rectangularly, and that is a real limit rather than an oversight - see
/// [`frame_radius`] for why, and for the radius a layer rounds itself by.
///
/// Painting the corners back in the frame's colour was tried and is wrong: the
/// sliver outside the radius is where whatever sits *behind* the component
/// shows through, so filling it with the component's own surface draws a blob
/// over the backdrop rather than a rounded corner.
/// Places a component's decoration layers.
///
/// Two calls rather than one, because paint order is child order: the under
/// layer has to be the frame's first child and the over layer its last. The
/// `every_framed_component_places_both_decoration_layers` test is what keeps
/// a component from quietly honouring only one of them.
pub
/// A decoration that animates, and stops when nobody can see it.
///
/// `build` is handed a 0…1 that loops over `period`, and returns the element
/// to paint at that point in the loop. The loop runs only while the region is
/// on screen and unclipped, and holds at 0 when the reader has asked for less
/// motion — so an application's own effect answers to the same preference
/// every animation in this library does, without the application arranging it.
///
/// # Example
///
/// ```
/// use gpui_ai::prelude::decoration;
/// use gpui::{div, prelude::*, px};
/// use std::time::Duration;
///
/// let drifting = decoration::animated("tide", Duration::from_secs(8), |delta| {
/// div().absolute().top(px(delta * 40.)).size_full()
/// });
/// ```
/// Drives a decoration from a value the application already has.
///
/// Where [`animated`] loops on its own, this eases towards `target` whenever
/// the application moves it — a ripple started by a press, a tilt that
/// follows a pointer, a shake that grows as a value approaches its limit.
/// Returns `target` immediately when the reader has asked for less motion.