Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

polygon: Implement polygon gizmo selection and dragging #2030

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions app/node/generator/polygon/polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ NodeGizmo *PolygonGenerator::CreateAppropriateGizmo<PointGizmo>()
return AddDraggableGizmo<PointGizmo>();
}

template<>
NodeGizmo *PolygonGenerator::CreateAppropriateGizmo<SelectableGizmo>()
{
return AddDraggableGizmo<SelectableGizmo>();
}

template<typename T>
void PolygonGenerator::ValidateGizmoVectorSize(QVector<T*> &vec, int new_sz)
{
Expand Down Expand Up @@ -216,6 +222,21 @@ void PolygonGenerator::UpdateGizmoPositions(const NodeValueRow &row, const NodeG
poly_gizmo_->SetPath(GeneratePath(points).translated(half_res));
}

void PolygonGenerator::UpdateGizmosOnSelection(QList<PointGizmo*> &selected)
{
for (int i = 0; i < gizmo_position_handles_.size(); i++) {
auto& position_handle = gizmo_position_handles_[i];
bool point_selected = selected.contains(position_handle);
bool beziers_visible = (selected.size() == 1 && point_selected);
position_handle->SetSelected(point_selected);

gizmo_bezier_handles_[i*2]->SetVisible(beziers_visible);
gizmo_bezier_lines_[i*2]->SetVisible(beziers_visible);
gizmo_bezier_handles_[i*2+1]->SetVisible(beziers_visible);
gizmo_bezier_lines_[i*2+1]->SetVisible(beziers_visible);
}
}

ShaderCode PolygonGenerator::GetShaderCode(const ShaderRequest &request) const
{
if (request.id == QStringLiteral("rgb")) {
Expand Down
4 changes: 3 additions & 1 deletion app/node/generator/polygon/polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "node/generator/shape/generatorwithmerge.h"
#include "node/gizmo/line.h"
#include "node/gizmo/path.h"
#include "node/gizmo/selectable.h"
#include "node/gizmo/point.h"
#include "node/node.h"
#include "node/inputdragger.h"
Expand All @@ -53,6 +54,7 @@ class PolygonGenerator : public GeneratorWithMerge
virtual void GenerateFrame(FramePtr frame, const GenerateJob &job) const override;

virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override;
virtual void UpdateGizmosOnSelection(QList<PointGizmo*> &selected) override;

virtual ShaderCode GetShaderCode(const ShaderRequest &request) const override;

Expand All @@ -77,7 +79,7 @@ protected slots:
NodeGizmo *CreateAppropriateGizmo();

PathGizmo *poly_gizmo_;
QVector<PointGizmo*> gizmo_position_handles_;
QVector<SelectableGizmo*> gizmo_position_handles_;
QVector<PointGizmo*> gizmo_bezier_handles_;
QVector<LineGizmo*> gizmo_bezier_lines_;

Expand Down
1 change: 1 addition & 0 deletions app/node/gizmo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ set(OLIVE_SOURCES
node/gizmo/screen.h
node/gizmo/text.cpp
node/gizmo/text.h
node/gizmo/selectable.cpp
PARENT_SCOPE
)
16 changes: 9 additions & 7 deletions app/node/gizmo/point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,27 @@
***/

#include "point.h"
#include <qnamespace.h>

#include <QApplication>

namespace olive {

PointGizmo::PointGizmo(const Shape &shape, bool smaller, QObject *parent) :
PointGizmo::PointGizmo(const Shape &shape, bool smaller, QObject *parent, bool selectable) :
DraggableGizmo{parent},
shape_(shape),
smaller_(smaller)
smaller_(smaller),
selectable_(selectable)
{
}

PointGizmo::PointGizmo(const Shape &shape, QObject *parent) :
PointGizmo(shape, false, parent)
PointGizmo::PointGizmo(const Shape &shape, QObject *parent,bool selectable) :
PointGizmo(shape, false, parent, selectable)
{
}

PointGizmo::PointGizmo(QObject *parent) :
PointGizmo(kSquare, parent)
PointGizmo::PointGizmo(QObject *parent, bool selectable) :
PointGizmo(kSquare, parent, selectable)
{
}

Expand All @@ -47,7 +49,7 @@ void PointGizmo::Draw(QPainter *p) const

if (shape_ != kAnchorPoint) {
p->setPen(Qt::NoPen);
p->setBrush(Qt::white);
p->setBrush(selected_ ? Qt::red : Qt::white);
}

switch (shape_) {
Expand Down
13 changes: 10 additions & 3 deletions app/node/gizmo/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class PointGizmo : public DraggableGizmo
kAnchorPoint
};

explicit PointGizmo(const Shape &shape, bool smaller, QObject *parent = nullptr);
explicit PointGizmo(const Shape &shape, QObject *parent = nullptr);
explicit PointGizmo(QObject *parent = nullptr);
explicit PointGizmo(const Shape &shape, bool smaller, QObject *parent = nullptr, bool selectable = false);
explicit PointGizmo(const Shape &shape, QObject *parent = nullptr, bool selectable = false);
explicit PointGizmo(QObject *parent = nullptr, bool selectable = false);

const Shape &GetShape() const { return shape_; }
void SetShape(const Shape &s) { shape_ = s; }
Expand All @@ -50,6 +50,11 @@ class PointGizmo : public DraggableGizmo
bool GetSmaller() const { return smaller_; }
void SetSmaller(bool e) { smaller_ = e; }

bool IsSelectable() const { return selectable_; }

void SetSelected(bool e) { selected_ = e; }
bool IsSelected() const { return selected_; }

virtual void Draw(QPainter *p) const override;

QRectF GetClickingRect(const QTransform &t) const;
Expand All @@ -64,6 +69,8 @@ class PointGizmo : public DraggableGizmo
QPointF point_;

bool smaller_;
bool selected_ = false;
bool selectable_ = false;

};

Expand Down
7 changes: 7 additions & 0 deletions app/node/gizmo/selectable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "selectable.h"

namespace olive {
SelectableGizmo::SelectableGizmo(QObject *parent)
:PointGizmo(parent, true)
{}
}
13 changes: 13 additions & 0 deletions app/node/gizmo/selectable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef SELECTABLE_H
#define SELECTABLE_H
#include "node/gizmo/point.h"

namespace olive {
class SelectableGizmo: public PointGizmo {
Q_OBJECT
public:
explicit SelectableGizmo(QObject *parent = nullptr);
};
}

#endif
2 changes: 2 additions & 0 deletions app/node/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace olive {

class NodeGraph;
class Folder;
class PointGizmo;

/**
* @brief A single processing unit that can be connected with others to create intricate processing systems
Expand Down Expand Up @@ -905,6 +906,7 @@ class Node : public QObject
virtual QTransform GizmoTransformation(const NodeValueRow &row, const NodeGlobals &globals) const { return QTransform(); }

virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals){}
virtual void UpdateGizmosOnSelection(QList<PointGizmo*> &selected) {}

const QString& GetLabel() const;
void SetLabel(const QString& s);
Expand Down
81 changes: 60 additions & 21 deletions app/widget/viewer/viewerdisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "viewerdisplay.h"

#include <OpenImageIO/imagebuf.h>
#include <qnamespace.h>
#include <QAbstractTextDocumentLayout>
#include <QApplication>
#include <QFileInfo>
Expand Down Expand Up @@ -177,6 +178,7 @@ void ViewerDisplayWidget::SetGizmos(Node *node)
{
if (gizmos_ != node) {
gizmos_ = node;
selected_gizmos_.clear();

update();
}
Expand Down Expand Up @@ -445,6 +447,7 @@ void ViewerDisplayWidget::OnPaint()
p.setWorldTransform(gizmo_last_draw_transform_);

gizmos_->UpdateGizmoPositions(gizmo_db_, NodeTraverser::GenerateGlobals(gizmo_params_, range));
gizmos_->UpdateGizmosOnSelection(selected_gizmos_);
foreach (NodeGizmo *gizmo, gizmos_->GetGizmos()) {
if (gizmo->IsVisible()) {
gizmo->Draw(&p);
Expand Down Expand Up @@ -822,6 +825,25 @@ bool ViewerDisplayWidget::OnMousePress(QMouseEvent *event)
gizmo_start_drag_ = event->pos();
gizmo_last_drag_ = gizmo_start_drag_;
current_gizmo_->SetGlobals(NodeTraverser::GenerateGlobals(gizmo_params_, GenerateGizmoTime()));
//handle selection
if (PointGizmo* point_gizmo = dynamic_cast<PointGizmo*>(current_gizmo_)) {
if (point_gizmo->IsSelectable()) {
for (PointGizmo* pg: selected_gizmos_)
pg->SetGlobals(NodeTraverser::GenerateGlobals(gizmo_params_, GenerateGizmoTime()));
if (event->modifiers().testFlag(Qt::ControlModifier)) {
if (selected_gizmos_.contains(point_gizmo)) {
selected_gizmos_.removeOne(point_gizmo);
} else {
selected_gizmos_.append(point_gizmo);
}
} else if (!selected_gizmos_.contains(point_gizmo)) {
selected_gizmos_.clear();
selected_gizmos_.append(point_gizmo);
}

}
update();
}

} else {

Expand Down Expand Up @@ -872,40 +894,49 @@ bool ViewerDisplayWidget::OnMouseMove(QMouseEvent *event)
} else if (current_gizmo_) {

// Signal movement
if (DraggableGizmo *draggable = dynamic_cast<DraggableGizmo*>(current_gizmo_)) {
if (PointGizmo *point_gizmo = dynamic_cast<PointGizmo*>(current_gizmo_) ) {
if (!gizmo_drag_started_) {
QPointF start = gizmo_start_drag_ * gizmo_last_draw_transform_inverted_;

rational gizmo_time = GetGizmoTime();
NodeTraverser t;
t.SetCacheVideoParams(gizmo_params_);
NodeValueRow row = t.GenerateRow(gizmos_, TimeRange(gizmo_time, gizmo_time + gizmo_params_.frame_rate_as_time_base()));

draggable->DragStart(row, start.x(), start.y(), gizmo_time);

if (point_gizmo->IsSelected()) {
for (DraggableGizmo* gizmo: selected_gizmos_)
gizmo->DragStart(row, start.x(), start.y(), gizmo_time);
} else {
point_gizmo->DragStart(row, start.x(), start.y(), gizmo_time);
}
gizmo_drag_started_ = true;
}

QPointF v = event->pos() * gizmo_last_draw_transform_inverted_;
switch (draggable->GetDragValueBehavior()) {
case DraggableGizmo::kAbsolute:
// Above value is correct
break;
case DraggableGizmo::kDeltaFromPrevious:
v -= gizmo_last_drag_ * gizmo_last_draw_transform_inverted_;
gizmo_last_drag_ = event->pos();
break;
case DraggableGizmo::kDeltaFromStart:
v -= gizmo_start_drag_ * gizmo_last_draw_transform_inverted_;
break;
switch (point_gizmo->GetDragValueBehavior()) {
case DraggableGizmo::kAbsolute:
// Above value is correct
break;
case DraggableGizmo::kDeltaFromPrevious:
v -= gizmo_last_drag_ * gizmo_last_draw_transform_inverted_;
gizmo_last_drag_ = event->pos();
break;
case DraggableGizmo::kDeltaFromStart:
v -= gizmo_start_drag_ * gizmo_last_draw_transform_inverted_;
break;
}

draggable->DragMove(v.x(), v.y(), event->modifiers());
if (point_gizmo->IsSelected()) {
for (DraggableGizmo* gizmo: selected_gizmos_)
gizmo->DragMove(v.x(), v.y(), event->modifiers());
} else
point_gizmo->DragMove(v.x(), v.y(), event->modifiers());

update();
return true;
}

}
}


return false;
}

Expand Down Expand Up @@ -940,8 +971,13 @@ bool ViewerDisplayWidget::OnMouseRelease(QMouseEvent *e)
// Handle gizmo
if (gizmo_drag_started_) {
MultiUndoCommand *command = new MultiUndoCommand();
if (DraggableGizmo *draggable = dynamic_cast<DraggableGizmo*>(current_gizmo_)) {
draggable->DragEnd(command);
if (PointGizmo* point_gizmo= dynamic_cast<PointGizmo* >(current_gizmo_)) {

if (point_gizmo ->IsSelected()) {
for (DraggableGizmo* gizmo: selected_gizmos_)
gizmo->DragEnd(command);
} else
point_gizmo->DragEnd(command);
}
Core::instance()->undo_stack()->pushIfHasChildren(command);
gizmo_drag_started_ = false;
Expand All @@ -960,15 +996,18 @@ bool ViewerDisplayWidget::OnMouseDoubleClick(QMouseEvent *event)
if (text_edit_) {
return ForwardMouseEventToTextEdit(event);
} else if (event->button() == Qt::LeftButton && gizmos_) {
selected_gizmos_.clear();

QPointF ptr = TransformViewerSpaceToBufferSpace(event->pos());
foreach (NodeGizmo *g, gizmos_->GetGizmos()) {
if (TextGizmo *text = dynamic_cast<TextGizmo*>(g)) {
if (text->GetRect().contains(ptr)) {
OpenTextGizmo(text, event);
return true;
}
}
}
update();
return true;
}

return false;
Expand Down
4 changes: 4 additions & 0 deletions app/widget/viewer/viewerdisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace olive {
* the same texture object, use SetTexture() since it will nearly always be faster to just set it than to check *and*
* set it.
*/
class PointGizmo;
class ViewerDisplayWidget : public ManagedDisplayWidget, public TimeTargetObject
{
Q_OBJECT
Expand Down Expand Up @@ -290,6 +291,8 @@ protected slots:

void CloseTextEditor();

bool DragGizmo(DraggableGizmo* gizmo, QMouseEvent *event);

/**
* @brief Internal reference to the OpenGL texture to draw. Set in SetTexture() and used in paintGL().
*/
Expand Down Expand Up @@ -408,6 +411,7 @@ protected slots:
ViewerTextEditorToolBar *text_toolbar_;
QTransform text_transform_;
QTransform text_transform_inverted_;
QList<PointGizmo*> selected_gizmos_;

private slots:
void UpdateFromQueue();
Expand Down