Warning indicators for animators when Auto Keying is enabled during transform
authorJoshua Leung <aligorith@gmail.com>
Fri, 5 Oct 2012 13:22:09 +0000 (13:22 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 5 Oct 2012 13:22:09 +0000 (13:22 +0000)
Recently on the bf-funboard list, there have been some requests for clearer
indications for animators that autokeying has been enabled when transforming so
that corrective action can be taken sooner if this wasn't expected. This is
especially important in distributed+collaborative environments where multiple
artists may work on a single shot file: someone working on a shot from
another animator may not be aware that autokeying was enabled, thus accidentally
setting a whole bunch of extra keyframes.

In this current incarnation, we display using red (not hardcoded, but using an
existing theme color) a solid 1px border around the 3D view while transforming
with autokeying enabled. In addition to the border, a blinking indicator (record
icon + "Auto Keying On" text) appear in the top right corner, as inspired by the
traditional recording indicator icons on camcorders.

source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h

index 631418598e52bebb0ac65682b0381e8fcc3c0016..2bcbbc3a8a2a30c4e8fe8bff2ad6204ef13d217c 100644 (file)
@@ -57,6 +57,8 @@
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 
+#include "BLF_api.h"
+
 #include "BKE_nla.h"
 #include "BKE_bmesh.h"
 #include "BKE_context.h"
 #include "BLI_linklist.h"
 #include "BLI_smallhash.h"
 #include "BLI_array.h"
+#include "PIL_time.h"
 
+#include "UI_interface_icons.h"
 #include "UI_resources.h"
 
 #include "transform.h"
 
-#include <stdio.h>
+#include <stdio.h> // XXX: duplicated???
 
 static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg);
 static int doEdgeSlide(TransInfo *t, float perc);
@@ -827,7 +831,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
        float mati[3][3] = MAT3_UNITY;
        char cmode = constraintModeToChar(t);
        int handled = 1;
-
+       
        t->redraw |= handleMouseInput(t, &t->mouse, event);
 
        if (event->type == MOUSEMOVE) {
@@ -1271,10 +1275,13 @@ int transformEvent(TransInfo *t, wmEvent *event)
        if (t->handleEvent)
                t->redraw |= t->handleEvent(t, event);
 
-       if (handled || t->redraw)
+       if (handled || t->redraw) {
+               t->last_update = PIL_check_seconds_timer();
                return 0;
-       else
+       }
+       else {
                return OPERATOR_PASS_THROUGH;
+       }
 }
 
 int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2])
@@ -1557,14 +1564,63 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi
        drawNonPropEdge(C, t);
 }
 
-#if 0
-static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg))
+/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */
+static void drawAutoKeyWarning(const struct bContext *C, TransInfo *t, ARegion *ar)
 {
-//     TransInfo *t = arg;
-//
-//     drawHelpline(C, t->mval[0], t->mval[1], t);
+       int show_warning;
+       
+       /* red border around the viewport */
+       UI_ThemeColor(TH_REDALERT);
+       
+       glBegin(GL_LINE_LOOP);
+               glVertex2f(1,          1);
+               glVertex2f(1,          ar->winy-1);
+               glVertex2f(ar->winx-1, ar->winy-1);
+               glVertex2f(ar->winx-1, 1);
+       glEnd();
+       
+       /* Entire warning should "blink" to catch periphery attention without being overly distracting 
+        * much like how a traditional recording sign in the corner of a camcorder works
+        *
+        * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice).
+        *   We multiply by two to speed up the odd/even time-in-seconds = on/off toggle.
+        * - Always start with warning shown so that animators are more likely to notice when starting to transform
+        */
+       show_warning = (int)(t->last_update * 2.0) & 1;
+       
+       if ((show_warning) || (t->state == TRANS_STARTING)) {
+               const char printable[] = "Auto Keying On";
+               int xco, yco;
+               
+               xco = ar->winx - BLF_width_default(printable)  - 10;
+               yco = ar->winy - BLF_height_default(printable) - 10;
+               
+               /* red warning text */
+               UI_ThemeColor(TH_REDALERT);
+               BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable));
+               
+               /* autokey recording icon... */
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               glEnable(GL_BLEND);
+               
+               xco -= (ICON_DEFAULT_WIDTH + 2);
+               UI_icon_draw(xco, yco, ICON_REC);
+               
+               glDisable(GL_BLEND);
+       }
+}
+
+static void drawTransformPixel(const struct bContext *C, ARegion *ar, void *arg)
+{      
+       TransInfo *t = arg;
+       Scene *scene = t->scene;
+       Object *ob = OBACT;
+       
+       /* draw autokeyframing hint in the corner */
+       if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
+               drawAutoKeyWarning(C, t, ar);
+       }       
 }
-#endif
 
 void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 {
@@ -1734,7 +1790,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
 
                t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);
                t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
-               //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+               t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
                t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
        }
        else if (t->spacetype == SPACE_IMAGE) {
index e645cb2fed6682f367945c0021d0e876e7f4c5d3..40f53423d37a84c0ac009f5c2ce750eff53673b6 100644 (file)
@@ -322,6 +322,8 @@ typedef struct TransInfo {
        float           auto_values[4];
        float           axis[3];
        float           axis_orig[3];   /* TransCon can change 'axis', store the original value here */
+       
+       double      last_update;  /* Time of last update (in seconds) */
 
        void            *view;
        struct bContext *context; /* Only valid (non null) during an operator called function. */