Merge pull request #1 from olive-editor/master

Update
This commit is contained in:
Sun
2020-11-25 15:31:57 +08:00
committed by GitHub
36 changed files with 1071 additions and 823 deletions
+4
View File
@@ -151,6 +151,10 @@ void AudioVisualWaveform::Shift(const rational &from, const rational &to)
return;
}
if (from_index > data_.size()) {
return;
}
if (from_index > to_index) {
// Shifting backwards <-
int copy_sz = data_.size() - from_index;
@@ -59,6 +59,11 @@ ShaderCode CrossDissolveTransition::GetShaderCode(const QString &shader_id) cons
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/crossdissolve.frag"), QString());
}
void CrossDissolveTransition::ShaderJobEvent(NodeValueDatabase &value, ShaderJob &job) const
{
job.SetAlphaChannelRequired(true);
}
void CrossDissolveTransition::SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const
{
for (int i=0; i<out_samples->sample_count(); i++) {
@@ -43,6 +43,8 @@ public:
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
protected:
virtual void ShaderJobEvent(NodeValueDatabase& value, ShaderJob& job) const override;
virtual void SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const override;
};
@@ -83,6 +83,10 @@ NodeValueTable TransformDistortNode::Value(NodeValueDatabase &value) const
job.InsertValue(QStringLiteral("ove_mvpmat"), ShaderValue(real_matrix, NodeParam::kMatrix));
job.SetInterpolation(QStringLiteral("ove_maintex"), static_cast<Texture::Interpolation>(value[interpolation_input_].Get(NodeParam::kCombo).toInt()));
// FIXME: This should be optimized, we can use matrix math to determine if this operation will
// end up with gaps in the screen that will require an alpha channel.
job.SetAlphaChannelRequired(true);
table.Push(NodeParam::kShaderJob, QVariant::fromValue(job), this);
}
}
+9 -5
View File
@@ -82,6 +82,7 @@ OpenGLRenderer::OpenGLRenderer(QObject* parent) :
OpenGLRenderer::~OpenGLRenderer()
{
Destroy();
PostDestroy();
}
void OpenGLRenderer::Init(QOpenGLContext *existing_ctx)
@@ -114,6 +115,14 @@ bool OpenGLRenderer::Init()
return true;
}
void OpenGLRenderer::PostDestroy()
{
// Destroy surface if we created it
if (surface_.isValid()) {
surface_.destroy();
}
}
void OpenGLRenderer::PostInit()
{
// Make context current on that surface
@@ -142,11 +151,6 @@ void OpenGLRenderer::DestroyInternal()
delete context_;
}
context_ = nullptr;
// Destroy surface if we created it
if (surface_.isValid()) {
surface_.destroy();
}
}
}
+2
View File
@@ -44,6 +44,8 @@ public:
virtual bool Init() override;
virtual void PostDestroy() override;
public slots:
virtual void PostInit() override;
+2
View File
@@ -67,6 +67,8 @@ public:
void Destroy();
virtual void PostDestroy() = 0;
public slots:
virtual void PostInit() = 0;
+3 -1
View File
@@ -58,12 +58,14 @@ void RendererThreadWrapper::DestroyInternal()
{
if (thread_) {
QMetaObject::invokeMethod(inner_, "DestroyInternal", Qt::BlockingQueuedConnection);
inner_ = nullptr;
thread_->quit();
thread_->wait();
delete thread_;
thread_ = nullptr;
// Destroy in main thread
inner_->PostDestroy();
}
}
+3
View File
@@ -35,11 +35,14 @@ public:
virtual ~RendererThreadWrapper() override
{
Destroy();
PostDestroy();
delete inner_;
}
virtual bool Init() override;
virtual void PostDestroy() override {}
public slots:
virtual void PostInit() override;
+1
View File
@@ -75,6 +75,7 @@ RenderManager::~RenderManager()
delete still_cache_;
context_->Destroy();
context_->PostDestroy();
delete context_;
}
}
+6 -5
View File
@@ -270,11 +270,12 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
ColorManager* color_manager = Node::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
// Calculate footage divider that still fits in the divider chosen
int footage_divider = 1;
while (VideoParams::GetScaledDimension(video_stream->width(), footage_divider) > video_params.effective_width()
|| VideoParams::GetScaledDimension(video_stream->height(), footage_divider) > video_params.effective_height()) {
footage_divider++;
// See if we can make this divider larger (i.e. if the fooage is smaller)
int footage_divider = video_params.divider();
while (footage_divider > 1
&& VideoParams::GetScaledDimension(video_stream->width(), footage_divider-1) < video_params.effective_width()
&& VideoParams::GetScaledDimension(video_stream->height(), footage_divider-1) < video_params.effective_height()) {
footage_divider--;
}
StillImageCache::EntryPtr want_entry = std::make_shared<StillImageCache::Entry>(
+840 -726
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -89,7 +89,6 @@ CurveWidget::CurveWidget(QWidget *parent) :
ruler_view_layout->addWidget(ruler());
view_ = new CurveView();
connect(view_, &CurveView::RequestCenterScrollOnPlayhead, this, &CurveWidget::CenterScrollOnPlayhead);
ConnectTimelineView(view_);
ruler_view_layout->addWidget(view_);
@@ -208,6 +208,7 @@ void ManagedDisplayWidget::MenuColorspaceSelect(QAction *action)
void ManagedDisplayWidget::OnDestroy()
{
attached_renderer_->Destroy();
attached_renderer_->PostDestroy();
}
void ManagedDisplayWidget::SetColorTransform(const ColorTransform &transform)
@@ -85,7 +85,6 @@ NodeParamView::NodeParamView(QWidget *parent) :
keyframe_view_ = new KeyframeView();
keyframe_view_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ConnectTimelineView(keyframe_view_);
connect(keyframe_view_, &KeyframeView::RequestCenterScrollOnPlayhead, this, &NodeParamView::CenterScrollOnPlayhead);
keyframe_area_layout->addWidget(keyframe_view_);
// Connect ruler and keyframe view together
@@ -35,6 +35,7 @@ NodeParamViewRichText::NodeParamViewRichText(QWidget *parent) :
layout->setMargin(0);
line_edit_ = new QTextEdit();
line_edit_->setUndoRedoEnabled(true);
connect(line_edit_, &QTextEdit::textChanged, this, &NodeParamViewRichText::InnerWidgetTextChanged);
layout->addWidget(line_edit_);
+29
View File
@@ -23,6 +23,7 @@
#include <QInputDialog>
#include <QUndoCommand>
#include "common/autoscroll.h"
#include "common/timecodefunctions.h"
#include "config/config.h"
#include "core.h"
@@ -155,6 +156,22 @@ void TimeBasedWidget::ScrollBarResized(const double &multiplier)
SetScale(GetScale() * corrected_scale);
}
void TimeBasedWidget::PageScrollToPlayhead()
{
int playhead_pos = qRound(TimeToScene(GetTime()));
int viewport_width = ruler()->width();
int viewport_padding = viewport_width / 16;
if (playhead_pos < scrollbar()->value()) {
// Anchor the playhead to the RIGHT of where we scroll to
scrollbar()->setValue(playhead_pos - viewport_width + viewport_padding);
} else if (playhead_pos > scrollbar()->value() + viewport_width) {
// Anchor the playhead to the LEFT of where we scroll to
scrollbar()->setValue(playhead_pos - viewport_padding);
}
}
TimeRuler *TimeBasedWidget::ruler() const
{
return ruler_;
@@ -224,6 +241,18 @@ void TimeBasedWidget::SetTimestamp(int64_t timestamp)
{
ruler_->SetTime(timestamp);
switch (static_cast<AutoScroll::Method>(Config::Current()["Autoscroll"].toInt())) {
case AutoScroll::kNone:
// Do nothing
break;
case AutoScroll::kPage:
QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection);
break;
case AutoScroll::kSmooth:
QMetaObject::invokeMethod(this, "CenterScrollOnPlayhead", Qt::QueuedConnection);
break;
}
TimeChangedEvent(timestamp);
}
+8
View File
@@ -204,6 +204,14 @@ private slots:
void ScrollBarResized(const double& multiplier);
/**
* @brief Slot to handle page scrolling of the playhead
*
* If the playhead is outside the current scroll bounds, this function will scroll to where it is. Otherwise it will
* do nothing.
*/
void PageScrollToPlayhead();
};
}
+9 -12
View File
@@ -35,6 +35,7 @@
#include "tool/edit.h"
#include "tool/pointer.h"
#include "tool/razor.h"
#include "tool/record.h"
#include "tool/ripple.h"
#include "tool/rolling.h"
#include "tool/slide.h"
@@ -96,7 +97,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
tools_.replace(olive::Tool::kSlide, new SlideTool(this));
tools_.replace(olive::Tool::kZoom, new ZoomTool(this));
tools_.replace(olive::Tool::kTransition, new TransitionTool(this));
//tools_.replace(olive::Tool::kRecord, new PointerTool(this)); FIXME: Implement
tools_.replace(olive::Tool::kRecord, new RecordTool(this));
tools_.replace(olive::Tool::kAdd, new AddTool(this));
import_tool_ = new ImportTool(this);
@@ -131,7 +132,6 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
connect(view, &TimelineView::customContextMenuRequested, this, &TimelineWidget::ShowContextMenu);
connect(scrollbar(), &QScrollBar::valueChanged, view->horizontalScrollBar(), &QScrollBar::setValue);
connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, scrollbar(), &QScrollBar::setValue);
connect(view, &TimelineView::RequestCenterScrollOnPlayhead, this, &TimelineWidget::CenterScrollOnPlayhead);
connect(view, &TimelineView::MousePressed, this, &TimelineWidget::ViewMousePressed);
connect(view, &TimelineView::MouseMoved, this, &TimelineWidget::ViewMouseMoved);
@@ -299,7 +299,7 @@ void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata)
{
// Cache the earliest in point so all copied clips have a "relative" in point that can be pasted anywhere
QList<TimelineViewBlockItem*>& selected = *static_cast<QList<TimelineViewBlockItem*>*>(userdata);
QVector<TimelineViewBlockItem*>& selected = *static_cast<QVector<TimelineViewBlockItem*>*>(userdata);
rational earliest_in = RATIONAL_MAX;
foreach (TimelineViewBlockItem* item, selected) {
@@ -329,7 +329,7 @@ void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void
void TimelineWidget::PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData& xml_node_data, void *userdata)
{
QList<BlockPasteData>& paste_data = *static_cast<QList<BlockPasteData>*>(userdata);
QVector<BlockPasteData>& paste_data = *static_cast<QVector<BlockPasteData>*>(userdata);
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("block")) {
@@ -354,14 +354,6 @@ void TimelineWidget::PasteNodesFromClipboardInternal(QXmlStreamReader *reader, X
}
}
rational TimelineWidget::GetToolTipTimebase() const
{
if (GetConnectedNode() && use_audio_time_units_) {
return GetConnectedNode()->audio_params().time_base();
}
return timebase();
}
void TimelineWidget::SelectAll()
{
QVector<Block*> newly_selected_blocks;
@@ -1212,6 +1204,11 @@ TimelineView *TimelineWidget::GetFirstTimelineView()
return views_.first()->view();
}
rational TimelineWidget::GetTimebaseForTrackType(Timeline::TrackType type)
{
return views_.at(type)->view()->timebase();
}
const QRect& TimelineWidget::GetRubberBandGeometry() const
{
return rubberband_.geometry();
+2 -2
View File
@@ -154,8 +154,6 @@ public:
return !ghost_items_.isEmpty();
}
rational GetToolTipTimebase() const;
bool IsBlockSelected(Block* b) const
{
return selected_blocks_.contains(b);
@@ -167,6 +165,8 @@ public:
TimelineView* GetFirstTimelineView();
rational GetTimebaseForTrackType(Timeline::TrackType type);
const QRect &GetRubberBandGeometry() const;
/**
@@ -28,6 +28,8 @@ set(OLIVE_SOURCES
widget/timelinewidget/tool/pointer.h
widget/timelinewidget/tool/razor.cpp
widget/timelinewidget/tool/razor.h
widget/timelinewidget/tool/record.cpp
widget/timelinewidget/tool/record.h
widget/timelinewidget/tool/ripple.cpp
widget/timelinewidget/tool/ripple.h
widget/timelinewidget/tool/rolling.cpp
+9 -2
View File
@@ -149,9 +149,10 @@ void ImportTool::DragMove(TimelineViewMouseEvent *event)
}
// Generate tooltip (showing earliest in point of imported clip)
int64_t earliest_timestamp = Timecode::time_to_timestamp(earliest_ghost, parent()->GetToolTipTimebase());
rational tooltip_timebase = parent()->GetTimebaseForTrackType(event->GetTrack().type());
int64_t earliest_timestamp = Timecode::time_to_timestamp(earliest_ghost, tooltip_timebase);
QString tooltip_text = Timecode::timestamp_to_timecode(earliest_timestamp,
parent()->GetToolTipTimebase(),
tooltip_timebase,
Core::instance()->GetTimecodeDisplay());
// Force tooltip to update (otherwise the tooltip won't move as written in the documentation, and could get in the way
@@ -271,6 +272,12 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QList<DraggedFootag
footage_duration = Config::Current()["DefaultStillLength"].value<rational>();
}
// Snap footage duration to timebase
rational snap_mvmt = SnapMovementToTimebase(footage_duration, 0, dest_tb);
if (!snap_mvmt.isNull()) {
footage_duration += snap_mvmt;
}
foreach (TimelineViewGhostItem* ghost, footage_ghosts) {
ghost->SetIn(ghost_start);
ghost->SetOut(ghost_start + footage_duration);
+25 -5
View File
@@ -469,7 +469,7 @@ void PointerTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
}
// Validate ghosts that are being moved (clips from other track types do NOT get moved)
{
if (track_movement != 0) {
QVector<TimelineViewGhostItem*> validate_track_ghosts = parent()->GetGhostItems();
for (int i=0;i<validate_track_ghosts.size();i++) {
if (validate_track_ghosts.at(i)->GetTrack().type() != drag_track_type_) {
@@ -508,10 +508,11 @@ void PointerTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
// Regenerate tooltip and force it to update (otherwise the tooltip won't move as written in the
// documentation, and could get in the way of the cursor)
rational tooltip_timebase = parent()->GetTimebaseForTrackType(drag_start_.GetTrack().type());
QToolTip::hideText();
QToolTip::showText(QCursor::pos(),
Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, parent()->GetToolTipTimebase()),
parent()->GetToolTipTimebase(),
Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, tooltip_timebase),
tooltip_timebase,
Core::instance()->GetTimecodeDisplay(),
true),
parent());
@@ -872,6 +873,8 @@ bool PointerTool::AddMovingTransitionsToClipGhost(Block* block,
rational PointerTool::ValidateInTrimming(rational movement)
{
bool first_ghost = true;
foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) {
if (ghost->GetMode() != Timeline::kTrimIn) {
continue;
@@ -880,8 +883,11 @@ rational PointerTool::ValidateInTrimming(rational movement)
rational earliest_in = RATIONAL_MIN;
rational latest_in = ghost->GetOut();
rational ghost_timebase = parent()->GetTimebaseForTrackType(ghost->GetTrack().type());
// If the ghost must be at least one frame in size, limit the latest allowed in point
if (!ghost->CanHaveZeroLength()) {
latest_in -= parent()->timebase();
latest_in -= ghost_timebase;
}
// Clamp adjusted value between the earliest and latest values
@@ -891,6 +897,11 @@ rational PointerTool::ValidateInTrimming(rational movement)
if (clamped != adjusted) {
movement = clamped - ghost->GetIn();
}
if (first_ghost) {
movement = SnapMovementToTimebase(ghost->GetIn(), movement, ghost_timebase);
first_ghost = false;
}
}
return movement;
@@ -898,6 +909,8 @@ rational PointerTool::ValidateInTrimming(rational movement)
rational PointerTool::ValidateOutTrimming(rational movement)
{
bool first_ghost = true;
foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) {
if (ghost->GetMode() != Timeline::kTrimOut) {
continue;
@@ -906,8 +919,10 @@ rational PointerTool::ValidateOutTrimming(rational movement)
// Determine earliest and latest out points
rational earliest_out = ghost->GetIn();
rational ghost_timebase = parent()->GetTimebaseForTrackType(ghost->GetTrack().type());
if (!ghost->CanHaveZeroLength()) {
earliest_out += parent()->timebase();
earliest_out += ghost_timebase;
}
rational latest_out = RATIONAL_MAX;
@@ -919,6 +934,11 @@ rational PointerTool::ValidateOutTrimming(rational movement)
if (clamped != adjusted) {
movement = clamped - ghost->GetOut();
}
if (first_ghost) {
movement = SnapMovementToTimebase(ghost->GetOut(), movement, ghost_timebase);
first_ghost = false;
}
}
return movement;
+11
View File
@@ -0,0 +1,11 @@
#include "record.h"
namespace olive {
RecordTool::RecordTool(TimelineWidget *parent) :
BeamTool(parent)
{
}
}
+36
View File
@@ -0,0 +1,36 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2020 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef RECORDTIMELINETOOL_H
#define RECORDTIMELINETOOL_H
#include "beam.h"
namespace olive {
class RecordTool : public BeamTool
{
public:
RecordTool(TimelineWidget* parent);
};
}
#endif // RECORDTOOL_H
+3 -2
View File
@@ -54,10 +54,11 @@ void SlipTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
// Generate tooltip and force it to to update (otherwise the tooltip won't move as written in the
// documentation, and could get in the way of the cursor)
rational tooltip_timebase = parent()->GetTimebaseForTrackType(drag_start_.GetTrack().type());
QToolTip::hideText();
QToolTip::showText(QCursor::pos(),
Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, parent()->GetToolTipTimebase()),
parent()->GetToolTipTimebase(),
Timecode::timestamp_to_timecode(Timecode::time_to_timestamp(time_movement, tooltip_timebase),
tooltip_timebase,
Core::instance()->GetTimecodeDisplay(),
true),
parent());
+19
View File
@@ -53,8 +53,22 @@ Timeline::MovementMode TimelineTool::FlipTrimMode(const Timeline::MovementMode &
return trim_mode;
}
rational TimelineTool::SnapMovementToTimebase(const rational &start, rational movement, const rational &timebase)
{
rational proposed_position = start + movement;
rational snapped = Timecode::snap_time_to_timebase(proposed_position, timebase);
if (proposed_position != snapped) {
movement += snapped - proposed_position;
}
return movement;
}
rational TimelineTool::ValidateTimeMovement(rational movement)
{
bool first_ghost = true;
foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) {
if (ghost->GetMode() != Timeline::kMove) {
continue;
@@ -63,6 +77,11 @@ rational TimelineTool::ValidateTimeMovement(rational movement)
// Prevents any ghosts from going below 0:00:00 time
if (ghost->GetIn() + movement < 0) {
movement = -ghost->GetIn();
} else if (first_ghost) {
// Ensure ghost is snapped to a grid
movement = SnapMovementToTimebase(ghost->GetIn(), movement, parent()->GetTimebaseForTrackType(ghost->GetTrack().type()));
first_ghost = false;
}
}
+2
View File
@@ -53,6 +53,8 @@ public:
static Timeline::MovementMode FlipTrimMode(const Timeline::MovementMode& trim_mode);
static rational SnapMovementToTimebase(const rational& start, rational movement, const rational& timebase);
protected:
/**
* @brief Validates Ghosts that are moving horizontally (time-based)
+6 -1
View File
@@ -165,6 +165,7 @@ TrackRippleRemoveAreaCommand::TrackRippleRemoveAreaCommand(TrackOutput *track, r
in_(in),
out_(out),
splice_(false),
splice_split_command_(nullptr),
trim_out_(nullptr),
trim_in_(nullptr),
insert_(nullptr)
@@ -305,7 +306,6 @@ void TrackRippleRemoveAreaCommand::undo_internal()
trim_out_->set_length_and_media_out(trim_out_old_length_);
splice_split_command_->undo();
delete splice_split_command_;
} else {
@@ -344,6 +344,11 @@ void TrackRippleRemoveAreaCommand::undo_internal()
track_->Node::InvalidateCache(TimeRange(in_, insert_ ? out_ : RATIONAL_MAX),
track_->block_input(), track_->block_input());
if (splice_split_command_) {
delete splice_split_command_;
splice_split_command_ = nullptr;
}
}
TrackPlaceBlockCommand::TrackPlaceBlockCommand(TrackList *timeline, int track, Block *block, rational in, QUndoCommand *parent) :
@@ -115,13 +115,14 @@ void TimelineView::wheelEvent(QWheelEvent *event)
return;
} else {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
QPoint angle_delta = event->angleDelta();
if (Config::Current()["InvertTimelineScrollAxes"].toBool()) {
if (Config::Current()["InvertTimelineScrollAxes"].toBool() // Check if config is set to invert timeline axes
&& event->source() != Qt::MouseEventSynthesizedBySystem) { // Never flip axes on Apple trackpads though
angle_delta = QPoint(angle_delta.y(), angle_delta.x());
}
QWheelEvent e(
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
event->position(),
@@ -255,7 +256,8 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect)
painter->setBrush(Qt::NoBrush);
foreach (TimelineViewGhostItem* ghost, (*ghosts_)) {
if (ghost->GetTrack().type() == connected_track_list_->type()) {
if (ghost->GetTrack().type() == connected_track_list_->type()
&& !ghost->IsInvisible()) {
int track_index = ghost->GetAdjustedTrack().index();
painter->drawRect(TimeToScene(ghost->GetAdjustedIn()),
@@ -25,7 +25,6 @@
#include <QScrollBar>
#include <QTimer>
#include "common/autoscroll.h"
#include "common/timecodefunctions.h"
#include "config/config.h"
@@ -115,18 +114,6 @@ void TimelineViewBase::SetTime(const int64_t time)
{
playhead_ = time;
switch (static_cast<AutoScroll::Method>(Config::Current()["Autoscroll"].toInt())) {
case AutoScroll::kNone:
// Do nothing
break;
case AutoScroll::kPage:
QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection);
break;
case AutoScroll::kSmooth:
emit RequestCenterScrollOnPlayhead();
break;
}
// Force redraw for playhead
viewport()->update();
}
@@ -257,21 +244,6 @@ void TimelineViewBase::UpdateSceneRect()
}
}
void TimelineViewBase::PageScrollToPlayhead()
{
int playhead_pos = qRound(GetPlayheadX());
int viewport_padding = viewport()->width() / 16;
if (playhead_pos < horizontalScrollBar()->value()) {
// Anchor the playhead to the RIGHT of where we scroll to
horizontalScrollBar()->setValue(playhead_pos - viewport()->width() + viewport_padding);
} else if (playhead_pos > horizontalScrollBar()->value() + viewport()->width()) {
// Anchor the playhead to the LEFT of where we scroll to
horizontalScrollBar()->setValue(playhead_pos - viewport_padding);
}
}
void TimelineViewBase::resizeEvent(QResizeEvent *event)
{
QGraphicsView::resizeEvent(event);
@@ -60,8 +60,6 @@ signals:
void ScaleChanged(double scale);
void RequestCenterScrollOnPlayhead();
protected:
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
@@ -124,14 +122,6 @@ private slots:
*/
void UpdateSceneRect();
/**
* @brief Slot to handle page scrolling of the playhead
*
* If the playhead is outside the current scroll bounds, this function will scroll to where it is. Otherwise it will
* do nothing.
*/
void PageScrollToPlayhead();
};
}
@@ -74,17 +74,6 @@ void TimelineViewGhostItem::SetCanMoveTracks(bool e)
can_move_tracks_ = e;
}
/*void TimelineViewGhostItem::SetInvisible(bool invisible)
{
setBrush(Qt::NoBrush);
if (invisible) {
setPen(Qt::NoPen);
} else {
setPen(QPen(Qt::yellow, 2)); // FIXME: Make customizable via CSS
}
}*/
const rational &TimelineViewGhostItem::GetIn() const
{
return in_;
+8 -1
View File
@@ -38,7 +38,14 @@ QVariant GizmoTraverser::ProcessShader(const Node *node, const TimeRange &range,
Q_UNUSED(range)
Q_UNUSED(job)
return size_;
return GenerateResolution();
}
QVariant GizmoTraverser::ProcessFrameGeneration(const Node *node, const GenerateJob &job)
{
Q_UNUSED(node)
Q_UNUSED(job)
return GenerateResolution();
}
}
+5 -3
View File
@@ -34,15 +34,17 @@ public:
}
protected:
virtual QVariant ProcessVideoFootage(StreamPtr stream, const rational &input_time);
virtual QVariant ProcessVideoFootage(StreamPtr stream, const rational &input_time) override;
virtual QVariant ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job);
virtual QVariant ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job) override;
virtual QVector2D GenerateResolution() const
virtual QVector2D GenerateResolution() const override
{
return size_;
}
virtual QVariant ProcessFrameGeneration(const Node *node, const GenerateJob& job) override;
// FIXME: Do something about audio?
private:
+8 -3
View File
@@ -274,9 +274,14 @@ void MainWindow::ToggleMaximizedPanel()
// Find the currently focused panel
PanelWidget* currently_hovered = PanelManager::instance()->CurrentlyHovered();
// If no panel is hovered, do nothing
if (currently_hovered == nullptr) {
return;
// If no panel is hovered, fallback to the currently active panel
if (!currently_hovered) {
currently_hovered = PanelManager::instance()->CurrentlyFocused();
// If no panel is hovered or focused, do nothing
if (!currently_hovered) {
return;
}
}
// If this panel is not actually on the main window, this is a no-op