2008-12-20 08:24:24 +00:00
/**
* $ Id $
*
* * * * * * BEGIN GPL LICENSE BLOCK * * * * *
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* The Original Code is Copyright ( C ) 2008 Blender Foundation .
* All rights reserved .
*
*
* Contributor ( s ) : Joshua Leung
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
# include <string.h>
# include <stdio.h>
2009-06-08 02:33:24 +00:00
# include <math.h>
2008-12-20 08:24:24 +00:00
2009-01-20 11:07:42 +00:00
# include "DNA_anim_types.h"
2008-12-20 08:24:24 +00:00
# include "DNA_action_types.h"
# include "DNA_curve_types.h"
# include "DNA_object_types.h"
# include "DNA_space_types.h"
# include "DNA_scene_types.h"
# include "DNA_screen_types.h"
# include "DNA_windowmanager_types.h"
# include "MEM_guardedalloc.h"
# include "BLI_blenlib.h"
2009-06-23 13:25:31 +00:00
# include "BKE_animsys.h"
2008-12-22 08:13:25 +00:00
# include "BKE_action.h"
2008-12-20 08:24:24 +00:00
# include "BKE_context.h"
# include "BKE_global.h"
2009-01-20 11:07:42 +00:00
# include "BKE_fcurve.h"
2009-10-13 11:32:03 +00:00
# include "BKE_main.h"
2009-06-23 13:25:31 +00:00
# include "BKE_nla.h"
2008-12-21 03:14:01 +00:00
# include "BKE_object.h"
2008-12-20 08:24:24 +00:00
# include "BKE_screen.h"
# include "BKE_utildefines.h"
# include "ED_anim_api.h"
2009-01-03 06:01:11 +00:00
# include "ED_keyframes_edit.h"
2009-09-27 06:14:42 +00:00
# include "ED_types.h"
2008-12-20 08:24:24 +00:00
# include "ED_util.h"
# include "WM_api.h"
# include "WM_types.h"
# include "BIF_gl.h"
# include "BIF_glutil.h"
# include "UI_interface.h"
# include "UI_resources.h"
# include "UI_view2d.h"
2008-12-21 03:14:01 +00:00
/* XXX */
extern void ui_rasterpos_safe ( float x , float y , float aspect ) ;
2008-12-20 08:24:24 +00:00
/* *************************************************** */
/* CURRENT FRAME DRAWING */
/* Draw current frame number in a little green box beside the current frame indicator */
2008-12-22 09:43:29 +00:00
static void draw_cfra_number ( Scene * scene , View2D * v2d , float cfra , short time )
2008-12-20 08:24:24 +00:00
{
2008-12-21 03:14:01 +00:00
float xscale , yscale , x , y ;
2008-12-20 08:24:24 +00:00
char str [ 32 ] ;
2008-12-21 03:14:01 +00:00
short slen ;
2008-12-20 08:24:24 +00:00
/* because the frame number text is subject to the same scaling as the contents of the view */
UI_view2d_getscale ( v2d , & xscale , & yscale ) ;
2009-01-02 00:56:48 +00:00
glScalef ( 1.0f / xscale , 1.0f , 1.0f ) ;
2008-12-20 08:24:24 +00:00
2009-06-08 02:33:24 +00:00
if ( time ) {
2009-06-09 20:03:52 +00:00
/* Timecode:
2009-06-08 02:33:24 +00:00
* - In general , minutes and seconds should be shown , as most clips will be
* within this length . Hours will only be included if relevant .
* - Only show frames when zoomed in enough for them to be relevant
2009-06-09 20:03:52 +00:00
* ( using separator of ' ! ' for frames ) .
2009-06-08 02:33:24 +00:00
* When showing frames , use slightly different display to avoid confusion with mm : ss format
2009-06-09 20:03:52 +00:00
* TODO : factor into reusable function .
* Meanwhile keep in sync :
* source / blender / editors / animation / anim_draw . c
* source / blender / editors / interface / view2d . c
2009-06-08 02:33:24 +00:00
*/
float val = FRA2TIME ( CFRA ) ;
int hours = 0 , minutes = 0 , seconds = 0 , frames = 0 ;
char neg [ 2 ] = " " ;
/* get values */
if ( val < 0 ) {
/* correction for negative values */
sprintf ( neg , " - " ) ;
val = - val ;
}
if ( val > = 3600 ) {
/* hours */
/* XXX should we only display a single digit for hours since clips are
* VERY UNLIKELY to be more than 1 - 2 hours max ? However , that would
* go against conventions . . .
*/
hours = ( int ) val / 3600 ;
val = ( float ) fmod ( val , 3600 ) ;
}
if ( val > = 60 ) {
/* minutes */
minutes = ( int ) val / 60 ;
val = ( float ) fmod ( val , 60 ) ;
}
{
/* seconds + frames
* Frames are derived from ' fraction ' of second . We need to perform some additional rounding
* to cope with ' half ' frames , etc . , which should be fine in most cases
*/
seconds = ( int ) val ;
frames = ( int ) floor ( ( ( val - seconds ) * FPS ) + 0.5f ) ;
}
/* print timecode to temp string buffer */
2009-06-09 20:03:52 +00:00
if ( hours ) sprintf ( str , " %s%02d:%02d:%02d!%02d " , neg , hours , minutes , seconds , frames ) ;
else if ( minutes ) sprintf ( str , " %s%02d:%02d!%02d " , neg , minutes , seconds , frames ) ;
else sprintf ( str , " %s%d!%02d " , neg , seconds , frames ) ;
2009-06-08 02:33:24 +00:00
}
2008-12-20 08:24:24 +00:00
else
sprintf ( str , " %d " , CFRA ) ;
2009-04-10 16:30:28 +00:00
slen = ( short ) UI_GetStringWidth ( str ) - 1 ;
2008-12-20 08:24:24 +00:00
/* get starting coordinates for drawing */
x = cfra * xscale ;
2008-12-21 03:14:01 +00:00
y = 18 ;
2008-12-20 08:24:24 +00:00
/* draw green box around/behind text */
UI_ThemeColorShadeAlpha ( TH_CFRAME , 0 , - 100 ) ;
2008-12-21 03:14:01 +00:00
glRectf ( x , y , x + slen , y + 15 ) ;
2008-12-20 08:24:24 +00:00
/* draw current frame number - black text */
UI_ThemeColor ( TH_TEXT ) ;
2009-04-10 16:30:28 +00:00
UI_DrawString ( x - 5 , y + 3 , str ) ; // XXX may need to be updated for font stuff
2008-12-20 08:24:24 +00:00
/* restore view transform */
2008-12-21 03:14:01 +00:00
glScalef ( xscale , 1.0 , 1.0 ) ;
2008-12-20 08:24:24 +00:00
}
2009-10-20 12:04:56 +00:00
/* General call for drawing current frame indicator in animation editor */
2008-12-20 08:24:24 +00:00
void ANIM_draw_cfra ( const bContext * C , View2D * v2d , short flag )
{
Scene * scene = CTX_data_scene ( C ) ;
float vec [ 2 ] ;
/* Draw a light green line to indicate current frame */
vec [ 0 ] = ( float ) ( scene - > r . cfra * scene - > r . framelen ) ;
UI_ThemeColor ( TH_CFRAME ) ;
glLineWidth ( 2.0 ) ;
glBegin ( GL_LINE_STRIP ) ;
2009-07-02 18:12:46 +00:00
vec [ 1 ] = v2d - > cur . ymin - 500.0f ; /* XXX arbitrary... want it go to bottom */
2008-12-20 08:24:24 +00:00
glVertex2fv ( vec ) ;
vec [ 1 ] = v2d - > cur . ymax ;
glVertex2fv ( vec ) ;
glEnd ( ) ;
/* Draw dark green line if slow-parenting/time-offset is enabled */
if ( flag & DRAWCFRA_SHOW_TIMEOFS ) {
Object * ob = ( scene - > basact ) ? ( scene - > basact - > object ) : 0 ;
2009-01-20 11:07:42 +00:00
// XXX ob->ipoflag is depreceated!
if ( ( ob ) & & ( ob - > ipoflag & OB_OFFS_OB ) & & ( give_timeoffset ( ob ) ! = 0.0f ) ) {
2008-12-20 08:24:24 +00:00
vec [ 0 ] - = give_timeoffset ( ob ) ; /* could avoid calling twice */
UI_ThemeColorShade ( TH_CFRAME , - 30 ) ;
glBegin ( GL_LINE_STRIP ) ;
/*vec[1]= v2d->cur.ymax;*/ // this is set already. this line is only included
glVertex2fv ( vec ) ;
vec [ 1 ] = v2d - > cur . ymin ;
glVertex2fv ( vec ) ;
glEnd ( ) ;
}
}
glLineWidth ( 1.0 ) ;
/* Draw current frame number in a little box */
if ( flag & DRAWCFRA_SHOW_NUMBOX ) {
UI_view2d_view_orthoSpecial ( C , v2d , 1 ) ;
2008-12-22 09:43:29 +00:00
draw_cfra_number ( scene , v2d , vec [ 0 ] , ( flag & DRAWCFRA_UNIT_SECONDS ) ) ;
2008-12-20 08:24:24 +00:00
}
}
/* *************************************************** */
/* PREVIEW RANGE 'CURTAINS' */
2008-12-27 05:24:03 +00:00
/* Note: 'Preview Range' tools are defined in anim_ops.c */
2008-12-20 08:24:24 +00:00
/* Draw preview range 'curtains' for highlighting where the animation data is */
void ANIM_draw_previewrange ( const bContext * C , View2D * v2d )
{
Scene * scene = CTX_data_scene ( C ) ;
/* only draw this if preview range is set */
if ( scene - > r . psfra ) {
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glEnable ( GL_BLEND ) ;
glColor4f ( 0.0f , 0.0f , 0.0f , 0.4f ) ;
/* only draw two separate 'curtains' if there's no overlap between them */
if ( PSFRA < PEFRA ) {
2009-01-02 00:56:48 +00:00
glRectf ( v2d - > cur . xmin , v2d - > cur . ymin , ( float ) PSFRA , v2d - > cur . ymax ) ;
glRectf ( ( float ) PEFRA , v2d - > cur . ymin , v2d - > cur . xmax , v2d - > cur . ymax ) ;
2008-12-20 08:24:24 +00:00
}
else {
glRectf ( v2d - > cur . xmin , v2d - > cur . ymin , v2d - > cur . xmax , v2d - > cur . ymax ) ;
}
glDisable ( GL_BLEND ) ;
}
}
/* *************************************************** */
2009-01-03 06:01:11 +00:00
/* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes) */
2008-12-22 08:13:25 +00:00
2009-06-23 13:25:31 +00:00
/* Obtain the AnimData block providing NLA-mapping for the given channel (if applicable) */
AnimData * ANIM_nla_mapping_get ( bAnimContext * ac , bAnimListElem * ale )
2008-12-22 08:13:25 +00:00
{
/* sanity checks */
if ( ac = = NULL )
return NULL ;
/* handling depends on the type of animation-context we've got */
2009-07-28 06:50:30 +00:00
if ( ale )
return ale - > adt ;
else
return NULL ;
2008-12-22 08:13:25 +00:00
}
2009-01-03 06:01:11 +00:00
/* ------------------- */
2009-06-23 13:25:31 +00:00
/* helper function for ANIM_nla_mapping_apply_fcurve() -> "restore", i.e. mapping points back to action-time */
2009-01-03 06:01:11 +00:00
static short bezt_nlamapping_restore ( BeztEditData * bed , BezTriple * bezt )
{
2009-06-23 13:25:31 +00:00
/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
AnimData * adt = ( AnimData * ) bed - > data ;
2009-01-03 06:01:11 +00:00
short only_keys = ( short ) bed - > i1 ;
/* adjust BezTriple handles only if allowed to */
if ( only_keys = = 0 ) {
2009-06-28 07:32:00 +00:00
bezt - > vec [ 0 ] [ 0 ] = BKE_nla_tweakedit_remap ( adt , bezt - > vec [ 0 ] [ 0 ] , NLATIME_CONVERT_UNMAP ) ;
bezt - > vec [ 2 ] [ 0 ] = BKE_nla_tweakedit_remap ( adt , bezt - > vec [ 2 ] [ 0 ] , NLATIME_CONVERT_UNMAP ) ;
2009-06-23 13:25:31 +00:00
}
2009-06-28 07:32:00 +00:00
bezt - > vec [ 1 ] [ 0 ] = BKE_nla_tweakedit_remap ( adt , bezt - > vec [ 1 ] [ 0 ] , NLATIME_CONVERT_UNMAP ) ;
2009-01-03 10:03:26 +00:00
return 0 ;
2009-01-03 06:01:11 +00:00
}
2009-06-23 13:25:31 +00:00
/* helper function for ANIM_nla_mapping_apply_fcurve() -> "apply", i.e. mapping points to NLA-mapped global time */
2009-01-03 06:01:11 +00:00
static short bezt_nlamapping_apply ( BeztEditData * bed , BezTriple * bezt )
{
2009-06-23 13:25:31 +00:00
/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
AnimData * adt = ( AnimData * ) bed - > data ;
2009-01-03 06:01:11 +00:00
short only_keys = ( short ) bed - > i1 ;
/* adjust BezTriple handles only if allowed to */
if ( only_keys = = 0 ) {
2009-06-28 07:32:00 +00:00
bezt - > vec [ 0 ] [ 0 ] = BKE_nla_tweakedit_remap ( adt , bezt - > vec [ 0 ] [ 0 ] , NLATIME_CONVERT_MAP ) ;
bezt - > vec [ 2 ] [ 0 ] = BKE_nla_tweakedit_remap ( adt , bezt - > vec [ 2 ] [ 0 ] , NLATIME_CONVERT_MAP ) ;
2009-01-03 06:01:11 +00:00
}
2009-06-23 13:25:31 +00:00
2009-06-28 07:32:00 +00:00
bezt - > vec [ 1 ] [ 0 ] = BKE_nla_tweakedit_remap ( adt , bezt - > vec [ 1 ] [ 0 ] , NLATIME_CONVERT_MAP ) ;
2009-01-03 10:03:26 +00:00
return 0 ;
2009-01-03 06:01:11 +00:00
}
2009-01-20 11:07:42 +00:00
/* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve
* - restore = whether to map points back to non - mapped time
2009-01-03 06:01:11 +00:00
* - only_keys = whether to only adjust the location of the center point of beztriples
*/
2009-06-23 13:25:31 +00:00
void ANIM_nla_mapping_apply_fcurve ( AnimData * adt , FCurve * fcu , short restore , short only_keys )
2009-01-03 06:01:11 +00:00
{
BeztEditData bed ;
BeztEditFunc map_cb ;
/* init edit data
2009-06-23 13:25:31 +00:00
* - AnimData is stored in ' data '
2009-01-03 06:01:11 +00:00
* - only_keys is stored in ' i1 '
*/
memset ( & bed , 0 , sizeof ( BeztEditData ) ) ;
2009-06-23 13:25:31 +00:00
bed . data = ( void * ) adt ;
2009-01-03 06:01:11 +00:00
bed . i1 = ( int ) only_keys ;
/* get editing callback */
if ( restore )
map_cb = bezt_nlamapping_restore ;
else
map_cb = bezt_nlamapping_apply ;
2009-01-20 11:07:42 +00:00
/* apply to F-Curve */
ANIM_fcurve_keys_bezier_loop ( & bed , fcu , NULL , map_cb , NULL ) ;
2009-01-03 06:01:11 +00:00
}
2008-12-22 08:13:25 +00:00
/* *************************************************** */
2009-09-27 06:14:42 +00:00
/* ANIMATION EDITOR UI-WIDGETS */
/* ui button event */
# define B_REDR 1
/* standard header buttons for Animation Editors */
short ANIM_headerUI_standard_buttons ( const bContext * C , bDopeSheet * ads , uiBlock * block , short xco , short yco )
{
2009-10-13 11:32:03 +00:00
Main * mainptr = CTX_data_main ( C ) ;
2009-09-27 06:14:42 +00:00
ScrArea * sa = CTX_wm_area ( C ) ;
short nlaActive = ( ( sa ) & & ( sa - > spacetype = = SPACE_NLA ) ) ;
/* check if the DopeSheet data exists, just in case... */
if ( ads ) {
/* more 'generic' filtering options */
if ( nlaActive ) uiBlockBeginAlign ( block ) ;
uiDefIconButBitI ( block , TOG , ADS_FILTER_ONLYSEL , B_REDR , ICON_RESTRICT_SELECT_OFF , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Only display selected Objects " ) ;
if ( nlaActive ) uiDefIconButBitI ( block , TOGN , ADS_FILTER_NLA_NOACT , B_REDR , ICON_ACTION , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Include AnimData blocks with no NLA Data " ) ;
if ( nlaActive ) uiBlockEndAlign ( block ) ;
xco + = 5 ;
2009-10-13 11:32:03 +00:00
/* datatype based - only available datatypes are shown */
2009-09-27 06:14:42 +00:00
uiBlockBeginAlign ( block ) ;
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOSCE , B_REDR , ICON_SCENE_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Scene Animation " ) ;
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOWOR , B_REDR , ICON_WORLD_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display World Animation " ) ;
2009-11-11 05:03:49 +00:00
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NONTREE , B_REDR , ICON_NODETREE , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Node Tree Animation " ) ;
2009-10-13 11:32:03 +00:00
if ( mainptr & & mainptr - > key . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOSHAPEKEYS , B_REDR , ICON_SHAPEKEY_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display ShapeKeys " ) ;
if ( mainptr & & mainptr - > mat . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOMAT , B_REDR , ICON_MATERIAL_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Material Data " ) ;
if ( mainptr & & mainptr - > lamp . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOLAM , B_REDR , ICON_LAMP_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Lamp Data " ) ;
if ( mainptr & & mainptr - > camera . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOCAM , B_REDR , ICON_CAMERA_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Camera Data " ) ;
if ( mainptr & & mainptr - > curve . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOCUR , B_REDR , ICON_CURVE_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Curve Data " ) ;
if ( mainptr & & mainptr - > mball . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOMBA , B_REDR , ICON_META_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display MetaBall Data " ) ;
if ( mainptr & & mainptr - > armature . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOARM , B_REDR , ICON_ARMATURE_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Armature Data " ) ;
if ( mainptr & & mainptr - > particle . first )
uiDefIconButBitI ( block , TOGN , ADS_FILTER_NOPART , B_REDR , ICON_PARTICLE_DATA , ( short ) ( xco + = XIC ) , yco , XIC , YIC , & ( ads - > filterflag ) , 0 , 0 , 0 , 0 , " Display Particle Data " ) ;
2009-09-27 06:14:42 +00:00
uiBlockEndAlign ( block ) ;
xco + = 30 ;
}
else {
// XXX this case shouldn't happen at all... for now, just pad out same amount of space
printf ( " ERROR: dopesheet data not available when drawing Animation Editor header \n " ) ;
xco + = 11 * XIC + 30 ;
}
// TODO: include auto-snapping menu here too...
/* return the width of the buttons */
return xco ;
}
/* *************************************************** */