Adds the following selection methods to the Sequence Editor:
authorRoland Hess <me@harkyman.com>
Tue, 26 Jun 2007 17:46:12 +0000 (17:46 +0000)
committerRoland Hess <me@harkyman.com>
Tue, 26 Jun 2007 17:46:12 +0000 (17:46 +0000)
Ctrl-RMB and Alt-RMB now call for different selection methods that are helpful when working within a single channel that holds several strips. The Ctrl modifier signals "Right" and the Alt modifier signals "Left".

Ctrl-RMB clicking a strip will select that strips left handle and the adjacent handle of any strip that abuts it on the left, allowing you to move the boundary between the strips without changing their outer endpoints. Ctrl-RMB clicking again on that strip will add to the selection all strips to the left of it, allowing you to slide the entire set of strips out of the way for a new one.

Alt-RMB works the same, but to the right.

Ctrl-Alt-RMB on a strip selects the surrounding handles only, allowing you to move the targeted strip and have the surrounding two strips adjust to follow.

source/blender/include/BIF_editseq.h
source/blender/src/editseq.c
source/blender/src/header_seq.c

index 5b7378b3f9c31bb531227ff614dcb9b003d65b2f..c9d4bf6ab061695736b10afbc72ea8970d61d243 100644 (file)
@@ -48,9 +48,11 @@ void                         clear_last_seq();
 void                           del_seq(void);
 void                           enter_meta(void);
 void                           exit_meta(void);
+struct Sequence*       find_neighboring_sequence(struct Sequence *test, int lr);
 struct Sequence*       find_nearest_seq(int *hand);
 int                                    insert_gap(int gap, int cfra);
 void                           make_meta(void);
+void                           select_channel_direction(struct Sequence *test,int lr);
 void                           mouse_select_seq(void);
 void                           no_gaps(void);
 void                           seq_snap(short event);
@@ -63,6 +65,10 @@ void                         transform_seq(int mode, int context);
 void                           un_meta(void);
 void                           seq_cut(int cutframe);
 void                           reassign_inputs_seq_effect(void);
+void                           select_surrounding_handles(struct Sequence *test);
+void                           select_surround_from_last();
+void                           select_dir_from_last(int lr);
+void                           select_neighbor_from_last(int lr);
 struct Sequence*       alloc_sequence(ListBase *lb, int cfra, int machine); /*used from python*/
 
 /* drawseq.c */
index 968d1965ef479db6b543e9574870479ea60e0885..cfc8ef6517d7f8f1a6cf47f99b75d0b23553ebd3 100644 (file)
@@ -201,6 +201,46 @@ int sequence_is_free_transformable(Sequence * seq)
                || (get_sequence_effect_num_inputs(seq->type) == 0);
 }
 
