timeline: implemented in/out points
This commit is contained in:
@@ -118,6 +118,7 @@ private:
|
|||||||
|
|
||||||
QDebug operator<<(QDebug debug, const rational& r);
|
QDebug operator<<(QDebug debug, const rational& r);
|
||||||
|
|
||||||
|
// We define these limits at 32-bit to try avoiding integer overflow
|
||||||
#define RATIONAL_MIN rational(INT32_MIN, 1)
|
#define RATIONAL_MIN rational(INT32_MIN, 1)
|
||||||
#define RATIONAL_MAX rational(INT32_MAX, 1)
|
#define RATIONAL_MAX rational(INT32_MAX, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -134,3 +134,28 @@ void TimeBasedPanel::Retranslate()
|
|||||||
SetSubtitle(tr("(none)"));
|
SetSubtitle(tr("(none)"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimeBasedPanel::SetIn()
|
||||||
|
{
|
||||||
|
GetTimeBasedWidget()->SetInAtPlayhead();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedPanel::SetOut()
|
||||||
|
{
|
||||||
|
GetTimeBasedWidget()->SetOutAtPlayhead();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedPanel::ResetIn()
|
||||||
|
{
|
||||||
|
GetTimeBasedWidget()->ResetIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedPanel::ResetOut()
|
||||||
|
{
|
||||||
|
GetTimeBasedWidget()->ResetOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedPanel::ClearInOut()
|
||||||
|
{
|
||||||
|
GetTimeBasedWidget()->ClearInOutPoints();
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,6 +44,16 @@ public:
|
|||||||
|
|
||||||
virtual void ShuttleRight() override;
|
virtual void ShuttleRight() override;
|
||||||
|
|
||||||
|
virtual void SetIn() override;
|
||||||
|
|
||||||
|
virtual void SetOut() override;
|
||||||
|
|
||||||
|
virtual void ResetIn() override;
|
||||||
|
|
||||||
|
virtual void ResetOut() override;
|
||||||
|
|
||||||
|
virtual void ClearInOut() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void SetTimebase(const rational& timebase);
|
void SetTimebase(const rational& timebase);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "project/item/footage/audiostream.h"
|
#include "project/item/footage/audiostream.h"
|
||||||
#include "project/item/footage/imagestream.h"
|
#include "project/item/footage/imagestream.h"
|
||||||
#include "project/item/footage/videostream.h"
|
#include "project/item/footage/videostream.h"
|
||||||
|
#include "timeline/timelinepoints.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A reference to an external media file with metadata in a project structure
|
* @brief A reference to an external media file with metadata in a project structure
|
||||||
@@ -38,7 +39,7 @@
|
|||||||
* Footage objects store a list of Stream objects which store the majority of video/audio metadata. These streams
|
* Footage objects store a list of Stream objects which store the majority of video/audio metadata. These streams
|
||||||
* are identical to the stream data in the files.
|
* are identical to the stream data in the files.
|
||||||
*/
|
*/
|
||||||
class Footage : public Item
|
class Footage : public Item, public TimelinePoints
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Status {
|
enum Status {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "render/videoparams.h"
|
#include "render/videoparams.h"
|
||||||
#include "project/item/footage/stream.h"
|
#include "project/item/footage/stream.h"
|
||||||
#include "project/item/item.h"
|
#include "project/item/item.h"
|
||||||
|
#include "timeline/timelinepoints.h"
|
||||||
|
|
||||||
class Sequence;
|
class Sequence;
|
||||||
using SequencePtr = std::shared_ptr<Sequence>;
|
using SequencePtr = std::shared_ptr<Sequence>;
|
||||||
@@ -34,7 +35,7 @@ using SequencePtr = std::shared_ptr<Sequence>;
|
|||||||
/**
|
/**
|
||||||
* @brief The main timeline object, an graph of edited clips that forms a complete edit
|
* @brief The main timeline object, an graph of edited clips that forms a complete edit
|
||||||
*/
|
*/
|
||||||
class Sequence : public Item, public NodeGraph
|
class Sequence : public Item, public NodeGraph, public TimelinePoints
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sequence();
|
Sequence();
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ set(OLIVE_SOURCES
|
|||||||
${OLIVE_SOURCES}
|
${OLIVE_SOURCES}
|
||||||
timeline/timelinecoordinate.h
|
timeline/timelinecoordinate.h
|
||||||
timeline/timelinecoordinate.cpp
|
timeline/timelinecoordinate.cpp
|
||||||
|
timeline/timelinemarker.h
|
||||||
|
timeline/timelinemarker.cpp
|
||||||
|
timeline/timelinepoints.h
|
||||||
|
timeline/timelinepoints.cpp
|
||||||
|
timeline/timelineworkarea.h
|
||||||
|
timeline/timelineworkarea.cpp
|
||||||
timeline/trackreference.h
|
timeline/trackreference.h
|
||||||
timeline/trackreference.cpp
|
timeline/trackreference.cpp
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "timelinemarker.h"
|
||||||
|
|
||||||
|
TimelineMarker::TimelineMarker(const TimeRange &time, const QString &name, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
time_(time),
|
||||||
|
name_(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimeRange &TimelineMarker::time() const
|
||||||
|
{
|
||||||
|
return time_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineMarker::set_time(const TimeRange &time)
|
||||||
|
{
|
||||||
|
time_ = time;
|
||||||
|
emit TimeChanged(time_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &TimelineMarker::name() const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineMarker::set_name(const QString &name)
|
||||||
|
{
|
||||||
|
name_ = name;
|
||||||
|
emit NameChanged(name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineMarkerList::~TimelineMarkerList()
|
||||||
|
{
|
||||||
|
qDeleteAll(markers_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineMarkerList::AddMarker(const TimeRange &time, const QString &name)
|
||||||
|
{
|
||||||
|
TimelineMarker* m = new TimelineMarker(time, name);
|
||||||
|
markers_.append(m);
|
||||||
|
emit MarkerAdded(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineMarkerList::RemoveMarker(TimelineMarker *marker)
|
||||||
|
{
|
||||||
|
for (int i=0;i<markers_.size();i++) {
|
||||||
|
TimelineMarker* m = markers_.at(i);
|
||||||
|
|
||||||
|
if (m == marker) {
|
||||||
|
markers_.removeAt(i);
|
||||||
|
emit MarkerRemoved(m);
|
||||||
|
delete m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<TimelineMarker*> &TimelineMarkerList::list() const
|
||||||
|
{
|
||||||
|
return markers_;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef TIMELINEMARKER_H
|
||||||
|
#define TIMELINEMARKER_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "common/timerange.h"
|
||||||
|
|
||||||
|
class TimelineMarker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TimelineMarker(const TimeRange& time = TimeRange(), const QString& name = QString(), QObject* parent = nullptr);
|
||||||
|
|
||||||
|
const TimeRange &time() const;
|
||||||
|
void set_time(const TimeRange& time);
|
||||||
|
|
||||||
|
const QString& name() const;
|
||||||
|
void set_name(const QString& name);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void TimeChanged(const TimeRange& time);
|
||||||
|
|
||||||
|
void NameChanged(const QString& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TimeRange time_;
|
||||||
|
|
||||||
|
QString name_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TimelineMarkerList : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TimelineMarkerList() = default;
|
||||||
|
|
||||||
|
virtual ~TimelineMarkerList() override;
|
||||||
|
|
||||||
|
void AddMarker(const TimeRange& time = TimeRange(), const QString& name = QString());
|
||||||
|
|
||||||
|
void RemoveMarker(TimelineMarker* marker);
|
||||||
|
|
||||||
|
const QList<TimelineMarker *> &list() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void MarkerAdded(TimelineMarker* marker);
|
||||||
|
|
||||||
|
void MarkerRemoved(TimelineMarker* marker);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<TimelineMarker*> markers_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMELINEMARKER_H
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#include "timelinepoints.h"
|
||||||
|
|
||||||
|
TimelineMarkerList *TimelinePoints::markers()
|
||||||
|
{
|
||||||
|
return &markers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimelineMarkerList *TimelinePoints::markers() const
|
||||||
|
{
|
||||||
|
return &markers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimelineWorkArea *TimelinePoints::workarea() const
|
||||||
|
{
|
||||||
|
return &workarea_;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineWorkArea *TimelinePoints::workarea()
|
||||||
|
{
|
||||||
|
return &workarea_;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef TIMELINEPOINTS_H
|
||||||
|
#define TIMELINEPOINTS_H
|
||||||
|
|
||||||
|
#include "timelinemarker.h"
|
||||||
|
#include "timelineworkarea.h"
|
||||||
|
|
||||||
|
class TimelinePoints
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimelinePoints() = default;
|
||||||
|
|
||||||
|
TimelineMarkerList* markers();
|
||||||
|
const TimelineMarkerList* markers() const;
|
||||||
|
|
||||||
|
TimelineWorkArea* workarea();
|
||||||
|
const TimelineWorkArea* workarea() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TimelineMarkerList markers_;
|
||||||
|
|
||||||
|
TimelineWorkArea workarea_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMELINEPOINTS_H
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "timelineworkarea.h"
|
||||||
|
|
||||||
|
const rational TimelineWorkArea::kResetIn = 0;
|
||||||
|
const rational TimelineWorkArea::kResetOut = RATIONAL_MAX;
|
||||||
|
|
||||||
|
TimelineWorkArea::TimelineWorkArea(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimelineWorkArea::enabled() const
|
||||||
|
{
|
||||||
|
return workarea_enabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineWorkArea::set_enabled(bool e)
|
||||||
|
{
|
||||||
|
workarea_enabled_ = e;
|
||||||
|
emit EnabledChanged(workarea_enabled_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimeRange &TimelineWorkArea::range() const
|
||||||
|
{
|
||||||
|
return workarea_range_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineWorkArea::set_range(const TimeRange &range)
|
||||||
|
{
|
||||||
|
workarea_range_ = range;
|
||||||
|
emit RangeChanged(workarea_range_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rational &TimelineWorkArea::in() const
|
||||||
|
{
|
||||||
|
return workarea_range_.in();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rational &TimelineWorkArea::out() const
|
||||||
|
{
|
||||||
|
return workarea_range_.out();
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef TIMELINEWORKAREA_H
|
||||||
|
#define TIMELINEWORKAREA_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "common/timerange.h"
|
||||||
|
|
||||||
|
class TimelineWorkArea : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TimelineWorkArea(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
bool enabled() const;
|
||||||
|
void set_enabled(bool e);
|
||||||
|
|
||||||
|
const rational& in() const;
|
||||||
|
const rational& out() const;
|
||||||
|
const TimeRange& range() const;
|
||||||
|
void set_range(const TimeRange& range);
|
||||||
|
|
||||||
|
static const rational kResetIn;
|
||||||
|
static const rational kResetOut;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void EnabledChanged(bool e);
|
||||||
|
|
||||||
|
void RangeChanged(const TimeRange& r);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool workarea_enabled_;
|
||||||
|
|
||||||
|
TimeRange workarea_range_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMELINEWORKAREA_H
|
||||||
@@ -39,16 +39,16 @@ MenuShared::MenuShared()
|
|||||||
edit_paste_item_ = Menu::CreateItem(this, "paste", nullptr, nullptr, "Ctrl+V");
|
edit_paste_item_ = Menu::CreateItem(this, "paste", nullptr, nullptr, "Ctrl+V");
|
||||||
edit_paste_insert_item_ = Menu::CreateItem(this, "pasteinsert", nullptr, nullptr, "Ctrl+Shift+V");
|
edit_paste_insert_item_ = Menu::CreateItem(this, "pasteinsert", nullptr, nullptr, "Ctrl+Shift+V");
|
||||||
edit_duplicate_item_ = Menu::CreateItem(this, "duplicate", nullptr, nullptr, "Ctrl+D");
|
edit_duplicate_item_ = Menu::CreateItem(this, "duplicate", nullptr, nullptr, "Ctrl+D");
|
||||||
edit_delete_item_ = Menu::CreateItem(this, "delete", this, SLOT(DeleteSelected()), "Del");
|
edit_delete_item_ = Menu::CreateItem(this, "delete", this, SLOT(DeleteSelectedTriggered()), "Del");
|
||||||
edit_ripple_delete_item_ = Menu::CreateItem(this, "rippledelete", this, SLOT(RippleDelete()), "Shift+Del");
|
edit_ripple_delete_item_ = Menu::CreateItem(this, "rippledelete", this, SLOT(RippleDeleteTriggered()), "Shift+Del");
|
||||||
edit_split_item_ = Menu::CreateItem(this, "split", this, SLOT(SplitAtPlayhead()), "Ctrl+K");
|
edit_split_item_ = Menu::CreateItem(this, "split", this, SLOT(SplitAtPlayheadTriggered()), "Ctrl+K");
|
||||||
|
|
||||||
// "In/Out" menu shared items
|
// "In/Out" menu shared items
|
||||||
inout_set_in_item_ = Menu::CreateItem(this, "setinpoint", nullptr, nullptr, "I");
|
inout_set_in_item_ = Menu::CreateItem(this, "setinpoint", this, SLOT(SetInTriggered()), "I");
|
||||||
inout_set_out_item_ = Menu::CreateItem(this, "setoutpoint", nullptr, nullptr, "O");
|
inout_set_out_item_ = Menu::CreateItem(this, "setoutpoint", this, SLOT(SetOutTriggered()), "O");
|
||||||
inout_reset_in_item_ = Menu::CreateItem(this, "resetin", nullptr, nullptr);
|
inout_reset_in_item_ = Menu::CreateItem(this, "resetin", this, SLOT(ResetInTriggered()));
|
||||||
inout_reset_out_item_ = Menu::CreateItem(this, "resetout", nullptr, nullptr);
|
inout_reset_out_item_ = Menu::CreateItem(this, "resetout", this, SLOT(ResetOutTriggered()));
|
||||||
inout_clear_inout_item_ = Menu::CreateItem(this, "clearinout", nullptr, nullptr, "G");
|
inout_clear_inout_item_ = Menu::CreateItem(this, "clearinout", this, SLOT(ClearInOutTriggered()), "G");
|
||||||
|
|
||||||
// "Clip Edit" menu shared items
|
// "Clip Edit" menu shared items
|
||||||
clip_add_default_transition_item_ = Menu::CreateItem(this, "deftransition", nullptr, nullptr, "Ctrl+Shift+D");
|
clip_add_default_transition_item_ = Menu::CreateItem(this, "deftransition", nullptr, nullptr, "Ctrl+Shift+D");
|
||||||
@@ -112,7 +112,7 @@ MenuShared *MenuShared::instance()
|
|||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuShared::SplitAtPlayhead()
|
void MenuShared::SplitAtPlayheadTriggered()
|
||||||
{
|
{
|
||||||
TimelinePanel* timeline = PanelManager::instance()->MostRecentlyFocused<TimelinePanel>();
|
TimelinePanel* timeline = PanelManager::instance()->MostRecentlyFocused<TimelinePanel>();
|
||||||
|
|
||||||
@@ -121,16 +121,41 @@ void MenuShared::SplitAtPlayhead()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuShared::DeleteSelected()
|
void MenuShared::DeleteSelectedTriggered()
|
||||||
{
|
{
|
||||||
PanelManager::instance()->CurrentlyFocused()->DeleteSelected();
|
PanelManager::instance()->CurrentlyFocused()->DeleteSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuShared::RippleDelete()
|
void MenuShared::RippleDeleteTriggered()
|
||||||
{
|
{
|
||||||
PanelManager::instance()->CurrentlyFocused()->RippleDelete();
|
PanelManager::instance()->CurrentlyFocused()->RippleDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuShared::SetInTriggered()
|
||||||
|
{
|
||||||
|
PanelManager::instance()->CurrentlyFocused()->SetIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuShared::SetOutTriggered()
|
||||||
|
{
|
||||||
|
PanelManager::instance()->CurrentlyFocused()->SetOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuShared::ResetInTriggered()
|
||||||
|
{
|
||||||
|
PanelManager::instance()->CurrentlyFocused()->ResetIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuShared::ResetOutTriggered()
|
||||||
|
{
|
||||||
|
PanelManager::instance()->CurrentlyFocused()->ResetOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuShared::ClearInOutTriggered()
|
||||||
|
{
|
||||||
|
PanelManager::instance()->CurrentlyFocused()->ClearInOut();
|
||||||
|
}
|
||||||
|
|
||||||
void MenuShared::Retranslate()
|
void MenuShared::Retranslate()
|
||||||
{
|
{
|
||||||
// "New" menu shared items
|
// "New" menu shared items
|
||||||
|
|||||||
@@ -75,11 +75,21 @@ private:
|
|||||||
static MenuShared* instance_;
|
static MenuShared* instance_;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void SplitAtPlayhead();
|
void SplitAtPlayheadTriggered();
|
||||||
|
|
||||||
void DeleteSelected();
|
void DeleteSelectedTriggered();
|
||||||
|
|
||||||
void RippleDelete();
|
void RippleDeleteTriggered();
|
||||||
|
|
||||||
|
void SetInTriggered();
|
||||||
|
|
||||||
|
void SetOutTriggered();
|
||||||
|
|
||||||
|
void ResetInTriggered();
|
||||||
|
|
||||||
|
void ResetOutTriggered();
|
||||||
|
|
||||||
|
void ClearInOutTriggered();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,16 @@ public:
|
|||||||
|
|
||||||
virtual void DecreaseTrackHeight(){}
|
virtual void DecreaseTrackHeight(){}
|
||||||
|
|
||||||
|
virtual void SetIn(){}
|
||||||
|
|
||||||
|
virtual void SetOut(){}
|
||||||
|
|
||||||
|
virtual void ResetIn(){}
|
||||||
|
|
||||||
|
virtual void ResetOut(){}
|
||||||
|
|
||||||
|
virtual void ClearInOut(){}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief paintEvent
|
* @brief paintEvent
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
#include "timebased.h"
|
#include "timebased.h"
|
||||||
|
|
||||||
|
#include <QUndoCommand>
|
||||||
|
|
||||||
#include "common/timecodefunctions.h"
|
#include "common/timecodefunctions.h"
|
||||||
|
#include "core.h"
|
||||||
|
#include "project/item/sequence/sequence.h"
|
||||||
|
#include "widget/timelinewidget/undo/undo.h"
|
||||||
|
|
||||||
TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_status_visible, QWidget *parent) :
|
TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_status_visible, QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
@@ -44,6 +49,8 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
|||||||
DisconnectNodeInternal(viewer_node_);
|
DisconnectNodeInternal(viewer_node_);
|
||||||
|
|
||||||
disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
||||||
|
|
||||||
|
ruler()->ConnectTimelinePoints(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer_node_ = node;
|
viewer_node_ = node;
|
||||||
@@ -54,6 +61,8 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
|||||||
ConnectNodeInternal(viewer_node_);
|
ConnectNodeInternal(viewer_node_);
|
||||||
|
|
||||||
connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
||||||
|
|
||||||
|
ruler()->ConnectTimelinePoints(static_cast<Sequence*>(viewer_node_->parent()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,3 +251,99 @@ void TimeBasedWidget::CenterScrollOnPlayhead()
|
|||||||
{
|
{
|
||||||
scrollbar_->setValue(qRound(TimeToScene(Timecode::timestamp_to_time(ruler_->GetTime(), timebase()))) - scrollbar_->width()/2);
|
scrollbar_->setValue(qRound(TimeToScene(Timecode::timestamp_to_time(ruler_->GetTime(), timebase()))) - scrollbar_->width()/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::SetPoint(Timeline::MovementMode m, const rational& time)
|
||||||
|
{
|
||||||
|
if (!GetConnectedNode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUndoCommand* command = new QUndoCommand();
|
||||||
|
|
||||||
|
Sequence* s = static_cast<Sequence*>(GetConnectedNode()->parent());
|
||||||
|
|
||||||
|
// Enable workarea if it isn't already enabled
|
||||||
|
if (!s->workarea()->enabled()) {
|
||||||
|
new WorkareaSetEnabledCommand(s, true, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine our new range
|
||||||
|
rational in_point, out_point;
|
||||||
|
|
||||||
|
if (m == Timeline::kTrimIn) {
|
||||||
|
in_point = time;
|
||||||
|
|
||||||
|
if (!s->workarea()->enabled() || s->workarea()->out() < in_point) {
|
||||||
|
out_point = TimelineWorkArea::kResetOut;
|
||||||
|
} else {
|
||||||
|
out_point = s->workarea()->out();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out_point = time;
|
||||||
|
|
||||||
|
if (!s->workarea()->enabled() || s->workarea()->in() > out_point) {
|
||||||
|
in_point = TimelineWorkArea::kResetIn;
|
||||||
|
} else {
|
||||||
|
in_point = s->workarea()->in();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set workarea
|
||||||
|
new WorkareaSetRangeCommand(s, TimeRange(in_point, out_point), command);
|
||||||
|
|
||||||
|
Core::instance()->undo_stack()->push(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::ResetPoint(Timeline::MovementMode m)
|
||||||
|
{
|
||||||
|
if (!GetConnectedNode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sequence* s = static_cast<Sequence*>(GetConnectedNode()->parent());
|
||||||
|
|
||||||
|
if (!s->workarea()->enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeRange r = s->workarea()->range();
|
||||||
|
|
||||||
|
if (m == Timeline::kTrimIn) {
|
||||||
|
r.set_in(TimelineWorkArea::kResetIn);
|
||||||
|
} else {
|
||||||
|
r.set_out(TimelineWorkArea::kResetOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(s, r));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::SetInAtPlayhead()
|
||||||
|
{
|
||||||
|
SetPoint(Timeline::kTrimIn, GetTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::SetOutAtPlayhead()
|
||||||
|
{
|
||||||
|
SetPoint(Timeline::kTrimOut, GetTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::ResetIn()
|
||||||
|
{
|
||||||
|
ResetPoint(Timeline::kTrimIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::ResetOut()
|
||||||
|
{
|
||||||
|
ResetPoint(Timeline::kTrimOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeBasedWidget::ClearInOutPoints()
|
||||||
|
{
|
||||||
|
if (!GetConnectedNode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sequence* s = static_cast<Sequence*>(GetConnectedNode()->parent());
|
||||||
|
|
||||||
|
Core::instance()->undo_stack()->push(new WorkareaSetEnabledCommand(s, false));
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "common/timelinecommon.h"
|
||||||
#include "node/output/viewer/viewer.h"
|
#include "node/output/viewer/viewer.h"
|
||||||
#include "widget/resizablescrollbar/resizablescrollbar.h"
|
#include "widget/resizablescrollbar/resizablescrollbar.h"
|
||||||
#include "widget/timelinewidget/timelinescaledobject.h"
|
#include "widget/timelinewidget/timelinescaledobject.h"
|
||||||
@@ -48,6 +49,16 @@ public slots:
|
|||||||
|
|
||||||
void GoToNextCut();
|
void GoToNextCut();
|
||||||
|
|
||||||
|
void SetInAtPlayhead();
|
||||||
|
|
||||||
|
void SetOutAtPlayhead();
|
||||||
|
|
||||||
|
void ResetIn();
|
||||||
|
|
||||||
|
void ResetOut();
|
||||||
|
|
||||||
|
void ClearInOutPoints();
|
||||||
|
|
||||||
TimeRuler* ruler() const;
|
TimeRuler* ruler() const;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
@@ -84,6 +95,26 @@ signals:
|
|||||||
void TimebaseChanged(const rational&);
|
void TimebaseChanged(const rational&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Set either in or out point to the current playhead
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
*
|
||||||
|
* Set to kTrimIn or kTrimOut for setting the in point or out point respectively.
|
||||||
|
*/
|
||||||
|
void SetPoint(Timeline::MovementMode m, const rational &time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset either the in or out point
|
||||||
|
*
|
||||||
|
* Sets either the in point to 0 or the out point to `RATIONAL_MAX`.
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
*
|
||||||
|
* Set to kTrimIn or kTrimOut for setting the in point or out point respectively.
|
||||||
|
*/
|
||||||
|
void ResetPoint(Timeline::MovementMode m);
|
||||||
|
|
||||||
ViewerOutput* viewer_node_;
|
ViewerOutput* viewer_node_;
|
||||||
|
|
||||||
TimeRuler* ruler_;
|
TimeRuler* ruler_;
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ void TimelineWidget::SplitAtPlayhead()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineWidget::DeleteSelectedInternal(QList<Block *> blocks,
|
void TimelineWidget::DeleteSelectedInternal(const QList<Block *> &blocks,
|
||||||
bool transition_aware,
|
bool transition_aware,
|
||||||
bool remove_from_graph,
|
bool remove_from_graph,
|
||||||
QUndoCommand *command)
|
QUndoCommand *command)
|
||||||
@@ -426,7 +426,7 @@ void TimelineWidget::DeleteSelected(bool ripple)
|
|||||||
range_list.InsertTimeRange(TimeRange(b->in(), b->out()));
|
range_list.InsertTimeRange(TimeRange(b->in(), b->out()));
|
||||||
}
|
}
|
||||||
|
|
||||||
new TimelineRippleDeleteGapsAtRegions(GetConnectedNode(), range_list, command);
|
new TimelineRippleDeleteGapsAtRegionsCommand(GetConnectedNode(), range_list, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ private:
|
|||||||
bool dual_transition_;
|
bool dual_transition_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DeleteSelectedInternal(QList<Block *> blocks, bool transition_aware, bool remove_from_graph, QUndoCommand* command);
|
void DeleteSelectedInternal(const QList<Block *>& blocks, bool transition_aware, bool remove_from_graph, QUndoCommand* command);
|
||||||
|
|
||||||
void SetBlockLinksSelected(Block *block, bool selected);
|
void SetBlockLinksSelected(Block *block, bool selected);
|
||||||
|
|
||||||
|
|||||||
@@ -623,14 +623,14 @@ void BlockSetSpeedCommand::undo_internal()
|
|||||||
block_->set_speed(old_speed_);
|
block_->set_speed(old_speed_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimelineRippleDeleteGapsAtRegions::TimelineRippleDeleteGapsAtRegions(ViewerOutput *vo, const TimeRangeList ®ions, QUndoCommand *parent) :
|
TimelineRippleDeleteGapsAtRegionsCommand::TimelineRippleDeleteGapsAtRegionsCommand(ViewerOutput *vo, const TimeRangeList ®ions, QUndoCommand *parent) :
|
||||||
UndoCommand(parent),
|
UndoCommand(parent),
|
||||||
timeline_(vo),
|
timeline_(vo),
|
||||||
regions_(regions)
|
regions_(regions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineRippleDeleteGapsAtRegions::redo_internal()
|
void TimelineRippleDeleteGapsAtRegionsCommand::redo_internal()
|
||||||
{
|
{
|
||||||
foreach (const TimeRange& range, regions_) {
|
foreach (const TimeRange& range, regions_) {
|
||||||
rational max_ripple_length = range.length();
|
rational max_ripple_length = range.length();
|
||||||
@@ -671,7 +671,7 @@ void TimelineRippleDeleteGapsAtRegions::redo_internal()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineRippleDeleteGapsAtRegions::undo_internal()
|
void TimelineRippleDeleteGapsAtRegionsCommand::undo_internal()
|
||||||
{
|
{
|
||||||
for (int i=commands_.size()-1;i>=0;i--) {
|
for (int i=commands_.size()-1;i>=0;i--) {
|
||||||
commands_.at(i)->undo();
|
commands_.at(i)->undo();
|
||||||
@@ -679,3 +679,39 @@ void TimelineRippleDeleteGapsAtRegions::undo_internal()
|
|||||||
}
|
}
|
||||||
commands_.empty();
|
commands_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorkareaSetEnabledCommand::WorkareaSetEnabledCommand(TimelinePoints *points, bool enabled, QUndoCommand *parent) :
|
||||||
|
UndoCommand(parent),
|
||||||
|
points_(points),
|
||||||
|
old_enabled_(points_->workarea()->enabled()),
|
||||||
|
new_enabled_(enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkareaSetEnabledCommand::redo_internal()
|
||||||
|
{
|
||||||
|
points_->workarea()->set_enabled(new_enabled_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkareaSetEnabledCommand::undo_internal()
|
||||||
|
{
|
||||||
|
points_->workarea()->set_enabled(old_enabled_);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkareaSetRangeCommand::WorkareaSetRangeCommand(TimelinePoints *points, const TimeRange &range, QUndoCommand *parent) :
|
||||||
|
UndoCommand(parent),
|
||||||
|
points_(points),
|
||||||
|
old_range_(points_->workarea()->range()),
|
||||||
|
new_range_(range)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkareaSetRangeCommand::redo_internal()
|
||||||
|
{
|
||||||
|
points_->workarea()->set_range(new_range_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkareaSetRangeCommand::undo_internal()
|
||||||
|
{
|
||||||
|
points_->workarea()->set_range(old_range_);
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "node/block/gap/gap.h"
|
#include "node/block/gap/gap.h"
|
||||||
#include "node/output/track/track.h"
|
#include "node/output/track/track.h"
|
||||||
#include "node/output/track/tracklist.h"
|
#include "node/output/track/tracklist.h"
|
||||||
|
#include "timeline/timelinepoints.h"
|
||||||
#include "undo/undocommand.h"
|
#include "undo/undocommand.h"
|
||||||
|
|
||||||
class BlockResizeCommand : public UndoCommand {
|
class BlockResizeCommand : public UndoCommand {
|
||||||
@@ -280,9 +281,9 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimelineRippleDeleteGapsAtRegions : public UndoCommand {
|
class TimelineRippleDeleteGapsAtRegionsCommand : public UndoCommand {
|
||||||
public:
|
public:
|
||||||
TimelineRippleDeleteGapsAtRegions(ViewerOutput* vo, const TimeRangeList& regions, QUndoCommand* parent = nullptr);
|
TimelineRippleDeleteGapsAtRegionsCommand(ViewerOutput* vo, const TimeRangeList& regions, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void redo_internal() override;
|
virtual void redo_internal() override;
|
||||||
@@ -296,4 +297,38 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WorkareaSetEnabledCommand : public UndoCommand {
|
||||||
|
public:
|
||||||
|
WorkareaSetEnabledCommand(TimelinePoints* points, bool enabled, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void redo_internal() override;
|
||||||
|
virtual void undo_internal() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TimelinePoints* points_;
|
||||||
|
|
||||||
|
bool old_enabled_;
|
||||||
|
|
||||||
|
bool new_enabled_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorkareaSetRangeCommand : public UndoCommand {
|
||||||
|
public:
|
||||||
|
WorkareaSetRangeCommand(TimelinePoints* points, const TimeRange& range, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void redo_internal() override;
|
||||||
|
virtual void undo_internal() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TimelinePoints* points_;
|
||||||
|
|
||||||
|
TimeRange old_range_;
|
||||||
|
|
||||||
|
TimeRange new_range_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif // TIMELINEUNDOABLE_H
|
#endif // TIMELINEUNDOABLE_H
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ TimeRuler::TimeRuler(bool text_visible, bool cache_status_visible, QWidget* pare
|
|||||||
centered_text_(true),
|
centered_text_(true),
|
||||||
scale_(1.0),
|
scale_(1.0),
|
||||||
time_(0),
|
time_(0),
|
||||||
show_cache_status_(cache_status_visible)
|
show_cache_status_(cache_status_visible),
|
||||||
|
timeline_points_(nullptr)
|
||||||
{
|
{
|
||||||
QFontMetrics fm = fontMetrics();
|
QFontMetrics fm = fontMetrics();
|
||||||
|
|
||||||
@@ -81,6 +82,23 @@ void TimeRuler::SetTimebase(const rational &r)
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimeRuler::ConnectTimelinePoints(TimelinePoints *points)
|
||||||
|
{
|
||||||
|
if (timeline_points_) {
|
||||||
|
disconnect(timeline_points_->workarea(), &TimelineWorkArea::RangeChanged, this, &TimeRuler::TimelineWorkareaChanged);
|
||||||
|
disconnect(timeline_points_->workarea(), &TimelineWorkArea::EnabledChanged, this, &TimeRuler::TimelineWorkareaChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeline_points_ = points;
|
||||||
|
|
||||||
|
if (timeline_points_) {
|
||||||
|
connect(timeline_points_->workarea(), &TimelineWorkArea::RangeChanged, this, &TimeRuler::TimelineWorkareaChanged);
|
||||||
|
connect(timeline_points_->workarea(), &TimelineWorkArea::EnabledChanged, this, &TimeRuler::TimelineWorkareaChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
const int64_t &TimeRuler::GetTime()
|
const int64_t &TimeRuler::GetTime()
|
||||||
{
|
{
|
||||||
return time_;
|
return time_;
|
||||||
@@ -138,6 +156,22 @@ void TimeRuler::paintEvent(QPaintEvent *)
|
|||||||
|
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
|
|
||||||
|
// Draw timeline points if connected
|
||||||
|
if (timeline_points_) {
|
||||||
|
if (timeline_points_->workarea()->enabled()) {
|
||||||
|
int workarea_left = qMax(0, TimeToScreen(timeline_points_->workarea()->in()));
|
||||||
|
int workarea_right;
|
||||||
|
|
||||||
|
if (timeline_points_->workarea()->out() == TimelineWorkArea::kResetOut) {
|
||||||
|
workarea_right = width();
|
||||||
|
} else {
|
||||||
|
workarea_right = qMin(width(), TimeToScreen(timeline_points_->workarea()->out()));
|
||||||
|
}
|
||||||
|
|
||||||
|
p.fillRect(workarea_left, 0, workarea_right - workarea_left, height(), palette().highlight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double width_of_frame = timebase_dbl_ * scale_;
|
double width_of_frame = timebase_dbl_ * scale_;
|
||||||
double width_of_second = 0;
|
double width_of_second = 0;
|
||||||
do {
|
do {
|
||||||
@@ -381,6 +415,11 @@ void TimeRuler::SeekToScreenPoint(int screen)
|
|||||||
emit TimeChanged(timestamp);
|
emit TimeChanged(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimeRuler::TimelineWorkareaChanged()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void TimeRuler::UpdateHeight()
|
void TimeRuler::UpdateHeight()
|
||||||
{
|
{
|
||||||
int height = text_height_;
|
int height = text_height_;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "common/rational.h"
|
#include "common/rational.h"
|
||||||
#include "common/timerange.h"
|
#include "common/timerange.h"
|
||||||
|
#include "timeline/timelinepoints.h"
|
||||||
#include "widget/timelinewidget/view/timelineplayhead.h"
|
#include "widget/timelinewidget/view/timelineplayhead.h"
|
||||||
|
|
||||||
class TimeRuler : public QWidget
|
class TimeRuler : public QWidget
|
||||||
@@ -41,6 +42,8 @@ public:
|
|||||||
|
|
||||||
void SetCenteredText(bool c);
|
void SetCenteredText(bool c);
|
||||||
|
|
||||||
|
void ConnectTimelinePoints(TimelinePoints* points);
|
||||||
|
|
||||||
const int64_t& GetTime();
|
const int64_t& GetTime();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -115,6 +118,11 @@ private:
|
|||||||
|
|
||||||
TimeRangeList dirty_cache_ranges_;
|
TimeRangeList dirty_cache_ranges_;
|
||||||
|
|
||||||
|
TimelinePoints* timeline_points_;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void TimelineWorkareaChanged();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIMERULER_H
|
#endif // TIMERULER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user