Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_sequencer/sequencer_view.c')
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c335
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);
+}
+