11use std:: { rc:: Rc , time:: Duration } ;
22
33use gpui:: {
4- actions, anchored, div, hsla, prelude:: FluentBuilder , px, relative, Animation ,
4+ actions, anchored, div, hsla, point , prelude:: FluentBuilder , px, relative, Animation ,
55 AnimationExt as _, AnyElement , AppContext , Bounds , ClickEvent , Div , FocusHandle , Hsla ,
66 InteractiveElement , IntoElement , KeyBinding , MouseButton , ParentElement , Pixels , Point ,
77 RenderOnce , SharedString , Styled , WindowContext ,
@@ -11,7 +11,9 @@ use crate::{
1111 animation:: cubic_bezier,
1212 button:: { Button , ButtonVariants as _} ,
1313 theme:: ActiveTheme as _,
14- v_flex, ContextModal , IconName , Sizable as _,
14+ v_flex,
15+ window_border:: SHADOW_SIZE ,
16+ ContextModal , IconName , Sizable as _,
1517} ;
1618
1719actions ! ( modal, [ Escape ] ) ;
@@ -162,7 +164,7 @@ impl RenderOnce for Modal {
162164 fn render ( self , cx : & mut WindowContext ) -> impl gpui:: IntoElement {
163165 let layer_ix = self . layer_ix ;
164166 let on_close = self . on_close . clone ( ) ;
165- let view_size = cx. viewport_size ( ) ;
167+ let view_size = cx. viewport_size ( ) - gpui :: size ( SHADOW_SIZE * 2 , SHADOW_SIZE * 2 ) ;
166168 let bounds = Bounds {
167169 origin : Point :: default ( ) ,
168170 size : view_size,
@@ -171,78 +173,83 @@ impl RenderOnce for Modal {
171173 let y = self . margin_top . unwrap_or ( view_size. height / 10. ) + offset_top;
172174 let x = bounds. center ( ) . x - self . width / 2. ;
173175
174- anchored ( ) . snap_to_window ( ) . child (
175- div ( )
176- . occlude ( )
177- . w ( view_size. width )
178- . h ( view_size. height )
179- . when ( self . overlay_visible , |this| {
180- this. bg ( overlay_color ( self . overlay , cx) )
181- } )
182- . when ( self . overlay , |this| {
183- this. on_mouse_down ( MouseButton :: Left , {
176+ anchored ( )
177+ . position ( point ( SHADOW_SIZE , SHADOW_SIZE ) )
178+ . snap_to_window ( )
179+ . child (
180+ div ( )
181+ . occlude ( )
182+ . w ( view_size. width )
183+ . h ( view_size. height )
184+ . when ( self . overlay_visible , |this| {
185+ this. bg ( overlay_color ( self . overlay , cx) )
186+ } )
187+ . on_mouse_down ( MouseButton :: Left , {
184188 let on_close = self . on_close . clone ( ) ;
185189 move |_, cx| {
186190 on_close ( & ClickEvent :: default ( ) , cx) ;
187191 cx. close_modal ( ) ;
188192 }
189193 } )
190- } )
191- . child (
192- self . base
193- . id ( SharedString :: from ( format ! ( "modal-{layer_ix}" ) ) )
194- . key_context ( CONTEXT )
195- . track_focus ( & self . focus_handle )
196- . when ( self . keyboard , |this| {
197- this. on_action ( {
198- let on_close = self . on_close . clone ( ) ;
199- move |_: & Escape , cx| {
200- // FIXME:
201- //
202- // Here some Modal have no focus_handle, so it will not work will Escape key.
203- // But by now, we `cx.close_modal()` going to close the last active model, so the Escape is unexpected to work.
204- on_close ( & ClickEvent :: default ( ) , cx) ;
205- cx. close_modal ( ) ;
206- }
194+ . child (
195+ self . base
196+ . id ( SharedString :: from ( format ! ( "modal-{layer_ix}" ) ) )
197+ . key_context ( CONTEXT )
198+ . track_focus ( & self . focus_handle )
199+ . when ( self . keyboard , |this| {
200+ this. on_action ( {
201+ let on_close = self . on_close . clone ( ) ;
202+ move |_: & Escape , cx| {
203+ // FIXME:
204+ //
205+ // Here some Modal have no focus_handle, so it will not work will Escape key.
206+ // But by now, we `cx.close_modal()` going to close the last active model, so the Escape is unexpected to work.
207+ on_close ( & ClickEvent :: default ( ) , cx) ;
208+ cx. close_modal ( ) ;
209+ }
210+ } )
211+ } )
212+ . absolute ( )
213+ . occlude ( )
214+ . relative ( )
215+ . left ( x)
216+ . top ( y)
217+ . w ( self . width )
218+ . when_some ( self . max_width , |this, w| this. max_w ( w) )
219+ . when_some ( self . title , |this, title| {
220+ this. child ( div ( ) . line_height ( relative ( 1. ) ) . child ( title) )
207221 } )
208- } )
209- . absolute ( )
210- . occlude ( )
211- . relative ( )
212- . left ( x)
213- . top ( y)
214- . w ( self . width )
215- . when_some ( self . max_width , |this, w| this. max_w ( w) )
216- . when_some ( self . title , |this, title| {
217- this. child ( div ( ) . line_height ( relative ( 1. ) ) . child ( title) )
218- } )
219- . when ( self . show_close , |this| {
220- this. child (
221- Button :: new ( SharedString :: from ( format ! ( "modal-close-{layer_ix}" ) ) )
222+ . when ( self . show_close , |this| {
223+ this. child (
224+ Button :: new ( SharedString :: from ( format ! (
225+ "modal-close-{layer_ix}"
226+ ) ) )
222227 . absolute ( )
223228 . top_2 ( )
224229 . right_2 ( )
225230 . small ( )
226231 . ghost ( )
227232 . icon ( IconName :: Close )
228- . on_click ( move |_, cx| {
229- on_close ( & ClickEvent :: default ( ) , cx) ;
230- cx. close_modal ( ) ;
231- } ) ,
232- )
233- } )
234- . child ( self . content )
235- . children ( self . footer )
236- . with_animation (
237- "slide-down" ,
238- Animation :: new ( Duration :: from_secs_f64 ( 0.25 ) )
239- . with_easing ( cubic_bezier ( 0.32 , 0.72 , 0. , 1. ) ) ,
240- move |this, delta| {
241- let y_offset = px ( 0. ) + delta * px ( 30. ) ;
242- this. top ( y + y_offset) . opacity ( delta)
243- } ,
244- ) ,
245- ) ,
246- )
233+ . on_click (
234+ move |_, cx| {
235+ on_close ( & ClickEvent :: default ( ) , cx) ;
236+ cx. close_modal ( ) ;
237+ } ,
238+ ) ,
239+ )
240+ } )
241+ . child ( self . content )
242+ . children ( self . footer )
243+ . with_animation (
244+ "slide-down" ,
245+ Animation :: new ( Duration :: from_secs_f64 ( 0.25 ) )
246+ . with_easing ( cubic_bezier ( 0.32 , 0.72 , 0. , 1. ) ) ,
247+ move |this, delta| {
248+ let y_offset = px ( 0. ) + delta * px ( 30. ) ;
249+ this. top ( y + y_offset) . opacity ( delta)
250+ } ,
251+ ) ,
252+ ) ,
253+ )
247254 }
248255}
0 commit comments