@@ -136,6 +136,9 @@ impl DocumentMessageHandler {
136
136
// TODO: Add deduplication
137
137
( !path. is_empty ( ) ) . then ( || self . handle_folder_changed ( path[ ..path. len ( ) - 1 ] . to_vec ( ) ) ) . flatten ( )
138
138
}
139
+ fn selected_layers ( & self ) -> impl Iterator < Item = & Vec < LayerId > > {
140
+ self . active_document ( ) . layer_data . iter ( ) . filter_map ( |( path, data) | data. selected . then ( || path) )
141
+ }
139
142
fn layerdata ( & self , path : & [ LayerId ] ) -> & LayerData {
140
143
self . active_document ( ) . layer_data . get ( path) . expect ( "Layerdata does not exist" )
141
144
}
@@ -155,8 +158,7 @@ impl DocumentMessageHandler {
155
158
) ;
156
159
}
157
160
158
- /// Returns the paths to all layers in order, optionally including only selected or non
159
- /// selected layers.
161
+ /// Returns the paths to all layers in order, optionally including only selected or non-selected layers.
160
162
fn layers_sorted ( & self , selected : Option < bool > ) -> Vec < Vec < LayerId > > {
161
163
// Compute the indices for each layer to be able to sort them
162
164
let mut layers_with_indices: Vec < ( Vec < LayerId > , Vec < usize > ) > = self
@@ -366,17 +368,14 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
366
368
. into ( ) ,
367
369
) ,
368
370
SetBlendModeForSelectedLayers ( blend_mode) => {
369
- let active_document = self . active_document ( ) ;
370
-
371
- for path in active_document. layer_data . iter ( ) . filter_map ( |( path, data) | data. selected . then ( || path. clone ( ) ) ) {
371
+ for path in self . selected_layers ( ) . cloned ( ) {
372
372
responses. push_back ( DocumentOperation :: SetLayerBlendMode { path, blend_mode } . into ( ) ) ;
373
373
}
374
374
}
375
375
SetOpacityForSelectedLayers ( opacity) => {
376
376
let opacity = opacity. clamp ( 0. , 1. ) ;
377
- let active_document = self . active_document ( ) ;
378
377
379
- for path in active_document . layer_data . iter ( ) . filter_map ( | ( path , data ) | data . selected . then ( || path . clone ( ) ) ) {
378
+ for path in self . selected_layers ( ) . cloned ( ) {
380
379
responses. push_back ( DocumentOperation :: SetLayerOpacity { path, opacity } . into ( ) ) ;
381
380
}
382
381
}
@@ -388,8 +387,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
388
387
responses. extend ( self . handle_folder_changed ( path) ) ;
389
388
}
390
389
DeleteSelectedLayers => {
391
- let paths = self . selected_layers_sorted ( ) ;
392
- for path in paths {
390
+ for path in self . selected_layers ( ) . cloned ( ) {
393
391
responses. push_back ( DocumentOperation :: DeleteLayer { path } . into ( ) )
394
392
}
395
393
}
@@ -608,14 +606,12 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
608
606
responses. push_back ( FrontendMessage :: SetCanvasRotation { new_radians : new } . into ( ) ) ;
609
607
}
610
608
NudgeSelectedLayers ( x, y) => {
611
- let paths = self . selected_layers_sorted ( ) ;
612
-
613
609
let delta = {
614
610
let root_layer_rotation = self . layerdata_mut ( & [ ] ) . rotation ;
615
611
let rotate_to_viewport_space = DAffine2 :: from_angle ( root_layer_rotation) . inverse ( ) ;
616
612
rotate_to_viewport_space. transform_point2 ( ( x, y) . into ( ) )
617
613
} ;
618
- for path in paths {
614
+ for path in self . selected_layers ( ) . cloned ( ) {
619
615
let operation = DocumentOperation :: TransformLayer {
620
616
path,
621
617
transform : DAffine2 :: from_translation ( delta) . to_cols_array ( ) ,
@@ -711,13 +707,12 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
711
707
}
712
708
AlignSelectedLayers ( axis, aggregate) => {
713
709
// TODO: Handle folder nested transforms with the transforms API
714
- let selected_paths = self . selected_layers_sorted ( ) ;
715
- if selected_paths. is_empty ( ) {
710
+ if self . selected_layers ( ) . next ( ) . is_none ( ) {
716
711
return ;
717
712
}
718
713
719
- let selected_layers = selected_paths . iter ( ) . filter_map ( |path| {
720
- let layer = self . active_document ( ) . document . layer ( path) . unwrap ( ) ;
714
+ let selected_layers = self . selected_layers ( ) . cloned ( ) . filter_map ( |path| {
715
+ let layer = self . active_document ( ) . document . layer ( & path) . ok ( ) ? ;
721
716
let point = {
722
717
let bounding_box = layer. bounding_box ( layer. transform , layer. style ) ?;
723
718
match aggregate {
@@ -731,44 +726,33 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
731
726
AlignAxis :: X => ( point. x , layer. transform . translation . x ) ,
732
727
AlignAxis :: Y => ( point. y , layer. transform . translation . y ) ,
733
728
} ;
734
- Some ( ( path. clone ( ) , bounding_box_coord, translation_coord) )
729
+ Some ( ( path, bounding_box_coord, translation_coord) )
735
730
} ) ;
731
+ let selected_layers: Vec < _ > = selected_layers. collect ( ) ;
736
732
737
- let bounding_box_coords = selected_layers. clone ( ) . map ( |( _, bounding_box_coord, _) | bounding_box_coord) ;
738
- let aggregated_coord = match aggregate {
739
- AlignAggregate :: Min => bounding_box_coords. reduce ( |a, b| a. min ( b) ) . unwrap ( ) ,
740
- AlignAggregate :: Max => bounding_box_coords. reduce ( |a, b| a. max ( b) ) . unwrap ( ) ,
733
+ let bounding_box_coords = selected_layers. iter ( ) . map ( |( _, bounding_box_coord, _) | bounding_box_coord) . cloned ( ) ;
734
+ if let Some ( aggregated_coord) = match aggregate {
735
+ AlignAggregate :: Min => bounding_box_coords. reduce ( |a, b| a. min ( b) ) ,
736
+ AlignAggregate :: Max => bounding_box_coords. reduce ( |a, b| a. max ( b) ) ,
741
737
AlignAggregate :: Center => {
742
738
// TODO: Refactor with `reduce` and `merge_bounding_boxes` once the latter is added
743
- let bounding_boxes = selected_paths. iter ( ) . filter_map ( |path| {
744
- let layer = self . active_document ( ) . document . layer ( path) . unwrap ( ) ;
745
- layer. bounding_box ( layer. transform , layer. style )
746
- } ) ;
747
- let min = bounding_boxes
748
- . clone ( )
749
- . map ( |bbox| match axis {
750
- AlignAxis :: X => bbox[ 0 ] . x ,
751
- AlignAxis :: Y => bbox[ 0 ] . y ,
752
- } )
753
- . reduce ( |a, b| a. min ( b) )
754
- . unwrap ( ) ;
755
- let max = bounding_boxes
756
- . clone ( )
739
+ self . selected_layers ( )
740
+ . filter_map ( |path| self . active_document ( ) . document . layer ( path) . ok ( ) . map ( |layer| layer. bounding_box ( layer. transform , layer. style ) ) . flatten ( ) )
757
741
. map ( |bbox| match axis {
758
- AlignAxis :: X => bbox[ 1 ] . x ,
759
- AlignAxis :: Y => bbox[ 1 ] . y ,
742
+ AlignAxis :: X => ( bbox[ 0 ] . x , bbox [ 1 ] . x ) ,
743
+ AlignAxis :: Y => ( bbox[ 0 ] . y , bbox [ 1 ] . y ) ,
760
744
} )
761
- . reduce ( |a, b| a. max ( b) )
762
- . unwrap ( ) ;
763
- ( min + max) / 2.
745
+ . reduce ( |( a, b) , ( c, d) | ( a. min ( c) , b. max ( d) ) )
746
+ . map ( |( min, max) | ( min + max) / 2. )
764
747
}
765
- AlignAggregate :: Average => bounding_box_coords. sum :: < f64 > ( ) / selected_paths. len ( ) as f64 ,
766
- } ;
767
- for ( path, bounding_box_coord, translation_coord) in selected_layers {
768
- let new_coord = aggregated_coord - ( bounding_box_coord - translation_coord) ;
769
- match axis {
770
- AlignAxis :: X => responses. push_back ( DocumentMessage :: SetLayerTranslation ( path, Some ( new_coord) , None ) . into ( ) ) ,
771
- AlignAxis :: Y => responses. push_back ( DocumentMessage :: SetLayerTranslation ( path, None , Some ( new_coord) ) . into ( ) ) ,
748
+ AlignAggregate :: Average => Some ( bounding_box_coords. sum :: < f64 > ( ) / selected_layers. len ( ) as f64 ) ,
749
+ } {
750
+ for ( path, bounding_box_coord, translation_coord) in selected_layers {
751
+ let new_coord = aggregated_coord - ( bounding_box_coord - translation_coord) ;
752
+ match axis {
753
+ AlignAxis :: X => responses. push_back ( DocumentMessage :: SetLayerTranslation ( path, Some ( new_coord) , None ) . into ( ) ) ,
754
+ AlignAxis :: Y => responses. push_back ( DocumentMessage :: SetLayerTranslation ( path, None , Some ( new_coord) ) . into ( ) ) ,
755
+ }
772
756
}
773
757
}
774
758
}
0 commit comments