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
+11 -38
View File
@@ -31,7 +31,6 @@ namespace olive {
SeekableWidget::SeekableWidget(QWidget* parent) :
TimelineScaledWidget(parent),
time_(0),
timeline_points_(nullptr),
scroll_(0),
snap_service_(nullptr),
@@ -73,11 +72,6 @@ void SeekableWidget::SetSnapService(SnapService *service)
snap_service_ = service;
}
const int64_t &SeekableWidget::GetTime() const
{
return time_;
}
const int &SeekableWidget::GetScroll() const
{
return scroll_;
@@ -119,7 +113,7 @@ TimelinePoints *SeekableWidget::timeline_points() const
return timeline_points_;
}
void SeekableWidget::SetTime(const int64_t &r)
void SeekableWidget::SetTime(const rational &r)
{
time_ = r;
@@ -133,29 +127,14 @@ void SeekableWidget::SetScroll(int s)
update();
}
double SeekableWidget::ScreenToUnitFloat(int screen) const
{
return (screen + scroll_) / GetScale() / timebase_dbl();
}
int64_t SeekableWidget::ScreenToUnit(int screen) const
{
return qFloor(ScreenToUnitFloat(screen));
}
int64_t SeekableWidget::ScreenToUnitRounded(int screen) const
{
return qRound64(ScreenToUnitFloat(screen));
}
int SeekableWidget::UnitToScreen(int64_t unit) const
{
return qFloor(static_cast<double>(unit) * GetScale() * timebase_dbl()) - scroll_;
}
int SeekableWidget::TimeToScreen(const rational &time) const
{
return qFloor(time.toDouble() * GetScale()) - scroll_;
return qFloor(TimeToScene(time)) - scroll_;
}
rational SeekableWidget::ScreenToTime(int x) const
{
return qMax(rational(0), SceneToTime(x + scroll_));
}
void SeekableWidget::SeekToScreenPoint(int screen)
@@ -164,26 +143,20 @@ void SeekableWidget::SeekToScreenPoint(int screen)
return;
}
int64_t timestamp = qMax(static_cast<int64_t>(0), ScreenToUnitRounded(screen));
rational playhead_time = ScreenToTime(screen);
if (Core::instance()->snapping() && snap_service_) {
rational playhead_time = Timecode::timestamp_to_time(timestamp, timebase());
rational movement;
snap_service_->SnapPoint({playhead_time},
&movement,
SnapService::kSnapAll & ~SnapService::kSnapToPlayhead);
if (!movement.isNull()) {
timestamp = Timecode::time_to_timestamp(playhead_time + movement,
timebase());
}
}
if (timestamp != GetTime()) {
SetTime(timestamp);
if (playhead_time != GetTime()) {
SetTime(playhead_time);
emit TimeChanged(timestamp);
emit TimeChanged(playhead_time);
}
}
+8 -11
View File
@@ -34,7 +34,10 @@ class SeekableWidget : public TimelineScaledWidget
public:
SeekableWidget(QWidget *parent = nullptr);
const int64_t& GetTime() const;
const rational& GetTime() const
{
return time_;
}
const int& GetScroll() const;
@@ -48,7 +51,7 @@ public:
}
public slots:
void SetTime(const int64_t &r);
void SetTime(const rational &r);
void SetScroll(int s);
@@ -65,14 +68,8 @@ protected:
TimelinePoints* timeline_points() const;
double ScreenToUnitFloat(int screen) const;
int64_t ScreenToUnit(int screen) const;
int64_t ScreenToUnitRounded(int screen) const;
int UnitToScreen(int64_t unit) const;
int TimeToScreen(const rational& time) const;
rational ScreenToTime(int x) const;
void DrawPlayhead(QPainter* p, int x, int y);
@@ -88,10 +85,10 @@ signals:
/**
* @brief Signal emitted whenever the time changes on this ruler, either by user or programmatically
*/
void TimeChanged(int64_t);
void TimeChanged(const rational &time);
private:
int64_t time_;
rational time_;
TimelinePoints* timeline_points_;
+2 -2
View File
@@ -208,7 +208,7 @@ void TimeRuler::paintEvent(QPaintEvent *)
if (text_visible_) {
QRect text_rect;
Qt::Alignment text_align;
QString timecode_str = Timecode::timestamp_to_timecode(ScreenToUnit(i), timebase(), Core::instance()->GetTimecodeDisplay());
QString timecode_str = Timecode::time_to_timecode(ScreenToTime(i), timebase(), Core::instance()->GetTimecodeDisplay());
int timecode_width = QtUtils::QFontMetricsWidth(fm, timecode_str);
int timecode_left;
@@ -287,7 +287,7 @@ void TimeRuler::paintEvent(QPaintEvent *)
}
// Draw the playhead if it's on screen at the moment
int playhead_pos = UnitToScreen(GetTime());
int playhead_pos = TimeToScreen(GetTime());
p.setPen(Qt::NoPen);
p.setBrush(PLAYHEAD_COLOR);
DrawPlayhead(&p, playhead_pos, line_bottom);