@@ -578,110 +578,114 @@ App.controller("TimelineCtrl", function ($scope) {
578
578
} ) ;
579
579
} ;
580
580
581
- // Select clip in scope
582
- $scope . selectClip = function ( clip_id , clear_selections , event ) {
583
- // Trim clip_id
584
- var id = clip_id . replace ( "clip_" , "" ) ;
581
+ // Select item (either clip or transition)
582
+ $scope . selectItem = function ( item_id , item_type , clear_selections , event , force_ripple ) {
583
+ // Trim item_id
584
+ var id = item_id . replace ( ` ${ item_type } _` , "" ) ;
585
585
586
- // Is CTRL pressed?
586
+ // Check for modifier keys
587
587
var is_ctrl = event && event . ctrlKey ;
588
-
589
- // Clear transitions selection if needed
590
- if ( id !== "" && clear_selections && ! is_ctrl ) {
591
- $scope . selectTransition ( "" , true ) ;
588
+ var is_shift = event && event . shiftKey ;
589
+
590
+ // If no ID is provided (id == ""), unselect all items
591
+ if ( id === "" ) {
592
+ if ( clear_selections ) {
593
+ // Unselect all clips
594
+ $scope . project . clips . forEach ( function ( clip ) {
595
+ clip . selected = false ;
596
+ if ( $scope . Qt ) timeline . removeSelection ( clip . id , "clip" ) ;
597
+ } ) ;
598
+ // Unselect all transitions
599
+ $scope . project . effects . forEach ( function ( transition ) {
600
+ transition . selected = false ;
601
+ if ( $scope . Qt ) timeline . removeSelection ( transition . id , "transition" ) ;
602
+ } ) ;
603
+ }
604
+ return ; // Exit after clearing all selections
592
605
}
593
- // Call slice method and exit (don't actually select the clip)
594
- if ( id !== "" && $scope . enable_razor && $scope . Qt && typeof event !== 'undefined' ) {
606
+
607
+ // Razor mode check
608
+ if ( $scope . enable_razor && $scope . Qt && typeof event !== 'undefined' ) {
595
609
var cursor_seconds = $scope . getJavaScriptPosition ( event . clientX , null ) . position ;
596
- timeline . RazorSliceAtCursor ( id , "" , cursor_seconds ) ;
610
+ timeline . RazorSliceAtCursor ( item_type === "clip" ? id : "" , item_type === "transition" ? id : "" , cursor_seconds ) ;
611
+ return ; // Don't select if razor mode is enabled
612
+ }
597
613
598
- // Don't actually select clip
599
- return ;
614
+ // Clear all selections if necessary (no CTRL modifier)
615
+ if ( clear_selections && ! is_ctrl ) {
616
+ // Unselect all clips
617
+ $scope . project . clips . forEach ( function ( clip ) {
618
+ clip . selected = false ;
619
+ if ( $scope . Qt ) timeline . removeSelection ( clip . id , "clip" ) ;
620
+ } ) ;
621
+ // Unselect all transitions
622
+ $scope . project . effects . forEach ( function ( transition ) {
623
+ transition . selected = false ;
624
+ if ( $scope . Qt ) timeline . removeSelection ( transition . id , "transition" ) ;
625
+ } ) ;
600
626
}
601
627
602
- // Update selection for clips
603
- for ( var clip_index = 0 ; clip_index < $scope . project . clips . length ; clip_index ++ ) {
604
- if ( $scope . project . clips [ clip_index ] . id === id ) {
605
- // Invert selection if CTRL is pressed and not forced add and already selected
606
- if ( is_ctrl && clear_selections && ( $scope . project . clips [ clip_index ] . selected === true ) ) {
607
- $scope . project . clips [ clip_index ] . selected = false ;
608
- if ( $scope . Qt ) {
609
- timeline . removeSelection ( $scope . project . clips [ clip_index ] . id , "clip" ) ;
628
+ // Get the correct array based on item_type
629
+ var items = item_type === "clip" ? $scope . project . clips : $scope . project . effects ;
630
+
631
+ // Handle ripple selection (SHIFT key) for both clips and transitions
632
+ if ( is_shift || force_ripple ) {
633
+ var selected_item = items . find ( item => item . id === id ) ;
634
+ if ( selected_item ) {
635
+ var selected_layer = selected_item . layer ;
636
+ var selected_position = selected_item . position ;
637
+
638
+ // Select all clips and transitions to the right on the same layer
639
+ $scope . project . clips . forEach ( function ( clip ) {
640
+ if ( clip . layer === selected_layer && clip . position >= selected_position ) {
641
+ clip . selected = true ;
642
+ if ( $scope . Qt ) timeline . addSelection ( clip . id , "clip" , false ) ;
610
643
}
611
- }
612
- else {
613
- $scope . project . clips [ clip_index ] . selected = true ;
614
- if ( $scope . Qt ) {
615
- // Do not clear selection if CTRL is pressed
616
- if ( is_ctrl ) {
617
- timeline . addSelection ( id , "clip" , false ) ;
618
- }
619
- else {
620
- timeline . addSelection ( id , "clip" , clear_selections ) ;
621
- }
644
+ } ) ;
645
+ $scope . project . effects . forEach ( function ( transition ) {
646
+ if ( transition . layer === selected_layer && transition . position >= selected_position ) {
647
+ transition . selected = true ;
648
+ if ( $scope . Qt ) timeline . addSelection ( transition . id , "transition" , false ) ;
622
649
}
623
- }
650
+ } ) ;
624
651
}
625
- else if ( clear_selections && ! is_ctrl ) {
626
- $scope . project . clips [ clip_index ] . selected = false ;
627
- if ( $scope . Qt ) {
628
- timeline . removeSelection ( $scope . project . clips [ clip_index ] . id , "clip" ) ;
652
+ return ; // No need to do normal selection logic after ripple select
653
+ }
654
+
655
+ // Update selection for clips or transitions
656
+ for ( var i = 0 ; i < items . length ; i ++ ) {
657
+ var item = items [ i ] ;
658
+ if ( item . id === id ) {
659
+ // Invert selection if CTRL is pressed and item is already selected
660
+ if ( is_ctrl && clear_selections && item . selected ) {
661
+ item . selected = false ;
662
+ if ( $scope . Qt ) timeline . removeSelection ( item . id , item_type ) ;
663
+ } else {
664
+ item . selected = true ;
665
+ if ( $scope . Qt ) timeline . addSelection ( item . id , item_type , ! is_ctrl && clear_selections ) ;
629
666
}
630
667
}
631
668
}
632
669
} ;
633
670
634
- // Select transition in scope
635
- $scope . selectTransition = function ( tran_id , clear_selections , event ) {
636
- // Trim tran_id
637
- var id = tran_id . replace ( "transition_" , "" ) ;
638
-
639
- // Is CTRL pressed?
640
- var is_ctrl = event && event . ctrlKey ;
671
+ // Wrapper for ripple selecting clips
672
+ $scope . selectClipRipple = function ( clip_id , clear_selections , event ) {
673
+ $scope . selectItem ( clip_id , "clip" , clear_selections , event , true ) ;
674
+ } ;
641
675
642
- // Clear clips selection if needed
643
- if ( id !== "" && clear_selections && ! is_ctrl ) {
644
- $scope . selectClip ( "" , true ) ;
645
- }
646
- // Call slice method and exit (don't actually select the transition)
647
- if ( id !== "" && $scope . enable_razor && $scope . Qt && typeof event !== 'undefined' ) {
648
- var cursor_seconds = $scope . getJavaScriptPosition ( event . clientX , null ) . position ;
649
- timeline . RazorSliceAtCursor ( "" , id , cursor_seconds ) ;
676
+ // Wrapper for ripple selecting transitions
677
+ $scope . selectTransitionRipple = function ( tran_id , clear_selections , event ) {
678
+ $scope . selectItem ( tran_id , "transition" , clear_selections , event , true ) ;
679
+ } ;
650
680
651
- // Don't actually select transition
652
- return ;
653
- }
681
+ // Wrapper for selecting clips
682
+ $scope . selectClip = function ( clip_id , clear_selections , event ) {
683
+ $scope . selectItem ( clip_id , "clip" , clear_selections , event , false ) ;
684
+ } ;
654
685
655
- // Update selection for transitions
656
- for ( var tran_index = 0 ; tran_index < $scope . project . effects . length ; tran_index ++ ) {
657
- if ( $scope . project . effects [ tran_index ] . id === id ) {
658
- // Invert selection if CTRL is pressed and not forced add and already selected
659
- if ( is_ctrl && clear_selections && ( $scope . project . effects [ tran_index ] . selected === true ) ) {
660
- $scope . project . effects [ tran_index ] . selected = false ;
661
- if ( $scope . Qt ) {
662
- timeline . removeSelection ( $scope . project . effects [ tran_index ] . id , "transition" ) ;
663
- }
664
- }
665
- else {
666
- $scope . project . effects [ tran_index ] . selected = true ;
667
- if ( $scope . Qt ) {
668
- // Do not clear selection if CTRL is pressed
669
- if ( is_ctrl ) {
670
- timeline . addSelection ( id , "transition" , false ) ;
671
- }
672
- else {
673
- timeline . addSelection ( id , "transition" , clear_selections ) ;
674
- }
675
- }
676
- }
677
- }
678
- else if ( clear_selections && ! is_ctrl ) {
679
- $scope . project . effects [ tran_index ] . selected = false ;
680
- if ( $scope . Qt ) {
681
- timeline . removeSelection ( $scope . project . effects [ tran_index ] . id , "transition" ) ;
682
- }
683
- }
684
- }
686
+ // Wrapper for selecting transitions
687
+ $scope . selectTransition = function ( tran_id , clear_selections , event ) {
688
+ $scope . selectItem ( tran_id , "transition" , clear_selections , event , false ) ;
685
689
} ;
686
690
687
691
// Format the thumbnail path: http://127.0.0.1:8081/thumbnails/FILE-ID/FRAME-NUMBER/
0 commit comments