diff options
Diffstat (limited to 'source/blender/editors/space_sequencer/sequencer_view.c')
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_view.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 4d6ea865b40..a0f0c80883d 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -33,8 +33,10 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_rect.h" #include "DNA_scene_types.h" +#include "DNA_widget_types.h" #include "BKE_context.h" #include "BKE_main.h" @@ -47,6 +49,7 @@ #include "ED_image.h" #include "ED_screen.h" #include "ED_space_api.h" +#include "ED_sequencer.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -54,6 +57,8 @@ #include "UI_view2d.h" +#include "RNA_define.h" + /* own include */ #include "sequencer_intern.h" @@ -241,3 +246,333 @@ void SEQUENCER_OT_sample(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_BLOCKING; } + +/******** Backdrop Transform *******/ + +typedef struct OverDropTransformData { + ImBuf *ibuf; /* image to be transformed (preview image transformation widget) */ + int init_size[2]; + float init_zoom; + float init_offset[2]; + int event_type; + wmWidgetGroupType *cagetype; +} OverDropTransformData; + +static int sequencer_overdrop_transform_poll(bContext *C) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + ARegion *ar = CTX_wm_region(C); + + return (sseq && ar && ar->type->regionid == RGN_TYPE_WINDOW && (sseq->draw_flag & SEQ_DRAW_OVERDROP)); +} + +static void widgetgroup_overdrop_draw(const struct bContext *C, struct wmWidgetGroup *wgroup) +{ + ARegion *ar = CTX_wm_region(C); + wmOperator *op = wgroup->type->op; + Scene *sce = CTX_data_scene(C); + int sizex = (sce->r.size * sce->r.xsch) / 100; + int sizey = (sce->r.size * sce->r.ysch) / 100; + float origin[3]; + + wmWidget *cage = WIDGET_rect_transform_new(wgroup, WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM | + WIDGET_RECT_TRANSFORM_STYLE_TRANSLATE, sizex, sizey); + 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 sequencer_overdrop_transform_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ScrArea *sa = CTX_wm_area(C); + SpaceSeq *sseq = CTX_wm_space_seq(C); + /* no poll, lives always for the duration of the operator */ + wmWidgetGroupType *cagetype = WM_widgetgrouptype_new(NULL, widgetgroup_overdrop_draw, CTX_data_main(C), "Seq_Canvas", SPACE_SEQ, RGN_TYPE_WINDOW, false); + struct wmEventHandler *handler = WM_event_add_modal_handler(C, op); + OverDropTransformData *data = MEM_mallocN(sizeof(OverDropTransformData), "overdrop transform data"); + WM_modal_handler_attach_widgetgroup(C, handler, cagetype, op); + + RNA_float_set_array(op->ptr, "offset", sseq->overdrop_offset); + RNA_float_set(op->ptr, "scale", sseq->overdrop_zoom); + + copy_v2_v2(data->init_offset, sseq->overdrop_offset); + data->init_zoom = sseq->overdrop_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 sequencer_overdrop_finish(bContext *C, OverDropTransformData *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 sequencer_overdrop_cancel(struct bContext *C, struct wmOperator *op) +{ + OverDropTransformData *data = op->customdata; + sequencer_overdrop_finish(C, data); +} + +static int sequencer_overdrop_transform_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + OverDropTransformData *data = op->customdata; + + if (event->type == data->event_type && event->val == KM_PRESS) { + sequencer_overdrop_finish(C, data); + return OPERATOR_FINISHED; + } + + switch (event->type) { + case EVT_WIDGET_UPDATE: { + SpaceSeq *sseq = CTX_wm_space_seq(C); + RNA_float_get_array(op->ptr, "offset", sseq->overdrop_offset); + sseq->overdrop_zoom = RNA_float_get(op->ptr, "scale"); + break; + } + + case RKEY: + { + SpaceSeq *sseq = CTX_wm_space_seq(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(sseq->overdrop_offset, zero); + sseq->overdrop_zoom = 1.0; + ED_region_tag_redraw(ar); + /* add a mousemove to refresh the widget */ + WM_event_add_mousemove(C); + break; + } + case RETKEY: + case PADENTER: + case SPACEKEY: + { + sequencer_overdrop_finish(C, data); + return OPERATOR_FINISHED; + } + + case ESCKEY: + case RIGHTMOUSE: + { + SpaceSeq *sseq = CTX_wm_space_seq(C); + copy_v2_v2(sseq->overdrop_offset, data->init_offset); + sseq->overdrop_zoom = data->init_zoom; + + sequencer_overdrop_finish(C, data); + return OPERATOR_CANCELLED; + } + } + + return OPERATOR_RUNNING_MODAL; +} + +void SEQUENCER_OT_overdrop_transform(struct wmOperatorType *ot) +{ + float default_offset[2] = {0.0f, 0.0f}; + + /* identifiers */ + ot->name = "Change Data/Files"; + ot->idname = "SEQUENCER_OT_overdrop_transform"; + ot->description = ""; + + /* api callbacks */ + ot->invoke = sequencer_overdrop_transform_invoke; + ot->modal = sequencer_overdrop_transform_modal; + ot->poll = sequencer_overdrop_transform_poll; + ot->cancel = sequencer_overdrop_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); +} + +/******** transform widget (preview area) *******/ + +typedef struct ImageTransformData { + ImBuf *ibuf; /* image to be transformed (preview image transformation widget) */ + int init_size[2]; + int event_type; + wmWidgetGroupType *cagetype; +} ImageTransformData; + +static int sequencer_image_transform_widget_poll(bContext *C) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + ARegion *ar = CTX_wm_region(C); + + return (sseq && ar && ar->type->regionid == RGN_TYPE_PREVIEW); +} + +static void widgetgroup_image_transform_draw(const struct bContext *C, struct wmWidgetGroup *wgroup) +{ + ARegion *ar = CTX_wm_region(C); + View2D *v2d = &ar->v2d; + wmOperator *op = wgroup->type->op; + wmWidget *cage; + float origin[3]; + float viewrect[2]; + float scale[2]; + + sequencer_display_size(CTX_data_scene(C), CTX_wm_space_seq(C), viewrect); + UI_view2d_scale_get(v2d, &scale[0], &scale[1]); + + cage = WIDGET_rect_transform_new(wgroup, WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM | + WIDGET_RECT_TRANSFORM_STYLE_TRANSLATE, + viewrect[0] * scale[0], viewrect[1] * scale[1]); + WM_widget_property(cage, RECT_TRANSFORM_SLOT_SCALE, op->ptr, "scale"); + + origin[0] = -(v2d->cur.xmin * scale[0]); + origin[1] = -(v2d->cur.ymin * scale[1]); + WM_widget_set_origin(cage, origin); +} + +static int sequencer_image_transform_widget_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ScrArea *sa = CTX_wm_area(C); + SpaceSeq *sseq = CTX_wm_space_seq(C); + Scene *scene = CTX_data_scene(C); + /* no poll, lives always for the duration of the operator */ + wmWidgetGroupType *cagetype = WM_widgetgrouptype_new(NULL, widgetgroup_image_transform_draw, CTX_data_main(C), + "Seq_Canvas", SPACE_SEQ, RGN_TYPE_PREVIEW, false); + struct wmEventHandler *handler = WM_event_add_modal_handler(C, op); + ImageTransformData *data = MEM_mallocN(sizeof(ImageTransformData), "overdrop transform data"); + ImBuf *ibuf = sequencer_ibuf_get(CTX_data_main(C), scene, sseq, CFRA, 0, NULL); + + if (!ibuf || !ED_space_sequencer_check_show_imbuf(sseq)) { + return OPERATOR_CANCELLED; + } + + WM_modal_handler_attach_widgetgroup(C, handler, cagetype, op); + + copy_v2_v2_int(data->init_size, &ibuf->x); + data->cagetype = cagetype; + data->event_type = event->type; + data->ibuf = ibuf; + + 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 sequencer_image_transform_widget_finish(bContext *C, ImageTransformData *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 sequencer_image_transform_widget_cancel(struct bContext *C, struct wmOperator *op) +{ + ImageTransformData *data = op->customdata; + sequencer_image_transform_widget_finish(C, data); +} + +static int sequencer_image_transform_widget_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + ImageTransformData *data = op->customdata; + + if (event->type == data->event_type && event->val == KM_PRESS) { + sequencer_image_transform_widget_finish(C, data); + return OPERATOR_FINISHED; + } + + switch (event->type) { + case EVT_WIDGET_UPDATE: + { + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + wmWidgetMap *wmap = ar->widgetmaps.first; + float scale_fac = RNA_float_get(op->ptr, "scale"); + float new_size[2]; + float offset[2]; + + new_size[0] = (float)data->init_size[0] * scale_fac; + new_size[1] = (float)data->init_size[1] * scale_fac; + + /* sale image */ + IMB_scalefastImBuf(data->ibuf, (unsigned int)new_size[0], (unsigned int)new_size[1]); + + /* update view */ + scene->r.xsch = (int)(new_size[0] / ((float)scene->r.size / 100)); + scene->r.ysch = (int)(new_size[1] / ((float)scene->r.size / 100)); + + /* no offset needed in this case */ + offset[0] = offset[1] = 0; + WIDGET_rect_transform_set_offset(wmap->active_widget, offset); + break; + } + + case RKEY: + { +// SpaceSeq *sseq = CTX_wm_space_seq(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(sseq->overdrop_offset, zero); +// sseq->overdrop_zoom = 1.0; + ED_region_tag_redraw(ar); + /* add a mousemove to refresh the widget */ + WM_event_add_mousemove(C); + break; + } + case RETKEY: + case PADENTER: + case SPACEKEY: + { + sequencer_image_transform_widget_finish(C, data); + return OPERATOR_FINISHED; + } + + case ESCKEY: + case RIGHTMOUSE: + { +// SpaceSeq *sseq = CTX_wm_space_seq(C); +// copy_v2_v2(sseq->overdrop_offset, data->init_offset); +// sseq->overdrop_zoom = data->init_zoom; + + sequencer_image_transform_widget_finish(C, data); + return OPERATOR_CANCELLED; + } + } + + return OPERATOR_RUNNING_MODAL; +} + +void SEQUENCER_OT_image_transform_widget(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Image Transform"; + ot->idname = "SEQUENCER_OT_image_transform_widget"; + ot->description = "Transform the image using a widget"; + + /* api callbacks */ + ot->invoke = sequencer_image_transform_widget_invoke; + ot->modal = sequencer_image_transform_widget_modal; + ot->poll = sequencer_image_transform_widget_poll; + ot->cancel = sequencer_image_transform_widget_cancel; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_float(ot->srna, "scale", 1.0f, 0.0f, FLT_MAX, "Scale", "Scale of the backdrop", 0.0f, FLT_MAX); +} + |