fixed critical bug that corrupts transitions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#include "transformeffect.h"
|
||||
#include "transformeffect.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
@@ -13,19 +13,23 @@
|
||||
#include "project/clip.h"
|
||||
#include "project/sequence.h"
|
||||
#include "io/media.h"
|
||||
#include "io/math.h"
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/comboboxex.h"
|
||||
#include "panels/project.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "panels/panels.h"
|
||||
#include "panels/viewer.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
|
||||
#define BLEND_MODE_NORMAL 0
|
||||
#define BLEND_MODE_SCREEN 1
|
||||
#define BLEND_MODE_MULTIPLY 2
|
||||
#define BLEND_MODE_OVERLAY 3
|
||||
|
||||
TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) {
|
||||
enable_coords = true;
|
||||
enable_gizmos = true;
|
||||
enable_coords = true;
|
||||
|
||||
EffectRow* position_row = add_row("Position:");
|
||||
position_x = position_row->add_field(EFFECT_FIELD_DOUBLE, "posx"); // position X
|
||||
@@ -61,6 +65,15 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em)
|
||||
blend_mode_box->add_combo_item("Screen", BLEND_MODE_SCREEN);
|
||||
blend_mode_box->add_combo_item("Multiply", BLEND_MODE_MULTIPLY);
|
||||
|
||||
top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
top_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
top_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
bottom_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
bottom_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
bottom_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
left_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
right_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
|
||||
// set defaults
|
||||
scale_y->set_enabled(false);
|
||||
uniform_scale_field->set_bool_value(true);
|
||||
@@ -145,43 +158,17 @@ void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, i
|
||||
}
|
||||
|
||||
void TransformEffect::gizmo_draw(double timecode, GLTextureCoords& coords) {
|
||||
// proof of concept drawing pattern
|
||||
|
||||
/*float color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor4f(1.0, 0.0, 0.0, 0.5);
|
||||
glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, 1);
|
||||
glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, 1);
|
||||
glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, 1);
|
||||
glColor4f(0.0, 0.0, 1.0, 0.5);
|
||||
glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, 1);
|
||||
glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, 1);
|
||||
glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, 1);
|
||||
glEnd();
|
||||
|
||||
glColor4f(color[0], color[1], color[2], color[3]);*/
|
||||
top_left_gizmo->set_pos(coords.vertexTopLeftX, coords.vertexTopLeftY);
|
||||
top_center_gizmo->set_pos(lerp(coords.vertexTopLeftX, coords.vertexTopRightX, 0.5), lerp(coords.vertexTopLeftY, coords.vertexTopRightY, 0.5));
|
||||
top_right_gizmo->set_pos(coords.vertexTopRightX, coords.vertexTopRightY);
|
||||
right_center_gizmo->set_pos(lerp(coords.vertexTopRightX, coords.vertexBottomRightX, 0.5), lerp(coords.vertexTopRightY, coords.vertexBottomRightY, 0.5));
|
||||
bottom_right_gizmo->set_pos(coords.vertexBottomRightX, coords.vertexBottomRightY);
|
||||
bottom_center_gizmo->set_pos(lerp(coords.vertexBottomRightX, coords.vertexBottomLeftX, 0.5), lerp(coords.vertexBottomRightY, coords.vertexBottomLeftY, 0.5));
|
||||
bottom_left_gizmo->set_pos(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
|
||||
left_center_gizmo->set_pos(lerp(coords.vertexBottomLeftX, coords.vertexTopLeftX, 0.5), lerp(coords.vertexBottomLeftY, coords.vertexTopLeftY, 0.5));
|
||||
}
|
||||
|
||||
void TransformEffect::gizmo_down(QMouseEvent *event, double) {
|
||||
dragging = true;
|
||||
drag_start_x = event->pos().x();
|
||||
drag_start_y = event->pos().y();
|
||||
}
|
||||
|
||||
void TransformEffect::gizmo_move(QMouseEvent *event, double timecode) {
|
||||
if (dragging) {
|
||||
position_x->set_double_value(position_x->get_double_value(timecode) + (event->pos().x() - drag_start_x));
|
||||
position_y->set_double_value(position_y->get_double_value(timecode) + (event->pos().y() - drag_start_y));
|
||||
|
||||
drag_start_x = event->pos().x();
|
||||
drag_start_y = event->pos().y();
|
||||
|
||||
field_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void TransformEffect::gizmo_up(QMouseEvent *event, double) {
|
||||
dragging = false;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -11,29 +11,32 @@ public:
|
||||
void process_coords(double timecode, GLTextureCoords& coords, int data);
|
||||
|
||||
void gizmo_draw(double timecode, GLTextureCoords& coords);
|
||||
void gizmo_down(QMouseEvent *event, double);
|
||||
void gizmo_move(QMouseEvent *event, double);
|
||||
void gizmo_up(QMouseEvent *event, double);
|
||||
|
||||
EffectField* position_x;
|
||||
EffectField* position_y;
|
||||
EffectField* scale_x;
|
||||
EffectField* scale_y;
|
||||
EffectField* uniform_scale_field;
|
||||
EffectField* rotation;
|
||||
EffectField* anchor_x_box;
|
||||
EffectField* anchor_y_box;
|
||||
EffectField* opacity;
|
||||
EffectField* blend_mode_box;
|
||||
void gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode);
|
||||
public slots:
|
||||
void toggle_uniform_scale(bool enabled);
|
||||
private:
|
||||
int default_anchor_x;
|
||||
int default_anchor_y;
|
||||
EffectField* position_x;
|
||||
EffectField* position_y;
|
||||
EffectField* scale_x;
|
||||
EffectField* scale_y;
|
||||
EffectField* uniform_scale_field;
|
||||
EffectField* rotation;
|
||||
EffectField* anchor_x_box;
|
||||
EffectField* anchor_y_box;
|
||||
EffectField* opacity;
|
||||
EffectField* blend_mode_box;
|
||||
|
||||
bool dragging;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
EffectGizmo* top_left_gizmo;
|
||||
EffectGizmo* top_center_gizmo;
|
||||
EffectGizmo* top_right_gizmo;
|
||||
EffectGizmo* bottom_left_gizmo;
|
||||
EffectGizmo* bottom_center_gizmo;
|
||||
EffectGizmo* bottom_right_gizmo;
|
||||
EffectGizmo* left_center_gizmo;
|
||||
EffectGizmo* right_center_gizmo;
|
||||
|
||||
int default_anchor_x;
|
||||
int default_anchor_y;
|
||||
};
|
||||
|
||||
#endif // TRANSFORMEFFECT_H
|
||||
|
||||
@@ -88,7 +88,8 @@ SOURCES += \
|
||||
project/transition.cpp \
|
||||
project/effectrow.cpp \
|
||||
project/effectfield.cpp \
|
||||
effects/internal/cubetransition.cpp
|
||||
effects/internal/cubetransition.cpp \
|
||||
project/effectgizmo.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
@@ -156,7 +157,8 @@ HEADERS += \
|
||||
project/transition.h \
|
||||
project/effectrow.h \
|
||||
project/effectfield.h \
|
||||
effects/internal/cubetransition.h
|
||||
effects/internal/cubetransition.h \
|
||||
project/effectgizmo.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
|
||||
@@ -1496,6 +1496,7 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
|
||||
if (t != NULL) {
|
||||
stream.writeStartElement("transition");
|
||||
stream.writeAttribute("id", QString::number(j));
|
||||
stream.writeAttribute("length", QString::number(t->get_true_length()));
|
||||
t->save(stream);
|
||||
stream.writeEndElement(); // transition
|
||||
}
|
||||
|
||||
+39
-5
@@ -223,7 +223,6 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
|
||||
enable_shader(false),
|
||||
enable_coords(false),
|
||||
enable_superimpose(false),
|
||||
enable_gizmos(false),
|
||||
glslProgram(NULL),
|
||||
texture(NULL),
|
||||
isOpen(false),
|
||||
@@ -456,7 +455,21 @@ EffectRow* Effect::row(int i) {
|
||||
}
|
||||
|
||||
int Effect::row_count() {
|
||||
return rows.size();
|
||||
return rows.size();
|
||||
}
|
||||
|
||||
EffectGizmo *Effect::add_gizmo(int type) {
|
||||
EffectGizmo* gizmo = new EffectGizmo(type);
|
||||
gizmos.append(gizmo);
|
||||
return gizmo;
|
||||
}
|
||||
|
||||
EffectGizmo *Effect::gizmo(int i) {
|
||||
return gizmos.at(i);
|
||||
}
|
||||
|
||||
int Effect::gizmo_count(){
|
||||
return gizmos.size();
|
||||
}
|
||||
|
||||
void Effect::refresh() {}
|
||||
@@ -834,9 +847,30 @@ void Effect::process_audio(double, double, quint8*, int, int) {
|
||||
}
|
||||
|
||||
void Effect::gizmo_draw(double, GLTextureCoords &) {}
|
||||
void Effect::gizmo_down(QMouseEvent *, double) {}
|
||||
void Effect::gizmo_move(QMouseEvent *, double) {}
|
||||
void Effect::gizmo_up(QMouseEvent *, double) {}
|
||||
void Effect::gizmo_move(EffectGizmo* , int , int , double ) {}
|
||||
|
||||
void Effect::gizmo_world_to_screen() {
|
||||
GLfloat view_val[16];
|
||||
GLfloat projection_val[16];
|
||||
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]);
|
||||
|
||||
for (int i=0;i<gizmos.size();i++) {
|
||||
EffectGizmo* g = gizmos.at(i);
|
||||
|
||||
QVector4D world_pos(g->get_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());
|
||||
}
|
||||
}
|
||||
|
||||
bool Effect::are_gizmos_enabled() {
|
||||
return (gizmos.size() > 0);
|
||||
}
|
||||
|
||||
void Effect::redraw(double) {
|
||||
/*
|
||||
|
||||
+11
-6
@@ -1,4 +1,4 @@
|
||||
#ifndef EFFECT_H
|
||||
#ifndef EFFECT_H
|
||||
#define EFFECT_H
|
||||
|
||||
#include <QObject>
|
||||
@@ -105,6 +105,7 @@ qint16 mix_audio_sample(qint16 a, qint16 b);
|
||||
|
||||
#include "effectfield.h"
|
||||
#include "effectrow.h"
|
||||
#include "effectgizmo.h"
|
||||
|
||||
class Effect : public QObject {
|
||||
Q_OBJECT
|
||||
@@ -121,6 +122,10 @@ public:
|
||||
EffectRow* row(int i);
|
||||
int row_count();
|
||||
|
||||
EffectGizmo* add_gizmo(int type);
|
||||
EffectGizmo* gizmo(int i);
|
||||
int gizmo_count();
|
||||
|
||||
bool is_enabled();
|
||||
void set_enabled(bool b);
|
||||
|
||||
@@ -140,8 +145,7 @@ public:
|
||||
|
||||
bool enable_shader;
|
||||
bool enable_coords;
|
||||
bool enable_superimpose;
|
||||
bool enable_gizmos;
|
||||
bool enable_superimpose;
|
||||
|
||||
int getIterations();
|
||||
void setIterations(int i);
|
||||
@@ -154,9 +158,9 @@ public:
|
||||
virtual void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
|
||||
virtual void gizmo_draw(double timecode, GLTextureCoords& coords);
|
||||
virtual void gizmo_down(QMouseEvent* event, double);
|
||||
virtual void gizmo_move(QMouseEvent* event, double);
|
||||
virtual void gizmo_up(QMouseEvent* event, double);
|
||||
virtual void gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode);
|
||||
void gizmo_world_to_screen();
|
||||
bool are_gizmos_enabled();
|
||||
public slots:
|
||||
void field_changed();
|
||||
private slots:
|
||||
@@ -179,6 +183,7 @@ private:
|
||||
|
||||
bool isOpen;
|
||||
QVector<EffectRow*> rows;
|
||||
QVector<EffectGizmo*> gizmos;
|
||||
QGridLayout* ui_layout;
|
||||
QWidget* ui;
|
||||
bool bound;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "effectgizmo.h"
|
||||
|
||||
EffectGizmo::EffectGizmo(int type) :
|
||||
type(type)
|
||||
{}
|
||||
|
||||
void EffectGizmo::set_pos(int ix, int iy) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
}
|
||||
|
||||
int EffectGizmo::get_x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
int EffectGizmo::get_y() {
|
||||
return y;
|
||||
}
|
||||
|
||||
int EffectGizmo::get_type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
void EffectGizmo::set_screen_pos(int isx, int isy) {
|
||||
sx = isx;
|
||||
sy = isy;
|
||||
}
|
||||
|
||||
int EffectGizmo::get_screen_x() {
|
||||
return sx;
|
||||
}
|
||||
|
||||
int EffectGizmo::get_screen_y() {
|
||||
return sy;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef EFFECTGIZMO_H
|
||||
#define EFFECTGIZMO_H
|
||||
|
||||
#define GIZMO_TYPE_DOT 0
|
||||
#define GIZMO_TYPE_QUAD 1
|
||||
|
||||
#include <QString>
|
||||
|
||||
class EffectGizmo
|
||||
{
|
||||
public:
|
||||
EffectGizmo(int type);
|
||||
|
||||
void set_pos(int ix, int iy);
|
||||
int get_x();
|
||||
int get_y();
|
||||
int get_type();
|
||||
|
||||
void set_screen_pos(int isx, int isy);
|
||||
int get_screen_x();
|
||||
int get_screen_y();
|
||||
private:
|
||||
int type;
|
||||
int x;
|
||||
int y;
|
||||
int sx;
|
||||
int sy;
|
||||
};
|
||||
|
||||
#endif // EFFECTGIZMO_H
|
||||
+59
-12
@@ -135,9 +135,23 @@ double get_timecode(Clip* c, long playhead) {
|
||||
}
|
||||
|
||||
void ViewerWidget::mousePressEvent(QMouseEvent* event) {
|
||||
if (waveform) seek_from_click(event->x());
|
||||
dragging = true;
|
||||
if (gizmos != NULL) gizmos->gizmo_down(event, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead));
|
||||
if (waveform) {
|
||||
seek_from_click(event->x());
|
||||
} else {
|
||||
drag_start_x = event->pos().x();
|
||||
drag_start_y = event->pos().y();
|
||||
|
||||
if (gizmos != NULL) {
|
||||
int clicked = -1;
|
||||
for (int i=0;i<gizmos->gizmo_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;
|
||||
}
|
||||
}
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
|
||||
@@ -150,14 +164,24 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
|
||||
mimeData->setText("h"); // QMimeData will fail without some kind of data
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec();
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
|
||||
drag_start_x = event->pos().x();
|
||||
drag_start_y = event->pos().y();
|
||||
|
||||
gizmos->field_changed();
|
||||
}
|
||||
}
|
||||
if (gizmos != NULL) gizmos->gizmo_move(event, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead));
|
||||
}
|
||||
|
||||
void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
dragging = false;
|
||||
if (gizmos != NULL) gizmos->gizmo_up(event, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead));
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
void ViewerWidget::drawTitleSafeArea() {
|
||||
@@ -470,7 +494,7 @@ GLuint ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio)
|
||||
Effect* e = c->effects.at(j);
|
||||
process_effect(c, e, timecode, coords, composite_texture, fbo_switcher, TA_NO_TRANSITION);
|
||||
|
||||
if (!rendering && gizmos == NULL && e->enable_gizmos && (e->container->selected || panel_timeline->is_clip_selected(c, true))) {
|
||||
if (!rendering && gizmos == NULL && e->are_gizmos_enabled() && (e->container->selected || panel_timeline->is_clip_selected(c, true))) {
|
||||
gizmos = e;
|
||||
draw_gizmos = true;
|
||||
}
|
||||
@@ -528,9 +552,9 @@ GLuint ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio)
|
||||
float rows = coords.grid_size;
|
||||
float cols = coords.grid_size;
|
||||
|
||||
for (float i=0;i<rows;i++) {
|
||||
float row_prog = i/rows;
|
||||
float next_row_prog = (i+1)/rows;
|
||||
for (float k=0;k<rows;k++) {
|
||||
float row_prog = k/rows;
|
||||
float next_row_prog = (k+1)/rows;
|
||||
for (float j=0;j<cols;j++) {
|
||||
float col_prog = j/cols;
|
||||
float next_col_prog = (j+1)/cols;
|
||||
@@ -562,7 +586,30 @@ GLuint ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio)
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // unbind texture
|
||||
|
||||
if (draw_gizmos) {
|
||||
gizmos->gizmo_draw(timecode, coords);
|
||||
float color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||
|
||||
float multiplier = (float) width() / (float) viewer->seq->width;
|
||||
float dot_size = 20 * multiplier;
|
||||
|
||||
gizmos->gizmo_draw(timecode, coords); // set correct gizmo coords
|
||||
gizmos->gizmo_world_to_screen();
|
||||
for (int j=0;j<gizmos->gizmo_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);
|
||||
glEnd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glColor4f(color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
|
||||
if (!nests.isEmpty()) {
|
||||
|
||||
+5
-1
@@ -1,4 +1,4 @@
|
||||
#ifndef VIEWERWIDGET_H
|
||||
#ifndef VIEWERWIDGET_H
|
||||
#define VIEWERWIDGET_H
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
@@ -14,6 +14,7 @@ struct Clip;
|
||||
struct MediaStream;
|
||||
class QOpenGLFramebufferObject;
|
||||
class Effect;
|
||||
class EffectGizmo;
|
||||
struct GLTextureCoords;
|
||||
|
||||
class ViewerWidget : public QOpenGLWidget
|
||||
@@ -48,6 +49,9 @@ private:
|
||||
GLuint draw_clip(QOpenGLFramebufferObject *clip, GLuint texture, bool clear);
|
||||
void process_effect(Clip* c, Effect* e, double timecode, GLTextureCoords& coords, GLuint& composite_texture, bool& fbo_switcher, int data);
|
||||
Effect* gizmos;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
EffectGizmo* selected_gizmo;
|
||||
private slots:
|
||||
void retry();
|
||||
void show_context_menu();
|
||||
|
||||
Reference in New Issue
Block a user