== PoseLib - Overhauled Implementation ==
[blender.git] / source / blender / src / editaction.c
index cb032ddfb61cf7be25e808507eec7ae0f8eaae35..c70f20aed896a0f6a9c0c3a0ccf8f2b4fa0d355f 100644 (file)
@@ -2227,9 +2227,11 @@ void column_select_action_keys(int mode)
 }
 
 /* some quick defines for borderselect modes */
-#define ACTEDIT_BORDERSEL_ALL 0
-#define ACTEDIT_BORDERSEL_FRA 1
-#define ACTEDIT_BORDERSEL_CHA 2
+enum {
+       ACTEDIT_BORDERSEL_ALL = 0,
+       ACTEDIT_BORDERSEL_FRA,
+       ACTEDIT_BORDERSEL_CHA
+};
 
 /* borderselect: for keyframes only */
 void borderselect_action (void)
@@ -2351,7 +2353,7 @@ static void mouse_action (int selectmode)
        bActionChannel *achan= NULL;
        bConstraintChannel *conchan= NULL;
        IpoCurve *icu= NULL;
-       TimeMarker *marker;
+       TimeMarker *marker, *pmarker;
        
        void *act_channel;
        short sel, act_type;
@@ -2363,9 +2365,63 @@ static void mouse_action (int selectmode)
        if (datatype == ACTCONT_ACTION) act= (bAction *)data;
 
        act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan);
