widget: use rational for internal playhead value

Fixes #1688
This commit is contained in:
itsmattkc
2021-08-02 10:55:01 -07:00
parent 4510f6d36a
commit 438cce1ce5
38 changed files with 217 additions and 334 deletions
+6 -19
View File
@@ -33,7 +33,6 @@ const double TimeBasedView::kMaximumScale = 8192;
TimeBasedView::TimeBasedView(QWidget *parent) :
HandMovableView(parent),
playhead_(0),
playhead_scene_left_(-1),
playhead_scene_right_(-1),
dragging_playhead_(false),
@@ -150,7 +149,7 @@ void TimeBasedView::SetYScale(const double &y_scale)
}
}
void TimeBasedView::SetTime(const int64_t time)
void TimeBasedView::SetTime(const rational &time)
{
playhead_ = time;
@@ -194,11 +193,6 @@ void TimeBasedView::drawForeground(QPainter *painter, const QRectF &rect)
}
}
rational TimeBasedView::GetPlayheadTime() const
{
return Timecode::timestamp_to_time(playhead_, timebase());
}
bool TimeBasedView::PlayheadPress(QMouseEvent *event)
{
QPointF scene_pos = mapToScene(event->pos());
@@ -217,23 +211,16 @@ bool TimeBasedView::PlayheadMove(QMouseEvent *event)
}
QPointF scene_pos = mapToScene(event->pos());
rational mouse_time = SceneToTime(scene_pos.x());
int64_t target_ts = qMax(static_cast<int64_t>(0), Timecode::time_to_timestamp(mouse_time, timebase()));
rational mouse_time = qMax(rational(0), SceneToTime(scene_pos.x()));
if (Core::instance()->snapping() && snap_service_) {
rational target_time = Timecode::timestamp_to_time(target_ts, timebase());
rational movement;
snap_service_->SnapPoint({target_time}, &movement, SnapService::kSnapAll & ~SnapService::kSnapToPlayhead);
if (!movement.isNull()) {
target_ts = Timecode::time_to_timestamp(target_time + movement, timebase());
}
snap_service_->SnapPoint({mouse_time}, &movement, SnapService::kSnapAll & ~SnapService::kSnapToPlayhead);
}
SetTime(target_ts);
emit TimeChanged(target_ts);
SetTime(mouse_time);
emit TimeChanged(mouse_time);
return true;
}
@@ -255,7 +242,7 @@ bool TimeBasedView::PlayheadRelease(QMouseEvent*)
qreal TimeBasedView::GetPlayheadX()
{
return TimeToScene(Timecode::timestamp_to_time(playhead_, timebase()));
return TimeToScene(playhead_);
}
void TimeBasedView::SetEndTime(const rational &length)
+7 -4
View File
@@ -56,12 +56,12 @@ public:
}
public slots:
void SetTime(const int64_t time);
void SetTime(const rational &time);
void SetEndTime(const rational& length);
signals:
void TimeChanged(const int64_t& time);
void TimeChanged(const rational& time);
void ScaleChanged(double scale);
@@ -78,7 +78,10 @@ protected:
virtual void ZoomIntoCursorPosition(QWheelEvent *event, double multiplier, const QPointF &cursor_pos) override;
rational GetPlayheadTime() const;
const rational &GetPlayheadTime() const
{
return playhead_;
}
bool PlayheadPress(QMouseEvent* event);
bool PlayheadMove(QMouseEvent* event);
@@ -105,7 +108,7 @@ protected slots:
private:
qreal GetPlayheadX();
int64_t playhead_;
rational playhead_;
double playhead_scene_left_;
double playhead_scene_right_;
+35 -35
View File
@@ -57,12 +57,7 @@ void TimeBasedWidget::SetScaleAndCenterOnPlayhead(const double &scale)
QTimer::singleShot(0, this, &TimeBasedWidget::CenterScrollOnPlayhead);
}
rational TimeBasedWidget::GetTime() const
{
return Timecode::timestamp_to_time(ruler()->GetTime(), timebase());
}
const int64_t &TimeBasedWidget::GetTimestamp() const
const rational &TimeBasedWidget::GetTime() const
{
return ruler_->GetTime();
}
@@ -273,8 +268,7 @@ void TimeBasedWidget::resizeEvent(QResizeEvent *event)
void TimeBasedWidget::ConnectTimelineView(TimeBasedView *base, bool connect_time_change_event)
{
if (connect_time_change_event) {
connect(base, &TimeBasedView::TimeChanged, this, &TimeBasedWidget::SetTimestamp);
connect(base, &TimeBasedView::TimeChanged, this, &TimeBasedWidget::TimeChanged);
connect(base, &TimeBasedView::TimeChanged, this, &TimeBasedWidget::SetTimeAndSignal);
}
timeline_views_.append(base);
@@ -286,7 +280,7 @@ void TimeBasedWidget::PassWheelEventsToScrollBar(QObject *object)
object->installEventFilter(this);
}
void TimeBasedWidget::SetTimestamp(int64_t timestamp)
void TimeBasedWidget::SetTime(const rational &time)
{
if (UserIsDraggingPlayhead()) {
// If the user is dragging the playhead, we will simply nudge over and not use autoscroll rules.
@@ -306,9 +300,9 @@ void TimeBasedWidget::SetTimestamp(int64_t timestamp)
}
}
ruler_->SetTime(timestamp);
ruler_->SetTime(time);
TimeChangedEvent(timestamp);
TimeChangedEvent(time);
}
void TimeBasedWidget::SetTimebase(const rational &timebase)
@@ -341,20 +335,18 @@ void TimeBasedWidget::GoToPrevCut()
return;
}
if (GetTimestamp() == 0) {
if (GetTime().isNull()) {
return;
}
int64_t closest_cut = 0;
rational closest_cut = 0;
foreach (Track* track, sequence->GetTracks()) {
int64_t this_track_closest_cut = 0;
rational this_track_closest_cut = 0;
foreach (Block* block, track->Blocks()) {
int64_t block_out_ts = Timecode::time_to_timestamp(block->out(), timebase());
if (block_out_ts < GetTimestamp()) {
this_track_closest_cut = block_out_ts;
if (block->out() < GetTime()) {
this_track_closest_cut = block->out();
} else {
break;
}
@@ -375,20 +367,18 @@ void TimeBasedWidget::GoToNextCut()
return;
}
int64_t closest_cut = INT64_MAX;
rational closest_cut = RATIONAL_MAX;
foreach (Track* track, sequence->GetTracks()) {
int64_t this_track_closest_cut = Timecode::time_to_timestamp(track->track_length(), timebase());
rational this_track_closest_cut = track->track_length();
if (this_track_closest_cut <= GetTimestamp()) {
this_track_closest_cut = INT64_MAX;
if (this_track_closest_cut <= GetTime()) {
this_track_closest_cut = RATIONAL_MAX;
}
foreach (Block* block, track->Blocks()) {
int64_t block_in_ts = Timecode::time_to_timestamp(block->in(), timebase());
if (block_in_ts > GetTimestamp()) {
this_track_closest_cut = block_in_ts;
if (block->in() > GetTime()) {
this_track_closest_cut = block->in();
break;
}
}
@@ -396,7 +386,7 @@ void TimeBasedWidget::GoToNextCut()
closest_cut = qMin(closest_cut, this_track_closest_cut);
}
if (closest_cut < INT64_MAX) {
if (closest_cut < RATIONAL_MAX) {
SetTimeAndSignal(closest_cut);
}
}
@@ -411,33 +401,43 @@ void TimeBasedWidget::GoToStart()
void TimeBasedWidget::PrevFrame()
{
if (viewer_node_) {
SetTimeAndSignal(qMax(static_cast<int64_t>(0), ruler()->GetTime() - 1));
rational proposed_time = Timecode::snap_time_to_timebase(GetTime() - timebase(), timebase(), Timecode::kCeil);
if (proposed_time == GetTime()) {
// Catch rounding error, assume this time is snapped and just subtract a timebase
proposed_time -= timebase();
}
SetTimeAndSignal(qMax(rational(0), proposed_time));
}
}
void TimeBasedWidget::NextFrame()
{
if (viewer_node_) {
SetTimeAndSignal(ruler()->GetTime() + 1);
rational proposed_time = Timecode::snap_time_to_timebase(GetTime() + timebase(), timebase(), Timecode::kFloor);
if (proposed_time == GetTime()) {
// Catch rounding error, assume this time is snapped and just add a timebase
proposed_time += timebase();
}
SetTimeAndSignal(proposed_time);
}
}
void TimeBasedWidget::GoToEnd()
{
if (viewer_node_) {
SetTimeAndSignal(Timecode::time_to_timestamp(viewer_node_->GetLength(), timebase()));
SetTimeAndSignal(viewer_node_->GetLength());
}
}
void TimeBasedWidget::SetTimeAndSignal(const int64_t &t)
void TimeBasedWidget::SetTimeAndSignal(const rational &t)
{
SetTimestamp(t);
SetTime(t);
emit TimeChanged(t);
}
void TimeBasedWidget::CenterScrollOnPlayhead()
{
scrollbar_->setValue(qRound(TimeToScene(Timecode::timestamp_to_time(ruler_->GetTime(), timebase()))) - scrollbar_->width()/2);
scrollbar_->setValue(qRound(TimeToScene(ruler_->GetTime())) - scrollbar_->width()/2);
}
void TimeBasedWidget::SetAutoSetTimebase(bool e)
@@ -639,7 +639,7 @@ void TimeBasedWidget::GoToIn()
{
if (GetConnectedNode()) {
if (GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) {
SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase()));
SetTimeAndSignal(GetConnectedNode()->GetTimelinePoints()->workarea()->in());
} else {
GoToStart();
}
@@ -650,7 +650,7 @@ void TimeBasedWidget::GoToOut()
{
if (GetConnectedNode()) {
if (GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) {
SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->out(), timebase()));
SetTimeAndSignal(GetConnectedNode()->GetTimelinePoints()->workarea()->out());
} else {
GoToEnd();
}
+5 -7
View File
@@ -38,9 +38,7 @@ class TimeBasedWidget : public TimelineScaledWidget
public:
TimeBasedWidget(bool ruler_text_visible = true, bool ruler_cache_status_visible = false, QWidget* parent = nullptr);
rational GetTime() const;
const int64_t& GetTimestamp() const;
const rational &GetTime() const;
void ZoomIn();
@@ -57,7 +55,7 @@ public:
virtual bool eventFilter(QObject* object, QEvent* event) override;
public slots:
void SetTimestamp(int64_t timestamp);
void SetTime(const rational &time);
void SetTimebase(const rational& timebase);
@@ -94,14 +92,14 @@ public slots:
void GoToOut();
protected slots:
void SetTimeAndSignal(const int64_t& t);
void SetTimeAndSignal(const rational& t);
protected:
ResizableTimelineScrollBar* scrollbar() const;
virtual void TimebaseChangedEvent(const rational&) override;
virtual void TimeChangedEvent(const int64_t&){}
virtual void TimeChangedEvent(const rational&){}
virtual void ScaleChangedEvent(const double &) override;
@@ -134,7 +132,7 @@ protected slots:
static void PageScrollInternal(QScrollBar* bar, int maximum, int screen_position, bool whole_page_scroll);
signals:
void TimeChanged(const int64_t&);
void TimeChanged(const rational&);
void TimebaseChanged(const rational&);
+2 -2
View File
@@ -72,12 +72,12 @@ rational TimeScaledObject::SceneToTime(const double &x, const double &x_scale, c
return rational(rounded_x_mvmt * timebase.numerator(), timebase.denominator());
}
double TimeScaledObject::TimeToScene(const rational &time)
double TimeScaledObject::TimeToScene(const rational &time) const
{
return time.toDouble() * scale_;
}
rational TimeScaledObject::SceneToTime(const double &x, bool round)
rational TimeScaledObject::SceneToTime(const double &x, bool round) const
{
return SceneToTime(x, scale_, timebase_, round);
}
+2 -2
View File
@@ -51,8 +51,8 @@ public:
static double CalculateScaleFromDimensions(double viewport_sz, double content_sz);
static double CalculatePaddingFromDimensionScale(double viewport_sz);
double TimeToScene(const rational& time);
rational SceneToTime(const double &x, bool round = false);
double TimeToScene(const rational& time) const;
rational SceneToTime(const double &x, bool round = false) const;
protected:
virtual void TimebaseChangedEvent(const rational&){}