Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2009 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation, Joshua Leung 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <string.h> 00033 #include <stdio.h> 00034 #include <math.h> 00035 #include <float.h> 00036 00037 #include "DNA_anim_types.h" 00038 00039 #include "BLI_utildefines.h" 00040 00041 #include "MEM_guardedalloc.h" 00042 00043 #include "BLI_math.h" 00044 #include "BLI_blenlib.h" 00045 #include "BLI_editVert.h" 00046 #include "BLI_rand.h" 00047 00048 #include "BLF_translation.h" 00049 00050 #include "BKE_nla.h" 00051 #include "BKE_context.h" 00052 #include "BKE_screen.h" 00053 00054 00055 #include "WM_api.h" 00056 #include "WM_types.h" 00057 00058 #include "RNA_access.h" 00059 00060 #include "ED_anim_api.h" 00061 #include "ED_screen.h" 00062 00063 #include "UI_interface.h" 00064 #include "UI_resources.h" 00065 00066 #include "nla_intern.h" // own include 00067 00068 00069 /* ******************* nla editor space & buttons ************** */ 00070 00071 #define B_NOP 1 00072 #define B_REDR 2 00073 00074 /* -------------- */ 00075 00076 static void do_nla_region_buttons(bContext *C, void *UNUSED(arg), int event) 00077 { 00078 //Scene *scene= CTX_data_scene(C); 00079 00080 switch(event) { 00081 00082 } 00083 00084 /* default for now */ 00085 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00086 WM_event_add_notifier(C, NC_SCENE|ND_TRANSFORM, NULL); 00087 } 00088 00089 static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr) 00090 { 00091 bAnimContext ac; 00092 bAnimListElem *ale= NULL; 00093 ListBase anim_data = {NULL, NULL}; 00094 short found=0; 00095 int filter; 00096 00097 /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools) 00098 * to work correctly is able to be correctly retrieved. There's no point showing empty panels? 00099 */ 00100 if (ANIM_animdata_get_context(C, &ac) == 0) 00101 return 0; 00102 00103 /* extract list of active channel(s), of which we should only take the first one 00104 * - we need the channels flag to get the active AnimData block when there are no NLA Tracks 00105 */ 00106 // XXX: double-check active! 00107 filter= (ANIMFILTER_DATA_VISIBLE|ANIMFILTER_LIST_VISIBLE|ANIMFILTER_ACTIVE|ANIMFILTER_LIST_CHANNELS); 00108 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); 00109 00110 for (ale= anim_data.first; ale; ale= ale->next) { 00111 switch (ale->type) { 00112 case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */ 00113 { 00114 NlaTrack *nlt= (NlaTrack *)ale->data; 00115 AnimData *adt= ale->adt; 00116 00117 /* found it, now set the pointers */ 00118 if (adt_ptr) { 00119 /* AnimData pointer */ 00120 RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr); 00121 } 00122 if (nlt_ptr) { 00123 /* NLA-Track pointer */ 00124 RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr); 00125 } 00126 if (strip_ptr) { 00127 /* NLA-Strip pointer */ 00128 NlaStrip *strip= BKE_nlastrip_find_active(nlt); 00129 RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr); 00130 } 00131 00132 found= 1; 00133 } 00134 break; 00135 00136 case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */ 00137 case ANIMTYPE_OBJECT: 00138 case ANIMTYPE_FILLACTD: /* Action Expander */ 00139 case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ 00140 case ANIMTYPE_DSLAM: 00141 case ANIMTYPE_DSCAM: 00142 case ANIMTYPE_DSCUR: 00143 case ANIMTYPE_DSSKEY: 00144 case ANIMTYPE_DSWOR: 00145 case ANIMTYPE_DSNTREE: 00146 case ANIMTYPE_DSPART: 00147 case ANIMTYPE_DSMBALL: 00148 case ANIMTYPE_DSARM: 00149 case ANIMTYPE_DSSPK: 00150 { 00151 /* for these channels, we only do AnimData */ 00152 if (ale->id && ale->adt) { 00153 if (adt_ptr) { 00154 /* AnimData pointer */ 00155 RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr); 00156 00157 /* set found status to -1, since setting to 1 would break the loop 00158 * and potentially skip an active NLA-Track in some cases... 00159 */ 00160 found= -1; 00161 } 00162 } 00163 } 00164 break; 00165 } 00166 00167 if (found > 0) 00168 break; 00169 } 00170 00171 /* free temp data */ 00172 BLI_freelistN(&anim_data); 00173 00174 return found; 00175 } 00176 00177 #if 0 00178 static int nla_panel_poll(const bContext *C, PanelType *pt) 00179 { 00180 return nla_panel_context(C, NULL, NULL); 00181 } 00182 #endif 00183 00184 static int nla_animdata_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00185 { 00186 PointerRNA ptr; 00187 return (nla_panel_context(C, &ptr, NULL, NULL) && (ptr.data != NULL)); 00188 } 00189 00190 static int nla_track_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00191 { 00192 PointerRNA ptr; 00193 return (nla_panel_context(C, NULL, &ptr, NULL) && (ptr.data != NULL)); 00194 } 00195 00196 static int nla_strip_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00197 { 00198 PointerRNA ptr; 00199 return (nla_panel_context(C, NULL, NULL, &ptr) && (ptr.data != NULL)); 00200 } 00201 00202 static int nla_strip_actclip_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00203 { 00204 PointerRNA ptr; 00205 NlaStrip *strip; 00206 00207 if (!nla_panel_context(C, NULL, NULL, &ptr)) 00208 return 0; 00209 if (ptr.data == NULL) 00210 return 0; 00211 00212 strip= ptr.data; 00213 return (strip->type == NLASTRIP_TYPE_CLIP); 00214 } 00215 00216 static int nla_strip_eval_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00217 { 00218 PointerRNA ptr; 00219 NlaStrip *strip; 00220 00221 if (!nla_panel_context(C, NULL, NULL, &ptr)) 00222 return 0; 00223 if (ptr.data == NULL) 00224 return 0; 00225 00226 strip= ptr.data; 00227 00228 if (strip->type == NLASTRIP_TYPE_SOUND) 00229 return 0; 00230 00231 return 1; 00232 } 00233 00234 /* -------------- */ 00235 00236 /* active AnimData */ 00237 static void nla_panel_animdata (const bContext *C, Panel *pa) 00238 { 00239 PointerRNA adt_ptr; 00240 /* AnimData *adt; */ 00241 uiLayout *layout= pa->layout; 00242 uiLayout *row; 00243 uiBlock *block; 00244 00245 /* check context and also validity of pointer */ 00246 if (!nla_panel_context(C, &adt_ptr, NULL, NULL)) 00247 return; 00248 00249 /* adt= adt_ptr.data; */ 00250 00251 block= uiLayoutGetBlock(layout); 00252 uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); 00253 00254 /* Active Action Properties ------------------------------------- */ 00255 /* action */ 00256 row= uiLayoutRow(layout, 1); 00257 uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, NULL /*"ACTION_OT_unlink"*/); // XXX: need to make these operators 00258 00259 /* extrapolation */ 00260 row= uiLayoutRow(layout, 1); 00261 uiItemR(row, &adt_ptr, "action_extrapolation", 0, NULL, ICON_NONE); 00262 00263 /* blending */ 00264 row= uiLayoutRow(layout, 1); 00265 uiItemR(row, &adt_ptr, "action_blend_type", 0, NULL, ICON_NONE); 00266 00267 /* influence */ 00268 row= uiLayoutRow(layout, 1); 00269 uiItemR(row, &adt_ptr, "action_influence", 0, NULL, ICON_NONE); 00270 } 00271 00272 /* active NLA-Track */ 00273 static void nla_panel_track (const bContext *C, Panel *pa) 00274 { 00275 PointerRNA nlt_ptr; 00276 uiLayout *layout= pa->layout; 00277 uiLayout *row; 00278 uiBlock *block; 00279 00280 /* check context and also validity of pointer */ 00281 if (!nla_panel_context(C, NULL, &nlt_ptr, NULL)) 00282 return; 00283 00284 block= uiLayoutGetBlock(layout); 00285 uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); 00286 00287 /* Info - Active NLA-Context:Track ---------------------- */ 00288 row= uiLayoutRow(layout, 1); 00289 uiItemR(row, &nlt_ptr, "name", 0, NULL, ICON_NLA); 00290 } 00291 00292 /* generic settings for active NLA-Strip */ 00293 static void nla_panel_properties(const bContext *C, Panel *pa) 00294 { 00295 PointerRNA strip_ptr; 00296 uiLayout *layout= pa->layout; 00297 uiLayout *column, *row, *sub; 00298 uiBlock *block; 00299 short showEvalProps = 1; 00300 00301 if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) 00302 return; 00303 00304 block= uiLayoutGetBlock(layout); 00305 uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); 00306 00307 /* Strip Properties ------------------------------------- */ 00308 /* strip type */ 00309 row= uiLayoutColumn(layout, 1); 00310 uiItemR(row, &strip_ptr, "name", 0, NULL, ICON_NLA); // XXX icon? 00311 uiItemR(row, &strip_ptr, "type", 0, NULL, ICON_NONE); 00312 00313 /* strip extents */ 00314 column= uiLayoutColumn(layout, 1); 00315 uiItemL(column, "Strip Extents:", ICON_NONE); 00316 uiItemR(column, &strip_ptr, "frame_start", 0, NULL, ICON_NONE); 00317 uiItemR(column, &strip_ptr, "frame_end", 0, NULL, ICON_NONE); 00318 00319 /* Evaluation-Related Strip Properties ------------------ */ 00320 00321 /* sound properties strips don't have these settings */ 00322 if (RNA_enum_get(&strip_ptr, "type") == NLASTRIP_TYPE_SOUND) 00323 showEvalProps = 0; 00324 00325 /* only show if allowed to... */ 00326 if (showEvalProps) { 00327 /* extrapolation */ 00328 row= uiLayoutRow(layout, 1); 00329 uiItemR(row, &strip_ptr, "extrapolation", 0, NULL, ICON_NONE); 00330 00331 /* blending */ 00332 row= uiLayoutRow(layout, 1); 00333 uiItemR(row, &strip_ptr, "blend_type", 0, NULL, ICON_NONE); 00334 00335 /* blend in/out + autoblending 00336 * - blend in/out can only be set when autoblending is off 00337 */ 00338 column= uiLayoutColumn(layout, 1); 00339 uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_influence")==0); 00340 uiItemR(column, &strip_ptr, "use_auto_blend", 0, NULL, ICON_NONE); // XXX as toggle? 00341 00342 sub= uiLayoutColumn(column, 1); 00343 uiLayoutSetActive(sub, RNA_boolean_get(&strip_ptr, "use_auto_blend")==0); 00344 uiItemR(sub, &strip_ptr, "blend_in", 0, NULL, ICON_NONE); 00345 uiItemR(sub, &strip_ptr, "blend_out", 0, NULL, ICON_NONE); 00346 00347 /* settings */ 00348 column= uiLayoutColumn(layout, 1); 00349 uiLayoutSetActive(column, !(RNA_boolean_get(&strip_ptr, "use_animated_influence") || RNA_boolean_get(&strip_ptr, "use_animated_time"))); 00350 uiItemL(column, "Playback Settings:", ICON_NONE); 00351 uiItemR(column, &strip_ptr, "mute", 0, NULL, ICON_NONE); 00352 uiItemR(column, &strip_ptr, "use_reverse", 0, NULL, ICON_NONE); 00353 } 00354 } 00355 00356 00357 /* action-clip only settings for active NLA-Strip */ 00358 static void nla_panel_actclip(const bContext *C, Panel *pa) 00359 { 00360 PointerRNA strip_ptr; 00361 uiLayout *layout= pa->layout; 00362 uiLayout *column, *row; 00363 uiBlock *block; 00364 00365 /* check context and also validity of pointer */ 00366 if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) 00367 return; 00368 00369 block= uiLayoutGetBlock(layout); 00370 uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); 00371 00372 /* Strip Properties ------------------------------------- */ 00373 /* action pointer */ 00374 row= uiLayoutRow(layout, 1); 00375 uiItemR(row, &strip_ptr, "action", 0, NULL, ICON_ACTION); 00376 00377 /* action extents */ 00378 // XXX custom names were used here (to avoid the prefixes)... probably not necessary in future? 00379 column= uiLayoutColumn(layout, 1); 00380 uiItemL(column, "Action Extents:", ICON_NONE); 00381 uiItemR(column, &strip_ptr, "action_frame_start", 0, "Start Frame", ICON_NONE); 00382 uiItemR(column, &strip_ptr, "action_frame_end", 0, "End Frame", ICON_NONE); 00383 uiItemO(column, NULL, ICON_NONE, "NLA_OT_action_sync_length"); 00384 00385 /* action usage */ 00386 column= uiLayoutColumn(layout, 1); 00387 uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_time")==0); 00388 uiItemL(column, "Playback Settings:", ICON_NONE); 00389 uiItemR(column, &strip_ptr, "scale", 0, NULL, ICON_NONE); 00390 uiItemR(column, &strip_ptr, "repeat", 0, NULL, ICON_NONE); 00391 } 00392 00393 /* evaluation settings for active NLA-Strip */ 00394 static void nla_panel_evaluation(const bContext *C, Panel *pa) 00395 { 00396 PointerRNA strip_ptr; 00397 uiLayout *layout= pa->layout; 00398 uiLayout *col, *sub; 00399 uiBlock *block; 00400 00401 /* check context and also validity of pointer */ 00402 if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) 00403 return; 00404 00405 block= uiLayoutGetBlock(layout); 00406 uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); 00407 00408 col= uiLayoutColumn(layout, 1); 00409 uiItemR(col, &strip_ptr, "use_animated_influence", 0, NULL, ICON_NONE); 00410 00411 sub= uiLayoutColumn(col, 1); 00412 uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_influence")); 00413 uiItemR(sub, &strip_ptr, "influence", 0, NULL, ICON_NONE); 00414 00415 col= uiLayoutColumn(layout, 1); 00416 sub= uiLayoutRow(col, 0); 00417 uiItemR(sub, &strip_ptr, "use_animated_time", 0, NULL, ICON_NONE); 00418 uiItemR(sub, &strip_ptr, "use_animated_time_cyclic", 0, NULL, ICON_NONE); 00419 00420 sub= uiLayoutRow(col, 0); 00421 uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_time")); 00422 uiItemR(sub, &strip_ptr, "strip_time", 0, NULL, ICON_NONE); 00423 } 00424 00425 /* F-Modifiers for active NLA-Strip */ 00426 static void nla_panel_modifiers(const bContext *C, Panel *pa) 00427 { 00428 PointerRNA strip_ptr; 00429 NlaStrip *strip; 00430 FModifier *fcm; 00431 uiLayout *col, *row; 00432 uiBlock *block; 00433 00434 /* check context and also validity of pointer */ 00435 if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) 00436 return; 00437 strip= strip_ptr.data; 00438 00439 block= uiLayoutGetBlock(pa->layout); 00440 uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); 00441 00442 /* 'add modifier' button at top of panel */ 00443 { 00444 row= uiLayoutRow(pa->layout, 0); 00445 block= uiLayoutGetBlock(row); 00446 00447 // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator 00448 // FIXME: we need to set the only-active property so that this will only add modifiers for the active strip (not all selected) 00449 uiDefButO(block, BUT, "NLA_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20, 00450 TIP_("Adds a new F-Modifier for the active NLA Strip")); 00451 00452 /* copy/paste (as sub-row)*/ 00453 row= uiLayoutRow(row, 1); 00454 uiItemO(row, "", ICON_COPYDOWN, "NLA_OT_fmodifier_copy"); 00455 uiItemO(row, "", ICON_PASTEDOWN, "NLA_OT_fmodifier_paste"); 00456 } 00457 00458 /* draw each modifier */ 00459 for (fcm= strip->modifiers.first; fcm; fcm= fcm->next) { 00460 col= uiLayoutColumn(pa->layout, 1); 00461 00462 ANIM_uiTemplate_fmodifier_draw(col, strip_ptr.id.data, &strip->modifiers, fcm); 00463 } 00464 } 00465 00466 /* ******************* general ******************************** */ 00467 00468 00469 void nla_buttons_register(ARegionType *art) 00470 { 00471 PanelType *pt; 00472 00473 pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel animdata"); 00474 strcpy(pt->idname, "NLA_PT_animdata"); 00475 strcpy(pt->label, "Animation Data"); 00476 pt->draw= nla_panel_animdata; 00477 pt->poll= nla_animdata_panel_poll; 00478 pt->flag= PNL_DEFAULT_CLOSED; 00479 BLI_addtail(&art->paneltypes, pt); 00480 00481 pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel track"); 00482 strcpy(pt->idname, "NLA_PT_track"); 00483 strcpy(pt->label, "Active Track"); 00484 pt->draw= nla_panel_track; 00485 pt->poll= nla_track_panel_poll; 00486 BLI_addtail(&art->paneltypes, pt); 00487 00488 pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel properties"); 00489 strcpy(pt->idname, "NLA_PT_properties"); 00490 strcpy(pt->label, "Active Strip"); 00491 pt->draw= nla_panel_properties; 00492 pt->poll= nla_strip_panel_poll; 00493 BLI_addtail(&art->paneltypes, pt); 00494 00495 pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel properties"); 00496 strcpy(pt->idname, "NLA_PT_actionclip"); 00497 strcpy(pt->label, "Action Clip"); 00498 pt->draw= nla_panel_actclip; 00499 pt->poll= nla_strip_actclip_panel_poll; 00500 BLI_addtail(&art->paneltypes, pt); 00501 00502 pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel evaluation"); 00503 strcpy(pt->idname, "NLA_PT_evaluation"); 00504 strcpy(pt->label, "Evaluation"); 00505 pt->draw= nla_panel_evaluation; 00506 pt->poll= nla_strip_eval_panel_poll; 00507 BLI_addtail(&art->paneltypes, pt); 00508 00509 pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel modifiers"); 00510 strcpy(pt->idname, "NLA_PT_modifiers"); 00511 strcpy(pt->label, "Modifiers"); 00512 pt->draw= nla_panel_modifiers; 00513 pt->poll= nla_strip_eval_panel_poll; 00514 BLI_addtail(&art->paneltypes, pt); 00515 } 00516 00517 static int nla_properties(bContext *C, wmOperator *UNUSED(op)) 00518 { 00519 ScrArea *sa= CTX_wm_area(C); 00520 ARegion *ar= nla_has_buttons_region(sa); 00521 00522 if(ar) 00523 ED_region_toggle_hidden(C, ar); 00524 00525 return OPERATOR_FINISHED; 00526 } 00527 00528 void NLA_OT_properties(wmOperatorType *ot) 00529 { 00530 ot->name= "Properties"; 00531 ot->idname= "NLA_OT_properties"; 00532 ot->description= "Toggle display properties panel"; 00533 00534 ot->exec= nla_properties; 00535 ot->poll= ED_operator_nla_active; 00536 00537 /* flags */ 00538 ot->flag= 0; 00539 }