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