diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 691dc26c937..be9c76111db 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -325,18 +325,27 @@ static int rct_fits(rcti *rect, char dir, int size) static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) { + rcti *remainder_prev= remainder; int prefsizex, prefsizey; + int alignment; if(ar==NULL) return; BLI_init_rcti(&ar->winrct, 0, 0, 0, 0); + /* for test; allow split of previously defined region */ + if(ar->alignment & RGN_SPLIT_PREV) + if(ar->prev) + remainder= &ar->prev->winrct; + + alignment = ar->alignment & ~RGN_SPLIT_PREV; + /* clear state flags first */ ar->flag &= ~RGN_FLAG_TOO_SMALL; /* user errors */ - if(ar->next==NULL && ar->alignment!=RGN_ALIGN_QSPLIT) - ar->alignment= RGN_ALIGN_NONE; + if(ar->next==NULL && alignment!=RGN_ALIGN_QSPLIT) + alignment= RGN_ALIGN_NONE; prefsizex= ar->type->minsizex; prefsizey= ar->type->minsizey; @@ -344,17 +353,17 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) /* hidden is user flag */ if(ar->flag & RGN_FLAG_HIDDEN); /* XXX floating area region, not handled yet here */ - else if(ar->alignment == RGN_ALIGN_FLOAT); + else if(alignment == RGN_ALIGN_FLOAT); /* remainder is too small for any usage */ else if( rct_fits(remainder, 'v', 1)<0 || rct_fits(remainder, 'h', 1) < 0 ) { ar->flag |= RGN_FLAG_TOO_SMALL; } - else if(ar->alignment==RGN_ALIGN_NONE) { + else if(alignment==RGN_ALIGN_NONE) { /* typically last region */ ar->winrct= *remainder; BLI_init_rcti(remainder, 0, 0, 0, 0); } - else if(ar->alignment==RGN_ALIGN_TOP || ar->alignment==RGN_ALIGN_BOTTOM) { + else if(alignment==RGN_ALIGN_TOP || alignment==RGN_ALIGN_BOTTOM) { if( rct_fits(remainder, 'v', prefsizey) < 0 ) { ar->flag |= RGN_FLAG_TOO_SMALL; @@ -367,7 +376,7 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) ar->winrct= *remainder; - if(ar->alignment==RGN_ALIGN_TOP) { + if(alignment==RGN_ALIGN_TOP) { ar->winrct.ymin= ar->winrct.ymax - prefsizey + 1; remainder->ymax= ar->winrct.ymin - 1; } @@ -377,7 +386,7 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) } } } - else if( ELEM4(ar->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) { + else if( ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) { if( rct_fits(remainder, 'h', prefsizex) < 0 ) { ar->flag |= RGN_FLAG_TOO_SMALL; @@ -390,23 +399,23 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) ar->winrct= *remainder; - if(ELEM(ar->alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) { + if(ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) { ar->winrct.xmin= ar->winrct.xmax - prefsizex + 1; - if(ar->alignment==RGN_ALIGN_RIGHT) + if(alignment==RGN_ALIGN_RIGHT) remainder->xmax= ar->winrct.xmin - 1; } else { ar->winrct.xmax= ar->winrct.xmin + prefsizex - 1; - if(ar->alignment==RGN_ALIGN_LEFT) + if(alignment==RGN_ALIGN_LEFT) remainder->xmin= ar->winrct.xmax + 1; } } } - else if(ar->alignment==RGN_ALIGN_VSPLIT || ar->alignment==RGN_ALIGN_HSPLIT) { + else if(alignment==RGN_ALIGN_VSPLIT || alignment==RGN_ALIGN_HSPLIT) { /* percentage subdiv*/ ar->winrct= *remainder; - if(ar->alignment==RGN_ALIGN_HSPLIT) { + if(alignment==RGN_ALIGN_HSPLIT) { if( rct_fits(remainder, 'h', prefsizex) > 4) { ar->winrct.xmax= (remainder->xmin+remainder->xmax)/2; remainder->xmin= ar->winrct.xmax+1; @@ -425,7 +434,7 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) } } } - else if(ar->alignment==RGN_ALIGN_QSPLIT) { + else if(alignment==RGN_ALIGN_QSPLIT) { ar->winrct= *remainder; /* test if there's still 4 regions left */ @@ -473,6 +482,14 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder, int quad) ar->winx= ar->winrct.xmax - ar->winrct.xmin + 1; ar->winy= ar->winrct.ymax - ar->winrct.ymin + 1; + /* restore test exception */ + if(ar->alignment & RGN_SPLIT_PREV) { + if(ar->prev) { + remainder= remainder_prev; + ar->prev->winx= ar->prev->winrct.xmax - ar->prev->winrct.xmin + 1; + ar->prev->winy= ar->prev->winrct.ymax - ar->prev->winrct.ymin + 1; + } + } region_rect_recursive(ar->next, remainder, quad); } diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index b4aaad1826d..0e8836fdc6b 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -25,28 +25,33 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#ifndef ED_IPO_INTERN_H -#define ED_IPO_INTERN_H +#ifndef ED_GRAPH_INTERN_H +#define ED_GRAPH_INTERN_H struct bContext; struct wmWindowManager; struct bAnimContext; struct SpaceIpo; +struct ScrArea; struct ARegion; /* internal exports only */ +/* ***************************************** */ +/* space_graph.c */ +struct ARegion *graph_has_buttons_region(struct ScrArea *sa); + /* ***************************************** */ /* ipo_draw.c */ void graph_draw_channel_names(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar); void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar); /* ***************************************** */ -/* ipo_header.c */ +/* graph_header.c */ void graph_header_buttons(const bContext *C, struct ARegion *ar); /* ***************************************** */ -/* ipo_select.c */ +/* graph_select.c */ void GRAPHEDIT_OT_keyframes_deselectall(struct wmOperatorType *ot); void GRAPHEDIT_OT_keyframes_borderselect(struct wmOperatorType *ot); @@ -70,7 +75,7 @@ enum { } eGraphKeys_ColumnSelect_Mode; /* ***************************************** */ -/* ipo_edit.c */ +/* graph_edit.c */ void GRAPHEDIT_OT_set_previewrange(struct wmOperatorType *ot); void GRAPHEDIT_OT_view_all(struct wmOperatorType *ot); @@ -114,10 +119,15 @@ enum { } eGraphKeys_Mirror_Mode; /* ***************************************** */ -/* ipo_ops.c */ +/* graph_buttons.c */ +void GRAPHEDIT_OT_properties(struct wmOperatorType *ot); +void graph_region_buttons(const struct bContext *C, struct ARegion *ar); + +/* ***************************************** */ +/* graph_ops.c */ void graphedit_keymap(struct wmWindowManager *wm); void graphedit_operatortypes(void); -#endif /* ED_IPO_INTERN_H */ +#endif /* ED_GRAPH_INTERN_H */ diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 0a31cc48334..f9900306c53 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -99,6 +99,7 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPHEDIT_OT_view_togglehandles); WM_operatortype_append(GRAPHEDIT_OT_set_previewrange); WM_operatortype_append(GRAPHEDIT_OT_view_all); + WM_operatortype_append(GRAPHEDIT_OT_properties); /* keyframes */ /* selection */ @@ -199,6 +200,10 @@ void graphedit_keymap(wmWindowManager *wm) { ListBase *keymap; + /* keymap for all regions */ + keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + WM_keymap_add_item(keymap, "GRAPHEDIT_OT_properties", NKEY, KM_PRESS, 0, 0); + /* channels */ /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module. * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index da18e4d9726..11922a2b383 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -61,6 +61,36 @@ #include "graph_intern.h" // own include +/* ******************** manage regions ********************* */ + +ARegion *graph_has_buttons_region(ScrArea *sa) +{ + ARegion *ar, *arnew; + + for(ar= sa->regionbase.first; ar; ar= ar->next) + if(ar->regiontype==RGN_TYPE_UI) + return ar; + + /* add subdiv level; after channel */ + for(ar= sa->regionbase.first; ar; ar= ar->next) + if(ar->regiontype==RGN_TYPE_CHANNELS) + break; + + /* is error! */ + if(ar==NULL) return NULL; + + arnew= MEM_callocN(sizeof(ARegion), "buttons for view3d"); + + BLI_insertlinkafter(&sa->regionbase, ar, arnew); + arnew->regiontype= RGN_TYPE_UI; + arnew->alignment= RGN_ALIGN_TOP|RGN_SPLIT_PREV; + + arnew->flag = RGN_FLAG_HIDDEN; + + return arnew; +} + + /* ******************** default callbacks for ipo space ***************** */ static SpaceLink *graph_new(const bContext *C) @@ -94,6 +124,14 @@ static SpaceLink *graph_new(const bContext *C) ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM); + /* ui buttons */ + ar= MEM_callocN(sizeof(ARegion), "main area for graphedit"); + + BLI_addtail(&sipo->regionbase, ar); + ar->regiontype= RGN_TYPE_UI; + ar->alignment= RGN_ALIGN_TOP|RGN_SPLIT_PREV; + ar->flag = RGN_FLAG_HIDDEN; + /* main area */ ar= MEM_callocN(sizeof(ARegion), "main area for graphedit"); @@ -166,6 +204,8 @@ static void graph_main_area_init(wmWindowManager *wm, ARegion *ar) /* own keymap */ keymap= WM_keymap_listbase(wm, "GraphEdit Keys", SPACE_IPO, 0); /* XXX weak? */ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); } static void graph_main_area_draw(const bContext *C, ARegion *ar) @@ -229,6 +269,8 @@ static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar) /* own keymap */ keymap= WM_keymap_listbase(wm, "Animation_Channels", 0, 0); /* XXX weak? */ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); } static void graph_channel_area_draw(const bContext *C, ARegion *ar) @@ -288,6 +330,37 @@ static void graph_header_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); } +/* add handlers, stuff you only do once or on area/region changes */ +static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar) +{ + ListBase *keymap; + + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST_UI, ar->winx, ar->winy); + + keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); +} + +static void graph_buttons_area_draw(const bContext *C, ARegion *ar) +{ + float col[3]; + + /* clear */ + UI_GetThemeColor3fv(TH_HEADER, col); + + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* set view2d view matrix for scrolling (without scrollers) */ + UI_view2d_view_ortho(C, &ar->v2d); + + graph_region_buttons(C, ar); + + /* restore view matrix? */ + UI_view2d_view_restore(C); +} + + static void graph_region_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ @@ -490,6 +563,16 @@ void ED_spacetype_ipo(void) BLI_addhead(&st->regiontypes, art); + /* regions: UI buttons */ + art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); + art->regionid = RGN_TYPE_UI; + art->minsizey= 160; + art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES; + art->listener= NULL; // graph_region_listener; + art->init= graph_buttons_area_init; + art->draw= graph_buttons_area_draw; + + BLI_addhead(&st->regiontypes, art); BKE_spacetype_register(st); } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index bc845ec177a..d90527040dd 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -217,6 +217,8 @@ typedef struct ARegion { #define RGN_OVERLAP_LEFT 11 #define RGN_OVERLAP_RIGHT 12 +#define RGN_SPLIT_PREV 32 + /* region flag */ #define RGN_FLAG_HIDDEN 1 #define RGN_FLAG_TOO_SMALL 2