11use std:: collections:: VecDeque ;
22
33use compiler:: compile:: { SolvedValue , ifmatvec} ;
4+ use enumify:: enumify;
45use geometry:: transform:: TransformationMatrix ;
56use gpui:: {
67 BorderStyle , Bounds , Context , Corners , DefiniteLength , DragMoveEvent , Edges , Element , Entity ,
78 InteractiveElement , IntoElement , Length , MouseButton , MouseDownEvent , MouseMoveEvent ,
8- MouseUpEvent , PaintQuad , ParentElement , Pixels , Point , Render , ScrollWheelEvent , Size , Style ,
9- Styled , Subscription , Window , div, pattern_slash, rgb, rgba, solid_background,
9+ MouseUpEvent , PaintQuad , ParentElement , Pixels , Point , Render , Rgba , ScrollWheelEvent , Size ,
10+ Style , Styled , Subscription , Window , div, pattern_slash, rgb, rgba, solid_background,
1011} ;
1112use itertools:: Itertools ;
1213
@@ -19,11 +20,18 @@ pub enum ShapeFill {
1920}
2021
2122#[ derive( Copy , Clone , Hash , PartialEq , Eq , Debug ) ]
22- pub struct RectId {
23+ pub struct ElementId {
2324 scope : ScopeAddress ,
2425 idx : usize ,
2526}
2627
28+ #[ enumify]
29+ #[ derive( Copy , Clone , Hash , PartialEq , Eq , Debug ) ]
30+ pub enum RectId {
31+ Element ( ElementId ) ,
32+ Scope ( ScopeAddress ) ,
33+ }
34+
2735#[ derive( Clone , PartialEq ) ]
2836pub struct Rect {
2937 pub x0 : f32 ,
@@ -62,6 +70,7 @@ pub struct LayoutCanvas {
6270 #[ allow( unused) ]
6371 subscriptions : Vec < Subscription > ,
6472 rects : Vec < ( Rect , LayerState ) > ,
73+ scope_rects : Vec < Rect > ,
6574}
6675
6776impl IntoElement for CanvasElement {
@@ -72,6 +81,46 @@ impl IntoElement for CanvasElement {
7281 }
7382}
7483
84+ fn get_paint_quad (
85+ r : & Rect ,
86+ bounds : Bounds < Pixels > ,
87+ scale : f32 ,
88+ offset : Point < Pixels > ,
89+ fill : ShapeFill ,
90+ color : Rgba ,
91+ border_color : Rgba ,
92+ ) -> Option < PaintQuad > {
93+ let rect_bounds = Bounds :: new (
94+ Point :: new ( scale * Pixels ( r. x0 ) , scale * Pixels ( r. y0 ) ) + offset + bounds. origin ,
95+ Size :: new ( scale * Pixels ( r. x1 - r. x0 ) , scale * Pixels ( r. y1 - r. y0 ) ) ,
96+ ) ;
97+ let background = match fill {
98+ ShapeFill :: Solid => solid_background ( color) ,
99+ ShapeFill :: Stippling => pattern_slash ( color. into ( ) , 1. , 9. ) ,
100+ } ;
101+ if let Some ( clipped) = intersect ( & rect_bounds, & bounds) {
102+ let left_border = f32:: clamp ( ( rect_bounds. left ( ) . 0 + 2. ) - bounds. left ( ) . 0 , 0. , 2. ) ;
103+ let right_border = f32:: clamp ( bounds. right ( ) . 0 - ( rect_bounds. right ( ) . 0 - 2. ) , 0. , 2. ) ;
104+ let top_border = f32:: clamp ( ( rect_bounds. top ( ) . 0 + 2. ) - bounds. top ( ) . 0 , 0. , 2. ) ;
105+ let bot_border = f32:: clamp ( bounds. bottom ( ) . 0 - ( rect_bounds. bottom ( ) . 0 - 2. ) , 0. , 2. ) ;
106+ let mut border_widths = Edges :: all ( Pixels ( 2. ) ) ;
107+ border_widths. left = Pixels ( left_border) ;
108+ border_widths. right = Pixels ( right_border) ;
109+ border_widths. top = Pixels ( top_border) ;
110+ border_widths. bottom = Pixels ( bot_border) ;
111+ Some ( PaintQuad {
112+ bounds : clipped,
113+ corner_radii : Corners :: all ( Pixels ( 0. ) ) ,
114+ background,
115+ border_widths,
116+ border_color : border_color. into ( ) ,
117+ border_style : BorderStyle :: Solid ,
118+ } )
119+ } else {
120+ None
121+ }
122+ }
123+
75124impl Element for CanvasElement {
76125 type RequestLayoutState = ( ) ;
77126 type PrepaintState = ( ) ;
@@ -125,6 +174,7 @@ impl Element for CanvasElement {
125174 let layers = & inner. state . read ( cx) . layers . read ( cx) ;
126175
127176 let mut rects = Vec :: new ( ) ;
177+ let mut scope_rects = Vec :: new ( ) ;
128178 if let Some ( solved_cell) = solved_cell {
129179 let mut queue = VecDeque :: from_iter ( [ (
130180 solved_cell. selected_scope ,
@@ -134,9 +184,21 @@ impl Element for CanvasElement {
134184 while let Some ( ( curr_address @ ScopeAddress { scope, cell } , mat, ofs) ) =
135185 queue. pop_front ( )
136186 {
137- let scope_info = & solved_cell. output . cells [ & cell] . scopes [ & scope] ;
138- let visible = solved_cell. state [ & curr_address] . visible ;
139- if !visible {
187+ let cell_info = & solved_cell. output . cells [ & cell] ;
188+ let scope_info = & cell_info. scopes [ & scope] ;
189+ let scope_state = & solved_cell. state [ & curr_address] ;
190+ if !scope_state. visible {
191+ if let Some ( bbox) = & scope_state. bbox {
192+ let p0p = ifmatvec ( mat, ( bbox. x0 , bbox. y0 ) ) ;
193+ let p1p = ifmatvec ( mat, ( bbox. x1 , bbox. y1 ) ) ;
194+ scope_rects. push ( Rect {
195+ x0 : ( p0p. 0 . min ( p1p. 0 ) + ofs. 0 ) as f32 ,
196+ y0 : ( p0p. 1 . min ( p1p. 1 ) + ofs. 1 ) as f32 ,
197+ x1 : ( p0p. 0 . max ( p1p. 0 ) + ofs. 0 ) as f32 ,
198+ y1 : ( p0p. 1 . max ( p1p. 1 ) + ofs. 1 ) as f32 ,
199+ id : RectId :: Scope ( curr_address) ,
200+ } ) ;
201+ }
140202 continue ;
141203 }
142204 for ( i, value) in scope_info. elts . iter ( ) . enumerate ( ) {
@@ -157,10 +219,10 @@ impl Element for CanvasElement {
157219 y0 : ( p0p. 1 . min ( p1p. 1 ) + ofs. 1 ) as f32 ,
158220 x1 : ( p0p. 0 . max ( p1p. 0 ) + ofs. 0 ) as f32 ,
159221 y1 : ( p0p. 1 . max ( p1p. 1 ) + ofs. 1 ) as f32 ,
160- id : RectId {
222+ id : RectId :: Element ( ElementId {
161223 scope : curr_address,
162224 idx : i,
163- } ,
225+ } ) ,
164226 } ,
165227 layer. clone ( ) ,
166228 ) ) ;
@@ -178,11 +240,27 @@ impl Element for CanvasElement {
178240 scope : solved_cell. output . cells [ & inst. cell ] . root ,
179241 cell : inst. cell ,
180242 } ;
181- queue. push_back ( (
182- inst_address,
183- mat * inst_mat,
184- ( inst_ofs. 0 + ofs. 0 , inst_ofs. 1 + ofs. 1 ) ,
185- ) ) ;
243+ let new_mat = mat * inst_mat;
244+ let new_ofs = ( inst_ofs. 0 + ofs. 0 , inst_ofs. 1 + ofs. 1 ) ;
245+ let scope_state = & solved_cell. state [ & inst_address] ;
246+ if !scope_state. visible {
247+ if let Some ( bbox) = & scope_state. bbox {
248+ let p0p = ifmatvec ( new_mat, ( bbox. x0 , bbox. y0 ) ) ;
249+ let p1p = ifmatvec ( new_mat, ( bbox. x1 , bbox. y1 ) ) ;
250+ scope_rects. push ( Rect {
251+ x0 : ( p0p. 0 . min ( p1p. 0 ) + new_ofs. 0 ) as f32 ,
252+ y0 : ( p0p. 1 . min ( p1p. 1 ) + new_ofs. 1 ) as f32 ,
253+ x1 : ( p0p. 0 . max ( p1p. 0 ) + new_ofs. 0 ) as f32 ,
254+ y1 : ( p0p. 1 . max ( p1p. 1 ) + new_ofs. 1 ) as f32 ,
255+ id : RectId :: Element ( ElementId {
256+ scope : curr_address,
257+ idx : i,
258+ } ) ,
259+ } ) ;
260+ }
261+ continue ;
262+ }
263+ queue. push_back ( ( inst_address, new_mat, new_ofs) ) ;
186264 }
187265 _ => { }
188266 }
@@ -208,60 +286,61 @@ impl Element for CanvasElement {
208286 . clone ( )
209287 . paint ( bounds, window, cx, |window, _cx| {
210288 window. paint_layer ( bounds, |window| {
289+ let mut selected_quads = Vec :: new ( ) ;
211290 for ( r, l) in & rects {
212- let rect_bounds = Bounds :: new (
213- Point :: new ( scale * Pixels ( r. x0 ) , scale * Pixels ( r. y0 ) )
214- + offset
215- + bounds. origin ,
216- Size :: new ( scale * Pixels ( r. x1 - r. x0 ) , scale * Pixels ( r. y1 - r. y0 ) ) ,
217- ) ;
218- let background = match l. fill {
219- ShapeFill :: Solid => solid_background ( l. color ) ,
220- ShapeFill :: Stippling => pattern_slash ( l. color . into ( ) , 1. , 9. ) ,
221- } ;
222- if let Some ( clipped) = intersect ( & rect_bounds, & bounds) {
223- let left_border =
224- f32:: clamp ( ( rect_bounds. left ( ) . 0 + 2. ) - bounds. left ( ) . 0 , 0. , 2. ) ;
225- let right_border =
226- f32:: clamp ( bounds. right ( ) . 0 - ( rect_bounds. right ( ) . 0 - 2. ) , 0. , 2. ) ;
227- let top_border =
228- f32:: clamp ( ( rect_bounds. top ( ) . 0 + 2. ) - bounds. top ( ) . 0 , 0. , 2. ) ;
229- let bot_border = f32:: clamp (
230- bounds. bottom ( ) . 0 - ( rect_bounds. bottom ( ) . 0 - 2. ) ,
231- 0. ,
232- 2. ,
233- ) ;
234- let mut border_widths = Edges :: all ( Pixels ( 2. ) ) ;
235- border_widths. left = Pixels ( left_border) ;
236- border_widths. right = Pixels ( right_border) ;
237- border_widths. top = Pixels ( top_border) ;
238- border_widths. bottom = Pixels ( bot_border) ;
239- window. paint_quad ( PaintQuad {
240- bounds : clipped,
241- corner_radii : Corners :: all ( Pixels ( 0. ) ) ,
242- background,
243- border_widths,
244- border_color : l. border_color . into ( ) ,
245- border_style : BorderStyle :: Solid ,
246- } ) ;
291+ if let Some ( quad) = get_paint_quad (
292+ r,
293+ bounds,
294+ scale,
295+ offset,
296+ l. fill ,
297+ l. color ,
298+ l. border_color ,
299+ ) {
300+ window. paint_quad ( quad. clone ( ) ) ;
247301 if let Some ( selected_rect) = selected_rect
248302 && r. id == selected_rect
249303 {
250- window. paint_quad ( PaintQuad {
251- bounds : clipped,
252- corner_radii : Corners :: all ( Pixels ( 0. ) ) ,
304+ selected_quads. push ( PaintQuad {
253305 background : solid_background ( rgba ( 0 ) ) ,
254- border_widths,
255306 border_color : rgb ( 0xffff00 ) . into ( ) ,
256307 border_style : BorderStyle :: Solid ,
308+ ..quad
257309 } ) ;
258310 }
259311 }
260312 }
313+ for r in & scope_rects {
314+ if let Some ( quad) = get_paint_quad (
315+ r,
316+ bounds,
317+ scale,
318+ offset,
319+ ShapeFill :: Solid ,
320+ rgba ( 0 ) ,
321+ rgba ( 0xffffffff ) ,
322+ ) {
323+ window. paint_quad ( quad. clone ( ) ) ;
324+ if let Some ( selected_rect) = selected_rect
325+ && r. id == selected_rect
326+ {
327+ selected_quads. push ( PaintQuad {
328+ background : solid_background ( rgba ( 0 ) ) ,
329+ border_color : rgb ( 0xffff00 ) . into ( ) ,
330+ border_style : BorderStyle :: Solid ,
331+ ..quad
332+ } ) ;
333+ }
334+ }
335+ }
336+ for q in selected_quads {
337+ window. paint_quad ( q) ;
338+ }
261339 } )
262340 } ) ;
263341 self . inner . update ( cx, |inner, cx| {
264342 inner. rects = rects;
343+ inner. scope_rects = scope_rects;
265344 cx. notify ( ) ;
266345 } ) ;
267346 }
@@ -310,6 +389,7 @@ impl LayoutCanvas {
310389 subscriptions : vec ! [ cx. observe( state, |_, _, cx| cx. notify( ) ) ] ,
311390 state : state. clone ( ) ,
312391 rects : Vec :: new ( ) ,
392+ scope_rects : Vec :: new ( ) ,
313393 }
314394 }
315395
@@ -322,47 +402,60 @@ impl LayoutCanvas {
322402 let rects = self
323403 . rects
324404 . iter ( )
325- . cloned ( )
405+ . rev ( )
326406 . sorted_by_key ( |( _, layer) | usize:: MAX - layer. z )
327- . collect_vec ( ) ;
407+ . map ( | ( r , _ ) | r ) ;
328408 let scale = self . scale ;
329409 let offset = self . offset ;
330- for ( r, _) in rects {
410+ let mut selected_rect = None ;
411+ for r in rects. chain ( self . scope_rects . iter ( ) ) {
331412 let rect_bounds = Bounds :: new (
332413 Point :: new ( scale * Pixels ( r. x0 ) , scale * Pixels ( r. y0 ) )
333414 + offset
334415 + self . screen_origin ,
335416 Size :: new ( scale * Pixels ( r. x1 - r. x0 ) , scale * Pixels ( r. y1 - r. y0 ) ) ,
336417 ) ;
337418 if rect_bounds. contains ( & event. position ) {
338- self . state . update ( cx, |state, cx| {
339- state. solved_cell . update ( cx, |cell, cx| {
340- if let Some ( cell) = cell. as_mut ( ) {
341- cell. selected_rect = Some ( r. id ) ;
342- state. lsp_client . select_rect (
343- cell. output . cells [ & r. id . scope . cell ] . scopes [ & r. id . scope . scope ] . elts
344- [ r. id . idx ]
345- . as_ref ( )
346- . unwrap_rect ( )
347- . source
348- . as_ref ( )
349- . map ( |source| ( cell. file . clone ( ) , source. span ) ) ,
350- ) ;
351- cx. notify ( ) ;
352- }
353- } ) ;
354- } ) ;
355- return ;
419+ selected_rect = Some ( r) ;
356420 }
357421 }
358- self . state . update ( cx, |state, cx| {
359- state. solved_cell . update ( cx, |cell, cx| {
360- if let Some ( cell) = cell. as_mut ( ) {
361- cell. selected_rect = None ;
362- cx. notify ( ) ;
363- }
422+ if let Some ( r) = selected_rect. cloned ( ) {
423+ self . state . update ( cx, |state, cx| {
424+ state. solved_cell . update ( cx, |cell, cx| {
425+ if let Some ( cell) = cell. as_mut ( ) {
426+ cell. selected_rect = Some ( r. id ) ;
427+ let args = match r. id {
428+ RectId :: Element ( id) => {
429+ match & cell. output . cells [ & id. scope . cell ] . scopes [ & id. scope . scope ]
430+ . elts [ id. idx ]
431+ {
432+ SolvedValue :: Rect ( r) => r
433+ . source
434+ . as_ref ( )
435+ . map ( |source| ( cell. file . clone ( ) , source. span ) ) ,
436+ _ => None ,
437+ }
438+ }
439+ RectId :: Scope ( id) => Some ( (
440+ cell. file . clone ( ) ,
441+ cell. output . cells [ & id. cell ] . scopes [ & id. scope ] . span ,
442+ ) ) ,
443+ } ;
444+ state. lsp_client . select_rect ( args) ;
445+ cx. notify ( ) ;
446+ }
447+ } ) ;
364448 } ) ;
365- } ) ;
449+ } else {
450+ self . state . update ( cx, |state, cx| {
451+ state. solved_cell . update ( cx, |cell, cx| {
452+ if let Some ( cell) = cell. as_mut ( ) {
453+ cell. selected_rect = None ;
454+ cx. notify ( ) ;
455+ }
456+ } ) ;
457+ } ) ;
458+ }
366459 }
367460
368461 #[ allow( unused) ]
0 commit comments