2009-02-21 10:38:58 +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 ) 2009 Blender Foundation .
* All rights reserved .
*
*
* Contributor ( s ) : Blender Foundation , Joshua Leung
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
# include <string.h>
# include <stdio.h>
# include <math.h>
# include <float.h>
# include "DNA_anim_types.h"
# include "DNA_action_types.h"
# include "DNA_object_types.h"
# include "DNA_space_types.h"
# include "DNA_scene_types.h"
# include "DNA_screen_types.h"
# include "DNA_userdef_types.h"
# include "MEM_guardedalloc.h"
# include "BLI_arithb.h"
# include "BLI_blenlib.h"
# include "BLI_editVert.h"
# include "BLI_rand.h"
# include "BKE_animsys.h"
# include "BKE_action.h"
# include "BKE_context.h"
# include "BKE_curve.h"
# include "BKE_customdata.h"
# include "BKE_depsgraph.h"
2009-03-15 10:39:02 +00:00
# include "BKE_fcurve.h"
2009-02-21 10:38:58 +00:00
# include "BKE_object.h"
# include "BKE_global.h"
# include "BKE_scene.h"
# include "BKE_screen.h"
# include "BKE_utildefines.h"
# include "BIF_gl.h"
# include "WM_api.h"
# include "WM_types.h"
# include "RNA_access.h"
# include "RNA_define.h"
# include "ED_anim_api.h"
# include "ED_keyframing.h"
# include "ED_screen.h"
# include "ED_types.h"
# include "ED_util.h"
# include "UI_interface.h"
# include "UI_resources.h"
# include "UI_view2d.h"
# include "graph_intern.h" // own include
2009-04-19 12:26:31 +00:00
/* XXX */
/* temporary definition for limits of float number buttons (FLT_MAX tends to infinity with old system) */
# define UI_FLT_MAX 10000.0f
2009-02-21 10:38:58 +00:00
2009-02-22 09:30:18 +00:00
/* ******************* graph editor space & buttons ************** */
2009-02-21 10:38:58 +00:00
# define B_NOP 1
# define B_REDR 2
2009-02-22 09:30:18 +00:00
/* -------------- */
2009-02-21 10:38:58 +00:00
static void do_graph_region_buttons ( bContext * C , void * arg , int event )
{
//Scene *scene= CTX_data_scene(C);
switch ( event ) {
}
/* default for now */
//WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
}
2009-02-22 09:30:18 +00:00
static void graph_panel_properties ( const bContext * C , ARegion * ar , short cntrl , bAnimListElem * ale )
2009-02-21 10:38:58 +00:00
{
2009-02-22 09:30:18 +00:00
FCurve * fcu = ( FCurve * ) ale - > data ;
2009-02-21 10:38:58 +00:00
uiBlock * block ;
2009-02-21 11:22:06 +00:00
char name [ 128 ] ;
2009-02-21 10:38:58 +00:00
2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
(was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
a several calls using different args.
Further just added the missing includes, and removed unused vars.
2009-04-14 15:59:52 +00:00
block = uiBeginBlock ( C , ar , " graph_panel_properties " , UI_EMBOSS ) ;
2009-02-22 09:30:18 +00:00
if ( uiNewPanel ( C , ar , block , " Properties " , " Graph " , 340 , 30 , 318 , 254 ) = = 0 ) return ;
2009-02-21 10:38:58 +00:00
uiBlockSetHandleFunc ( block , do_graph_region_buttons , NULL ) ;
/* to force height */
2009-02-21 11:22:06 +00:00
uiNewPanelHeight ( block , 204 ) ;
2009-02-21 10:38:58 +00:00
2009-02-22 09:30:18 +00:00
/* Info - Active F-Curve */
2009-02-21 11:22:06 +00:00
uiDefBut ( block , LABEL , 1 , " Active F-Curve: " , 10 , 200 , 150 , 19 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-02-22 09:30:18 +00:00
if ( ale - > id ) {
// icon of active blocktype - is this really necessary?
int icon = geticon_anim_blocktype ( GS ( ale - > id - > name ) ) ;
// xxx type of icon-but is currently "LABEL", as that one is plain...
uiDefIconBut ( block , LABEL , 1 , icon , 10 , 180 , 20 , 19 , NULL , 0 , 0 , 0 , 0 , " ID-type that F-Curve belongs to " ) ;
}
getname_anim_fcurve ( name , ale - > id , fcu ) ;
uiDefBut ( block , LABEL , 1 , name , 30 , 180 , 300 , 19 , NULL , 0.0 , 0.0 , 0 , 0 , " Name of Active F-Curve " ) ;
2009-02-21 11:22:06 +00:00
2009-02-22 09:30:18 +00:00
/* TODO: the following settings could be added here
* - F - Curve coloring mode - mode selector + color selector
* - Access details ( ID - block + RNA - Path + Array Index )
* - . . .
*/
2009-02-21 10:38:58 +00:00
}
2009-03-21 03:49:22 +00:00
/* ******************* drivers ******************************** */
2009-02-22 09:30:18 +00:00
# define B_IPO_DEPCHANGE 10
static void do_graph_region_driver_buttons ( bContext * C , void * arg , int event )
{
Scene * scene = CTX_data_scene ( C ) ;
2009-04-11 00:29:21 +00:00
switch ( event ) {
2009-02-22 09:30:18 +00:00
case B_IPO_DEPCHANGE :
{
/* rebuild depsgraph for the new deps */
DAG_scene_sort ( scene ) ;
2009-04-13 00:46:32 +00:00
/* force an update of depsgraph */
ED_anim_dag_flush_update ( C ) ;
2009-02-22 09:30:18 +00:00
}
break ;
}
/* default for now */
2009-04-17 02:13:35 +00:00
WM_event_add_notifier ( C , NC_SCENE , scene ) ;
2009-02-22 09:30:18 +00:00
}
2009-04-11 06:48:39 +00:00
/* callback to remove the active driver */
static void driver_remove_cb ( bContext * C , void * ale_v , void * dummy_v )
{
bAnimListElem * ale = ( bAnimListElem * ) ale_v ;
ID * id = ale - > id ;
FCurve * fcu = ale - > data ;
/* try to get F-Curve that driver lives on, and ID block which has this AnimData */
if ( ELEM ( NULL , id , fcu ) )
return ;
/* call API method to remove this driver */
ANIM_remove_driver ( id , fcu - > rna_path , fcu - > array_index , 0 ) ;
}
2009-04-16 12:38:44 +00:00
/* callback to add a target variable to the active driver */
static void driver_add_var_cb ( bContext * C , void * driver_v , void * dummy_v )
{
ChannelDriver * driver = ( ChannelDriver * ) driver_v ;
/* add a new var */
driver_add_new_target ( driver ) ;
}
/* callback to remove target variable from active driver */
static void driver_delete_var_cb ( bContext * C , void * driver_v , void * dtar_v )
{
ChannelDriver * driver = ( ChannelDriver * ) driver_v ;
DriverTarget * dtar = ( DriverTarget * ) dtar_v ;
/* add a new var */
driver_free_target ( driver , dtar ) ;
}
2009-04-11 06:48:39 +00:00
/* callback to reset the driver's flags */
static void driver_update_flags_cb ( bContext * C , void * fcu_v , void * dummy_v )
{
FCurve * fcu = ( FCurve * ) fcu_v ;
ChannelDriver * driver = fcu - > driver ;
/* clear invalid flags */
driver - > flag & = ~ DRIVER_FLAG_INVALID ;
}
Animato - Drivers with Multiple Targets:
Drivers now support multiple targets which act as 'variables'. The targets have a short 'name' (see later), and reference some property (in much the same way as F-Curves do, using RNA-Paths) which acts as the 'value'.
These named variables can then be used in a Python Expression which relates them to each other for more fine-grained control over the result of the driver. By using only the names of these variables in the expressions, we are able to define expressions/relationships in a much more readable way, as data access is separated from data use. This makes the underlying relationships easier to understand.
By default, if no Python Expression is given, the variables are simply averaged together, so old files won't break. :)
For example, check the following diagram (thanks Cessen/Nathan V from Peach team):
http://download.blender.org/ftp/incoming/250_drivers_mockup_cessen.png
TODO List:
* Depsgraph building for new driver relationships doesn't work yet. This needs to be recoded again, but this new system makes this much easier, since the targets are clearly defined (i.e. no need to parse py expressions to get list of objects)
* Graph Editor interface for editing these needs to be rewritten
* Python function for evaluating these expressions is needed (Campbell?)
2009-04-16 07:37:06 +00:00
2009-02-22 09:30:18 +00:00
static void graph_panel_drivers ( const bContext * C , ARegion * ar , short cntrl , bAnimListElem * ale )
{
FCurve * fcu = ( FCurve * ) ale - > data ;
ChannelDriver * driver = fcu - > driver ;
2009-04-16 12:38:44 +00:00
DriverTarget * dtar ;
PointerRNA rna_ptr ;
2009-02-22 09:30:18 +00:00
uiBlock * block ;
uiBut * but ;
2009-04-16 12:38:44 +00:00
int yco = 85 , i = 0 ;
2009-02-22 09:30:18 +00:00
2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
(was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
a several calls using different args.
Further just added the missing includes, and removed unused vars.
2009-04-14 15:59:52 +00:00
block = uiBeginBlock ( C , ar , " graph_panel_drivers " , UI_EMBOSS ) ;
2009-02-22 09:30:18 +00:00
if ( uiNewPanel ( C , ar , block , " Drivers " , " Graph " , 340 , 30 , 318 , 254 ) = = 0 ) return ;
uiBlockSetHandleFunc ( block , do_graph_region_driver_buttons , NULL ) ;
/* to force height */
uiNewPanelHeight ( block , 204 ) ;
2009-04-11 06:48:39 +00:00
/* general actions */
but = uiDefBut ( block , BUT , B_IPO_DEPCHANGE , " Update Dependencies " , 10 , 200 , 180 , 22 , NULL , 0.0 , 0.0 , 0 , 0 , " Force updates of dependencies " ) ;
uiButSetFunc ( but , driver_update_flags_cb , fcu , NULL ) ;
but = uiDefBut ( block , BUT , B_IPO_DEPCHANGE , " Remove Driver " , 200 , 200 , 110 , 18 , NULL , 0.0 , 0.0 , 0 , 0 , " Remove this driver " ) ;
uiButSetFunc ( but , driver_remove_cb , ale , NULL ) ;
2009-02-22 09:30:18 +00:00
/* type */
2009-04-11 06:48:39 +00:00
uiDefBut ( block , LABEL , 1 , " Type: " , 10 , 170 , 60 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-02-22 09:30:18 +00:00
uiDefButI ( block , MENU , B_IPO_DEPCHANGE ,
2009-04-16 12:38:44 +00:00
" Driver Type%t|Normal%x0|Scripted Expression%x1|Rotational Difference%x2 " ,
70 , 170 , 240 , 20 , & driver - > type , 0 , 0 , 0 , 0 , " Driver type " ) ;
/* show expression box if doing scripted drivers */
if ( driver - > type = = DRIVER_TYPE_PYTHON ) {
uiDefBut ( block , TEX , B_REDR , " Expr: " , 10 , 150 , 300 , 20 , driver - > expression , 0 , 255 , 0 , 0 , " One-liner Python Expression to use as Scripted Expression " ) ;
2009-02-22 09:30:18 +00:00
2009-04-11 06:48:39 +00:00
/* errors */
2009-02-22 09:30:18 +00:00
if ( driver - > flag & DRIVER_FLAG_INVALID ) {
2009-04-16 12:38:44 +00:00
uiDefIconBut ( block , LABEL , 1 , ICON_ERROR , 10 , 130 , 48 , 48 , NULL , 0 , 0 , 0 , 0 , " " ) ; // a bit larger
2009-02-22 09:30:18 +00:00
uiDefBut ( block , LABEL , 0 , " Error: invalid Python expression " ,
2009-04-16 12:38:44 +00:00
50 , 110 , 230 , 19 , NULL , 0 , 0 , 0 , 0 , " " ) ;
}
}
else {
/* errors */
if ( driver - > flag & DRIVER_FLAG_INVALID ) {
uiDefIconBut ( block , LABEL , 1 , ICON_ERROR , 10 , 130 , 48 , 48 , NULL , 0 , 0 , 0 , 0 , " " ) ; // a bit larger
uiDefBut ( block , LABEL , 0 , " Error: invalid target channel(s) " ,
50 , 130 , 230 , 19 , NULL , 0 , 0 , 0 , 0 , " " ) ;
2009-02-22 09:30:18 +00:00
}
}
2009-04-16 12:38:44 +00:00
but = uiDefBut ( block , BUT , B_IPO_DEPCHANGE , " Add Variable " , 10 , 110 , 300 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " Add a new target variable for this Driver " ) ;
uiButSetFunc ( but , driver_add_var_cb , driver , NULL ) ;
/* loop over targets, drawing them */
for ( dtar = driver - > targets . first ; dtar ; dtar = dtar - > next ) {
2009-04-17 02:13:35 +00:00
short height = ( dtar - > id ) ? 80 : 60 ;
/* panel behind buttons */
uiDefBut ( block , ROUNDBOX , B_REDR , " " , 5 , yco - height + 25 , 310 , height , NULL , 5.0 , 0.0 , 12.0 , 0 , " " ) ;
2009-02-22 09:30:18 +00:00
2009-04-16 12:38:44 +00:00
/* variable name */
2009-04-16 13:10:08 +00:00
uiDefButC ( block , TEX , B_REDR , " Name: " , 10 , yco , 280 , 20 , dtar - > name , 0 , 63 , 0 , 0 , " Name of target variable (No spaces or dots are allowed. Also, must not start with a symbol or digit). " ) ;
2009-04-11 00:29:21 +00:00
2009-04-16 12:38:44 +00:00
/* remove button */
but = uiDefIconBut ( block , BUT , B_REDR , ICON_X , 290 , yco , 20 , 20 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Delete target variable. " ) ;
uiButSetFunc ( but , driver_delete_var_cb , driver , dtar ) ;
2009-02-22 09:30:18 +00:00
2009-04-11 06:48:39 +00:00
2009-04-16 12:38:44 +00:00
/* Target Object */
uiDefBut ( block , LABEL , 1 , " Value: " , 10 , yco - 30 , 60 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
uiDefIDPoinBut ( block , test_obpoin_but , ID_OB , B_REDR , " Ob: " , 70 , yco - 30 , 240 , 20 , & dtar - > id , " Object to use as Driver target " ) ;
// XXX should we hide these technical details?
if ( dtar - > id ) {
uiBlockBeginAlign ( block ) ;
/* RNA Path */
RNA_pointer_create ( ale - > id , & RNA_DriverTarget , dtar , & rna_ptr ) ;
uiDefButR ( block , TEX , 0 , " Path: " , 10 , yco - 50 , 250 , 20 , & rna_ptr , " rna_path " , 0 , 0 , 0 , - 1 , - 1 , " RNA Path (from Driver Object) to property used as Driver. " ) ;
/* Array Index */
uiDefButI ( block , NUM , B_REDR , " " , 260 , yco - 50 , 50 , 20 , & dtar - > array_index , 0 , INT_MAX , 0 , 0 , " Index to the specific property used as Driver if applicable. " ) ;
uiBlockEndAlign ( block ) ;
2009-04-11 06:48:39 +00:00
}
2009-04-16 12:38:44 +00:00
/* adjust y-coordinate for next target */
yco - = height ;
i + + ;
2009-02-22 09:30:18 +00:00
}
2009-04-16 12:38:44 +00:00
/* since these buttons can have variable height */
if ( yco < 0 )
uiNewPanelHeight ( block , ( 204 - yco ) ) ;
else
uiNewPanelHeight ( block , 204 ) ;
2009-02-22 09:30:18 +00:00
}
2009-03-21 03:49:22 +00:00
/* ******************* f-modifiers ******************************** */
2009-02-22 09:30:18 +00:00
2009-03-15 10:39:02 +00:00
# define B_FMODIFIER_REDRAW 20
2009-02-22 09:30:18 +00:00
static void do_graph_region_modifier_buttons ( bContext * C , void * arg , int event )
{
2009-03-16 11:11:44 +00:00
switch ( event ) {
2009-03-15 10:39:02 +00:00
case B_REDR :
2009-03-16 11:11:44 +00:00
case B_FMODIFIER_REDRAW : // XXX this should send depsgraph updates too
2009-03-15 10:39:02 +00:00
ED_area_tag_redraw ( CTX_wm_area ( C ) ) ;
return ; /* no notifier! */
}
}
2009-03-16 01:12:37 +00:00
/* macro for use here to draw background box and set height */
2009-03-16 11:11:44 +00:00
// XXX for now, roundbox has it's callback func set to NULL to not intercept events
# define DRAW_BACKDROP(height) \
2009-03-16 01:12:37 +00:00
{ \
2009-04-17 02:13:35 +00:00
uiDefBut ( block , ROUNDBOX , B_REDR , " " , - 3 , * yco - height , width + 3 , height - 1 , NULL , 5.0 , 0.0 , 12.0 , ( float ) rb_col , " " ) ; \
2009-03-16 01:12:37 +00:00
}
2009-03-16 11:11:44 +00:00
/* callback to verify modifier data */
static void validate_fmodifier_cb ( bContext * C , void * fcu_v , void * fcm_v )
{
FModifier * fcm = ( FModifier * ) fcm_v ;
FModifierTypeInfo * fmi = fmodifier_get_typeinfo ( fcm ) ;
/* call the verify callback on the modifier if applicable */
if ( fmi & & fmi - > verify_data )
fmi - > verify_data ( fcm ) ;
}
2009-03-17 06:37:50 +00:00
2009-03-18 10:58:18 +00:00
/* callback to set the active modifier */
static void activate_fmodifier_cb ( bContext * C , void * fcu_v , void * fcm_v )
{
FCurve * fcu = ( FCurve * ) fcu_v ;
FModifier * fcm = ( FModifier * ) fcm_v ;
/* call API function to set the active modifier for active F-Curve */
fcurve_set_active_modifier ( fcu , fcm ) ;
}
2009-03-17 06:37:50 +00:00
/* callback to remove the given modifier */
static void delete_fmodifier_cb ( bContext * C , void * fcu_v , void * fcm_v )
{
FCurve * fcu = ( FCurve * ) fcu_v ;
FModifier * fcm = ( FModifier * ) fcm_v ;
/* remove the given F-Modifier from the F-Curve */
fcurve_remove_modifier ( fcu , fcm ) ;
}
2009-03-21 03:49:22 +00:00
/* --------------- */
2009-03-16 11:11:44 +00:00
2009-03-16 01:12:37 +00:00
/* draw settings for generator modifier */
2009-03-17 06:37:50 +00:00
static void draw_modifier__generator ( uiBlock * block , FCurve * fcu , FModifier * fcm , int * yco , short * height , short width , short active , int rb_col )
2009-03-16 01:12:37 +00:00
{
FMod_Generator * data = ( FMod_Generator * ) fcm - > data ;
2009-03-16 11:11:44 +00:00
char gen_mode [ ] = " Generator Type%t|Expanded Polynomial%x0|Factorised Polynomial%x1|Built-In Function%x2|Expression%x3 " ;
2009-03-16 11:43:02 +00:00
char fn_type [ ] = " Built-In Function%t|Sin%x0|Cos%x1|Tan%x2|Square Root%x3|Natural Log%x4 " ;
2009-03-16 11:11:44 +00:00
int cy = * yco - 30 ;
uiBut * but ;
2009-03-16 01:12:37 +00:00
2009-03-16 11:11:44 +00:00
/* set the height */
2009-03-26 11:12:39 +00:00
( * height ) = 90 ;
2009-03-16 11:11:44 +00:00
switch ( data - > mode ) {
case FCM_GENERATOR_POLYNOMIAL : /* polynomial expression */
2009-04-17 02:13:35 +00:00
( * height ) + = 20 * ( data - > poly_order + 1 ) + 20 ;
2009-03-16 11:11:44 +00:00
break ;
case FCM_GENERATOR_POLYNOMIAL_FACTORISED : /* factorised polynomial */
2009-04-17 02:13:35 +00:00
( * height ) + = 20 * data - > poly_order + 15 ;
2009-03-16 11:11:44 +00:00
break ;
case FCM_GENERATOR_FUNCTION : /* builtin function */
2009-04-17 02:13:35 +00:00
( * height ) + = 55 ; // xxx
2009-03-16 11:11:44 +00:00
break ;
case FCM_GENERATOR_EXPRESSION : /* py-expression */
// xxx nothing to draw
break ;
}
/* basic settings (backdrop + mode selector + some padding) */
2009-04-17 02:13:35 +00:00
DRAW_BACKDROP ( ( * height ) ) ;
2009-03-26 11:12:39 +00:00
uiBlockBeginAlign ( block ) ;
but = uiDefButS ( block , MENU , B_FMODIFIER_REDRAW , gen_mode , 10 , cy , width - 30 , 19 , & data - > mode , 0 , 0 , 0 , 0 , " Selects type of generator algorithm. " ) ;
uiButSetFunc ( but , validate_fmodifier_cb , fcu , fcm ) ;
cy - = 20 ;
uiDefButBitS ( block , TOG , FCM_GENERATOR_ADDITIVE , B_FMODIFIER_REDRAW , " Additive " , 10 , cy , width - 30 , 19 , & data - > flag , 0 , 0 , 0 , 0 , " Values generated by this modifier are applied on top of the existing values instead of overwriting them " ) ;
cy - = 35 ;
uiBlockEndAlign ( block ) ;
2009-03-16 11:11:44 +00:00
2009-03-17 06:37:50 +00:00
/* now add settings for individual modes */
2009-03-16 01:12:37 +00:00
switch ( data - > mode ) {
case FCM_GENERATOR_POLYNOMIAL : /* polynomial expression */
{
2009-03-16 11:11:44 +00:00
float * cp = NULL ;
char xval [ 32 ] ;
2009-03-16 01:12:37 +00:00
unsigned int i ;
2009-03-16 11:11:44 +00:00
/* draw polynomial order selector */
but = uiDefButS ( block , NUM , B_FMODIFIER_REDRAW , " Poly Order: " , 10 , cy , width - 30 , 19 , & data - > poly_order , 1 , 100 , 0 , 0 , " 'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1 " ) ;
uiButSetFunc ( but , validate_fmodifier_cb , fcu , fcm ) ;
cy - = 35 ;
2009-03-16 01:12:37 +00:00
2009-03-16 11:11:44 +00:00
/* draw controls for each coefficient and a + sign at end of row */
2009-03-16 11:43:02 +00:00
uiDefBut ( block , LABEL , 1 , " y = " , 0 , cy , 50 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-03-16 01:12:37 +00:00
cp = data - > coefficients ;
for ( i = 0 ; ( i < data - > arraysize ) & & ( cp ) ; i + + , cp + + ) {
2009-03-16 11:11:44 +00:00
/* coefficient */
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 50 , cy , 150 , 20 , cp , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Coefficient for polynomial " ) ;
2009-03-16 11:11:44 +00:00
/* 'x' param (and '+' if necessary) */
if ( i = = 0 )
strcpy ( xval , " " ) ;
else if ( i = = 1 )
strcpy ( xval , " x " ) ;
else
sprintf ( xval , " x^%d " , i ) ;
uiDefBut ( block , LABEL , 1 , xval , 200 , cy , 50 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " Power of x " ) ;
if ( ( i ! = ( data - > arraysize - 1 ) ) | | ( ( i = = 0 ) & & data - > arraysize = = 2 ) )
2009-03-16 11:43:02 +00:00
uiDefBut ( block , LABEL , 1 , " + " , 250 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-03-16 11:11:44 +00:00
cy - = 20 ;
2009-03-16 01:12:37 +00:00
}
}
break ;
2009-03-16 11:43:02 +00:00
case FCM_GENERATOR_POLYNOMIAL_FACTORISED : /* factorised polynomial expression */
{
float * cp = NULL ;
unsigned int i ;
/* draw polynomial order selector */
but = uiDefButS ( block , NUM , B_FMODIFIER_REDRAW , " Poly Order: " , 10 , cy , width - 30 , 19 , & data - > poly_order , 1 , 100 , 0 , 0 , " 'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1 " ) ;
uiButSetFunc ( but , validate_fmodifier_cb , fcu , fcm ) ;
cy - = 35 ;
/* draw controls for each pair of coefficients */
uiDefBut ( block , LABEL , 1 , " y = " , 0 , cy , 50 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
cp = data - > coefficients ;
for ( i = 0 ; ( i < data - > poly_order ) & & ( cp ) ; i + + , cp + = 2 ) {
/* opening bracket */
uiDefBut ( block , LABEL , 1 , " ( " , 40 , cy , 50 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
/* coefficients */
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 50 , cy , 100 , 20 , cp , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Coefficient of x " ) ;
2009-03-16 11:43:02 +00:00
uiDefBut ( block , LABEL , 1 , " x + " , 150 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 180 , cy , 100 , 20 , cp + 1 , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Second coefficient " ) ;
2009-03-16 11:43:02 +00:00
/* closing bracket and '+' sign */
if ( ( i ! = ( data - > poly_order - 1 ) ) | | ( ( i = = 0 ) & & data - > poly_order = = 2 ) )
2009-05-02 04:20:36 +00:00
uiDefBut ( block , LABEL , 1 , " ) ◊ " , 280 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-03-16 11:43:02 +00:00
else
uiDefBut ( block , LABEL , 1 , " ) " , 280 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
cy - = 20 ;
}
}
break ;
case FCM_GENERATOR_FUNCTION : /* built-in function */
{
2009-03-17 00:31:10 +00:00
float * cp = data - > coefficients ;
2009-03-16 11:43:02 +00:00
/* draw function selector */
but = uiDefButS ( block , MENU , B_FMODIFIER_REDRAW , fn_type , 10 , cy , width - 30 , 19 , & data - > func_type , 0 , 0 , 0 , 0 , " Built-In Function to use " ) ;
uiButSetFunc ( but , validate_fmodifier_cb , fcu , fcm ) ;
cy - = 35 ;
2009-03-17 00:31:10 +00:00
/* draw controls for equation of coefficients */
/* row 1 */
{
uiDefBut ( block , LABEL , 1 , " y = " , 0 , cy , 50 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 50 , cy , 150 , 20 , cp + 3 , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Coefficient (D) for function " ) ;
2009-03-17 00:31:10 +00:00
uiDefBut ( block , LABEL , 1 , " + " , 200 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
cy - = 20 ;
}
/* row 2 */
{
char func_name [ 32 ] ;
/* coefficient outside bracket */
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 5 , cy , 80 , 20 , cp , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Coefficient (A) for function " ) ;
2009-03-17 00:31:10 +00:00
/* opening bracket */
switch ( data - > func_type )
{
case FCM_GENERATOR_FN_SIN : /* sine wave */
sprintf ( func_name , " sin( " ) ;
break ;
case FCM_GENERATOR_FN_COS : /* cosine wave */
sprintf ( func_name , " cos( " ) ;
break ;
case FCM_GENERATOR_FN_TAN : /* tangent wave */
sprintf ( func_name , " tan( " ) ;
break ;
case FCM_GENERATOR_FN_LN : /* natural log */
sprintf ( func_name , " ln( " ) ;
break ;
case FCM_GENERATOR_FN_SQRT : /* square root */
sprintf ( func_name , " sqrt( " ) ;
break ;
default : /* unknown */
sprintf ( func_name , " <fn?>( " ) ;
break ;
}
2009-04-17 02:13:35 +00:00
uiDefBut ( block , LABEL , 1 , func_name , 85 , cy , 40 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-03-17 00:31:10 +00:00
/* coefficients inside bracket */
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 120 , cy , 75 , 20 , cp + 1 , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Coefficient (B) of x " ) ;
2009-03-17 00:31:10 +00:00
2009-04-17 02:13:35 +00:00
uiDefBut ( block , LABEL , 1 , " x+ " , 195 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-03-17 00:31:10 +00:00
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 225 , cy , 80 , 20 , cp + 2 , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " Coefficient (C) of function " ) ;
2009-03-17 00:31:10 +00:00
/* closing bracket */
uiDefBut ( block , LABEL , 1 , " ) " , 300 , cy , 30 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
cy - = 20 ;
}
2009-03-16 11:43:02 +00:00
}
break ;
2009-03-16 01:12:37 +00:00
case FCM_GENERATOR_EXPRESSION : /* py-expression */
// TODO...
break ;
}
}
2009-03-21 03:49:22 +00:00
/* --------------- */
/* draw settings for cycles modifier */
2009-03-17 06:37:50 +00:00
static void draw_modifier__cycles ( uiBlock * block , FCurve * fcu , FModifier * fcm , int * yco , short * height , short width , short active , int rb_col )
{
FMod_Cycles * data = ( FMod_Cycles * ) fcm - > data ;
2009-05-04 10:04:46 +00:00
char cyc_mode [ ] = " Cycling Mode%t|No Cycles%x0|Repeat Motion%x1|Repeat with Offset%x2|Repeat Mirrored%x3 " ;
2009-03-17 06:37:50 +00:00
int cy = ( * yco - 30 ) , cy1 = ( * yco - 50 ) , cy2 = ( * yco - 70 ) ;
/* set the height */
2009-04-17 02:13:35 +00:00
( * height ) = 80 ;
2009-03-17 06:37:50 +00:00
/* basic settings (backdrop + some padding) */
2009-04-17 02:13:35 +00:00
DRAW_BACKDROP ( ( * height ) ) ;
2009-03-17 06:37:50 +00:00
/* 'before' range */
2009-04-19 12:26:31 +00:00
uiDefBut ( block , LABEL , 1 , " Before: " , 4 , cy , 80 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " Settings for cycling before first keyframe " ) ;
2009-03-17 06:37:50 +00:00
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButS ( block , MENU , B_FMODIFIER_REDRAW , cyc_mode , 3 , cy1 , 150 , 20 , & data - > before_mode , 0 , 0 , 0 , 0 , " Cycling mode to use before first keyframe " ) ;
uiDefButS ( block , NUM , B_FMODIFIER_REDRAW , " Max Cycles: " , 3 , cy2 , 150 , 20 , & data - > before_cycles , 0 , 10000 , 10 , 3 , " Maximum number of cycles to allow (0 = infinite) " ) ;
2009-03-17 06:37:50 +00:00
uiBlockEndAlign ( block ) ;
/* 'after' range */
2009-04-17 02:13:35 +00:00
uiDefBut ( block , LABEL , 1 , " After: " , 155 , cy , 80 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " Settings for cycling after last keyframe " ) ;
2009-03-17 06:37:50 +00:00
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButS ( block , MENU , B_FMODIFIER_REDRAW , cyc_mode , 157 , cy1 , 150 , 20 , & data - > after_mode , 0 , 0 , 0 , 0 , " Cycling mode to use after first keyframe " ) ;
uiDefButS ( block , NUM , B_FMODIFIER_REDRAW , " Max Cycles: " , 157 , cy2 , 150 , 20 , & data - > after_cycles , 0 , 10000 , 10 , 3 , " Maximum number of cycles to allow (0 = infinite) " ) ;
2009-03-17 06:37:50 +00:00
uiBlockEndAlign ( block ) ;
}
2009-02-22 09:30:18 +00:00
2009-03-21 03:49:22 +00:00
/* --------------- */
2009-05-02 04:20:36 +00:00
/* draw settings for noise modifier */
static void draw_modifier__noise ( uiBlock * block , FCurve * fcu , FModifier * fcm , int * yco , short * height , short width , short active , int rb_col )
{
FMod_Noise * data = ( FMod_Noise * ) fcm - > data ;
int cy = ( * yco - 30 ) , cy1 = ( * yco - 50 ) , cy2 = ( * yco - 70 ) ;
char cyc_mode [ ] = " Modification %t|Replace %x0|Add %x1|Subtract %x2|Multiply %x3 " ;
/* set the height */
( * height ) = 80 ;
/* basic settings (backdrop + some padding) */
DRAW_BACKDROP ( ( * height ) ) ;
uiDefButS ( block , MENU , B_FMODIFIER_REDRAW , cyc_mode ,
3 , cy , 150 , 20 , & data - > modification , 0 , 0 , 0 , 0 , " Method of modifying the existing F-Curve use before first keyframe " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Size: " ,
3 , cy1 , 150 , 20 , & data - > size , 0.000001 , 10000.0 , 0.01 , 3 , " " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Strength: " ,
3 , cy2 , 150 , 20 , & data - > strength , 0.0 , 10000.0 , 0.01 , 3 , " " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Phase: " ,
155 , cy1 , 150 , 20 , & data - > phase , 0.0 , 100000.0 , 0.1 , 3 , " " ) ;
uiDefButS ( block , NUM , B_FMODIFIER_REDRAW , " Depth: " ,
155 , cy2 , 150 , 20 , & data - > depth , 0 , 128 , 1 , 3 , " " ) ;
}
/* --------------- */
2009-03-21 03:49:22 +00:00
# define BINARYSEARCH_FRAMEEQ_THRESH 0.0001
/* Binary search algorithm for finding where to insert Envelope Data Point.
* Returns the index to insert at ( data already at that index will be offset if replace is 0 )
*/
static int binarysearch_fcm_envelopedata_index ( FCM_EnvelopeData array [ ] , float frame , int arraylen , short * exists )
{
int start = 0 , end = arraylen ;
int loopbreaker = 0 , maxloop = arraylen * 2 ;
/* initialise exists-flag first */
* exists = 0 ;
/* sneaky optimisations (don't go through searching process if...):
* - keyframe to be added is to be added out of current bounds
* - keyframe to be added would replace one of the existing ones on bounds
*/
if ( ( arraylen < = 0 ) | | ( array = = NULL ) ) {
printf ( " Warning: binarysearch_fcm_envelopedata_index() encountered invalid array \n " ) ;
return 0 ;
}
else {
/* check whether to add before/after/on */
float framenum ;
/* 'First' Point (when only one point, this case is used) */
framenum = array [ 0 ] . time ;
if ( IS_EQT ( frame , framenum , BINARYSEARCH_FRAMEEQ_THRESH ) ) {
* exists = 1 ;
return 0 ;
}
else if ( frame < framenum )
return 0 ;
/* 'Last' Point */
framenum = array [ ( arraylen - 1 ) ] . time ;
if ( IS_EQT ( frame , framenum , BINARYSEARCH_FRAMEEQ_THRESH ) ) {
* exists = 1 ;
return ( arraylen - 1 ) ;
}
else if ( frame > framenum )
return arraylen ;
}
/* most of the time, this loop is just to find where to put it
* - ' loopbreaker ' is just here to prevent infinite loops
*/
for ( loopbreaker = 0 ; ( start < = end ) & & ( loopbreaker < maxloop ) ; loopbreaker + + ) {
/* compute and get midpoint */
int mid = start + ( ( end - start ) / 2 ) ; /* we calculate the midpoint this way to avoid int overflows... */
float midfra = array [ mid ] . time ;
/* check if exactly equal to midpoint */
if ( IS_EQT ( frame , midfra , BINARYSEARCH_FRAMEEQ_THRESH ) ) {
* exists = 1 ;
return mid ;
}
/* repeat in upper/lower half */
if ( frame > midfra )
start = mid + 1 ;
else if ( frame < midfra )
end = mid - 1 ;
}
/* print error if loop-limit exceeded */
if ( loopbreaker = = ( maxloop - 1 ) ) {
printf ( " Error: binarysearch_fcm_envelopedata_index() was taking too long \n " ) ;
// include debug info
printf ( " \t round = %d: start = %d, end = %d, arraylen = %d \n " , loopbreaker , start , end , arraylen ) ;
}
/* not found, so return where to place it */
return start ;
}
/* callback to add new envelope data point */
// TODO: should we have a separate file for things like this?
static void fmod_envelope_addpoint_cb ( bContext * C , void * fcm_dv , void * dummy )
{
Scene * scene = CTX_data_scene ( C ) ;
FMod_Envelope * env = ( FMod_Envelope * ) fcm_dv ;
FCM_EnvelopeData * fedn ;
FCM_EnvelopeData fed ;
/* init template data */
fed . min = - 1.0f ;
fed . max = 1.0f ;
fed . time = ( float ) scene - > r . cfra ; // XXX make this int for ease of use?
fed . f1 = fed . f2 = 0 ;
/* check that no data exists for the current frame... */
if ( env - > data ) {
short exists = - 1 ;
int i = binarysearch_fcm_envelopedata_index ( env - > data , ( float ) ( scene - > r . cfra ) , env - > totvert , & exists ) ;
/* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
if ( exists )
return ;
/* add new */
fedn = MEM_callocN ( ( env - > totvert + 1 ) * sizeof ( FCM_EnvelopeData ) , " FCM_EnvelopeData " ) ;
/* add the points that should occur before the point to be pasted */
if ( i > 0 )
memcpy ( fedn , env - > data , i * sizeof ( FCM_EnvelopeData ) ) ;
/* add point to paste at index i */
* ( fedn + i ) = fed ;
/* add the points that occur after the point to be pasted */
if ( i < env - > totvert )
memcpy ( fedn + i + 1 , env - > data + i , ( env - > totvert - i ) * sizeof ( FCM_EnvelopeData ) ) ;
/* replace (+ free) old with new */
MEM_freeN ( env - > data ) ;
env - > data = fedn ;
env - > totvert + + ;
}
else {
env - > data = MEM_callocN ( sizeof ( FCM_EnvelopeData ) , " FCM_EnvelopeData " ) ;
* ( env - > data ) = fed ;
env - > totvert = 1 ;
}
}
/* callback to remove envelope data point */
// TODO: should we have a separate file for things like this?
static void fmod_envelope_deletepoint_cb ( bContext * C , void * fcm_dv , void * ind_v )
{
FMod_Envelope * env = ( FMod_Envelope * ) fcm_dv ;
FCM_EnvelopeData * fedn ;
int index = GET_INT_FROM_POINTER ( ind_v ) ;
/* check that no data exists for the current frame... */
if ( env - > totvert > 1 ) {
/* allocate a new smaller array */
fedn = MEM_callocN ( sizeof ( FCM_EnvelopeData ) * ( env - > totvert - 1 ) , " FCM_EnvelopeData " ) ;
memcpy ( fedn , & env - > data , sizeof ( FCM_EnvelopeData ) * ( index ) ) ;
memcpy ( & fedn [ index ] , & env - > data [ index + 1 ] , sizeof ( FCM_EnvelopeData ) * ( env - > totvert - index - 1 ) ) ;
/* free old array, and set the new */
MEM_freeN ( env - > data ) ;
env - > data = fedn ;
env - > totvert - - ;
}
else {
/* just free array, since the only vert was deleted */
if ( env - > data )
MEM_freeN ( env - > data ) ;
env - > totvert = 0 ;
}
}
/* draw settings for envelope modifier */
static void draw_modifier__envelope ( uiBlock * block , FCurve * fcu , FModifier * fcm , int * yco , short * height , short width , short active , int rb_col )
{
FMod_Envelope * env = ( FMod_Envelope * ) fcm - > data ;
FCM_EnvelopeData * fed ;
uiBut * but ;
2009-04-17 02:13:35 +00:00
int cy = ( * yco - 28 ) ;
2009-03-21 03:49:22 +00:00
int i ;
/* set the height:
* - basic settings + variable height from envelope controls
*/
2009-04-17 02:13:35 +00:00
( * height ) = 115 + ( 35 * env - > totvert ) ;
2009-03-21 03:49:22 +00:00
/* basic settings (backdrop + general settings + some padding) */
2009-04-17 02:13:35 +00:00
DRAW_BACKDROP ( ( * height ) ) ;
2009-03-21 03:49:22 +00:00
/* General Settings */
uiDefBut ( block , LABEL , 1 , " Envelope: " , 10 , cy , 100 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " Settings for cycling before first keyframe " ) ;
cy - = 20 ;
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Reference Val: " , 10 , cy , 300 , 20 , & env - > midval , - UI_FLT_MAX , UI_FLT_MAX , 10 , 3 , " " ) ;
2009-03-21 03:49:22 +00:00
cy - = 20 ;
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Min: " , 10 , cy , 150 , 20 , & env - > min , - UI_FLT_MAX , env - > max , 10 , 3 , " Minimum value (relative to Reference Value) that is used as the 'normal' minimum value " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Max: " , 160 , cy , 150 , 20 , & env - > max , env - > min , UI_FLT_MAX , 10 , 3 , " Maximum value (relative to Reference Value) that is used as the 'normal' maximum value " ) ;
2009-03-21 03:49:22 +00:00
cy - = 35 ;
uiBlockEndAlign ( block ) ;
/* Points header */
uiDefBut ( block , LABEL , 1 , " Control Points: " , 10 , cy , 150 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " " ) ;
but = uiDefBut ( block , BUT , B_FMODIFIER_REDRAW , " Add Point " , 160 , cy , 150 , 19 , NULL , 0 , 0 , 0 , 0 , " Adds a new control-point to the envelope on the current frame " ) ;
uiButSetFunc ( but , fmod_envelope_addpoint_cb , env , NULL ) ;
cy - = 35 ;
/* Points List */
for ( i = 0 , fed = env - > data ; i < env - > totvert ; i + + , fed + + ) {
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
but = uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Fra: " , 2 , cy , 90 , 20 , & fed - > time , - UI_FLT_MAX , UI_FLT_MAX , 10 , 1 , " Frame that envelope point occurs " ) ;
2009-03-21 03:49:22 +00:00
uiButSetFunc ( but , validate_fmodifier_cb , fcu , fcm ) ;
2009-04-19 12:26:31 +00:00
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Min: " , 92 , cy , 100 , 20 , & fed - > min , - UI_FLT_MAX , UI_FLT_MAX , 10 , 2 , " Minimum bound of envelope at this point " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " Max: " , 192 , cy , 100 , 20 , & fed - > max , - UI_FLT_MAX , UI_FLT_MAX , 10 , 2 , " Maximum bound of envelope at this point " ) ;
2009-03-21 03:49:22 +00:00
2009-04-17 02:13:35 +00:00
but = uiDefIconBut ( block , BUT , B_FMODIFIER_REDRAW , ICON_X , 292 , cy , 18 , 20 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Delete envelope control point " ) ;
2009-03-21 03:49:22 +00:00
uiButSetFunc ( but , fmod_envelope_deletepoint_cb , env , SET_INT_IN_POINTER ( i ) ) ;
uiBlockBeginAlign ( block ) ;
cy - = 25 ;
}
}
/* --------------- */
2009-04-14 11:53:41 +00:00
/* draw settings for limits modifier */
static void draw_modifier__limits ( uiBlock * block , FCurve * fcu , FModifier * fcm , int * yco , short * height , short width , short active , int rb_col )
{
FMod_Limits * data = ( FMod_Limits * ) fcm - > data ;
const int togButWidth = 50 ;
const int textButWidth = ( ( width / 2 ) - togButWidth ) ;
/* set the height */
2009-04-19 12:26:31 +00:00
( * height ) = 60 ;
2009-04-14 11:53:41 +00:00
/* basic settings (backdrop + some padding) */
2009-04-17 02:13:35 +00:00
DRAW_BACKDROP ( ( * height ) ) ;
2009-04-14 11:53:41 +00:00
/* Draw Pairs of LimitToggle+LimitValue */
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButBitI ( block , TOGBUT , FCM_LIMIT_XMIN , B_FMODIFIER_REDRAW , " xMin " , 5 , * yco - 30 , togButWidth , 18 , & data - > flag , 0 , 24 , 0 , 0 , " Use minimum x value " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 5 + togButWidth , * yco - 30 , ( textButWidth - 5 ) , 18 , & data - > rect . xmin , - UI_FLT_MAX , UI_FLT_MAX , 0.1 , 0.5 , " Lowest x value to allow " ) ;
2009-04-14 11:53:41 +00:00
uiBlockEndAlign ( block ) ;
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButBitI ( block , TOGBUT , FCM_LIMIT_XMAX , B_FMODIFIER_REDRAW , " XMax " , 5 + ( width - ( textButWidth - 5 ) - togButWidth ) , * yco - 30 , 50 , 18 , & data - > flag , 0 , 24 , 0 , 0 , " Use maximum x value " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 5 + ( width - textButWidth - 5 ) , * yco - 30 , ( textButWidth - 5 ) , 18 , & data - > rect . xmax , - UI_FLT_MAX , UI_FLT_MAX , 0.1 , 0.5 , " Highest x value to allow " ) ;
2009-04-14 11:53:41 +00:00
uiBlockEndAlign ( block ) ;
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButBitI ( block , TOGBUT , FCM_LIMIT_YMIN , B_FMODIFIER_REDRAW , " yMin " , 5 , * yco - 52 , togButWidth , 18 , & data - > flag , 0 , 24 , 0 , 0 , " Use minimum y value " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 5 + togButWidth , * yco - 52 , ( textButWidth - 5 ) , 18 , & data - > rect . ymin , - UI_FLT_MAX , UI_FLT_MAX , 0.1 , 0.5 , " Lowest y value to allow " ) ;
2009-04-14 11:53:41 +00:00
uiBlockEndAlign ( block ) ;
uiBlockBeginAlign ( block ) ;
2009-04-19 12:26:31 +00:00
uiDefButBitI ( block , TOGBUT , FCM_LIMIT_YMAX , B_FMODIFIER_REDRAW , " YMax " , 5 + ( width - ( textButWidth - 5 ) - togButWidth ) , * yco - 52 , 50 , 18 , & data - > flag , 0 , 24 , 0 , 0 , " Use maximum y value " ) ;
uiDefButF ( block , NUM , B_FMODIFIER_REDRAW , " " , 5 + ( width - textButWidth - 5 ) , * yco - 52 , ( textButWidth - 5 ) , 18 , & data - > rect . ymax , - UI_FLT_MAX , UI_FLT_MAX , 0.1 , 0.5 , " Highest y value to allow " ) ;
2009-04-14 11:53:41 +00:00
uiBlockEndAlign ( block ) ;
}
/* --------------- */
2009-03-15 10:39:02 +00:00
static void graph_panel_modifier_draw ( uiBlock * block , FCurve * fcu , FModifier * fcm , int * yco )
{
FModifierTypeInfo * fmi = fmodifier_get_typeinfo ( fcm ) ;
uiBut * but ;
short active = ( fcm - > flag & FMODIFIER_FLAG_ACTIVE ) ;
short width = 314 ;
short height = 0 ;
int rb_col ;
/* draw header */
{
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
/* rounded header */
2009-04-17 02:13:35 +00:00
rb_col = ( active ) ? - 20 : 20 ;
but = uiDefBut ( block , ROUNDBOX , B_REDR , " " , 0 , * yco - 2 , width , 24 , NULL , 5.0 , 0.0 , 15.0 , ( float ) ( rb_col - 20 ) , " " ) ;
2009-03-15 10:39:02 +00:00
/* expand */
2009-05-02 04:51:14 +00:00
uiDefIconButBitS ( block , ICONTOG , FMODIFIER_FLAG_EXPANDED , B_REDR , ICON_TRIA_RIGHT , 5 , * yco - 1 , 20 , 20 , & fcm - > flag , 0.0 , 0.0 , 0 , 0 , " Modifier is expanded. " ) ;
2009-03-21 03:49:22 +00:00
/* checkbox for 'active' status (for now) */
2009-05-02 04:51:14 +00:00
but = uiDefIconButBitS ( block , ICONTOG , FMODIFIER_FLAG_ACTIVE , B_REDR , ICON_RADIOBUT_OFF , 25 , * yco - 1 , 20 , 20 , & fcm - > flag , 0.0 , 0.0 , 0 , 0 , " Modifier is active one. " ) ;
2009-03-21 03:49:22 +00:00
uiButSetFunc ( but , activate_fmodifier_cb , fcu , fcm ) ;
2009-03-15 10:39:02 +00:00
/* name */
if ( fmi )
2009-05-02 04:51:14 +00:00
uiDefBut ( block , LABEL , 1 , fmi - > name , 10 + 40 , * yco , 150 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " F-Curve Modifier Type. Click to make modifier active one. " ) ;
2009-03-15 10:39:02 +00:00
else
2009-05-02 04:51:14 +00:00
uiDefBut ( block , LABEL , 1 , " <Unknown Modifier> " , 10 + 40 , * yco , 150 , 20 , NULL , 0.0 , 0.0 , 0 , 0 , " F-Curve Modifier Type. Click to make modifier active one. " ) ;
/* 'mute' button */
uiDefIconButBitS ( block , ICONTOG , FMODIFIER_FLAG_MUTED , B_REDR , ICON_MUTE_IPO_OFF , 10 + ( width - 60 ) , * yco - 1 , 20 , 20 , & fcm - > flag , 0.0 , 0.0 , 0 , 0 , " Modifier is temporarily muted (not evaluated). " ) ;
2009-03-15 10:39:02 +00:00
/* delete button */
2009-03-18 10:58:18 +00:00
but = uiDefIconBut ( block , BUT , B_REDR , ICON_X , 10 + ( width - 30 ) , * yco , 19 , 19 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Delete F-Curve Modifier. " ) ;
2009-03-17 06:37:50 +00:00
uiButSetFunc ( but , delete_fmodifier_cb , fcu , fcm ) ;
2009-03-16 11:11:44 +00:00
2009-03-15 10:39:02 +00:00
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
2009-02-22 09:30:18 +00:00
}
2009-03-15 10:39:02 +00:00
/* when modifier is expanded, draw settings */
if ( fcm - > flag & FMODIFIER_FLAG_EXPANDED ) {
2009-03-16 01:12:37 +00:00
/* draw settings for individual modifiers */
switch ( fcm - > type ) {
case FMODIFIER_TYPE_GENERATOR : /* Generator */
2009-03-17 06:37:50 +00:00
draw_modifier__generator ( block , fcu , fcm , yco , & height , width , active , rb_col ) ;
break ;
case FMODIFIER_TYPE_CYCLES : /* Cycles */
draw_modifier__cycles ( block , fcu , fcm , yco , & height , width , active , rb_col ) ;
2009-03-16 01:12:37 +00:00
break ;
2009-03-21 03:49:22 +00:00
case FMODIFIER_TYPE_ENVELOPE : /* Envelope */
draw_modifier__envelope ( block , fcu , fcm , yco , & height , width , active , rb_col ) ;
break ;
2009-04-14 11:53:41 +00:00
case FMODIFIER_TYPE_LIMITS : /* Limits */
draw_modifier__limits ( block , fcu , fcm , yco , & height , width , active , rb_col ) ;
break ;
2009-03-16 01:12:37 +00:00
2009-05-02 04:20:36 +00:00
case FMODIFIER_TYPE_NOISE : /* Noise */
draw_modifier__noise ( block , fcu , fcm , yco , & height , width , active , rb_col ) ;
break ;
2009-03-16 01:12:37 +00:00
default : /* unknown type */
2009-03-16 11:11:44 +00:00
height = 96 ;
//DRAW_BACKDROP(height); // XXX buggy...
2009-03-16 01:12:37 +00:00
break ;
}
2009-03-15 10:39:02 +00:00
}
/* adjust height for new to start */
( * yco ) - = ( height + 27 ) ;
2009-02-22 09:30:18 +00:00
}
static void graph_panel_modifiers ( const bContext * C , ARegion * ar , short cntrl , bAnimListElem * ale )
{
2009-03-15 10:39:02 +00:00
FCurve * fcu = ( FCurve * ) ale - > data ;
FModifier * fcm ;
2009-02-22 09:30:18 +00:00
uiBlock * block ;
2009-03-15 10:39:02 +00:00
int yco = 190 ;
2009-03-16 11:11:44 +00:00
2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
(was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
a several calls using different args.
Further just added the missing includes, and removed unused vars.
2009-04-14 15:59:52 +00:00
block = uiBeginBlock ( C , ar , " graph_panel_modifiers " , UI_EMBOSS ) ;
2009-02-22 09:30:18 +00:00
if ( uiNewPanel ( C , ar , block , " Modifiers " , " Graph " , 340 , 30 , 318 , 254 ) = = 0 ) return ;
uiBlockSetHandleFunc ( block , do_graph_region_modifier_buttons , NULL ) ;
2009-03-16 11:11:44 +00:00
uiNewPanelHeight ( block , 204 ) ;
2009-03-15 10:39:02 +00:00
/* 'add modifier' button at top of panel */
// XXX for now, this will be a operator button which calls a temporary 'add modifier' operator
uiDefButO ( block , BUT , " GRAPHEDIT_OT_fmodifier_add " , WM_OP_INVOKE_REGION_WIN , " Add Modifier " , 10 , 225 , 150 , 20 , " Adds a new F-Curve Modifier for the active F-Curve " ) ;
/* draw each modifier */
for ( fcm = fcu - > modifiers . first ; fcm ; fcm = fcm - > next )
graph_panel_modifier_draw ( block , fcu , fcm , & yco ) ;
2009-02-22 09:30:18 +00:00
2009-03-15 10:39:02 +00:00
/* since these buttons can have variable height */
if ( yco < 0 )
uiNewPanelHeight ( block , ( 204 - yco ) ) ;
else
uiNewPanelHeight ( block , 204 ) ;
2009-02-22 09:30:18 +00:00
}
2009-03-21 03:49:22 +00:00
/* ******************* general ******************************** */
2009-02-22 09:30:18 +00:00
2009-02-21 11:22:06 +00:00
/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
* We return the ' wrapper ' since it contains valuable context info ( about hierarchy ) , which will need to be freed
* when the caller is done with it .
*/
// TODO: move this to anim api with another name?
2009-03-15 10:39:02 +00:00
bAnimListElem * get_active_fcurve_channel ( bAnimContext * ac )
2009-02-21 11:22:06 +00:00
{
ListBase anim_data = { NULL , NULL } ;
int filter = ( ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE | ANIMFILTER_CURVESONLY ) ;
int items = ANIM_animdata_filter ( ac , & anim_data , filter , ac - > data , ac - > datatype ) ;
/* We take the first F-Curve only, since some other ones may have had 'active' flag set
* if they were from linked data .
*/
if ( items ) {
bAnimListElem * ale = ( bAnimListElem * ) anim_data . first ;
/* remove first item from list, then free the rest of the list and return the stored one */
BLI_remlink ( & anim_data , ale ) ;
BLI_freelistN ( & anim_data ) ;
return ale ;
}
/* no active F-Curve */
return NULL ;
}
2009-02-21 10:38:58 +00:00
void graph_region_buttons ( const bContext * C , ARegion * ar )
{
SpaceIpo * sipo = ( SpaceIpo * ) CTX_wm_space_data ( C ) ;
2009-02-21 11:22:06 +00:00
bAnimContext ac ;
bAnimListElem * ale = NULL ;
/* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
* to work correctly is able to be correctly retrieved . There ' s no point showing empty panels ?
*/
if ( ANIM_animdata_get_context ( C , & ac ) = = 0 )
return ;
2009-02-21 10:38:58 +00:00
2009-02-21 11:22:06 +00:00
/* try to find 'active' F-Curve */
ale = get_active_fcurve_channel ( & ac ) ;
if ( ale = = NULL )
return ;
2009-04-02 01:39:33 +00:00
uiBeginPanels ( C , ar ) ;
2009-02-22 09:30:18 +00:00
/* for now, the properties panel displays info about the selected channels */
2009-02-21 11:22:06 +00:00
graph_panel_properties ( C , ar , 0 , ale ) ;
2009-02-21 10:38:58 +00:00
/* driver settings for active F-Curve (only for 'Drivers' mode) */
2009-02-22 09:30:18 +00:00
if ( sipo - > mode = = SIPO_MODE_DRIVERS )
graph_panel_drivers ( C , ar , 0 , ale ) ;
/* modifiers */
graph_panel_modifiers ( C , ar , 0 , ale ) ;
2009-02-21 11:22:06 +00:00
2009-04-02 01:39:33 +00:00
uiEndPanels ( C , ar ) ;
2009-02-21 10:38:58 +00:00
2009-02-21 11:22:06 +00:00
/* free temp data */
MEM_freeN ( ale ) ;
2009-02-21 10:38:58 +00:00
}
static int graph_properties ( bContext * C , wmOperator * op )
{
ScrArea * sa = CTX_wm_area ( C ) ;
ARegion * ar = graph_has_buttons_region ( sa ) ;
if ( ar ) {
ar - > flag ^ = RGN_FLAG_HIDDEN ;
ar - > v2d . flag & = ~ V2D_IS_INITIALISED ; /* XXX should become hide/unhide api? */
ED_area_initialize ( CTX_wm_manager ( C ) , CTX_wm_window ( C ) , sa ) ;
ED_area_tag_redraw ( sa ) ;
}
return OPERATOR_FINISHED ;
}
void GRAPHEDIT_OT_properties ( wmOperatorType * ot )
{
ot - > name = " Properties " ;
ot - > idname = " GRAPHEDIT_OT_properties " ;
ot - > exec = graph_properties ;
ot - > poll = ED_operator_ipo_active ; // xxx
/* flags */
ot - > flag = 0 ;
}