static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked) { ActKeyColumn *ak; ActKeyBlock *ab; float alpha; float xscale; float iconsize = U.widget_unit / 4.0f; glEnable(GL_BLEND); /* get View2D scaling factor */ UI_view2d_scale_get(v2d, &xscale, NULL); /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ /* TODO: allow this opacity factor to be themed? */ alpha = (channelLocked) ? 0.25f : 1.0f; /* draw keyblocks */ if (blocks) { float sel_color[4], unsel_color[4]; /* cache colours first */ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color); UI_GetThemeColor4fv(TH_STRIP, unsel_color); sel_color[3] *= alpha; unsel_color[3] *= alpha; /* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */ for (ab = blocks->first; ab; ab = ab->next) { if (actkeyblock_is_valid(ab, keys)) { /* draw block */ if (ab->sel) glColor4fv(sel_color); else glColor4fv(unsel_color); glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); } } } /* draw keys */ if (keys) { for (ak = keys->first; ak; ak = ak->next) { /* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw * - this might give some improvements, since we current have to flip between view/region matrices */ if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0) continue; /* draw using OpenGL - uglier but faster */ /* NOTE1: a previous version of this didn't work nice for some intel cards * NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */ draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha); } } glDisable(GL_BLEND); }
/* get colors for drawing Action-Line * NOTE: color returned includes fine-tuned alpha! */ void nla_action_get_color(AnimData *adt, bAction *act, float color[4]) { if (adt && (adt->flag & ADT_NLA_EDIT_ON)) { /* greenish color (same as tweaking strip) */ UI_GetThemeColor4fv(TH_NLA_TWEAK, color); } else { if (act) { /* reddish color - same as dopesheet summary */ UI_GetThemeColor4fv(TH_ANIM_ACTIVE, color); } else { /* grayish-red color */ UI_GetThemeColor4fv(TH_ANIM_INACTIVE, color); } } /* when an NLA track is tagged "solo", action doesn't contribute, so shouldn't be as prominent */ if (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) color[3] *= 0.15f; }
/* draw a simple diamond shape with OpenGL */ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, short key_type, short mode, float alpha) { static GLuint displist1 = 0; static GLuint displist2 = 0; /* initialize 2 display lists for diamond shape - one empty, one filled */ if (displist1 == 0) { displist1 = glGenLists(1); glNewList(displist1, GL_COMPILE); glBegin(GL_LINE_LOOP); glVertex2fv(_unit_diamond_shape[0]); glVertex2fv(_unit_diamond_shape[1]); glVertex2fv(_unit_diamond_shape[2]); glVertex2fv(_unit_diamond_shape[3]); glEnd(); glEndList(); } if (displist2 == 0) { displist2 = glGenLists(1); glNewList(displist2, GL_COMPILE); glBegin(GL_QUADS); glVertex2fv(_unit_diamond_shape[0]); glVertex2fv(_unit_diamond_shape[1]); glVertex2fv(_unit_diamond_shape[2]); glVertex2fv(_unit_diamond_shape[3]); glEnd(); glEndList(); } /* tweak size of keyframe shape according to type of keyframe * - 'proper' keyframes have key_type = 0, so get drawn at full size */ hsize -= 0.5f * key_type; /* adjust view transform before starting */ glTranslatef(x, y, 0.0f); glScalef(1.0f / xscale * hsize, hsize, 1.0f); /* anti-aliased lines for more consistent appearance */ glEnable(GL_LINE_SMOOTH); /* draw! */ if (ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH)) { float inner_col[4]; /* get interior colors from theme (for selected and unselected only) */ switch (key_type) { case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */ { if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_BREAKDOWN_SELECT, inner_col); else UI_GetThemeColor4fv(TH_KEYTYPE_BREAKDOWN, inner_col); break; } case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */ { if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_EXTREME_SELECT, inner_col); else UI_GetThemeColor4fv(TH_KEYTYPE_EXTREME, inner_col); break; } case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */ { if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_JITTER_SELECT, inner_col); else UI_GetThemeColor4fv(TH_KEYTYPE_JITTER, inner_col); break; } case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */ default: { if (sel) UI_GetThemeColor4fv(TH_KEYTYPE_KEYFRAME_SELECT, inner_col); else UI_GetThemeColor4fv(TH_KEYTYPE_KEYFRAME, inner_col); break; } } /* NOTE: we don't use the straight alpha from the theme, or else effects such as * greying out protected/muted channels doesn't work correctly! */ inner_col[3] *= alpha; glColor4fv(inner_col); /* draw the "filled in" interior poly now */ glCallList(displist2); } if (ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH)) { float border_col[4]; /* exterior - black frame */ if (sel) UI_GetThemeColor4fv(TH_KEYBORDER_SELECT, border_col); else UI_GetThemeColor4fv(TH_KEYBORDER, border_col); border_col[3] *= alpha; glColor4fv(border_col); glCallList(displist1); } glDisable(GL_LINE_SMOOTH); /* restore view transform */ glScalef(xscale / hsize, 1.0f / hsize, 1.0f); glTranslatef(-x, -y, 0.0f); }