@@ -54,6 +54,7 @@ pub enum DocumentMessage {
5454 WheelCanvasZoom ,
5555 SetCanvasRotation ( f64 ) ,
5656 NudgeSelectedLayers ( f64 , f64 ) ,
57+ MoveSelectedLayer ( i32 ) ,
5758}
5859
5960impl From < DocumentOperation > for DocumentMessage {
@@ -161,6 +162,32 @@ impl DocumentMessageHandler {
161162 layers_with_indices. sort_by_key ( |( _, indices) | indices. clone ( ) ) ;
162163 return layers_with_indices. into_iter ( ) . map ( |( path, _) | path) . collect ( ) ;
163164 }
165+
166+ /// Returns the paths to all layers in order
167+ fn all_layers_sorted ( & self ) -> Vec < Vec < LayerId > > {
168+ // Compute the indices for each layer to be able to sort them
169+ let mut layers_with_indices: Vec < ( Vec < LayerId > , Vec < usize > ) > = self
170+ . active_document ( )
171+ . layer_data
172+ . iter ( )
173+ . filter_map ( |( path, _) | ( path. len ( ) > 0 ) . then ( || path. clone ( ) ) ) // Ignore root layer data
174+ . filter_map ( |path| {
175+ // Currently it is possible that layer_data contains layers that are don't actually exist
176+ // and thus indices_for_path can return an error. We currently skip these layers and log a warning.
177+ // Once this problem is solved this code can be simplified
178+ match self . active_document ( ) . document . indices_for_path ( & path) {
179+ Err ( err) => {
180+ warn ! ( "all_layers_sorted: Could not get indices for the layer {:?}: {:?}" , path, err) ;
181+ None
182+ }
183+ Ok ( indices) => Some ( ( path, indices) ) ,
184+ }
185+ } )
186+ . collect ( ) ;
187+
188+ layers_with_indices. sort_by_key ( |( _, indices) | indices. clone ( ) ) ;
189+ return layers_with_indices. into_iter ( ) . map ( |( path, _) | path) . collect ( ) ;
190+ }
164191}
165192
166193impl Default for DocumentMessageHandler {
@@ -554,6 +581,33 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
554581 responses. push_back ( operation. into ( ) ) ;
555582 }
556583 }
584+ MoveSelectedLayer ( delta) => {
585+ let paths: Vec < Vec < LayerId > > = self . selected_layers_sorted ( ) ;
586+ // TODO: Support moving more than one layer
587+ if paths. len ( ) == 1 {
588+ let all_layer_indices = self . all_layers_sorted ( ) ;
589+
590+ let max_index = all_layer_indices. len ( ) as i32 - 1 ;
591+
592+ let mut selected_layer_index = -1 ;
593+ let mut next_layer_index = -1 ;
594+ for ( i, path) in all_layer_indices. iter ( ) . enumerate ( ) {
595+ if * path == paths[ 0 ] {
596+ selected_layer_index = i as i32 ;
597+ next_layer_index = ( selected_layer_index + delta) . clamp ( 0 , max_index) ;
598+ break ;
599+ }
600+ }
601+
602+ if next_layer_index != -1 && next_layer_index != selected_layer_index {
603+ let operation = DocumentOperation :: ReorderLayers {
604+ source_path : paths[ 0 ] . clone ( ) ,
605+ target_path : all_layer_indices[ next_layer_index as usize ] . to_vec ( ) ,
606+ } ;
607+ responses. push_back ( operation. into ( ) ) ;
608+ }
609+ }
610+ }
557611 message => todo ! ( "document_action_handler does not implement: {}" , message. to_discriminant( ) . global_name( ) ) ,
558612 }
559613 }
@@ -589,6 +643,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
589643 DuplicateSelectedLayers ,
590644 CopySelectedLayers ,
591645 NudgeSelectedLayers ,
646+ MoveSelectedLayer ,
592647 ) ;
593648 common. extend ( select) ;
594649 }
0 commit comments