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