viewer: allow adding objects with a rect
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -325,6 +325,8 @@ private slots:
|
||||
|
||||
void UpdateAudioProcessor();
|
||||
|
||||
void CreateAddableAt(QRectF f);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user