|
Blender
V2.59
|
00001 /* 00002 * $Id: space_graph.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_fcurve.h" 00051 #include "BKE_screen.h" 00052 00053 #include "ED_space_api.h" 00054 #include "ED_screen.h" 00055 #include "ED_anim_api.h" 00056 #include "ED_markers.h" 00057 00058 #include "BIF_gl.h" 00059 00060 #include "WM_api.h" 00061 #include "WM_types.h" 00062 00063 #include "UI_resources.h" 00064 #include "UI_view2d.h" 00065 00066 #include "graph_intern.h" // own include 00067 00068 /* ******************** manage regions ********************* */ 00069 00070 ARegion *graph_has_buttons_region(ScrArea *sa) 00071 { 00072 ARegion *ar, *arnew; 00073 00074 ar= BKE_area_find_region_type(sa, RGN_TYPE_UI); 00075 if(ar) return ar; 00076 00077 /* add subdiv level; after main */ 00078 ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); 00079 00080 /* is error! */ 00081 if (ar==NULL) return NULL; 00082 00083 arnew= MEM_callocN(sizeof(ARegion), "buttons for graph"); 00084 00085 BLI_insertlinkafter(&sa->regionbase, ar, arnew); 00086 arnew->regiontype= RGN_TYPE_UI; 00087 arnew->alignment= RGN_ALIGN_RIGHT; 00088 00089 arnew->flag = RGN_FLAG_HIDDEN; 00090 00091 return arnew; 00092 } 00093 00094 00095 /* ******************** default callbacks for ipo space ***************** */ 00096 00097 static SpaceLink *graph_new(const bContext *C) 00098 { 00099 Scene *scene= CTX_data_scene(C); 00100 ARegion *ar; 00101 SpaceIpo *sipo; 00102 00103 /* Graph Editor - general stuff */ 00104 sipo= MEM_callocN(sizeof(SpaceIpo), "init graphedit"); 00105 sipo->spacetype= SPACE_IPO; 00106 00107 sipo->autosnap= SACTSNAP_FRAME; 00108 00109 /* allocate DopeSheet data for Graph Editor */ 00110 sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet"); 00111 sipo->ads->source= (ID *)scene; 00112 00113 /* header */ 00114 ar= MEM_callocN(sizeof(ARegion), "header for graphedit"); 00115 00116 BLI_addtail(&sipo->regionbase, ar); 00117 ar->regiontype= RGN_TYPE_HEADER; 00118 ar->alignment= RGN_ALIGN_BOTTOM; 00119 00120 /* channels */ 00121 ar= MEM_callocN(sizeof(ARegion), "channels area for graphedit"); 00122 00123 BLI_addtail(&sipo->regionbase, ar); 00124 ar->regiontype= RGN_TYPE_CHANNELS; 00125 ar->alignment= RGN_ALIGN_LEFT; 00126 00127 ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM); 00128 00129 /* ui buttons */ 00130 ar= MEM_callocN(sizeof(ARegion), "buttons area for graphedit"); 00131 00132 BLI_addtail(&sipo->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 graphedit"); 00139 00140 BLI_addtail(&sipo->regionbase, ar); 00141 ar->regiontype= RGN_TYPE_WINDOW; 00142 00143 ar->v2d.tot.xmin= 0.0f; 00144 ar->v2d.tot.ymin= (float)scene->r.sfra - 10.0f; 00145 ar->v2d.tot.xmax= (float)scene->r.efra; 00146 ar->v2d.tot.ymax= 10.0f; 00147 00148 ar->v2d.cur= ar->v2d.tot; 00149 00150 ar->v2d.min[0]= FLT_MIN; 00151 ar->v2d.min[1]= FLT_MIN; 00152 00153 ar->v2d.max[0]= MAXFRAMEF; 00154 ar->v2d.max[1]= FLT_MAX; 00155 00156 ar->v2d.scroll= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); 00157 ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL); 00158 00159 ar->v2d.keeptot= 0; 00160 00161 return (SpaceLink *)sipo; 00162 } 00163 00164 /* not spacelink itself */ 00165 static void graph_free(SpaceLink *sl) 00166 { 00167 SpaceIpo *si= (SpaceIpo *)sl; 00168 00169 if (si->ads) { 00170 BLI_freelistN(&si->ads->chanbase); 00171 MEM_freeN(si->ads); 00172 } 00173 00174 if (si->ghostCurves.first) 00175 free_fcurves(&si->ghostCurves); 00176 } 00177 00178 00179 /* spacetype; init callback */ 00180 static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa) 00181 { 00182 SpaceIpo *sipo= (SpaceIpo *)sa->spacedata.first; 00183 00184 /* init dopesheet data if non-existant (i.e. for old files) */ 00185 if (sipo->ads == NULL) { 00186 sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet"); 00187 sipo->ads->source= (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now... 00188 } 00189 00190 ED_area_tag_refresh(sa); 00191 } 00192 00193 static SpaceLink *graph_duplicate(SpaceLink *sl) 00194 { 00195 SpaceIpo *sipon= MEM_dupallocN(sl); 00196 00197 /* clear or remove stuff from old */ 00198 BLI_duplicatelist(&sipon->ghostCurves, &((SpaceIpo *)sl)->ghostCurves); 00199 sipon->ads= MEM_dupallocN(sipon->ads); 00200 00201 return (SpaceLink *)sipon; 00202 } 00203 00204 /* add handlers, stuff you only do once or on area/region changes */ 00205 static void graph_main_area_init(wmWindowManager *wm, ARegion *ar) 00206 { 00207 wmKeyMap *keymap; 00208 00209 UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); 00210 00211 /* own keymap */ 00212 keymap= WM_keymap_find(wm->defaultconf, "Graph Editor", SPACE_IPO, 0); 00213 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00214 keymap= WM_keymap_find(wm->defaultconf, "Graph Editor Generic", SPACE_IPO, 0); 00215 WM_event_add_keymap_handler(&ar->handlers, keymap); 00216 } 00217 00218 static void graph_main_area_draw(const bContext *C, ARegion *ar) 00219 { 00220 /* draw entirely, view changes should be handled here */ 00221 SpaceIpo *sipo= CTX_wm_space_graph(C); 00222 bAnimContext ac; 00223 View2D *v2d= &ar->v2d; 00224 View2DGrid *grid; 00225 View2DScrollers *scrollers; 00226 float col[3]; 00227 short unitx=0, unity=V2D_UNIT_VALUES, flag=0; 00228 00229 /* clear and setup matrix */ 00230 UI_GetThemeColor3fv(TH_BACK, col); 00231 glClearColor(col[0], col[1], col[2], 0.0); 00232 glClear(GL_COLOR_BUFFER_BIT); 00233 00234 UI_view2d_view_ortho(v2d); 00235 00236 /* grid */ 00237 unitx= (sipo->flag & SIPO_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE; 00238 grid= UI_view2d_grid_calc(CTX_data_scene(C), v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy); 00239 UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL); 00240 00241 /* draw data */ 00242 if (ANIM_animdata_get_context(C, &ac)) { 00243 /* draw ghost curves */ 00244 graph_draw_ghost_curves(&ac, sipo, ar); 00245 00246 /* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */ 00247 graph_draw_curves(&ac, sipo, ar, grid, 0); 00248 graph_draw_curves(&ac, sipo, ar, grid, 1); 00249 00250 /* XXX the slow way to set tot rect... but for nice sliders needed (ton) */ 00251 get_graph_keyframe_extents(&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, FALSE); 00252 /* extra offset so that these items are visible */ 00253 v2d->tot.xmin -= 10.0f; 00254 v2d->tot.xmax += 10.0f; 00255 } 00256 00257 /* only free grid after drawing data, as we need to use it to determine sampling rate */ 00258 UI_view2d_grid_free(grid); 00259 00260 /* horizontal component of value-cursor (value line before the current frame line) */ 00261 if ((sipo->flag & SIPO_NODRAWCURSOR)==0) { 00262 float vec[2]; 00263 00264 /* Draw a green line to indicate the cursor value */ 00265 vec[1]= sipo->cursorVal; 00266 00267 UI_ThemeColorShadeAlpha(TH_CFRAME, -10, -50); 00268 glLineWidth(2.0); 00269 00270 glEnable(GL_BLEND); 00271 glBegin(GL_LINE_STRIP); 00272 vec[0]= v2d->cur.xmin; 00273 glVertex2fv(vec); 00274 00275 vec[0]= v2d->cur.xmax; 00276 glVertex2fv(vec); 00277 glEnd(); // GL_LINE_STRIP 00278 glDisable(GL_BLEND); 00279 } 00280 00281 /* current frame */ 00282 if (sipo->flag & SIPO_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS; 00283 if ((sipo->flag & SIPO_NODRAWCFRANUM)==0) flag |= DRAWCFRA_SHOW_NUMBOX; 00284 ANIM_draw_cfra(C, v2d, flag); 00285 00286 /* markers */ 00287 UI_view2d_view_orthoSpecial(ar, v2d, 1); 00288 draw_markers_time(C, 0); 00289 00290 /* preview range */ 00291 UI_view2d_view_ortho(v2d); 00292 ANIM_draw_previewrange(C, v2d); 00293 00294 /* reset view matrix */ 00295 UI_view2d_view_restore(C); 00296 00297 /* scrollers */ 00298 // FIXME: args for scrollers depend on the type of data being shown... 00299 scrollers= UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP); 00300 UI_view2d_scrollers_draw(C, v2d, scrollers); 00301 UI_view2d_scrollers_free(scrollers); 00302 } 00303 00304 static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar) 00305 { 00306 wmKeyMap *keymap; 00307 00308 UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); 00309 00310 /* own keymap */ 00311 keymap= WM_keymap_find(wm->defaultconf, "Animation Channels", 0, 0); 00312 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00313 keymap= WM_keymap_find(wm->defaultconf, "Graph Editor Generic", SPACE_IPO, 0); 00314 WM_event_add_keymap_handler(&ar->handlers, keymap); 00315 } 00316 00317 static void graph_channel_area_draw(const bContext *C, ARegion *ar) 00318 { 00319 bAnimContext ac; 00320 View2D *v2d= &ar->v2d; 00321 View2DScrollers *scrollers; 00322 float col[3]; 00323 00324 /* clear and setup matrix */ 00325 UI_GetThemeColor3fv(TH_BACK, col); 00326 glClearColor(col[0], col[1], col[2], 0.0); 00327 glClear(GL_COLOR_BUFFER_BIT); 00328 00329 UI_view2d_view_ortho(v2d); 00330 00331 /* draw channels */ 00332 if (ANIM_animdata_get_context(C, &ac)) { 00333 graph_draw_channel_names((bContext*)C, &ac, ar); 00334 } 00335 00336 /* reset view matrix */ 00337 UI_view2d_view_restore(C); 00338 00339 /* scrollers */ 00340 scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); 00341 UI_view2d_scrollers_draw(C, v2d, scrollers); 00342 UI_view2d_scrollers_free(scrollers); 00343 } 00344 00345 /* add handlers, stuff you only do once or on area/region changes */ 00346 static void graph_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) 00347 { 00348 ED_region_header_init(ar); 00349 } 00350 00351 static void graph_header_area_draw(const bContext *C, ARegion *ar) 00352 { 00353 ED_region_header(C, ar); 00354 } 00355 00356 /* add handlers, stuff you only do once or on area/region changes */ 00357 static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar) 00358 { 00359 wmKeyMap *keymap; 00360 00361 ED_region_panels_init(wm, ar); 00362 00363 keymap= WM_keymap_find(wm->defaultconf, "Graph Editor Generic", SPACE_IPO, 0); 00364 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00365 } 00366 00367 static void graph_buttons_area_draw(const bContext *C, ARegion *ar) 00368 { 00369 ED_region_panels(C, ar, 1, NULL, -1); 00370 } 00371 00372 static void graph_region_listener(ARegion *ar, wmNotifier *wmn) 00373 { 00374 /* context changes */ 00375 switch(wmn->category) { 00376 case NC_ANIMATION: 00377 ED_region_tag_redraw(ar); 00378 break; 00379 case NC_SCENE: 00380 switch(wmn->data) { 00381 case ND_RENDER_OPTIONS: 00382 case ND_OB_ACTIVE: 00383 case ND_FRAME: 00384 case ND_MARKERS: 00385 ED_region_tag_redraw(ar); 00386 break; 00387 case ND_SEQUENCER: 00388 if (wmn->action == NA_SELECTED) 00389 ED_region_tag_redraw(ar); 00390 break; 00391 } 00392 break; 00393 case NC_OBJECT: 00394 switch(wmn->data) { 00395 case ND_BONE_ACTIVE: 00396 case ND_BONE_SELECT: 00397 case ND_KEYS: 00398 ED_region_tag_redraw(ar); 00399 break; 00400 case ND_MODIFIER: 00401 if(wmn->action == NA_RENAME) 00402 ED_region_tag_redraw(ar); 00403 break; 00404 } 00405 break; 00406 case NC_NODE: 00407 switch(wmn->action) { 00408 case NA_EDITED: 00409 case NA_SELECTED: 00410 ED_region_tag_redraw(ar); 00411 break; 00412 } 00413 break; 00414 case NC_ID: 00415 if(wmn->action == NA_RENAME) 00416 ED_region_tag_redraw(ar); 00417 break; 00418 default: 00419 if(wmn->data==ND_KEYS) 00420 ED_region_tag_redraw(ar); 00421 00422 } 00423 } 00424 00425 /* editor level listener */ 00426 static void graph_listener(ScrArea *sa, wmNotifier *wmn) 00427 { 00428 SpaceIpo *sipo= (SpaceIpo *)sa->spacedata.first; 00429 00430 /* context changes */ 00431 switch (wmn->category) { 00432 case NC_ANIMATION: 00433 /* for selection changes of animation data, we can just redraw... otherwise autocolor might need to be done again */ 00434 if (ELEM(wmn->data, ND_KEYFRAME, ND_ANIMCHAN) && (wmn->action == NA_SELECTED)) 00435 ED_area_tag_redraw(sa); 00436 else 00437 ED_area_tag_refresh(sa); 00438 break; 00439 case NC_SCENE: 00440 switch (wmn->data) { 00441 case ND_OB_ACTIVE: /* selection changed, so force refresh to flush (needs flag set to do syncing) */ 00442 case ND_OB_SELECT: 00443 sipo->flag |= SIPO_TEMP_NEEDCHANSYNC; 00444 ED_area_tag_refresh(sa); 00445 break; 00446 00447 default: /* just redrawing the view will do */ 00448 ED_area_tag_redraw(sa); 00449 break; 00450 } 00451 break; 00452 case NC_OBJECT: 00453 switch (wmn->data) { 00454 case ND_BONE_SELECT: /* selection changed, so force refresh to flush (needs flag set to do syncing) */ 00455 case ND_BONE_ACTIVE: 00456 sipo->flag |= SIPO_TEMP_NEEDCHANSYNC; 00457 ED_area_tag_refresh(sa); 00458 break; 00459 case ND_TRANSFORM: 00460 break; /*do nothing*/ 00461 00462 default: /* just redrawing the view will do */ 00463 ED_area_tag_redraw(sa); 00464 break; 00465 } 00466 break; 00467 case NC_SPACE: 00468 if(wmn->data == ND_SPACE_GRAPH) 00469 ED_area_tag_redraw(sa); 00470 break; 00471 00472 // XXX: restore the case below if not enough updates occur... 00473 //default: 00474 // if(wmn->data==ND_KEYS) 00475 // ED_area_tag_redraw(sa); 00476 } 00477 } 00478 00479 00480 00481 static void graph_refresh(const bContext *C, ScrArea *sa) 00482 { 00483 SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first; 00484 bAnimContext ac; 00485 00486 /* updates to data needed depends on Graph Editor mode... */ 00487 switch (sipo->mode) { 00488 case SIPO_MODE_ANIMATION: /* all animation */ 00489 { 00490 00491 } 00492 break; 00493 00494 case SIPO_MODE_DRIVERS: /* drivers only */ 00495 { 00496 00497 } 00498 break; 00499 } 00500 00501 /* region updates? */ 00502 // XXX resizing y-extents of tot should go here? 00503 00504 /* update the state of the animchannels in response to changes from the data they represent 00505 * NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled 00506 */ 00507 if (sipo->flag & SIPO_TEMP_NEEDCHANSYNC) { 00508 ANIM_sync_animchannels_to_data(C); 00509 sipo->flag &= ~SIPO_TEMP_NEEDCHANSYNC; 00510 } 00511 00512 /* init/adjust F-Curve colors */ 00513 if (ANIM_animdata_get_context(C, &ac)) { 00514 ListBase anim_data = {NULL, NULL}; 00515 bAnimListElem *ale; 00516 int filter; 00517 int items, i; 00518 00519 /* build list of F-Curves which will be visible as channels in channel-region 00520 * - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a 00521 * mismatch between channel-colors and the drawn curves 00522 */ 00523 filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY|ANIMFILTER_NODUPLIS); 00524 items= ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); 00525 00526 /* loop over F-Curves, assigning colors */ 00527 for (ale=anim_data.first, i=0; ale; ale= ale->next, i++) { 00528 FCurve *fcu= (FCurve *)ale->data; 00529 00530 /* set color of curve here */ 00531 switch (fcu->color_mode) { 00532 case FCURVE_COLOR_CUSTOM: 00533 /* User has defined a custom color for this curve already (we assume it's not going to cause clashes with text colors), 00534 * which should be left alone... Nothing needs to be done here. 00535 */ 00536 break; 00537 00538 case FCURVE_COLOR_AUTO_RGB: 00539 { 00540 /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors. 00541 * TODO: find a way to module the hue so that not all curves have same color... 00542 */ 00543 float *col= fcu->color; 00544 00545 switch(fcu->array_index) { 00546 case 0: 00547 col[0]= 1.0f; col[1]= 0.0f; col[2]= 0.0f; 00548 break; 00549 case 1: 00550 col[0]= 0.0f; col[1]= 1.0f; col[2]= 0.0f; 00551 break; 00552 case 2: 00553 col[0]= 0.0f; col[1]= 0.0f; col[2]= 1.0f; 00554 break; 00555 default: 00556 /* 'unknown' color - bluish so as to not conflict with handles */ 00557 col[0]= 0.3f; col[1]= 0.8f; col[2]= 1.0f; 00558 break; 00559 } 00560 } 00561 break; 00562 00563 case FCURVE_COLOR_AUTO_RAINBOW: 00564 default: 00565 { 00566 /* determine color 'automatically' using 'magic function' which uses the given args 00567 * of current item index + total items to determine some RGB color 00568 */ 00569 getcolor_fcurve_rainbow(i, items, fcu->color); 00570 } 00571 break; 00572 } 00573 } 00574 00575 /* free temp list */ 00576 BLI_freelistN(&anim_data); 00577 } 00578 } 00579 00580 /* only called once, from space/spacetypes.c */ 00581 void ED_spacetype_ipo(void) 00582 { 00583 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype ipo"); 00584 ARegionType *art; 00585 00586 st->spaceid= SPACE_IPO; 00587 strncpy(st->name, "Graph", BKE_ST_MAXNAME); 00588 00589 st->new= graph_new; 00590 st->free= graph_free; 00591 st->init= graph_init; 00592 st->duplicate= graph_duplicate; 00593 st->operatortypes= graphedit_operatortypes; 00594 st->keymap= graphedit_keymap; 00595 st->listener= graph_listener; 00596 st->refresh= graph_refresh; 00597 00598 /* regions: main window */ 00599 art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); 00600 art->regionid = RGN_TYPE_WINDOW; 00601 art->init= graph_main_area_init; 00602 art->draw= graph_main_area_draw; 00603 art->listener= graph_region_listener; 00604 art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION|ED_KEYMAP_FRAMES; 00605 00606 BLI_addhead(&st->regiontypes, art); 00607 00608 /* regions: header */ 00609 art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); 00610 art->regionid = RGN_TYPE_HEADER; 00611 art->prefsizey= HEADERY; 00612 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; 00613 art->listener= graph_region_listener; 00614 art->init= graph_header_area_init; 00615 art->draw= graph_header_area_draw; 00616 00617 BLI_addhead(&st->regiontypes, art); 00618 00619 /* regions: channels */ 00620 art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); 00621 art->regionid = RGN_TYPE_CHANNELS; 00622 art->prefsizex= 200+V2D_SCROLL_WIDTH; /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */ 00623 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES; 00624 art->listener= graph_region_listener; 00625 art->init= graph_channel_area_init; 00626 art->draw= graph_channel_area_draw; 00627 00628 BLI_addhead(&st->regiontypes, art); 00629 00630 /* regions: UI buttons */ 00631 art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); 00632 art->regionid = RGN_TYPE_UI; 00633 art->prefsizex= 200; 00634 art->keymapflag= ED_KEYMAP_UI; 00635 art->listener= graph_region_listener; 00636 art->init= graph_buttons_area_init; 00637 art->draw= graph_buttons_area_draw; 00638 00639 BLI_addhead(&st->regiontypes, art); 00640 00641 graph_buttons_register(art); 00642 00643 BKE_spacetype_register(st); 00644 } 00645