diff options
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 49 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_draw.c | 38 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_edit.c | 252 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_intern.h | 6 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_ops.c | 38 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_select.c | 32 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_utils.c | 9 | ||||
-rw-r--r-- | source/blender/editors/space_graph/space_graph.c | 43 |
8 files changed, 388 insertions, 79 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index a2b64afdb15..c1e3d855e7d 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -139,6 +139,13 @@ static void graph_panel_view(const bContext *C, Panel *pa) row = uiLayoutSplit(sub, 0.7f, true); uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE); + + col = uiLayoutColumn(pa->layout, false); + uiItemR(col, &spaceptr, "show_backdrop", 0, NULL, ICON_NONE); + col = uiLayoutColumn(pa->layout, false); + uiLayoutSetActive(col, RNA_boolean_get(&spaceptr, "show_backdrop")); + uiItemR(col, &spaceptr, "backdrop_camera", 0, "Camera", ICON_NONE); + uiItemR(col, &spaceptr, "backdrop_opacity", 0, "Opacity", ICON_NONE); } /* ******************* active F-Curve ************** */ @@ -165,9 +172,28 @@ static void graph_panel_properties(const bContext *C, Panel *pa) RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr); /* user-friendly 'name' for F-Curve */ - /* TODO: only show the path if this is invalid? */ col = uiLayoutColumn(layout, false); - icon = getname_anim_fcurve(name, ale->id, fcu); + if (ale->type == ANIMTYPE_FCURVE) { + /* get user-friendly name for F-Curve */ + icon = getname_anim_fcurve(name, ale->id, fcu); + } + else { + /* NLA Control Curve, etc. */ + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + + /* get name */ + if (acf && acf->name) { + acf->name(ale, name); + } + else { + strcpy(name, IFACE_("<invalid>")); + icon = ICON_ERROR; + } + + /* icon */ + if (ale->type == ANIMTYPE_NLACURVE) + icon = ICON_NLA; + } uiItemL(col, name, icon); /* RNA-Path Editing - only really should be enabled when things aren't working */ @@ -864,6 +890,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) FModifier *fcm; uiLayout *col, *row; uiBlock *block; + bool active; if (!graph_panel_context(C, &ale, &fcu)) return; @@ -888,9 +915,11 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste"); } + active = !(fcu->flag & FCURVE_MOD_OFF); /* draw each modifier */ for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) { col = uiLayoutColumn(pa->layout, true); + uiLayoutSetActive(col, active); ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm); } @@ -898,6 +927,21 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) MEM_freeN(ale); } +/* ******************* Others ************************ */ + +/* Graph Editor Backdrop Settings */ +static void UNUSED_FUNCTION(graph_panel_backdrop)(const bContext *C, Panel *UNUSED(pa)) +{ + bScreen *sc = CTX_wm_screen(C); + SpaceIpo *sipo = CTX_wm_space_graph(C); + PointerRNA spaceptr; + // uiLayout *col; + + /* get RNA pointers for use when creating the UI elements */ + RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr); + +} + /* ******************* general ******************************** */ void graph_buttons_register(ARegionType *art) @@ -909,7 +953,6 @@ void graph_buttons_register(ARegionType *art) strcpy(pt->label, N_("View Properties")); strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); pt->draw = graph_panel_view; - pt->flag |= PNL_DEFAULT_CLOSED; BLI_addtail(&art->paneltypes, pt); pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties"); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 2d8a0a3da29..87e7cab4d15 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -481,7 +481,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d ChannelDriver *driver; float samplefreq; float stime, etime; - float unitFac; + float unitFac, offset; float dx, dy; short mapping_flag = ANIM_get_normalization_flags(ac); int i, n; @@ -498,7 +498,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d fcu->driver = NULL; /* compute unit correction factor */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); /* Note about sampling frequency: * Ideally, this is chosen such that we have 1-2 pixels = 1 segment @@ -550,7 +550,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d n = (etime - stime) / samplefreq + 0.5f; for (i = 0; i <= n; i++) { float ctime = stime + i * samplefreq; - glVertex2f(ctime, evaluate_fcurve(fcu, ctime) * unitFac); + glVertex2f(ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac); } glEnd(); @@ -566,13 +566,14 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie FPoint *fpt = prevfpt + 1; float fac, v[2]; int b = fcu->totvert - 1; - float unit_scale; + float unit_scale, offset; short mapping_flag = ANIM_get_normalization_flags(ac); /* apply unit mapping */ glPushMatrix(); - unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); glScalef(1.0f, unit_scale, 1.0f); + glTranslatef(0.0f, offset, 0.0f); glBegin(GL_LINE_STRIP); @@ -665,14 +666,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 float fac = 0.0f; int b = fcu->totvert - 1; int resol; - float unit_scale; + float unit_scale, offset; short mapping_flag = ANIM_get_normalization_flags(ac); /* apply unit mapping */ glPushMatrix(); - unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); glScalef(1.0f, unit_scale, 1.0f); - + glTranslatef(0.0f, offset, 0.0f); + glBegin(GL_LINE_STRIP); /* extrapolate to left? */ @@ -826,7 +828,8 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) ChannelDriver *driver = fcu->driver; View2D *v2d = &ac->ar->v2d; short mapping_flag = ANIM_get_normalization_flags(ac); - float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + float offset; + float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); /* for now, only show when debugging driver... */ //if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0) @@ -850,10 +853,10 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) glBegin(GL_LINES); { t = v2d->cur.xmin; - glVertex2f(t, t * unitfac); + glVertex2f(t, (t + offset) * unitfac); t = v2d->cur.xmax; - glVertex2f(t, t * unitfac); + glVertex2f(t, (t + offset) * unitfac); } glEnd(); @@ -908,7 +911,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) glPointSize(7.0); glBegin(GL_POINTS); - glVertex2f(x, y); + glVertex2f(x, y); glEnd(); /* inner frame */ @@ -916,7 +919,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) glPointSize(3.0); glBegin(GL_POINTS); - glVertex2f(x, y); + glVertex2f(x, y); glEnd(); glPointSize(1.0f); @@ -1067,10 +1070,12 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid } else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { short mapping_flag = ANIM_get_normalization_flags(ac); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); glPushMatrix(); glScalef(1.0f, unit_scale, 1.0f); + glTranslatef(0.0f, offset, 0.0f); if (fcu->bezt) { bool do_handles = draw_fcurve_handles_check(sipo, fcu); @@ -1137,6 +1142,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) /* loop through channels, and set up drawing depending on their type */ { /* first pass: just the standard GL-drawing for backdrop + text */ + size_t channel_index = 0; + y = (float)ACHANNEL_FIRST; for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) { @@ -1148,11 +1155,12 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) { /* draw all channels using standard channel-drawing API */ - ANIM_channel_draw(ac, ale, yminc, ymaxc); + ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index); } /* adjust y-position for next one */ y -= ACHANNEL_STEP; + channel_index++; } } { /* second pass: widgets */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 2944901663b..f55a9dc45f3 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -59,6 +59,7 @@ #include "BKE_nla.h" #include "BKE_context.h" #include "BKE_report.h" +#include "BKE_screen.h" #include "UI_view2d.h" @@ -109,7 +110,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa AnimData *adt = ANIM_nla_mapping_get(ac, ale); FCurve *fcu = (FCurve *)ale->key_data; float txmin, txmax, tymin, tymax; - float unitFac; + float unitFac, offset; /* get range */ if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) { @@ -122,7 +123,9 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa } /* apply unit corrections */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); + tymin += offset; + tymax += offset; tymin *= unitFac; tymax *= unitFac; @@ -256,6 +259,14 @@ static int graphkeys_view_selected_exec(bContext *C, wmOperator *op) return graphkeys_viewall(C, true, include_handles, smooth_viewtx); } +static int graphkeys_view_frame_exec(bContext *C, wmOperator *op) +{ + const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + ANIM_center_frame(C, smooth_viewtx); + return OPERATOR_FINISHED; +} + + void GRAPH_OT_view_all(wmOperatorType *ot) { /* identifiers */ @@ -294,6 +305,21 @@ void GRAPH_OT_view_selected(wmOperatorType *ot) "Include handles of keyframes when calculating extents"); } +void GRAPH_OT_view_frame(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "View Frame"; + ot->idname = "GRAPH_OT_view_frame"; + ot->description = "Reset viewable area to show range around current frame"; + + /* api callbacks */ + ot->exec = graphkeys_view_frame_exec; + ot->poll = ED_operator_graphedit_active; /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */ + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ******************** Create Ghost-Curves Operator *********************** */ /* This operator samples the data of the selected F-Curves to F-Points, storing them * as 'ghost curves' in the active Graph Editor @@ -327,7 +353,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) AnimData *adt = ANIM_nla_mapping_get(ac, ale); ChannelDriver *driver = fcu->driver; FPoint *fpt; - float unitFac; + float unitFac, offset; int cfra; SpaceIpo *sipo = (SpaceIpo *) ac->sl; short mapping_flag = ANIM_get_normalization_flags(ac); @@ -336,7 +362,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) fcu->driver = NULL; /* calculate unit-mapping factor */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); /* create samples, but store them in a new curve * - we cannot use fcurve_store_samples() as that will only overwrite the original curve @@ -349,7 +375,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); fpt->vec[0] = cfrae; - fpt->vec[1] = fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) * unitFac; + fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) + offset) * unitFac; } /* set color of ghost curve @@ -498,12 +524,17 @@ static void insert_graph_keys(bAnimContext *ac, short mode) else cfra = (float)CFRA; - /* if there's an id */ - if (ale->id) + /* read value from property the F-Curve represents, or from the curve only? + * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path + * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone, + * so it's easier for now to just read the F-Curve directly. + * (TODO: add the full-blown PointerRNA relative parsing case here...) + */ + if (ale->id && !ale->owner) insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag); else insert_vert_fcurve(fcu, cfra, fcu->curval, 0); - + ale->update |= ANIM_UPDATE_DEFAULT; } @@ -582,7 +613,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) ListBase anim_data; short mapping_flag = ANIM_get_normalization_flags(&ac); - + float scale, offset; /* get frame and value from props */ frame = RNA_float_get(op->ptr, "frame"); val = RNA_float_get(op->ptr, "value"); @@ -592,16 +623,18 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP); /* apply inverse unit-mapping to value to get correct value for F-Curves */ - val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE); - + scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset); + + val = val * scale - offset; + /* insert keyframe on the specified frame + value */ insert_vert_fcurve(fcu, frame, val, 0); - + ale->update |= ANIM_UPDATE_DEPS; - + BLI_listbase_clear(&anim_data); BLI_addtail(&anim_data, ale); - + ANIM_animdata_update(&ac, &anim_data); } else { @@ -851,13 +884,6 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - graphkeys_duplicate_exec(C, op); - - return OPERATOR_FINISHED; -} - void GRAPH_OT_duplicate(wmOperatorType *ot) { /* identifiers */ @@ -866,7 +892,6 @@ void GRAPH_OT_duplicate(wmOperatorType *ot) ot->description = "Make a copy of all selected keyframes"; /* api callbacks */ - ot->invoke = graphkeys_duplicate_invoke; ot->exec = graphkeys_duplicate_exec; ot->poll = graphop_editable_keyframes_poll; @@ -958,7 +983,7 @@ void GRAPH_OT_delete(wmOperatorType *ot) /* ******************** Clean Keyframes Operator ************************* */ -static void clean_graph_keys(bAnimContext *ac, float thresh) +static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; @@ -970,7 +995,7 @@ static void clean_graph_keys(bAnimContext *ac, float thresh) /* loop through filtered data and clean curves */ for (ale = anim_data.first; ale; ale = ale->next) { - clean_fcurve((FCurve *)ale->key_data, thresh); + clean_fcurve(ac, ale, thresh, clean_chan); ale->update |= ANIM_UPDATE_DEFAULT; } @@ -985,6 +1010,7 @@ static int graphkeys_clean_exec(bContext *C, wmOperator *op) { bAnimContext ac; float thresh; + bool clean_chan; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) @@ -992,9 +1018,9 @@ static int graphkeys_clean_exec(bContext *C, wmOperator *op) /* get cleaning threshold */ thresh = RNA_float_get(op->ptr, "threshold"); - + clean_chan = RNA_boolean_get(op->ptr, "channels"); /* clean keyframes */ - clean_graph_keys(&ac, thresh); + clean_graph_keys(&ac, thresh, clean_chan); /* set notifier that keyframes have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); @@ -1019,6 +1045,7 @@ void GRAPH_OT_clean(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f); + RNA_def_boolean(ot->srna, "channels", false, "Channels", ""); } /* ******************** Bake F-Curve Operator *********************** */ @@ -1155,6 +1182,11 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", path); + if (!BLI_is_file(path)) { + BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path); + return OPERATOR_CANCELLED; + } + scene = ac.scene; /* current scene */ /* store necessary data for the baking steps */ @@ -1877,7 +1909,8 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ANIM_nla_mapping_get(&ac, ale); short mapping_flag = ANIM_get_normalization_flags(&ac); KeyframeEditData current_ked; - float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset); memset(¤t_ked, 0, sizeof(current_ked)); @@ -1891,7 +1924,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) ked.f1 += current_ked.f1; ked.i1 += current_ked.i1; - ked.f2 += current_ked.f2 * unit_scale; + ked.f2 += (current_ked.f2 + offset) * unit_scale; ked.i2 += current_ked.i2; } @@ -1984,9 +2017,10 @@ static void snap_graph_keys(bAnimContext *ac, short mode) /* normalise cursor value (for normalised F-Curves display) */ if (mode == GRAPHKEYS_SNAP_VALUE) { short mapping_flag = ANIM_get_normalization_flags(ac); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset); - ked.f1 = cursor_value / unit_scale; + ked.f1 = (cursor_value / unit_scale) - offset; } /* perform snapping */ @@ -2111,9 +2145,10 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) /* apply unit corrections */ if (mode == GRAPHKEYS_MIRROR_VALUE) { short mapping_flag = ANIM_get_normalization_flags(ac); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset); - ked.f1 = cursor_value * unit_scale; + ked.f1 = (cursor_value + offset) * unit_scale; } /* perform actual mirroring */ @@ -2243,7 +2278,7 @@ static EnumPropertyItem *graph_fmodifier_itemf(bContext *C, PointerRNA *UNUSED(p /* start from 1 to skip the 'Invalid' modifier type */ for (i = 1; i < FMODIFIER_NUM_TYPES; i++) { - FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i); + const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i); int index; /* check if modifier is valid for this context */ @@ -2459,3 +2494,154 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot) } /* ************************************************************************** */ + +typedef struct BackDropTransformData { + float init_offset[2]; + float init_zoom; + short event_type; + wmWidgetGroupType *cagetype; +} BackDropTransformData; + +static int graph_widget_backdrop_transform_poll(bContext *C) +{ + SpaceIpo *sipo = CTX_wm_space_graph(C); + ARegion *ar = CTX_wm_region(C); + + return ((sipo != NULL) && + (ar->type->regionid == RGN_TYPE_WINDOW) && + (sipo->flag & SIPO_DRAW_BACKDROP) && + (sipo->backdrop_camera)); +} + +static void widgetgroup_backdrop_draw(const struct bContext *C, struct wmWidgetGroup *wgroup) +{ + ARegion *ar = CTX_wm_region(C); + wmOperator *op = wgroup->type->op; + Scene *scene = CTX_data_scene(C); + int width = (scene->r.size * scene->r.xsch) / 150.0f; + int height = (scene->r.size * scene->r.ysch) / 150.0f; + float origin[3]; + + wmWidget *cage = WIDGET_rect_transform_new(wgroup, WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM | + WIDGET_RECT_TRANSFORM_STYLE_TRANSLATE, width, height); + WM_widget_property(cage, RECT_TRANSFORM_SLOT_OFFSET, op->ptr, "offset"); + WM_widget_property(cage, RECT_TRANSFORM_SLOT_SCALE, op->ptr, "scale"); + + origin[0] = BLI_rcti_size_x(&ar->winrct) / 2.0f; + origin[1] = BLI_rcti_size_y(&ar->winrct) / 2.0f; + + WM_widget_set_origin(cage, origin); +} + +static int graph_widget_backdrop_transform_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ScrArea *sa = CTX_wm_area(C); + SpaceIpo *sipo = CTX_wm_space_graph(C); + /* no poll, lives always for the duration of the operator */ + wmWidgetGroupType *cagetype = WM_widgetgrouptype_new(NULL, widgetgroup_backdrop_draw, CTX_data_main(C), "Graph_Canvas", SPACE_IPO, RGN_TYPE_WINDOW, false); + struct wmEventHandler *handler = WM_event_add_modal_handler(C, op); + BackDropTransformData *data = MEM_mallocN(sizeof(BackDropTransformData), "overdrop transform data"); + WM_modal_handler_attach_widgetgroup(C, handler, cagetype, op); + + RNA_float_set_array(op->ptr, "offset", sipo->backdrop_offset); + RNA_float_set(op->ptr, "scale", sipo->backdrop_zoom); + + copy_v2_v2(data->init_offset, sipo->backdrop_offset); + data->init_zoom = sipo->backdrop_zoom; + data->cagetype = cagetype; + data->event_type = event->type; + + op->customdata = data; + + ED_area_headerprint(sa, "Drag to place, and scale, Space/Enter/Caller key to confirm, R to recenter, RClick/Esc to cancel"); + + return OPERATOR_RUNNING_MODAL; +} + +static void graph_widget_backdrop_transform_finish(bContext *C, BackDropTransformData *data) +{ + ScrArea *sa = CTX_wm_area(C); + ED_area_headerprint(sa, NULL); + WM_widgetgrouptype_unregister(C, CTX_data_main(C), data->cagetype); + MEM_freeN(data); +} + +static void graph_widget_backdrop_transform_cancel(struct bContext *C, struct wmOperator *op) +{ + BackDropTransformData *data = op->customdata; + graph_widget_backdrop_transform_finish(C, data); +} + +static int graph_widget_backdrop_transform_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + BackDropTransformData *data = op->customdata; + + if (event->type == data->event_type && event->val == KM_PRESS) { + graph_widget_backdrop_transform_finish(C, data); + return OPERATOR_FINISHED; + } + + switch (event->type) { + case EVT_WIDGET_UPDATE: { + SpaceIpo *sipo = CTX_wm_space_graph(C); + RNA_float_get_array(op->ptr, "offset", sipo->backdrop_offset); + sipo->backdrop_zoom = RNA_float_get(op->ptr, "scale"); + break; + } + case RKEY: + { + SpaceIpo *sipo = CTX_wm_space_graph(C); + ARegion *ar = CTX_wm_region(C); + float zero[2] = {0.0f}; + RNA_float_set_array(op->ptr, "offset", zero); + RNA_float_set(op->ptr, "scale", 1.0f); + copy_v2_v2(sipo->backdrop_offset, zero); + sipo->backdrop_zoom = 1.0f; + ED_region_tag_redraw(ar); + /* add a mousemove to refresh the widget */ + WM_event_add_mousemove(C); + break; + } + case RETKEY: + case PADENTER: + case SPACEKEY: + { + graph_widget_backdrop_transform_finish(C, data); + return OPERATOR_FINISHED; + } + case ESCKEY: + case RIGHTMOUSE: + { + SpaceIpo *sipo = CTX_wm_space_graph(C); + copy_v2_v2(sipo->backdrop_offset, data->init_offset); + sipo->backdrop_zoom = data->init_zoom; + + graph_widget_backdrop_transform_finish(C, data); + return OPERATOR_CANCELLED; + } + } + + return OPERATOR_RUNNING_MODAL; +} + +void GRAPH_OT_widget_backdrop_transform(struct wmOperatorType *ot) +{ + float default_offset[2] = {0.0f, 0.0f}; + + /* identifiers */ + ot->name = "Transform Backdrop"; + ot->idname = "GRAPH_OT_widget_backdrop_transform"; + ot->description = ""; + + /* api callbacks */ + ot->invoke = graph_widget_backdrop_transform_invoke; + ot->modal = graph_widget_backdrop_transform_modal; + ot->poll = graph_widget_backdrop_transform_poll; + ot->cancel = graph_widget_backdrop_transform_cancel; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_float_array(ot->srna, "offset", 2, default_offset, FLT_MIN, FLT_MAX, "Offset", "Offset of the backdrop", FLT_MIN, FLT_MAX); + RNA_def_float(ot->srna, "scale", 1.0f, 0.0f, FLT_MAX, "Scale", "Scale of the backdrop", 0.0f, FLT_MAX); +} diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 50412952139..35267cbf999 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -32,11 +32,8 @@ #define __GRAPH_INTERN_H__ struct bContext; -struct wmWindowManager; struct bAnimContext; struct bAnimListElem; -struct FCurve; -struct FModifier; struct SpaceIpo; struct ScrArea; struct ARegion; @@ -94,6 +91,7 @@ void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xma void GRAPH_OT_previewrange_set(struct wmOperatorType *ot); void GRAPH_OT_view_all(struct wmOperatorType *ot); void GRAPH_OT_view_selected(struct wmOperatorType *ot); +void GRAPH_OT_view_frame(struct wmOperatorType *ot); void GRAPH_OT_click_insert(struct wmOperatorType *ot); void GRAPH_OT_keyframe_insert(struct wmOperatorType *ot); @@ -119,6 +117,8 @@ void GRAPH_OT_frame_jump(struct wmOperatorType *ot); void GRAPH_OT_snap(struct wmOperatorType *ot); void GRAPH_OT_mirror(struct wmOperatorType *ot); +void GRAPH_OT_widget_backdrop_transform(struct wmOperatorType *ot); + /* defines for snap keyframes * NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h) */ diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index da308d0b1f1..9b5fa3b744a 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -87,8 +87,9 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op) * NOTE: sync this part of the code with ANIM_OT_change_frame */ CFRA = RNA_int_get(op->ptr, "frame"); + FRAMENUMBER_MIN_CLAMP(CFRA); SUBFRA = 0.f; - sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); /* set the cursor value */ sipo->cursorVal = RNA_float_get(op->ptr, "value"); @@ -138,12 +139,16 @@ static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent /* Modal Operator init */ static int graphview_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + wmWindow *win = CTX_wm_window(C); /* Change to frame that mouse is over before adding modal handler, * as user could click on a single frame (jump to frame) as well as * click-dragging over a range (modal scrubbing). */ graphview_cursor_setprops(C, op, event); - + + if (win->screen) + win->screen->scrubbing = true; + /* apply these changes first */ graphview_cursor_apply(C, op); @@ -155,9 +160,13 @@ static int graphview_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *e /* Modal event handling of cursor changing */ static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *event) { + wmWindow *win = CTX_wm_window(C); + /* execute the events */ switch (event->type) { case ESCKEY: + if (win->screen) + win->screen->scrubbing = false; return OPERATOR_FINISHED; case MOUSEMOVE: @@ -172,8 +181,12 @@ static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *ev /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init * the modal op) doesn't work for some reason */ - if (event->val == KM_RELEASE) + if (event->val == KM_RELEASE) { + if (win->screen) + win->screen->scrubbing = false; + return OPERATOR_FINISHED; + } break; } @@ -380,6 +393,7 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_view_all); WM_operatortype_append(GRAPH_OT_view_selected); WM_operatortype_append(GRAPH_OT_properties); + WM_operatortype_append(GRAPH_OT_view_frame); WM_operatortype_append(GRAPH_OT_ghost_curves_create); WM_operatortype_append(GRAPH_OT_ghost_curves_clear); @@ -427,6 +441,8 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_fmodifier_add); WM_operatortype_append(GRAPH_OT_fmodifier_copy); WM_operatortype_append(GRAPH_OT_fmodifier_paste); + + WM_operatortype_append(GRAPH_OT_widget_backdrop_transform); } void ED_operatormacros_graph(void) @@ -440,6 +456,7 @@ void ED_operatormacros_graph(void) WM_operatortype_macro_define(ot, "GRAPH_OT_duplicate"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform"); RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE); + RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF); } @@ -562,15 +579,14 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) WM_keymap_add_item(keymap, "GRAPH_OT_easing_type", EKEY, KM_PRESS, KM_CTRL, 0); /* destructive */ - WM_keymap_add_item(keymap, "GRAPH_OT_clean", OKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GRAPH_OT_smooth", OKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "GRAPH_OT_sample", OKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "GRAPH_OT_bake", CKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "GRAPH_OT_delete", XKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "GRAPH_OT_delete", DELKEY, KM_PRESS, 0, 0); - + WM_keymap_add_menu(keymap, "GRAPH_MT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "GRAPH_MT_delete", DELKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "GRAPH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); /* insertkey */ @@ -594,7 +610,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GRAPH_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GRAPH_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); - + WM_keymap_add_item(keymap, "GRAPH_OT_view_frame", PAD0, KM_PRESS, 0, 0); + /* F-Modifiers */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "only_active", false); @@ -608,6 +625,9 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* transform system */ transform_keymap_for_space(keyconf, keymap, SPACE_IPO); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_fcurve"); + /* pivot point settings */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); @@ -661,5 +681,7 @@ void graphedit_keymap(wmKeyConfig *keyconf) /* keyframes */ keymap = WM_keymap_find(keyconf, "Graph Editor", SPACE_IPO, 0); graphedit_keymap_keyframes(keyconf, keymap); + + WM_keymap_add_item(keymap, "GRAPH_OT_widget_backdrop_transform", WKEY, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 78dbae7618b..4cf8a1de7ab 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -272,7 +272,8 @@ static void borderselect_graphkeys( for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); FCurve *fcu = (FCurve *)ale->key_data; - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); /* apply NLA mapping to all the keyframes, since it's easier than trying to * guess when a callback might use something different @@ -282,8 +283,8 @@ static void borderselect_graphkeys( scaled_rectf.xmin = rectf.xmin; scaled_rectf.xmax = rectf.xmax; - scaled_rectf.ymin = rectf.ymin / unit_scale; - scaled_rectf.ymax = rectf.ymax / unit_scale; + scaled_rectf.ymin = rectf.ymin / unit_scale - offset; + scaled_rectf.ymax = rectf.ymax / unit_scale - offset; /* set horizontal range (if applicable) * NOTE: these values are only used for x-range and y-range but not region @@ -1089,6 +1090,8 @@ typedef struct tNearestVertInfo { short hpoint; /* the handle index that we hit (eHandleIndex) */ short sel; /* whether the handle is selected or not */ int dist; /* distance from mouse to vert */ + + eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */ } tNearestVertInfo; /* Tags for the type of graph vert that we have */ @@ -1116,8 +1119,8 @@ static bool fcurve_handle_sel_check(SpaceIpo *sipo, BezTriple *bezt) /* check if the given vertex is within bounds or not */ // TODO: should we return if we hit something? static void nearest_fcurve_vert_store( - ListBase *matches, View2D *v2d, FCurve *fcu, - BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale) + ListBase *matches, View2D *v2d, FCurve *fcu, eAnim_ChannelType ctype, + BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale, float offset) { /* Keyframes or Samples? */ if (bezt) { @@ -1129,7 +1132,7 @@ static void nearest_fcurve_vert_store( * 'vec' matrix */ if (UI_view2d_view_to_region_clip(v2d, - bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale, + bezt->vec[hpoint + 1][0], (bezt->vec[hpoint + 1][1] + offset) * unit_scale, &screen_co[0], &screen_co[1]) && /* check if distance from mouse cursor to vert in screen space is within tolerance */ ((dist = len_v2v2_int(mval, screen_co)) <= GVERTSEL_TOL)) @@ -1149,6 +1152,8 @@ static void nearest_fcurve_vert_store( /* store values */ nvi->fcu = fcu; + nvi->ctype = ctype; + nvi->bezt = bezt; nvi->hpoint = hpoint; nvi->dist = dist; @@ -1189,30 +1194,31 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L for (ale = anim_data.first; ale; ale = ale->next) { FCurve *fcu = (FCurve *)ale->key_data; AnimData *adt = ANIM_nla_mapping_get(ac, ale); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); - + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); + /* apply NLA mapping to all the keyframes */ if (adt) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0); - + if (fcu->bezt) { BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL; int i; for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) { /* keyframe */ - nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale); + nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale, offset); /* handles - only do them if they're visible */ if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) { /* first handle only visible if previous segment had handles */ if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) { - nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale); + nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale, offset); } /* second handle only visible if this segment is bezier */ if (bezt1->ipo == BEZT_IPO_BEZ) { - nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale); + nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale, offset); } } } @@ -1405,7 +1411,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m /* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */ if (nvi->fcu->flag & FCURVE_SELECTED) { int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); - ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE); + ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype); } /* free temp sample data for filtering */ diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index eea360ced45..0e56dc817e4 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -210,13 +210,18 @@ int graphop_active_fcurve_poll(bContext *C) if (ale == NULL) return 0; - /* free temp data... */ - has_fcurve = ((ale->data) && (ale->type == ANIMTYPE_FCURVE)); + /* do we have a suitable F-Curves? + * - For most cases, NLA Control Curves are sufficiently similar to NLA curves to serve this role too. + * Under the hood, they are F-Curves too. The only problems which will arise here are if these need to be + * in an Action too (but drivers would then also be affected!) + */ + has_fcurve = ((ale->data) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)); if (has_fcurve) { FCurve *fcu = (FCurve *)ale->data; has_fcurve = (fcu->flag & FCURVE_VISIBLE) != 0; } + /* free temp data... */ MEM_freeN(ale); /* return success */ diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index ad6f3ff5c7e..4fd6276a28f 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -103,6 +103,10 @@ static SpaceLink *graph_new(const bContext *C) sipo->autosnap = SACTSNAP_FRAME; + sipo->backdrop_camera = scene->camera; + sipo->backdrop_zoom = 1.0f; + sipo->backdrop_opacity = 0.7f; + /* allocate DopeSheet data for Graph Editor */ sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet"); sipo->ads->source = (ID *)scene; @@ -219,18 +223,25 @@ static void graph_main_area_init(wmWindowManager *wm, ARegion *ar) WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); keymap = WM_keymap_find(wm->defaultconf, "Graph Editor Generic", SPACE_IPO, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* widgets */ + if (BLI_listbase_is_empty(&ar->widgetmaps)) { + BLI_addhead(&ar->widgetmaps, WM_widgetmap_from_type("Graph_Canvas", SPACE_IPO, RGN_TYPE_WINDOW, false)); + } } static void graph_main_area_draw(const bContext *C, ARegion *ar) { /* draw entirely, view changes should be handled here */ SpaceIpo *sipo = CTX_wm_space_graph(C); + Scene *scene = CTX_data_scene(C); bAnimContext ac; View2D *v2d = &ar->v2d; View2DGrid *grid; View2DScrollers *scrollers; float col[3]; short unitx = 0, unity = V2D_UNIT_VALUES, flag = 0; + const bool draw_backdrop = ((sipo->flag & SIPO_DRAW_BACKDROP) && (sipo->backdrop_camera != NULL)); /* clear and setup matrix */ UI_GetThemeColor3fv(TH_BACK, col); @@ -241,11 +252,26 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar) /* grid */ unitx = (sipo->flag & SIPO_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE; - grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy); + grid = UI_view2d_grid_calc(scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy); UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL); ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - + + if (draw_backdrop) { + int width = (scene->r.size * scene->r.xsch) / 150 * sipo->backdrop_zoom; + int height = (scene->r.size * scene->r.ysch) / 150 * sipo->backdrop_zoom; + float xofs = (BLI_rcti_size_x(&ar->winrct) - width) / 2.0f + sipo->backdrop_offset[0]; + float yofs = (BLI_rcti_size_y(&ar->winrct) - height) / 2.0f + sipo->backdrop_offset[1]; + + /* reset view matrix */ + UI_view2d_view_restore(C); + + ED_region_draw_backdrop_view3d(C, sipo->backdrop_camera, sipo->backdrop_opacity, + width, height, xofs, yofs, 1.0f, 1.0f, true); + + UI_view2d_view_ortho(v2d); + } + /* draw data */ if (ANIM_animdata_get_context(C, &ac)) { /* draw ghost curves */ @@ -306,6 +332,10 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar) /* reset view matrix */ UI_view2d_view_restore(C); + /* finally draw any widgets here */ + WM_widgets_update(C, ar->widgetmaps.first); + WM_widgets_draw(C, ar->widgetmaps.first, false); + /* scrollers */ // FIXME: args for scrollers depend on the type of data being shown... scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP); @@ -611,6 +641,14 @@ static void graph_refresh(const bContext *C, ScrArea *sa) } } +/* ************************************* */ + +static void graph_widgets(void) +{ + /* create the widgetmap for the area here */ + WM_widgetmaptype_find("Graph_Canvas", SPACE_IPO, RGN_TYPE_WINDOW, false, true); +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_ipo(void) { @@ -628,6 +666,7 @@ void ED_spacetype_ipo(void) st->keymap = graphedit_keymap; st->listener = graph_listener; st->refresh = graph_refresh; + st->widgets = graph_widgets; /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); |