@@ -527,11 +527,11 @@ impl Fsm for SelectToolFsmState {
527
527
. selected_visible_and_unlocked_layers ( & document. network_interface )
528
528
. filter ( |layer| !document. network_interface . is_artboard ( & layer. to_node ( ) , & [ ] ) )
529
529
{
530
- overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) ) ;
530
+ overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) , None ) ;
531
531
532
532
if is_layer_fed_by_node_of_name ( layer, & document. network_interface , "Text" ) {
533
533
let transformed_quad = document. metadata ( ) . transform_to_viewport ( layer) * text_bounding_box ( layer, document, font_cache) ;
534
- overlay_context. dashed_quad ( transformed_quad, None , Some ( 7. ) , Some ( 5. ) , None ) ;
534
+ overlay_context. dashed_quad ( transformed_quad, None , None , Some ( 7. ) , Some ( 5. ) , None ) ;
535
535
}
536
536
}
537
537
}
@@ -573,7 +573,38 @@ impl Fsm for SelectToolFsmState {
573
573
let not_selected_click = click. filter ( |& hovered_layer| !document. network_interface . selected_nodes ( ) . selected_layers_contains ( hovered_layer, document. metadata ( ) ) ) ;
574
574
if let Some ( layer) = not_selected_click {
575
575
if overlay_context. visibility_settings . hover_outline ( ) {
576
- overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) ) ;
576
+ let mut hover_overlay_draw = |layer : LayerNodeIdentifier , color : Option < & str > | {
577
+ if layer. has_children ( document. metadata ( ) ) {
578
+ if let Some ( bounds) = document. metadata ( ) . bounding_box_viewport ( layer) {
579
+ overlay_context. quad ( Quad :: from_box ( bounds) , color, None ) ;
580
+ }
581
+ } else {
582
+ overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) , color) ;
583
+ }
584
+ } ;
585
+ let layer = match tool_data. nested_selection_behavior {
586
+ NestedSelectionBehavior :: Deepest => document. find_deepest ( & [ layer] ) ,
587
+ NestedSelectionBehavior :: Shallowest => layer_selected_shallowest ( layer, document) ,
588
+ }
589
+ . unwrap_or ( layer) ;
590
+ hover_overlay_draw ( layer, None ) ;
591
+ if matches ! ( tool_data. nested_selection_behavior, NestedSelectionBehavior :: Shallowest ) {
592
+ let mut selected = document. network_interface . selected_nodes ( ) ;
593
+ selected. add_selected_nodes ( vec ! [ layer. to_node( ) ] ) ;
594
+ if let Some ( new_selected) = click. unwrap ( ) . ancestors ( document. metadata ( ) ) . filter ( not_artboard ( document) ) . find ( |ancestor| {
595
+ ancestor
596
+ . parent ( document. metadata ( ) )
597
+ . is_some_and ( |parent| selected. selected_layers_contains ( parent, document. metadata ( ) ) )
598
+ } ) {
599
+ let mut fill_color = graphene_std:: Color :: from_rgb_str ( COLOR_OVERLAY_BLUE . strip_prefix ( '#' ) . unwrap ( ) )
600
+ . unwrap ( )
601
+ . with_alpha ( 0.5 )
602
+ . to_rgba_hex_srgb ( ) ;
603
+ fill_color. insert ( 0 , '#' ) ;
604
+ let fill_color = Some ( fill_color. as_str ( ) ) ;
605
+ hover_overlay_draw ( new_selected, fill_color) ;
606
+ }
607
+ }
577
608
}
578
609
579
610
// Measure with Alt held down
@@ -786,7 +817,7 @@ impl Fsm for SelectToolFsmState {
786
817
if overlay_context. visibility_settings . selection_outline ( ) {
787
818
// Draws a temporary outline on the layers that will be selected by the current box/lasso area
788
819
for layer in layers_to_outline {
789
- overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) ) ;
820
+ overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) , None ) ;
790
821
}
791
822
}
792
823
@@ -801,10 +832,10 @@ impl Fsm for SelectToolFsmState {
801
832
let polygon = & tool_data. lasso_polygon ;
802
833
803
834
match ( selection_shape, current_selection_mode) {
804
- ( SelectionShapeType :: Box , SelectionMode :: Enclosed ) => overlay_context. dashed_quad ( quad, fill_color, Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ,
805
- ( SelectionShapeType :: Lasso , SelectionMode :: Enclosed ) => overlay_context. dashed_polygon ( polygon, fill_color, Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ,
806
- ( SelectionShapeType :: Box , _) => overlay_context. quad ( quad, fill_color) ,
807
- ( SelectionShapeType :: Lasso , _) => overlay_context. polygon ( polygon, fill_color) ,
835
+ ( SelectionShapeType :: Box , SelectionMode :: Enclosed ) => overlay_context. dashed_quad ( quad, None , fill_color, Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ,
836
+ ( SelectionShapeType :: Lasso , SelectionMode :: Enclosed ) => overlay_context. dashed_polygon ( polygon, None , fill_color, Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ,
837
+ ( SelectionShapeType :: Box , _) => overlay_context. quad ( quad, None , fill_color) ,
838
+ ( SelectionShapeType :: Lasso , _) => overlay_context. polygon ( polygon, None , fill_color) ,
808
839
}
809
840
}
810
841
self
@@ -1733,6 +1764,34 @@ fn drag_shallowest_manipulation(responses: &mut VecDeque<Message>, selected: Vec
1733
1764
} ) ;
1734
1765
}
1735
1766
1767
+ fn layer_selected_shallowest ( clicked_layer : LayerNodeIdentifier , document : & DocumentMessageHandler ) -> Option < LayerNodeIdentifier > {
1768
+ let metadata = document. metadata ( ) ;
1769
+ let selected_layers = document. network_interface . selected_nodes ( ) . selected_layers ( document. metadata ( ) ) . collect :: < Vec < _ > > ( ) ;
1770
+ let final_selection: Option < LayerNodeIdentifier > = ( !selected_layers. is_empty ( ) && selected_layers != vec ! [ LayerNodeIdentifier :: ROOT_PARENT ] ) . then_some ( ( ) ) . and_then ( |_| {
1771
+ let mut relevant_layers = document. network_interface . selected_nodes ( ) . selected_layers ( document. metadata ( ) ) . collect :: < Vec < _ > > ( ) ;
1772
+ if !relevant_layers. contains ( & clicked_layer) {
1773
+ relevant_layers. push ( clicked_layer) ;
1774
+ }
1775
+ clicked_layer
1776
+ . ancestors ( metadata)
1777
+ . filter ( not_artboard ( document) )
1778
+ . find ( |& ancestor| relevant_layers. iter ( ) . all ( |layer| * layer == ancestor || ancestor. is_ancestor_of ( metadata, layer) ) )
1779
+ . and_then ( |least_common_ancestor| {
1780
+ let common_siblings: Vec < _ > = least_common_ancestor. children ( metadata) . collect ( ) ;
1781
+ ( clicked_layer == least_common_ancestor)
1782
+ . then_some ( least_common_ancestor)
1783
+ . or_else ( || common_siblings. iter ( ) . find ( |& & child| clicked_layer == child || child. is_ancestor_of ( metadata, & clicked_layer) ) . copied ( ) )
1784
+ } )
1785
+ } ) ;
1786
+
1787
+ if final_selection. is_some_and ( |layer| selected_layers. iter ( ) . any ( |selected| layer. is_child_of ( metadata, selected) ) ) {
1788
+ return None ;
1789
+ }
1790
+
1791
+ let new_selected = final_selection. unwrap_or_else ( || clicked_layer. ancestors ( document. metadata ( ) ) . filter ( not_artboard ( document) ) . last ( ) . unwrap_or ( clicked_layer) ) ;
1792
+ Some ( new_selected)
1793
+ }
1794
+
1736
1795
fn drag_deepest_manipulation ( responses : & mut VecDeque < Message > , selected : Vec < LayerNodeIdentifier > , tool_data : & mut SelectToolData , document : & DocumentMessageHandler , remove : bool ) {
1737
1796
let layer = document. find_deepest ( & selected) . unwrap_or (
1738
1797
LayerNodeIdentifier :: ROOT_PARENT
0 commit comments