diff --git a/effects/internal/cornerpineffect.cpp b/effects/internal/cornerpineffect.cpp index 1f8650e0e..d2ff57ba9 100644 --- a/effects/internal/cornerpineffect.cpp +++ b/effects/internal/cornerpineffect.cpp @@ -27,6 +27,11 @@ CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em) perspective = add_row("Perspective:")->add_field(EFFECT_FIELD_BOOL, "perspective"); perspective->set_bool_value(true); + top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT); + top_right_gizmo = add_gizmo(GIZMO_TYPE_DOT); + bottom_left_gizmo = add_gizmo(GIZMO_TYPE_DOT); + bottom_right_gizmo = add_gizmo(GIZMO_TYPE_DOT); + vertPath = "cornerpin.vert"; fragPath = "cornerpin.frag"; } @@ -50,5 +55,28 @@ void CornerPinEffect::process_shader(double timecode, GLTextureCoords &coords) { glslProgram->setUniformValue("p1", (GLfloat) coords.vertexBottomRightX, (GLfloat) coords.vertexBottomRightY); glslProgram->setUniformValue("p2", (GLfloat) coords.vertexTopLeftX, (GLfloat) coords.vertexTopLeftY); glslProgram->setUniformValue("p3", (GLfloat) coords.vertexTopRightX, (GLfloat) coords.vertexTopRightY); - glslProgram->setUniformValue("perspective", perspective->get_bool_value(timecode)); + glslProgram->setUniformValue("perspective", perspective->get_bool_value(timecode)); +} + +void CornerPinEffect::gizmo_draw(double timecode, GLTextureCoords &coords) { + top_left_gizmo->set_pos(coords.vertexTopLeftX, coords.vertexTopLeftY); + top_right_gizmo->set_pos(coords.vertexTopRightX, coords.vertexTopRightY); + bottom_right_gizmo->set_pos(coords.vertexBottomRightX, coords.vertexBottomRightY); + bottom_left_gizmo->set_pos(coords.vertexBottomLeftX, coords.vertexBottomLeftY); +} + +void CornerPinEffect::gizmo_move(EffectGizmo *sender, int x_movement, int y_movement, double timecode) { + if (sender == bottom_right_gizmo) { + bottom_right_x->set_double_value(bottom_right_x->get_double_value(timecode) + x_movement); + bottom_right_y->set_double_value(bottom_right_y->get_double_value(timecode) + y_movement); + } else if (sender == top_left_gizmo) { + top_left_x->set_double_value(top_left_x->get_double_value(timecode) + x_movement); + top_left_y->set_double_value(top_left_y->get_double_value(timecode) + y_movement); + } else if (sender == bottom_left_gizmo) { + bottom_left_x->set_double_value(bottom_left_x->get_double_value(timecode) + x_movement); + bottom_left_y->set_double_value(bottom_left_y->get_double_value(timecode) + y_movement); + } else if (sender == top_right_gizmo) { + top_right_x->set_double_value(top_right_x->get_double_value(timecode) + x_movement); + top_right_y->set_double_value(top_right_y->get_double_value(timecode) + y_movement); + } } diff --git a/effects/internal/cornerpineffect.h b/effects/internal/cornerpineffect.h index 164101a58..b0d615142 100644 --- a/effects/internal/cornerpineffect.h +++ b/effects/internal/cornerpineffect.h @@ -9,6 +9,8 @@ public: CornerPinEffect(Clip* c, const EffectMeta* em); void process_coords(double timecode, GLTextureCoords& coords, int data); void process_shader(double timecode, GLTextureCoords& coords); + void gizmo_draw(double timecode, GLTextureCoords& coords); + void gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode); private: EffectField* top_left_x; EffectField* top_left_y; @@ -19,6 +21,11 @@ private: EffectField* bottom_right_x; EffectField* bottom_right_y; EffectField* perspective; + + EffectGizmo* top_left_gizmo; + EffectGizmo* top_right_gizmo; + EffectGizmo* bottom_left_gizmo; + EffectGizmo* bottom_right_gizmo; }; #endif // CORNERPINEFFECT_H diff --git a/effects/internal/transformeffect.cpp b/effects/internal/transformeffect.cpp index 73d4353fd..bc793d8f0 100644 --- a/effects/internal/transformeffect.cpp +++ b/effects/internal/transformeffect.cpp @@ -74,6 +74,15 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) left_center_gizmo = add_gizmo(GIZMO_TYPE_DOT); right_center_gizmo = add_gizmo(GIZMO_TYPE_DOT); + top_left_gizmo->set_cursor(Qt::SizeFDiagCursor); + top_center_gizmo->set_cursor(Qt::SizeVerCursor); + top_right_gizmo->set_cursor(Qt::SizeBDiagCursor); + bottom_left_gizmo->set_cursor(Qt::SizeBDiagCursor); + bottom_center_gizmo->set_cursor(Qt::SizeVerCursor); + bottom_right_gizmo->set_cursor(Qt::SizeFDiagCursor); + left_center_gizmo->set_cursor(Qt::SizeHorCursor); + right_center_gizmo->set_cursor(Qt::SizeHorCursor); + // set defaults scale_y->set_enabled(false); uniform_scale_field->set_bool_value(true); @@ -169,6 +178,39 @@ void TransformEffect::gizmo_draw(double timecode, GLTextureCoords& coords) { } void TransformEffect::gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode) { - position_x->set_double_value(position_x->get_double_value(timecode) + x_movement); - position_y->set_double_value(position_y->get_double_value(timecode) + y_movement); + double x_percent = ((double) x_movement / parent_clip->sequence->width)*200; + double y_percent = ((double) y_movement / parent_clip->sequence->height)*200; + + if (sender == bottom_right_gizmo) { + scale_x->set_double_value(scale_x->get_double_value(timecode) + x_percent); + if (!uniform_scale_field->get_bool_value(timecode)) scale_y->set_double_value(scale_y->get_double_value(timecode) + y_percent); + } else if (sender == top_left_gizmo) { + scale_x->set_double_value(scale_x->get_double_value(timecode) - x_percent); + if (!uniform_scale_field->get_bool_value(timecode)) scale_y->set_double_value(scale_y->get_double_value(timecode) - y_percent); + } else if (sender == bottom_left_gizmo) { + scale_x->set_double_value(scale_x->get_double_value(timecode) - x_percent); + if (!uniform_scale_field->get_bool_value(timecode)) scale_y->set_double_value(scale_y->get_double_value(timecode) + y_percent); + } else if (sender == top_right_gizmo) { + scale_x->set_double_value(scale_x->get_double_value(timecode) + x_percent); + if (!uniform_scale_field->get_bool_value(timecode)) scale_y->set_double_value(scale_y->get_double_value(timecode) - y_percent); + } else if (sender == left_center_gizmo) { + scale_x->set_double_value(scale_x->get_double_value(timecode) - x_percent); + } else if (sender == right_center_gizmo) { + scale_x->set_double_value(scale_x->get_double_value(timecode) + x_percent); + } else if (sender == top_center_gizmo) { + if (uniform_scale_field->get_bool_value(timecode)) { + scale_x->set_double_value(scale_x->get_double_value(timecode) - y_percent); + } else { + scale_y->set_double_value(scale_y->get_double_value(timecode) - y_percent); + } + } else if (sender == bottom_center_gizmo) { + if (uniform_scale_field->get_bool_value(timecode)) { + scale_x->set_double_value(scale_x->get_double_value(timecode) + y_percent); + } else { + scale_y->set_double_value(scale_y->get_double_value(timecode) + y_percent); + } + } else { + position_x->set_double_value(position_x->get_double_value(timecode) + x_movement); + position_y->set_double_value(position_y->get_double_value(timecode) + y_movement); + } } diff --git a/project/effect.cpp b/project/effect.cpp index 228c45bee..8bf538fca 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -855,8 +855,8 @@ void Effect::gizmo_world_to_screen() { glGetFloatv(GL_MODELVIEW_MATRIX, view_val); glGetFloatv(GL_PROJECTION_MATRIX, projection_val); - QMatrix4x4 view_matrix(view_val[0], view_val[4], view_val[8], view_val[12], view_val[1], view_val[5], view_val[9], view_val[13], view_val[2], view_val[6], view_val[10], view_val[14], view_val[3], view_val[7], view_val[11], view_val[15]); - QMatrix4x4 projection_matrix(projection_val[0], projection_val[4], projection_val[8], projection_val[12], projection_val[1], projection_val[5], projection_val[9], projection_val[13], projection_val[2], projection_val[6], projection_val[10], projection_val[14], projection_val[3], projection_val[7], projection_val[11], projection_val[15]); + QMatrix4x4 view_matrix(view_val); + QMatrix4x4 projection_matrix(projection_val); for (int i=0;iget_x(), g->get_y(), 0, 1.0); QVector4D screen_pos = world_pos * (view_matrix * projection_matrix); - g->set_screen_pos(screen_pos.x(), screen_pos.y()); + int adjusted_sx = qRound(((screen_pos.x()*0.5)+0.5)*parent_clip->sequence->width); + int adjusted_sy = qRound((1.0-((screen_pos.y()*0.5)+0.5))*parent_clip->sequence->height); + + g->set_screen_pos(adjusted_sx, adjusted_sy); } } diff --git a/project/effectgizmo.cpp b/project/effectgizmo.cpp index a6a747863..8cb3c7437 100644 --- a/project/effectgizmo.cpp +++ b/project/effectgizmo.cpp @@ -1,7 +1,8 @@ #include "effectgizmo.h" EffectGizmo::EffectGizmo(int type) : - type(type) + type(type), + cursor(-1) {} void EffectGizmo::set_pos(int ix, int iy) { @@ -33,3 +34,11 @@ int EffectGizmo::get_screen_x() { int EffectGizmo::get_screen_y() { return sy; } + +int EffectGizmo::get_cursor() { + return cursor; +} + +void EffectGizmo::set_cursor(int c) { + cursor = c; +} diff --git a/project/effectgizmo.h b/project/effectgizmo.h index 6a9588d95..6473af0f7 100644 --- a/project/effectgizmo.h +++ b/project/effectgizmo.h @@ -4,7 +4,10 @@ #define GIZMO_TYPE_DOT 0 #define GIZMO_TYPE_QUAD 1 +#define GIZMO_DOT_SIZE 2.5F + #include +#include class EffectGizmo { @@ -19,12 +22,16 @@ public: void set_screen_pos(int isx, int isy); int get_screen_x(); int get_screen_y(); + + int get_cursor(); + void set_cursor(int c); private: int type; int x; int y; int sx; int sy; + int cursor; }; #endif // EFFECTGIZMO_H diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index e1470406e..ab6f50930 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -39,8 +39,10 @@ ViewerWidget::ViewerWidget(QWidget *parent) : QOpenGLWidget(parent), default_fbo(NULL), waveform(false), - dragging(false) + dragging(false), + selected_gizmo(NULL) { + setMouseTracking(true); setFocusPolicy(Qt::ClickFocus); QSurfaceFormat format; @@ -134,6 +136,25 @@ double get_timecode(Clip* c, long playhead) { return ((double)(playhead-c->get_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate); } +EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { + if (gizmos != NULL) { + double multiplier = (double) width() / (double) viewer->seq->width; + int dot_size = qRound(GIZMO_DOT_SIZE / width() * viewer->seq->width); + for (int i=0;igizmo_count();i++) { + EffectGizmo* g = gizmos->gizmo(i); + + if (x > g->get_screen_x()*multiplier - dot_size + && y > g->get_screen_y()*multiplier - dot_size + && x < g->get_screen_x()*multiplier + dot_size + && y < g->get_screen_y()*multiplier + dot_size) { + return g; + break; + } + } + } + return NULL; +} + void ViewerWidget::mousePressEvent(QMouseEvent* event) { if (waveform) { seek_from_click(event->x()); @@ -141,15 +162,7 @@ void ViewerWidget::mousePressEvent(QMouseEvent* event) { drag_start_x = event->pos().x(); drag_start_y = event->pos().y(); - if (gizmos != NULL) { - int clicked = -1; - for (int i=0;igizmo_count();i++) { - EffectGizmo* g = gizmos->gizmo(i); - - dout << "gizmo" << i << "screen pos was" << g->get_screen_x() << g->get_screen_y() << "compared to" << g->get_x() << g->get_y(); - } - dout << "clicked on" << clicked; - } + selected_gizmo = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); } dragging = true; } @@ -164,20 +177,28 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) { mimeData->setText("h"); // QMimeData will fail without some kind of data drag->setMimeData(mimeData); drag->exec(); - } else { + } else if (selected_gizmo != NULL) { double multiplier = (double) viewer->seq->width / (double) width(); int x_movement = (event->pos().x() - drag_start_x)*multiplier; int y_movement = (event->pos().y() - drag_start_y)*multiplier; -// gizmos->gizmo_move(g, x_movement, y_movement, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead)); + gizmos->gizmo_move(selected_gizmo, x_movement, y_movement, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead)); drag_start_x = event->pos().x(); drag_start_y = event->pos().y(); gizmos->field_changed(); } - } + } else { + unsetCursor(); + EffectGizmo* g = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); + if (g != NULL) { + if (g->get_cursor() > -1) { + setCursor(static_cast(g->get_cursor())); + } + } + } } void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) { @@ -466,9 +487,7 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) composite_texture = draw_clip(c->fbo[fbo_switcher], textureID, true); } - fbo_switcher = !fbo_switcher; - - bool draw_gizmos = false; + fbo_switcher = !fbo_switcher; GLTextureCoords coords; coords.grid_size = 1; @@ -490,16 +509,28 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) // EFFECT CODE START double timecode = get_timecode(c, playhead); + + Effect* first_gizmo_effect = NULL; + Effect* selected_effect = NULL; + for (int j=0;jeffects.size();j++) { Effect* e = c->effects.at(j); process_effect(c, e, timecode, coords, composite_texture, fbo_switcher, TA_NO_TRANSITION); - if (!rendering && gizmos == NULL && e->are_gizmos_enabled() && (e->container->selected || panel_timeline->is_clip_selected(c, true))) { - gizmos = e; - draw_gizmos = true; + if (e->are_gizmos_enabled()) { + if (first_gizmo_effect == NULL) first_gizmo_effect = e; + if (e->container->selected) selected_effect = e; } } + if (!rendering) { + if (selected_effect != NULL) { + gizmos = selected_effect; + } else if (panel_timeline->is_clip_selected(c, true)) { + gizmos = first_gizmo_effect; + } + } + if (c->get_opening_transition() != NULL) { int transition_progress = playhead - c->get_timeline_in_with_transition(); if (transition_progress < c->get_opening_transition()->get_length()) { @@ -585,29 +616,33 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glBindTexture(GL_TEXTURE_2D, 0); // unbind texture - if (draw_gizmos) { + if (gizmos != NULL) { float color[4]; glGetFloatv(GL_CURRENT_COLOR, color); - float multiplier = (float) width() / (float) viewer->seq->width; - float dot_size = 20 * multiplier; + float dot_size = GIZMO_DOT_SIZE / width() * viewer->seq->width; gizmos->gizmo_draw(timecode, coords); // set correct gizmo coords gizmos->gizmo_world_to_screen(); + + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, viewer->seq->width, viewer->seq->height, 0, -1, 1); for (int j=0;jgizmo_count();j++) { EffectGizmo* g = gizmos->gizmo(j); switch (g->get_type()) { case GIZMO_TYPE_DOT: // draw dot glBegin(GL_QUADS); glColor4f(1.0, 1.0, 1.0, 1.0); - glVertex2f(g->get_x()-dot_size, g->get_y()-dot_size); - glVertex2f(g->get_x()+dot_size, g->get_y()-dot_size); - glVertex2f(g->get_x()+dot_size, g->get_y()+dot_size); - glVertex2f(g->get_x()-dot_size, g->get_y()+dot_size); + glVertex2f(g->get_screen_x()-dot_size, g->get_screen_y()-dot_size); + glVertex2f(g->get_screen_x()+dot_size, g->get_screen_y()-dot_size); + glVertex2f(g->get_screen_x()+dot_size, g->get_screen_y()+dot_size); + glVertex2f(g->get_screen_x()-dot_size, g->get_screen_y()+dot_size); glEnd(); break; } } + glPopMatrix(); glColor4f(color[0], color[1], color[2], color[3]); } diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h index 0be77f172..ab909e842 100644 --- a/ui/viewerwidget.h +++ b/ui/viewerwidget.h @@ -52,6 +52,7 @@ private: int drag_start_x; int drag_start_y; EffectGizmo* selected_gizmo; + EffectGizmo* get_gizmo_from_mouse(int x, int y); private slots: void retry(); void show_context_menu();