+Sequence *find_neighboring_sequence(Sequence *test, int lr) {
+/* looks to the left on lr==1, to the right on lr==2 */
+       Sequence *seq,*foundneighbor;
+       int found=0;
+       Editing *ed;
+
+       ed= G.scene->ed;
+       if(ed==0) return 0;
+
+       seq= ed->seqbasep->first;
+       while(seq) {
+               if(seq!=test) {
+                       if (test->machine==seq->machine) {
+                               if(test->depth==seq->depth) {
+                                       switch (lr) {
+                                       case 1:
+                                               if (test->startdisp == (seq->enddisp)) {
+                                                       foundneighbor=seq;
+                                                       found=1;
+                                               }
+                                               break;
+                                       case 2:
+                                               if (test->enddisp == (seq->startdisp)) {
+                                                       foundneighbor=seq;
+                                                       found=1;
+                                               }
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               seq= seq->next;
+       }
+       if (found==1) {
+               return foundneighbor;
+       } else {
+               return 0;
+       }
+}
+
 Sequence *find_nearest_seq(int *hand)
 {
        Sequence *seq;
@@ -441,14 +481,100 @@ void swap_select_seq(void)
 
 }
 
+void select_channel_direction(Sequence *test,int lr) {
+/* selects all strips in a channel to one direction of the passed strip */
+       Sequence *seq;
+       Editing *ed;
+
+       ed= G.scene->ed;
+       if(ed==0) return;
+
+       seq= ed->seqbasep->first;
+       while(seq) {
+               if(seq!=test) {
+                       if (test->machine==seq->machine) {
+                               if(test->depth==seq->depth) {
+                                       if (((lr==1)&&(test->startdisp > (seq->startdisp)))||((lr==2)&&(test->startdisp < (seq->startdisp)))) {
+                                               seq->flag |= SELECT;
+                                               recurs_sel_seq(seq);
+                                       }
+                               }
+                       }
+               }
+               seq= seq->next;
+       }
+       test->flag |= SELECT;
+       recurs_sel_seq(test);
+}
+
+void select_dir_from_last(int lr)
+{
+       Sequence *seq=get_last_seq();
+       
+       if (seq) select_channel_direction(seq,lr);
+}
+
+void select_surrounding_handles(Sequence *test) 
+{
+       Sequence *neighbor;
+       
+       neighbor=find_neighboring_sequence(test, 1);
+       if (neighbor) {
+               neighbor->flag |= SELECT;
+               recurs_sel_seq(neighbor);
+               neighbor->flag |= SEQ_RIGHTSEL;
+       }
+       neighbor=find_neighboring_sequence(test, 2);
+       if (neighbor) {
+               neighbor->flag |= SELECT;
+               recurs_sel_seq(neighbor);
+               neighbor->flag |= SEQ_LEFTSEL;
+       }
+       test->flag |= SELECT;
+}
+
+void select_surround_from_last()
+{
+       Sequence *seq=get_last_seq();
+       
+       if (seq) select_surrounding_handles(seq);
+}
+
+void select_neighbor_from_last(int lr)
+{
+       Sequence *seq=get_last_seq();
+       Sequence *neighbor;
+       
+       if (seq) {
+               neighbor=find_neighboring_sequence(seq, lr);
+               if (neighbor) {
+                       switch (lr) {
+                       case 1:
+                               neighbor->flag |= SELECT;
+                               recurs_sel_seq(neighbor);
+                               neighbor->flag |= SEQ_RIGHTSEL;
+                               seq->flag |= SEQ_LEFTSEL;
+                               break;
+                       case 2:
+                               neighbor->flag |= SELECT;
+                               recurs_sel_seq(neighbor);
+                               neighbor->flag |= SEQ_LEFTSEL;
+                               seq->flag |= SEQ_RIGHTSEL;
+                               break;
+                       }
+               seq->flag |= SELECT;
+               }
+       }
+}
+
 void mouse_select_seq(void)
 {
-       Sequence *seq;
-       int hand;
+       Sequence *seq,*neighbor;
+       int hand,seldir;
 
        seq= find_nearest_seq(&hand);
 
-       if(!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+       if(!(G.qual & LR_SHIFTKEY)&&!(G.qual & LR_ALTKEY)&&!(G.qual & LR_CTRLKEY)) deselect_all_seq();
 
        if(seq) {
                set_last_seq(seq);
@@ -482,6 +608,53 @@ void mouse_select_seq(void)
                        if(hand==1) seq->flag |= SEQ_LEFTSEL;
                        if(hand==2) seq->flag |= SEQ_RIGHTSEL;
                }
+               
+               /* On Ctrl-Alt selection, select the strip and bordering handles */
+               if ((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) {
+                       if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                       seq->flag |= SELECT;
+                       select_surrounding_handles(seq);
+                       
+               /* Ctrl signals Left, Alt signals Right
+                  First click selects adjacent handles on that side.
+                  Second click selects all strips in that direction.
+                  If there are no adjacent strips, it just selects all in that direction. */
+               } else if (((G.qual & LR_CTRLKEY) || (G.qual & LR_ALTKEY)) && (seq->flag & SELECT)) {
+       
+                       if (G.qual & LR_CTRLKEY) seldir=1;
+                               else seldir=2;
+                       neighbor=find_neighboring_sequence(seq, seldir);
+                       if (neighbor) {
+                               switch (seldir) {
+                               case 1:
+                                       if ((seq->flag & SEQ_LEFTSEL)&&(neighbor->flag & SEQ_RIGHTSEL)) {
+                                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                                               select_channel_direction(seq,1);
+                                       } else {
+                                               neighbor->flag |= SELECT;
+                                               recurs_sel_seq(neighbor);
+                                               neighbor->flag |= SEQ_RIGHTSEL;
+                                               seq->flag |= SEQ_LEFTSEL;
+                                       }
+                                       break;
+                               case 2:
+                                       if ((seq->flag & SEQ_RIGHTSEL)&&(neighbor->flag & SEQ_LEFTSEL)) {
+                                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                                               select_channel_direction(seq,2);
+                                       } else {
+                                               neighbor->flag |= SELECT;
+                                               recurs_sel_seq(neighbor);
+                                               neighbor->flag |= SEQ_LEFTSEL;
+                                               seq->flag |= SEQ_RIGHTSEL;
+                                       }
+                                       break;
+                               }
+                       } else {
+                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                               select_channel_direction(seq,seldir);
+                       }
+               }
+               
                recurs_sel_seq(seq);
        }
 
index 566606c22d38d1ee21beb4af0bafbad72cb829a5..ffa810f6eb87d94e593abd07b744e2949f2675b7 100644 (file)
@@ -167,6 +167,21 @@ static void do_seq_selectmenu(void *arg, int event)
        case 1:
                swap_select_seq();
                break;
+       case 2:
+               select_dir_from_last(1);
+               break;
+       case 3:
+               select_dir_from_last(2);
+               break;
+       case 4:
+               select_surround_from_last();
+               break;
+       case 5:
+               select_neighbor_from_last(1);
+               break;
+       case 6:
+               select_neighbor_from_last(2);
+               break;
        }
 }
 
@@ -177,7 +192,14 @@ static uiBlock *seq_selectmenu(void *arg_unused)
 
        block= uiNewBlock(&curarea->uiblocks, "seq_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
        uiBlockSetButmFunc(block, do_seq_selectmenu, NULL);
-
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Strips to the Left", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Strips to the Right", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+       uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Surrounding Handles", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Left Handles", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Right Handles", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+       uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
        uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");