-       marker=find_nearest_marker(1);
+       marker= find_nearest_marker(SCE_MARKERS, 1);
+       pmarker= (act) ? find_nearest_marker(&act->markers, 1) : NULL;
+       
+       if (marker) {
+               /* what about scene's markers? */               
+               if (selectmode == SELECT_REPLACE) {                     
+                       deselect_markers(0, 0);
+                       marker->flag |= SELECT;
+               }
+               else if (selectmode == SELECT_INVERT) {
+                       if (marker->flag & SELECT)
+                               marker->flag &= ~SELECT;
+                       else
+                               marker->flag |= SELECT;
+               }
+               else if (selectmode == SELECT_ADD) 
+                       marker->flag |= SELECT;
+               else if (selectmode == SELECT_SUBTRACT)
+                       marker->flag &= ~SELECT;
+               
+               std_rmouse_transform(transform_markers);
+               
+               allqueue(REDRAWMARKER, 0);
+       }       
+       else if (pmarker) {
+               /* action's markers are drawn behind scene markers */           
+               if (selectmode == SELECT_REPLACE) {
+                       action_set_activemarker(act, pmarker, 1);
+                       pmarker->flag |= SELECT;
+               }
+               else if (selectmode == SELECT_INVERT) {
+                       if (pmarker->flag & SELECT) {
+                               pmarker->flag &= ~SELECT;
+                               action_set_activemarker(act, NULL, 0);
+                       }
+                       else {
+                               pmarker->flag |= SELECT;
+                               action_set_activemarker(act, pmarker, 0);
+                       }
+               }
+               else if (selectmode == SELECT_ADD)  {
+                       pmarker->flag |= SELECT;
+                       action_set_activemarker(act, pmarker, 0);
+               }
+               else if (selectmode == SELECT_SUBTRACT) {
+                       pmarker->flag &= ~SELECT;
+                       action_set_activemarker(act, NULL, 0);
+               }
                
-       if (act_channel) {
+               // TODO: local-markers cannot be moved atm...
+               //std_rmouse_transform(transform_markers);
+               
+               allqueue(REDRAWACTION, 0);
+               allqueue(REDRAWBUTSEDIT, 0);
+       }
+       else if (act_channel) {
+               /* must have been a channel */
                switch (act_type) {
                        case ACTTYPE_ICU:
                                icu= (IpoCurve *)act_channel;
@@ -2410,27 +2466,6 @@ static void mouse_action (int selectmode)
                allqueue(REDRAWOOPS, 0);
                allqueue(REDRAWBUTSALL, 0);
        }
-       else if (marker) {
-               /* not channel, so maybe marker */              
-               if (selectmode == SELECT_REPLACE) {                     
-                       deselect_markers(0, 0);
-                       marker->flag |= SELECT;
-               }
-               else if (selectmode == SELECT_INVERT) {
-                       if (marker->flag & SELECT)
-                               marker->flag &= ~SELECT;
-                       else
-                               marker->flag |= SELECT;
-               }
-               else if (selectmode == SELECT_ADD) 
-                       marker->flag |= SELECT;
-               else if (selectmode == SELECT_SUBTRACT)
-                       marker->flag &= ~SELECT;
-               
-               std_rmouse_transform(transform_markers);
-               
-               allqueue(REDRAWMARKER, 0);
-       }
 }
 
 /* lefthand side - mouse-click  */
@@ -2699,7 +2734,7 @@ void bottom_sel_action ()
                if (VISIBLE_ACHAN(achan)) {
                        if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) {
                                /* take it out off the chain keep data */
-                               BLI_remlink (&act->chanbase, achan);
+                               BLI_remlink(&act->chanbase, achan);
                                /* add at end */
                                BLI_addtail(&act->chanbase, achan);
                                achan->flag |= ACHAN_MOVED;
@@ -2720,6 +2755,141 @@ void bottom_sel_action ()
        allqueue(REDRAWNLA, 0);
 }
 
+/* **************************************************** */
+/* ACTION MARKERS (PoseLib features) */
+/* NOTE: yes, these duplicate code from edittime.c a bit, but these do a bit more...
+ * These could get merged with those someday if need be...  (Aligorith, 20071230)
+ */
+
+/* Makes the given marker the active one
+ *     - deselect indicates whether unactive ones should be deselected too
+ */
+void action_set_activemarker (bAction *act, TimeMarker *active, short deselect)
+{
+       TimeMarker *marker;
+       int index= 0;
+       
+       /* sanity checks */
+       if (act == NULL)
+               return;
+       act->active_marker= 0;
+       
+       /* set appropriate flags for all markers */
+       for (marker=act->markers.first; marker; marker=marker->next, index++) {
+               /* only active may be active */
+               if (marker == active) {
+                       act->active_marker= index + 1;
+                       marker->flag |= (SELECT|ACTIVE);
+               }
+               else {
+                       if (deselect)
+                               marker->flag &= ~(SELECT|ACTIVE);
+                       else
+                               marker->flag &= ~ACTIVE;
+               }
+       }       
+}
+
+/* Adds a local marker to the active action */
+void action_add_localmarker (bAction *act, int frame)
+{
+       TimeMarker *marker;
+       char name[64];
+       
+       /* sanity checks */
+       if (act == NULL) 
+               return;
+       
+       /* get name of marker */
+       sprintf(name, "Pose");
+       if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
+               return;
+       
+       /* add marker to action - replaces any existing marker there */
+       for (marker= act->markers.first; marker; marker= marker->next) {
+               if (marker->frame == frame) {
+                       BLI_strncpy(marker->name, name, sizeof(marker->name));
+                       break;
+               }
+       }
+       if (marker == NULL) {
+               marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
+               
+               BLI_strncpy(marker->name, name, sizeof(marker->name));
+               marker->frame= frame;
+               
+               BLI_addtail(&act->markers, marker);
+       }
+       
+       /* sets the newly added marker as the active one */
+       action_set_activemarker(act, marker, 1);
+       
+       BIF_undo_push("Action Add Marker");
+       allqueue(REDRAWACTION, 0);
+       allqueue(REDRAWBUTSEDIT, 0);
+}
+
+/* Renames the active local marker to the active action */
+void action_rename_localmarker (bAction *act)
+{
+       TimeMarker *marker;
+       char name[64];
+       int val;
+       
+       /* sanity checks */
+       if (act == NULL) 
+               return;
+       
+       /* get active marker to rename */
+       if (act->active_marker == 0)
+               return;
+       else
+               val= act->active_marker;
+       
+       if (val <= 0) return;
+       marker= BLI_findlink(&act->markers, val-1);
+       if (marker == NULL) return;
+       
+       /* get name of marker */
+       sprintf(name, marker->name);
+       if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
+               return;
+       
+       /* copy name */
+       BLI_strncpy(marker->name, name, sizeof(marker->name));
+       
+       /* undo and update */
+       BIF_undo_push("Action Rename Marker");
+       allqueue(REDRAWBUTSEDIT, 0);
+       allqueue(REDRAWACTION, 0);
+}
+
+/* Deletes all selected markers, and adjusts things as appropriate */
+void action_remove_localmarkers (bAction *act)
+{
+       TimeMarker *marker, *next;
+       
+       /* sanity checks */
+       if (act == NULL)
+               return;
+               
+       /* remove selected markers */
+       for (marker= act->markers.first; marker; marker= next) {
+               next= marker->next;
+               
+               if (marker->flag & SELECT)
+                       BLI_freelinkN(&act->markers, marker);
+       }
+       
+       /* clear active just in case */
+       act->active_marker= 0;
+       
+       /* undo and update */
+       BIF_undo_push("Action Remove Marker(s)");
+       allqueue(REDRAWBUTSEDIT, 0);
+       allqueue(REDRAWACTION, 0);
+}
+
 /* **************************************************** */
 /* EVENT HANDLING */
 
@@ -2860,6 +3030,18 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        allqueue(REDRAWMARKER, 0);
                        break;
                        
+               case LKEY:
+                       /* poselib manipulation - only for actions */
+                       if (datatype == ACTCONT_ACTION) {
+                               if (G.qual == LR_SHIFTKEY) 
+                                       action_add_localmarker(data, CFRA);
+                               else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+                                       action_rename_localmarker(data);
+                               else if (G.qual == LR_ALTKEY)
+                                       action_remove_localmarkers(data);
+                       }
+                       break;
+                       
                case MKEY:
                        if (G.qual & LR_SHIFTKEY) {
                                /* mirror keyframes */