NLA SoC: More Drawing Tweaks
authorJoshua Leung <aligorith@gmail.com>
Wed, 3 Jun 2009 11:22:49 +0000 (11:22 +0000)
committerJoshua Leung <aligorith@gmail.com>
Wed, 3 Jun 2009 11:22:49 +0000 (11:22 +0000)
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...

* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...

* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.

* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.

* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)

source/blender/blenkernel/intern/nla.c
source/blender/editors/space_nla/nla_draw.c
source/blender/editors/space_nla/nla_select.c
source/blender/editors/space_nla/space_nla.c

index cf115cb6faf02f8cd8699160e5672497ec08ba31..6235ec58d40d6923b46016c07fe140af9e774989 100644 (file)
@@ -455,6 +455,25 @@ void BKE_nlatrack_sort_strips (NlaTrack *nlt)
 
 /* NLA Strips -------------------------------------- */
 
+/* Find the active NLA-strip within the given track */
+NlaStrip *BKE_nlastrip_find_active (NlaTrack *nlt)
+{
+       NlaStrip *strip;
+       
+       /* sanity check */
+       if ELEM(NULL, nlt, nlt->strips.first)
+               return NULL;
+               
+       /* try to find the first active strip */
+       for (strip= nlt->strips.first; strip; strip= strip->next) {
+               if (strip->flag & NLASTRIP_FLAG_ACTIVE)
+                       return strip;
+       }
+       
+       /* none found */
+       return NULL;
+}
+
 /* Does the given NLA-strip fall within the given bounds (times)? */
 short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max)
 {
index 78fc4174f95e5b75e35b1f8f6eb2d0c6b405eab5..85bf733df87456a3681182ca0c7449ddc367541a 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
+#include <float.h>
 
 #include "DNA_listBase.h"
 #include "DNA_anim_types.h"
@@ -87,37 +88,103 @@ extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, flo
 /* *********************************************** */
 /* Strips */
 
-static void nla_draw_strip (NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc)
+static void nla_strip_get_color_inside (AnimData *adt, NlaStrip *strip, float color[3])
 {
-       /* draw extrapolation info first (as backdrop) */
-       // TODO...
-       
-       /* draw 'inside' of strip itself */
-               /* set color of strip - color is used to indicate status here */
-       if (strip->flag & NLASTRIP_FLAG_ACTIVE) {
-               /* tweaking strip should be drawn green when it is acting as the tweaking strip */
+       if ((strip->flag & NLASTRIP_FLAG_ACTIVE) && (adt && (adt->flag & ADT_NLA_EDIT_ON))) {
+               /* active strip should be drawn green when it is acting as the tweaking strip.
+                * however, this case should be skipped for when not in EditMode...
+                */
                // FIXME: hardcoded temp-hack colors
-               glColor3f(0.3f, 0.95f, 0.1f);
+               color[0]= 0.3f;
+               color[1]= 0.95f;
+               color[2]= 0.1f;
        }
        else if (strip->flag & NLASTRIP_FLAG_TWEAKUSER) {
                /* alert user that this strip is also used by the tweaking track (this is set when going into
                 * 'editmode' for that strip), since the edits made here may not be what the user anticipated
                 */
                // FIXME: hardcoded temp-hack colors
-               glColor3f(0.85f, 0.0f, 0.0f);
+               color[0]= 0.85f;
+               color[1]= 0.0f;
+               color[2]= 0.0f;
        }
        else if (strip->flag & NLASTRIP_FLAG_SELECT) {
                /* selected strip - use theme color for selected */
-               UI_ThemeColor(TH_STRIP_SELECT);
+               UI_GetThemeColor3fv(TH_STRIP_SELECT, color);
        }
        else {
                /* normal, unselected strip - use standard strip theme color */
-               UI_ThemeColor(TH_STRIP);
+               UI_GetThemeColor3fv(TH_STRIP, color);
+       }
+}
+
+static void nla_draw_strip (AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc)
+{
+       float color[3];
+       
+       /* get color of strip */
+       nla_strip_get_color_inside(adt, strip, color);
+       
+       /* draw extrapolation info first (as backdrop) */
+       if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+               /* enable transparency... */
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               glEnable(GL_BLEND);
+               
+               switch (strip->extendmode) {
+                       /* since this does both sides, only do the 'before' side, and leave the rest to the next case */
+                       case NLASTRIP_EXTEND_HOLD: 
+                               /* only need to draw here if there's no strip before since 
+                                * it only applies in such a situation 
+                                */
+                               if (strip->prev) {
+                                       /* set the drawing color to the color of the strip, but with very faint alpha */
+                                       glColor4f(color[0], color[1], color[2], 0.15f);
+                                       
+                                       /* draw the rect to the edge of the screen */
+                                       glBegin(GL_QUADS);
+                                               glVertex2f(v2d->cur.xmin, yminc);
+                                               glVertex2f(v2d->cur.xmin, ymaxc);
+                                               glVertex2f(strip->start, ymaxc);
+                                               glVertex2f(strip->start, yminc);
+                                       glEnd();
+                               }
+                               /* no break needed... */
+                               
+                       /* this only draws after the strip */
+                       case NLASTRIP_EXTEND_HOLD_FORWARD: 
+                               /* only need to try and draw if the next strip doesn't occur immediately after */
+                               if ((strip->next == NULL) || (IS_EQ(strip->next->start, strip->end)==0)) {
+                                       /* set the drawing color to the color of the strip, but this time less faint */
+                                       glColor4f(color[0], color[1], color[2], 0.3f);
+                                       
+                                       /* draw the rect to the next strip or the edge of the screen */
+                                       glBegin(GL_QUADS);
+                                               glVertex2f(strip->end, yminc);
+                                               glVertex2f(strip->end, ymaxc);
+                                               
+                                               if (strip->next) {
+                                                       glVertex2f(strip->next->start, ymaxc);
+                                                       glVertex2f(strip->next->start, yminc);
+                                               }
+                                               else {
+                                                       glVertex2f(v2d->cur.xmax, ymaxc);
+                                                       glVertex2f(v2d->cur.xmax, yminc);
+                                               }
+                                       glEnd();
+                               }
+                               break;
+               }
+               
+               glDisable(GL_BLEND);
        }
+       
+       /* draw 'inside' of strip itself */
+       glColor3fv(color);
        uiSetRoundBox(15); /* all corners rounded */
        gl_round_box_shade(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1);
        
-       /* draw strip outline */
+       /* draw strip outline - different colors are used here... */
        if (strip->flag & NLASTRIP_FLAG_ACTIVE) {
                /* strip should appear 'sunken', so draw a light border around it */
                glColor3f(0.9f, 1.0f, 0.9f); // FIXME: hardcoded temp-hack colors
@@ -150,6 +217,7 @@ static void nla_draw_strip_text (NlaTrack *nlt, NlaStrip *strip, int index, View
        /* set bounding-box for text 
         *      - padding of 2 'units' on either side
         */
+       // TODO: make this centered?
        rect.xmin= strip->start + 2;
        rect.ymin= yminc;
        rect.xmax= strip->end - 2;
@@ -204,6 +272,7 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
                        switch (ale->type) {
                                case ANIMTYPE_NLATRACK:
                                {
+                                       AnimData *adt= BKE_animdata_from_id(ale->id);
                                        NlaTrack *nlt= (NlaTrack *)ale->data;
                                        NlaStrip *strip;
                                        int index;
@@ -215,7 +284,7 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
                                        for (strip=nlt->strips.first, index=1; strip; strip=strip->next, index++) {
                                                if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
                                                        /* draw the visualisation of the strip */
-                                                       nla_draw_strip(nlt, strip, v2d, yminc, ymaxc);
+                                                       nla_draw_strip(adt, nlt, strip, v2d, yminc, ymaxc);
                                                        
                                                        /* add the text for this strip to the cache */
                                                        nla_draw_strip_text(nlt, strip, index, v2d, yminc, ymaxc);
@@ -235,11 +304,14 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
                                        else
                                                glColor4f(0.6f, 0.5f, 0.5f, 0.3f);      // greyish-red color - hardcoded for now
                                                
+                                       /* draw slightly shifted up for greater separation from standard channels,
+                                        * but also slightly shorter for some more contrast when viewing the strips
+                                        */
                                        glBegin(GL_QUADS);
-                                               glVertex2f(v2d->cur.xmin, yminc);
-                                               glVertex2f(v2d->cur.xmin, ymaxc);
-                                               glVertex2f(v2d->cur.xmax, ymaxc);
-                                               glVertex2f(v2d->cur.xmax, yminc);
+                                               glVertex2f(v2d->cur.xmin, yminc+NLACHANNEL_SKIP);
+                                               glVertex2f(v2d->cur.xmin, ymaxc-NLACHANNEL_SKIP);
+                                               glVertex2f(v2d->cur.xmax, ymaxc-NLACHANNEL_SKIP);
+                                               glVertex2f(v2d->cur.xmax, yminc+NLACHANNEL_SKIP);
                                        glEnd();
                                        
                                        glDisable(GL_BLEND);
@@ -570,8 +642,12 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
                                        glColor3f(0.6f, 0.5f, 0.5f);    // greyish-red color - hardcoded for now
                                        
                                offset += 7 * indent;
-                               uiSetRoundBox((1|2)); // only on top two corners, to show that this channel sits on top of the preceeding ones
-                               gl_round_box(GL_POLYGON, x+offset,  yminc, (float)NLACHANNEL_NAMEWIDTH, ymaxc, 8);
+                               
+                               /* only on top two corners, to show that this channel sits on top of the preceeding ones */
+                               uiSetRoundBox((1|2)); 
+                               
+                               /* draw slightly shifted up vertically to look like it has more separtion from other channels */
+                               gl_round_box(GL_POLYGON, x+offset,  yminc+NLACHANNEL_SKIP, (float)NLACHANNEL_NAMEWIDTH, ymaxc+NLACHANNEL_SKIP, 8);
                                
                                /* clear group value, otherwise we cause errors... */
                                group = 0;
index 5d9fe5f2a050a3e4772cdc0936d161802649c6b2..0626d9febe47b298dfa92f4f8226a9e10f1968a9 100644 (file)
@@ -98,10 +98,16 @@ static short selmodes_to_flagmodes (short sel)
  *     3) (de)select all - no testing is done; only for use internal tools as normal function...
  */
 
+enum {
+       DESELECT_STRIPS_NOTEST = 0,
+       DESELECT_STRIPS_TEST,
+       DESELECT_STRIPS_CLEARACTIVE,
+} eDeselectNlaStrips;
 /* Deselects strips in the NLA Editor
  *     - This is called by the deselect all operator, as well as other ones!
  *
- *     - test: check if select or deselect all
+ *     - test: check if select or deselect all (1) or clear all active (2)
  *     - sel: how to select keyframes 
  *             0 = deselect
  *             1 = select
@@ -121,7 +127,7 @@ static void deselect_nla_strips (bAnimContext *ac, short test, short sel)
        ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
        
        /* See if we should be selecting or deselecting */
-       if (test) {
+       if (test == DESELECT_STRIPS_TEST) {
                for (ale= anim_data.first; ale; ale= ale->next) {
                        NlaTrack *nlt= (NlaTrack *)ale->data;
                        NlaStrip *strip;
@@ -150,9 +156,11 @@ static void deselect_nla_strips (bAnimContext *ac, short test, short sel)
                /* apply same selection to all strips */
                for (strip= nlt->strips.first; strip; strip= strip->next) {
                        /* set selection */
-                       ACHANNEL_SET_FLAG(strip, smode, NLASTRIP_FLAG_SELECT);
+                       if (test != DESELECT_STRIPS_CLEARACTIVE)
+                               ACHANNEL_SET_FLAG(strip, smode, NLASTRIP_FLAG_SELECT);
                        
                        /* clear active flag */
+                       // TODO: for clear active, do we want to limit this to only doing this on a certain set of tracks though?
                        strip->flag &= ~NLASTRIP_FLAG_ACTIVE;
                }
        }
@@ -173,9 +181,9 @@ static int nlaedit_deselectall_exec(bContext *C, wmOperator *op)
                
        /* 'standard' behaviour - check if selected, then apply relevant selection */
        if (RNA_boolean_get(op->ptr, "invert"))
-               deselect_nla_strips(&ac, 0, SELECT_INVERT);
+               deselect_nla_strips(&ac, DESELECT_STRIPS_NOTEST, SELECT_INVERT);
        else
-               deselect_nla_strips(&ac, 1, SELECT_ADD);
+               deselect_nla_strips(&ac, DESELECT_STRIPS_TEST, SELECT_ADD);
        
        /* set notifier that things have changed */
        ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
@@ -292,7 +300,8 @@ static void mouse_nla_strips (bAnimContext *ac, int mval[2], short select_mode)
                        NlaTrack *nlt= (NlaTrack *)ale->data;
                        
                        nlt->flag |= NLATRACK_SELECTED;
-                       ANIM_set_active_channel(ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
+                       if (nlt->flag & NLATRACK_SELECTED)
+                               ANIM_set_active_channel(ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
                }
        }
        
@@ -302,6 +311,13 @@ static void mouse_nla_strips (bAnimContext *ac, int mval[2], short select_mode)
                if (strip) {
                        select_mode= selmodes_to_flagmodes(select_mode);
                        ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT);
+                       
+                       /* if we selected it, we can make it active too
+                        *      - we always need to clear the active strip flag though... 
+                        */
+                       deselect_nla_strips(ac, DESELECT_STRIPS_CLEARACTIVE, 0);
+                       if (strip->flag & NLASTRIP_FLAG_SELECT)
+                               strip->flag |= NLASTRIP_FLAG_ACTIVE;
                }
                
                /* free this channel */
index 1bed72b82fb607e14f07dfdf07a45ce8ed34e3ed..39579ec96da2c24f4c0ad0763140d11db82da921 100644 (file)
@@ -253,6 +253,8 @@ static void nla_main_area_draw(const bContext *C, ARegion *ar)
                UI_view2d_text_cache_draw(ar);
        }
        
+       UI_view2d_view_ortho(C, v2d);
+       
        /* current frame */
        if (snla->flag & SNLA_DRAWTIME)         flag |= DRAWCFRA_UNIT_SECONDS;
        if ((snla->flag & SNLA_NODRAWCFRANUM)==0)  flag |= DRAWCFRA_SHOW_NUMBOX;