viewer: allow adding objects with a rect

This commit is contained in:
itsmattkc
2022-05-12 13:40:11 -07:00
parent 18d10f6c8d
commit 1def68f1a4
6 changed files with 167 additions and 62 deletions
+76 -58
View File
@@ -25,6 +25,7 @@
#include "node/generator/shape/shapenode.h"
#include "node/generator/solid/solid.h"
#include "node/generator/text/textv3.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
#include "widget/timelinewidget/timelinewidget.h"
#include "widget/timelinewidget/undo/timelineundopointer.h"
@@ -94,8 +95,6 @@ void AddTool::MouseMove(TimelineViewMouseEvent *event)
void AddTool::MouseRelease(TimelineViewMouseEvent *event)
{
const Track::Reference& track = ghost_->GetTrack();
if (ghost_) {
if (!ghost_->GetAdjustedLength().isNull()) {
MultiUndoCommand* command = new MultiUndoCommand();
@@ -104,62 +103,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
command->add_child(subtitle_section_command);
}
ClipBlock* clip;
if (Core::instance()->GetSelectedAddableObject() == olive::Tool::kAddableSubtitle) {
clip = new SubtitleBlock();
} else {
clip = new ClipBlock();
}
clip->set_length_and_media_out(ghost_->GetAdjustedLength());
clip->SetLabel(olive::Tool::GetAddableObjectName(Core::instance()->GetSelectedAddableObject()));
NodeGraph* graph = static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent());
command->add_child(new NodeAddCommand(graph, clip));
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0)));
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track.type()),
track.index(),
clip,
ghost_->GetAdjustedIn()));
Node *node_to_add = nullptr;
switch (Core::instance()->GetSelectedAddableObject()) {
case olive::Tool::kAddableEmpty:
// Empty, nothing to be done
break;
case olive::Tool::kAddableSolid:
{
node_to_add = new SolidGenerator();
break;
}
case olive::Tool::kAddableShape:
node_to_add = new ShapeNode();
break;
case olive::Tool::kAddableTitle:
{
node_to_add = new TextGeneratorV3();
break;
}
case olive::Tool::kAddableBars:
case olive::Tool::kAddableTone:
// Not implemented yet
qWarning() << "Unimplemented add object:" << Core::instance()->GetSelectedAddableObject();
break;
case olive::Tool::kAddableSubtitle:
// The block itself is the node we want
break;
case olive::Tool::kAddableCount:
// Invalid value, do nothing
break;
}
if (node_to_add) {
QPointF extra_node_offset(kDefaultDistanceFromOutput, 0);
command->add_child(new NodeAddCommand(graph, node_to_add));
command->add_child(new NodeEdgeAddCommand(node_to_add, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionCommand(node_to_add, clip, extra_node_offset));
}
CreateAddableClip(command, parent()->sequence(), ghost_->GetTrack(), ghost_->GetAdjustedIn(), ghost_->GetAdjustedLength());
Core::instance()->undo_stack()->push(command);
}
@@ -170,6 +114,80 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
}
}
Node *AddTool::CreateAddableClip(MultiUndoCommand *command, Sequence *sequence, const Track::Reference &track, const rational &in, const rational &length, const QRectF &rect)
{
ClipBlock* clip;
if (Core::instance()->GetSelectedAddableObject() == olive::Tool::kAddableSubtitle) {
clip = new SubtitleBlock();
} else {
clip = new ClipBlock();
}
clip->set_length_and_media_out(length);
clip->SetLabel(olive::Tool::GetAddableObjectName(Core::instance()->GetSelectedAddableObject()));
NodeGraph* graph = sequence->parent();
command->add_child(new NodeAddCommand(graph, clip));
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0)));
command->add_child(new TrackPlaceBlockCommand(sequence->track_list(track.type()),
track.index(),
clip,
in));
Node *node_to_add = nullptr;
switch (Core::instance()->GetSelectedAddableObject()) {
case olive::Tool::kAddableEmpty:
// Empty, nothing to be done
break;
case olive::Tool::kAddableSolid:
{
node_to_add = new SolidGenerator();
break;
}
case olive::Tool::kAddableShape:
node_to_add = new ShapeNode();
break;
case olive::Tool::kAddableTitle:
{
node_to_add = new TextGeneratorV3();
break;
}
case olive::Tool::kAddableBars:
case olive::Tool::kAddableTone:
// Not implemented yet
qWarning() << "Unimplemented add object:" << Core::instance()->GetSelectedAddableObject();
break;
case olive::Tool::kAddableSubtitle:
// The block itself is the node we want
break;
case olive::Tool::kAddableCount:
// Invalid value, do nothing
break;
}
if (node_to_add) {
QPointF extra_node_offset(kDefaultDistanceFromOutput, 0);
command->add_child(new NodeAddCommand(graph, node_to_add));
command->add_child(new NodeEdgeAddCommand(node_to_add, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionCommand(node_to_add, clip, extra_node_offset));
if (!rect.isNull()) {
if (ShapeNodeBase *snb = dynamic_cast<ShapeNodeBase*>(node_to_add)) {
NodeInput pos(snb, ShapeNodeBase::kPositionInput);
NodeInput sz(snb, ShapeNodeBase::kSizeInput);
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(sz, 0), rect.width()));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(sz, 1), rect.height()));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(pos, 0), rect.x()));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(pos, 1), rect.y()));
}
}
}
return node_to_add;
}
void AddTool::MouseMoveInternal(const rational &cursor_frame, bool outwards)
{
// Calculate movement
+2
View File
@@ -34,6 +34,8 @@ public:
virtual void MouseMove(TimelineViewMouseEvent *event) override;
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
static Node *CreateAddableClip(MultiUndoCommand *command, Sequence *sequence, const Track::Reference &track, const rational &in, const rational &length, const QRectF &rect = QRectF());
protected:
void MouseMoveInternal(const rational& cursor_frame, bool outwards);
+45
View File
@@ -37,12 +37,14 @@
#include "common/timecodefunctions.h"
#include "config/config.h"
#include "core.h"
#include "node/block/gap/gap.h"
#include "node/project/project.h"
#include "render/rendermanager.h"
#include "task/taskmanager.h"
#include "viewerpreventsleep.h"
#include "widget/menu/menu.h"
#include "window/mainwindow/mainwindow.h"
#include "widget/timelinewidget/tool/add.h"
#include "widget/timeruler/timeruler.h"
namespace olive {
@@ -93,6 +95,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
connect(display_widget_, &ViewerDisplayWidget::Dropped, this, &ViewerWidget::Dropped);
connect(display_widget_, &ViewerDisplayWidget::TextureChanged, this, &ViewerWidget::TextureChanged);
connect(display_widget_, &ViewerDisplayWidget::QueueStarved, this, &ViewerWidget::ForceRequeueFromCurrentTime);
connect(display_widget_, &ViewerDisplayWidget::CreateAddableAt, this, &ViewerWidget::CreateAddableAt);
connect(sizer_, &ViewerSizer::RequestScale, display_widget_, &ViewerDisplayWidget::SetMatrixZoom);
connect(sizer_, &ViewerSizer::RequestTranslate, display_widget_, &ViewerDisplayWidget::SetMatrixTranslate);
connect(display_widget_, &ViewerDisplayWidget::HandDragMoved, sizer_, &ViewerSizer::HandDragMove);
@@ -385,6 +388,7 @@ void ViewerWidget::CacheSequenceInOut()
void ViewerWidget::SetGizmos(Node *node)
{
qDebug() << "setting gizmos to" << node;
display_widget_->SetTimeTarget(GetConnectedNode());
display_widget_->SetGizmos(node);
}
@@ -476,6 +480,47 @@ void ViewerWidget::UpdateAudioProcessor()
}
}
void ViewerWidget::CreateAddableAt(QRectF f)
{
if (Sequence *s = dynamic_cast<Sequence*>(GetConnectedNode())) {
Track::Type type = Track::kVideo;
int track_index = -1;
TrackList *list = s->track_list(type);
const rational &in = GetTime();
rational length = OLIVE_CONFIG("DefaultStillLength").value<rational>();
rational out = in + length;
// Find a free track where we won't overwrite anything
while (true) {
track_index++;
if (track_index >= list->GetTrackCount()) {
// Just create a new track
break;
}
Track *track = list->GetTrackAt(track_index);
if (track->IsLocked()) {
continue;
}
Block *b = track->NearestBlockBeforeOrAt(in);
if (!b || (dynamic_cast<GapBlock*>(b) && b->out() >= out)) {
break;
}
}
// Normalize around center of sequence
f.translate(-s->GetVideoParams().width()*0.5, -s->GetVideoParams().height()*0.5);
f.translate(f.width()*0.5, f.height()*0.5);
MultiUndoCommand *command = new MultiUndoCommand();
Node *clip = AddTool::CreateAddableClip(command, s, Track::Reference(type, track_index), in, length, f);
Core::instance()->undo_stack()->pushIfHasChildren(command);
SetGizmos(clip);
}
}
void ViewerWidget::CloseAudioProcessor()
{
audio_processor_.Close();
+2
View File
@@ -325,6 +325,8 @@ private slots:
void UpdateAudioProcessor();
void CreateAddableAt(QRectF f);
};
}
+32 -3
View File
@@ -67,9 +67,10 @@ ViewerDisplayWidget::ViewerDisplayWidget(QWidget *parent) :
show_fps_(false),
frames_skipped_(0),
show_widget_background_(false),
push_mode_(kPushNull)
push_mode_(kPushNull),
add_band_(nullptr)
{
connect(Core::instance(), &Core::ToolChanged, this, &ViewerDisplayWidget::UpdateCursor);
connect(Core::instance(), &Core::ToolChanged, this, &ViewerDisplayWidget::ToolChanged);
connect(this, &ViewerDisplayWidget::InnerWidgetMouseMove, this, &ViewerDisplayWidget::EmitColorAtCursor);
@@ -105,6 +106,8 @@ void ViewerDisplayWidget::UpdateCursor()
{
if (Core::instance()->tool() == Tool::kHand) {
setCursor(Qt::OpenHandCursor);
} else if (Core::instance()->tool() == Tool::kAdd) {
setCursor(Qt::CrossCursor);
} else {
unsetCursor();
}
@@ -136,6 +139,11 @@ void ViewerDisplayWidget::SetBlank()
update();
}
void ViewerDisplayWidget::ToolChanged()
{
UpdateCursor();
}
void ViewerDisplayWidget::SetDeinterlacing(bool e)
{
deinterlace_ = e;
@@ -235,7 +243,16 @@ void ViewerDisplayWidget::IncrementSkippedFrames()
void ViewerDisplayWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && gizmos_
if (event->button() == Qt::LeftButton && Core::instance()->tool() == Tool::kAdd
&& (Core::instance()->GetSelectedAddableObject() == Tool::kAddableShape || Core::instance()->GetSelectedAddableObject() == Tool::kAddableTitle)) {
add_band_start_ = event->pos();
add_band_ = new QRubberBand(QRubberBand::Rectangle, this);
add_band_->setGeometry(QRect(add_band_start_, add_band_start_));
add_band_->show();
} else if (event->button() == Qt::LeftButton && gizmos_
&& (current_gizmo_ = TryGizmoPress(gizmo_db_, TransformViewerSpaceToBufferSpace(event->pos())))) {
// Handle gizmo click
@@ -274,6 +291,10 @@ void ViewerDisplayWidget::mouseMoveEvent(QMouseEvent *event)
hand_last_drag_pos_ = event->pos();
} else if (add_band_) {
add_band_->setGeometry(QRect(event->pos(), add_band_start_).normalized());
} else if (current_gizmo_) {
// Signal movement
@@ -324,6 +345,14 @@ void ViewerDisplayWidget::mouseReleaseEvent(QMouseEvent *event)
hand_dragging_ = false;
UpdateCursor();
} else if (add_band_) {
QRectF r = GenerateGizmoTransform().inverted().mapRect(add_band_->geometry());
emit CreateAddableAt(r);
add_band_->deleteLater();
add_band_ = nullptr;
} else if (current_gizmo_) {
// Handle gizmo
+10 -1
View File
@@ -21,8 +21,9 @@
#ifndef VIEWERGLWIDGET_H
#define VIEWERGLWIDGET_H
#include <QOpenGLWidget>
#include <QMatrix4x4>
#include <QOpenGLWidget>
#include <QRubberBand>
#include "node/color/colormanager/colormanager.h"
#include "node/gizmo/text.h"
@@ -163,6 +164,8 @@ public slots:
*/
void UpdateCursor();
void ToolChanged();
/**
* @brief Enables/disables a basic deinterlace on the viewer
*/
@@ -208,6 +211,8 @@ signals:
void QueueStarved();
void CreateAddableAt(const QRectF &rect);
protected:
/**
* @brief Override the mouse press event for the DragStarted() signal and gizmos
@@ -371,6 +376,9 @@ private:
rational playback_timebase_;
QRubberBand *add_band_;
QPoint add_band_start_;
private slots:
void EmitColorAtCursor(QMouseEvent* e);
@@ -380,6 +388,7 @@ private slots:
void SubtitlesChanged(const TimeRange &r);
};
}