|
Blender
V2.59
|
00001 /* 00002 * $Id: space_nla.c 36788 2011-05-20 05:27:31Z 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) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <string.h> 00035 #include <stdio.h> 00036 00037 #include "DNA_anim_types.h" 00038 #include "DNA_scene_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_math.h" 00044 #include "BLI_rand.h" 00045 #include "BLI_utildefines.h" 00046 00047 #include "BKE_context.h" 00048 #include "BKE_global.h" 00049 #include "BKE_main.h" 00050 #include "BKE_screen.h" 00051 00052 #include "ED_space_api.h" 00053 #include "ED_anim_api.h" 00054 #include "ED_markers.h" 00055 #include "ED_screen.h" 00056 00057 #include "BIF_gl.h" 00058 00059 #include "WM_api.h" 00060 #include "WM_types.h" 00061 00062 #include "UI_resources.h" 00063 #include "UI_view2d.h" 00064 00065 #include "nla_intern.h" // own include 00066 00067 /* ******************** manage regions ********************* */ 00068 00069 ARegion *nla_has_buttons_region(ScrArea *sa) 00070 { 00071 ARegion *ar, *arnew; 00072 00073 ar= BKE_area_find_region_type(sa, RGN_TYPE_UI); 00074 if(ar) return ar; 00075 00076 /* add subdiv level; after main */ 00077 ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); 00078 00079 /* is error! */ 00080 if (ar==NULL) return NULL; 00081 00082 arnew= MEM_callocN(sizeof(ARegion), "buttons for nla"); 00083 00084 BLI_insertlinkafter(&sa->regionbase, ar, arnew); 00085 arnew->regiontype= RGN_TYPE_UI; 00086 arnew->alignment= RGN_ALIGN_RIGHT; 00087 00088 arnew->flag = RGN_FLAG_HIDDEN; 00089 00090 return arnew; 00091 } 00092 00093 00094 00095 /* ******************** default callbacks for nla space ***************** */ 00096 00097 static SpaceLink *nla_new(const bContext *C) 00098 { 00099 Scene *scene= CTX_data_scene(C); 00100 ScrArea *sa= CTX_wm_area(C); 00101 ARegion *ar; 00102 SpaceNla *snla; 00103 00104 snla= MEM_callocN(sizeof(SpaceNla), "initnla"); 00105 snla->spacetype= SPACE_NLA; 00106 00107 /* allocate DopeSheet data for NLA Editor */ 00108 snla->ads= MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet"); 00109 snla->ads->source= (ID *)scene; 00110 00111 /* set auto-snapping settings */ 00112 snla->autosnap = SACTSNAP_FRAME; 00113 00114 /* header */ 00115 ar= MEM_callocN(sizeof(ARegion), "header for nla"); 00116 00117 BLI_addtail(&snla->regionbase, ar); 00118 ar->regiontype= RGN_TYPE_HEADER; 00119 ar->alignment= RGN_ALIGN_BOTTOM; 00120 00121 /* channel list region */ 00122 ar= MEM_callocN(sizeof(ARegion), "channel list for nla"); 00123 BLI_addtail(&snla->regionbase, ar); 00124 ar->regiontype= RGN_TYPE_CHANNELS; 00125 ar->alignment= RGN_ALIGN_LEFT; 00126 00127 /* only need to set these settings since this will use the 'stack' configuration */ 00128 ar->v2d.scroll = V2D_SCROLL_BOTTOM; 00129 ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; 00130 00131 /* ui buttons */ 00132 ar= MEM_callocN(sizeof(ARegion), "buttons area for nla"); 00133 00134 BLI_addtail(&snla->regionbase, ar); 00135 ar->regiontype= RGN_TYPE_UI; 00136 ar->alignment= RGN_ALIGN_RIGHT; 00137 ar->flag = RGN_FLAG_HIDDEN; 00138 00139 /* main area */ 00140 ar= MEM_callocN(sizeof(ARegion), "main area for nla"); 00141 00142 BLI_addtail(&snla->regionbase, ar); 00143 ar->regiontype= RGN_TYPE_WINDOW; 00144 00145 ar->v2d.tot.xmin= (float)(SFRA-10); 00146 ar->v2d.tot.ymin= (float)(-sa->winy)/3.0f; 00147 ar->v2d.tot.xmax= (float)(EFRA+10); 00148 ar->v2d.tot.ymax= 0.0f; 00149 00150 ar->v2d.cur = ar->v2d.tot; 00151 00152 ar->v2d.min[0]= 0.0f; 00153 ar->v2d.min[1]= 0.0f; 00154 00155 ar->v2d.max[0]= MAXFRAMEF; 00156 ar->v2d.max[1]= 10000.0f; 00157 00158 ar->v2d.minzoom= 0.01f; 00159 ar->v2d.maxzoom= 50; 00160 ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); 00161 ar->v2d.scroll |= (V2D_SCROLL_RIGHT); 00162 ar->v2d.keepzoom= V2D_LOCKZOOM_Y; 00163 ar->v2d.keepofs= V2D_KEEPOFS_Y; 00164 ar->v2d.align= V2D_ALIGN_NO_POS_Y; 00165 ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL; 00166 00167 return (SpaceLink *)snla; 00168 } 00169 00170 /* not spacelink itself */ 00171 static void nla_free(SpaceLink *sl) 00172 { 00173 SpaceNla *snla= (SpaceNla*) sl; 00174 00175 if (snla->ads) { 00176 BLI_freelistN(&snla->ads->chanbase); 00177 MEM_freeN(snla->ads); 00178 } 00179 } 00180 00181 00182 /* spacetype; init callback */ 00183 static void nla_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa) 00184 { 00185 SpaceNla *snla= (SpaceNla *)sa->spacedata.first; 00186 00187 /* init dopesheet data if non-existant (i.e. for old files) */ 00188 if (snla->ads == NULL) { 00189 snla->ads= MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet"); 00190 snla->ads->source= (ID *)G.main->scene.first; // XXX this is bad, but we need this to be set correct 00191 } 00192 00193 ED_area_tag_refresh(sa); 00194 } 00195 00196 static SpaceLink *nla_duplicate(SpaceLink *sl) 00197 { 00198 SpaceNla *snlan= MEM_dupallocN(sl); 00199 00200 /* clear or remove stuff from old */ 00201 snlan->ads= MEM_dupallocN(snlan->ads); 00202 00203 return (SpaceLink *)snlan; 00204 } 00205 00206 /* add handlers, stuff you only do once or on area/region changes */ 00207 static void nla_channel_area_init(wmWindowManager *wm, ARegion *ar) 00208 { 00209 wmKeyMap *keymap; 00210 00211 UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); 00212 00213 /* own keymap */ 00214 /* own channels map first to override some channel keymaps */ 00215 keymap= WM_keymap_find(wm->defaultconf, "NLA Channels", SPACE_NLA, 0); 00216 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00217 /* now generic channels map for everything else that can apply */ 00218 keymap= WM_keymap_find(wm->defaultconf, "Animation Channels", 0, 0); 00219 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00220 00221 keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0); 00222 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00223 } 00224 00225 /* draw entirely, view changes should be handled here */ 00226 static void nla_channel_area_draw(const bContext *C, ARegion *ar) 00227 { 00228 bAnimContext ac; 00229 View2D *v2d= &ar->v2d; 00230 View2DScrollers *scrollers; 00231 00232 /* clear and setup matrix */ 00233 UI_ThemeClearColor(TH_BACK); 00234 glClear(GL_COLOR_BUFFER_BIT); 00235 00236 UI_view2d_view_ortho(v2d); 00237 00238 /* data */ 00239 if (ANIM_animdata_get_context(C, &ac)) { 00240 draw_nla_channel_list((bContext *)C, &ac, ar); 00241 } 00242 00243 /* reset view matrix */ 00244 UI_view2d_view_restore(C); 00245 00246 /* scrollers */ 00247 scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); 00248 UI_view2d_scrollers_draw(C, v2d, scrollers); 00249 UI_view2d_scrollers_free(scrollers); 00250 } 00251 00252 00253 /* add handlers, stuff you only do once or on area/region changes */ 00254 static void nla_main_area_init(wmWindowManager *wm, ARegion *ar) 00255 { 00256 wmKeyMap *keymap; 00257 00258 UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); 00259 00260 /* own keymap */ 00261 keymap= WM_keymap_find(wm->defaultconf, "NLA Editor", SPACE_NLA, 0); 00262 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00263 keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0); 00264 WM_event_add_keymap_handler(&ar->handlers, keymap); 00265 } 00266 00267 static void nla_main_area_draw(const bContext *C, ARegion *ar) 00268 { 00269 /* draw entirely, view changes should be handled here */ 00270 SpaceNla *snla= CTX_wm_space_nla(C); 00271 bAnimContext ac; 00272 View2D *v2d= &ar->v2d; 00273 View2DGrid *grid; 00274 View2DScrollers *scrollers; 00275 short unit=0, flag=0; 00276 00277 /* clear and setup matrix */ 00278 UI_ThemeClearColor(TH_BACK); 00279 glClear(GL_COLOR_BUFFER_BIT); 00280 00281 UI_view2d_view_ortho(v2d); 00282 00283 /* time grid */ 00284 unit= (snla->flag & SNLA_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; 00285 grid= UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); 00286 UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL); 00287 UI_view2d_grid_free(grid); 00288 00289 /* data */ 00290 if (ANIM_animdata_get_context(C, &ac)) { 00291 /* strips and backdrops */ 00292 draw_nla_main_data(&ac, snla, ar); 00293 00294 /* text draw cached, in pixelspace now */ 00295 UI_view2d_text_cache_draw(ar); 00296 } 00297 00298 UI_view2d_view_ortho(v2d); 00299 00300 /* current frame */ 00301 if (snla->flag & SNLA_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS; 00302 if ((snla->flag & SNLA_NODRAWCFRANUM)==0) flag |= DRAWCFRA_SHOW_NUMBOX; 00303 ANIM_draw_cfra(C, v2d, flag); 00304 00305 /* markers */ 00306 UI_view2d_view_orthoSpecial(ar, v2d, 1); 00307 draw_markers_time(C, 0); 00308 00309 /* preview range */ 00310 UI_view2d_view_ortho(v2d); 00311 ANIM_draw_previewrange(C, v2d); 00312 00313 /* reset view matrix */ 00314 UI_view2d_view_restore(C); 00315 00316 /* scrollers */ 00317 scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); 00318 UI_view2d_scrollers_draw(C, v2d, scrollers); 00319 UI_view2d_scrollers_free(scrollers); 00320 } 00321 00322 00323 /* add handlers, stuff you only do once or on area/region changes */ 00324 static void nla_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) 00325 { 00326 ED_region_header_init(ar); 00327 } 00328 00329 static void nla_header_area_draw(const bContext *C, ARegion *ar) 00330 { 00331 ED_region_header(C, ar); 00332 } 00333 00334 /* add handlers, stuff you only do once or on area/region changes */ 00335 static void nla_buttons_area_init(wmWindowManager *wm, ARegion *ar) 00336 { 00337 wmKeyMap *keymap; 00338 00339 ED_region_panels_init(wm, ar); 00340 00341 keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0); 00342 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00343 } 00344 00345 static void nla_buttons_area_draw(const bContext *C, ARegion *ar) 00346 { 00347 ED_region_panels(C, ar, 1, NULL, -1); 00348 } 00349 00350 static void nla_region_listener(ARegion *ar, wmNotifier *wmn) 00351 { 00352 /* context changes */ 00353 switch(wmn->category) { 00354 case NC_ANIMATION: 00355 ED_region_tag_redraw(ar); 00356 break; 00357 case NC_SCENE: 00358 switch(wmn->data) { 00359 case ND_OB_ACTIVE: 00360 case ND_FRAME: 00361 case ND_MARKERS: 00362 ED_region_tag_redraw(ar); 00363 break; 00364 } 00365 break; 00366 case NC_OBJECT: 00367 switch(wmn->data) { 00368 case ND_BONE_ACTIVE: 00369 case ND_BONE_SELECT: 00370 case ND_KEYS: 00371 ED_region_tag_redraw(ar); 00372 break; 00373 } 00374 break; 00375 default: 00376 if(wmn->data==ND_KEYS) 00377 ED_region_tag_redraw(ar); 00378 break; 00379 } 00380 } 00381 00382 00383 static void nla_main_area_listener(ARegion *ar, wmNotifier *wmn) 00384 { 00385 /* context changes */ 00386 switch(wmn->category) { 00387 case NC_ANIMATION: 00388 ED_region_tag_redraw(ar); 00389 break; 00390 case NC_SCENE: 00391 switch(wmn->data) { 00392 case ND_RENDER_OPTIONS: 00393 case ND_OB_ACTIVE: 00394 case ND_FRAME: 00395 case ND_MARKERS: 00396 ED_region_tag_redraw(ar); 00397 break; 00398 } 00399 break; 00400 case NC_OBJECT: 00401 switch(wmn->data) { 00402 case ND_BONE_ACTIVE: 00403 case ND_BONE_SELECT: 00404 case ND_KEYS: 00405 case ND_TRANSFORM: 00406 ED_region_tag_redraw(ar); 00407 break; 00408 } 00409 break; 00410 case NC_NODE: 00411 switch(wmn->action) { 00412 case NA_EDITED: 00413 ED_region_tag_redraw(ar); 00414 break; 00415 } 00416 break; 00417 case NC_ID: 00418 if(wmn->action == NA_RENAME) 00419 ED_region_tag_redraw(ar); 00420 break; 00421 default: 00422 if(wmn->data==ND_KEYS) 00423 ED_region_tag_redraw(ar); 00424 } 00425 } 00426 00427 static void nla_channel_area_listener(ARegion *ar, wmNotifier *wmn) 00428 { 00429 /* context changes */ 00430 switch(wmn->category) { 00431 case NC_ANIMATION: 00432 ED_region_tag_redraw(ar); 00433 break; 00434 case NC_SCENE: 00435 switch(wmn->data) { 00436 case ND_OB_ACTIVE: 00437 ED_region_tag_redraw(ar); 00438 break; 00439 } 00440 break; 00441 case NC_OBJECT: 00442 switch(wmn->data) { 00443 case ND_BONE_ACTIVE: 00444 case ND_BONE_SELECT: 00445 case ND_KEYS: 00446 ED_region_tag_redraw(ar); 00447 break; 00448 } 00449 break; 00450 case NC_ID: 00451 if(wmn->action == NA_RENAME) 00452 ED_region_tag_redraw(ar); 00453 break; 00454 00455 default: 00456 if(wmn->data==ND_KEYS) 00457 ED_region_tag_redraw(ar); 00458 } 00459 } 00460 00461 /* editor level listener */ 00462 static void nla_listener(ScrArea *sa, wmNotifier *wmn) 00463 { 00464 /* context changes */ 00465 switch (wmn->category) { 00466 case NC_ANIMATION: 00467 // TODO: filter specific types of changes? 00468 ED_area_tag_refresh(sa); 00469 break; 00470 case NC_SCENE: 00471 /*switch (wmn->data) { 00472 case ND_OB_ACTIVE: 00473 case ND_OB_SELECT: 00474 ED_area_tag_refresh(sa); 00475 break; 00476 }*/ 00477 ED_area_tag_refresh(sa); 00478 break; 00479 case NC_OBJECT: 00480 switch (wmn->data) { 00481 case ND_TRANSFORM: 00482 /* do nothing */ 00483 break; 00484 default: 00485 ED_area_tag_refresh(sa); 00486 break; 00487 } 00488 break; 00489 case NC_SPACE: 00490 if(wmn->data == ND_SPACE_NLA) 00491 ED_area_tag_redraw(sa); 00492 break; 00493 } 00494 } 00495 00496 /* only called once, from space/spacetypes.c */ 00497 void ED_spacetype_nla(void) 00498 { 00499 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype nla"); 00500 ARegionType *art; 00501 00502 st->spaceid= SPACE_NLA; 00503 strncpy(st->name, "NLA", BKE_ST_MAXNAME); 00504 00505 st->new= nla_new; 00506 st->free= nla_free; 00507 st->init= nla_init; 00508 st->duplicate= nla_duplicate; 00509 st->operatortypes= nla_operatortypes; 00510 st->listener= nla_listener; 00511 st->keymap= nla_keymap; 00512 00513 /* regions: main window */ 00514 art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); 00515 art->regionid = RGN_TYPE_WINDOW; 00516 art->init= nla_main_area_init; 00517 art->draw= nla_main_area_draw; 00518 art->listener= nla_main_area_listener; 00519 art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION|ED_KEYMAP_FRAMES; 00520 00521 BLI_addhead(&st->regiontypes, art); 00522 00523 /* regions: header */ 00524 art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); 00525 art->regionid = RGN_TYPE_HEADER; 00526 art->prefsizey= HEADERY; 00527 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; 00528 00529 art->init= nla_header_area_init; 00530 art->draw= nla_header_area_draw; 00531 00532 BLI_addhead(&st->regiontypes, art); 00533 00534 /* regions: channels */ 00535 art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); 00536 art->regionid = RGN_TYPE_CHANNELS; 00537 art->prefsizex= 200; 00538 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; 00539 00540 art->init= nla_channel_area_init; 00541 art->draw= nla_channel_area_draw; 00542 art->listener= nla_channel_area_listener; 00543 00544 BLI_addhead(&st->regiontypes, art); 00545 00546 /* regions: UI buttons */ 00547 art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); 00548 art->regionid = RGN_TYPE_UI; 00549 art->prefsizex= 200; 00550 art->keymapflag= ED_KEYMAP_UI; 00551 art->listener= nla_region_listener; 00552 art->init= nla_buttons_area_init; 00553 art->draw= nla_buttons_area_draw; 00554 00555 BLI_addhead(&st->regiontypes, art); 00556 00557 nla_buttons_register(art); 00558 00559 00560 BKE_spacetype_register(st); 00561 } 00562