use raw time values independent of timebase for scaling timeline ui
This commit is contained in:
@@ -45,6 +45,9 @@ TimelinePanel::TimelinePanel(QWidget *parent) :
|
||||
// End test code
|
||||
|
||||
Retranslate();
|
||||
|
||||
// ruler_->SetScale(90.0);
|
||||
// view_->SetScale(90.0);
|
||||
}
|
||||
|
||||
void TimelinePanel::Clear()
|
||||
|
||||
@@ -73,3 +73,9 @@ NodeViewItemWidget {
|
||||
qproperty-titlebarColor: #4040a0;
|
||||
qproperty-borderColor: #000000;
|
||||
}
|
||||
|
||||
/* Timeline playhead styling */
|
||||
TimelinePlayhead {
|
||||
qproperty-playheadColor: #ff0000;
|
||||
qproperty-playheadHighlightColor: rgba(255, 255, 255, 0.33);
|
||||
}
|
||||
|
||||
@@ -72,4 +72,10 @@ QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, Node
|
||||
NodeViewItemWidget {
|
||||
qproperty-titlebarColor: #a0a0ff;
|
||||
qproperty-borderColor: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Timeline playhead styling */
|
||||
TimelinePlayhead {
|
||||
qproperty-playheadColor: #ff0000;
|
||||
qproperty-playheadHighlightColor: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/timelineview/timelineplayhead.h
|
||||
widget/timelineview/timelineplayhead.cpp
|
||||
widget/timelineview/timelineview.h
|
||||
widget/timelineview/timelineview.cpp
|
||||
widget/timelineview/timelineviewrect.h
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "timelineplayhead.h"
|
||||
|
||||
TimelinePlayhead::TimelinePlayhead()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QColor TimelinePlayhead::PlayheadColor()
|
||||
{
|
||||
return playhead_color_;
|
||||
}
|
||||
|
||||
QColor TimelinePlayhead::PlayheadHighlightColor()
|
||||
{
|
||||
return playhead_highlight_color_;
|
||||
}
|
||||
|
||||
void TimelinePlayhead::SetPlayheadColor(QColor c)
|
||||
{
|
||||
playhead_color_ = c;
|
||||
}
|
||||
|
||||
void TimelinePlayhead::SetPlayheadHighlightColor(QColor c)
|
||||
{
|
||||
playhead_highlight_color_ = c;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef TIMELINEPLAYHEADSTYLE_H
|
||||
#define TIMELINEPLAYHEADSTYLE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class TimelinePlayhead : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor playheadColor READ PlayheadColor WRITE SetPlayheadColor DESIGNABLE true)
|
||||
Q_PROPERTY(QColor playheadHighlightColor READ PlayheadHighlightColor WRITE SetPlayheadHighlightColor DESIGNABLE true)
|
||||
public:
|
||||
TimelinePlayhead();
|
||||
|
||||
QColor PlayheadColor();
|
||||
QColor PlayheadHighlightColor();
|
||||
|
||||
void SetPlayheadColor(QColor c);
|
||||
void SetPlayheadHighlightColor(QColor c);
|
||||
|
||||
private:
|
||||
QColor playhead_color_;
|
||||
QColor playhead_highlight_color_;
|
||||
};
|
||||
|
||||
#endif // TIMELINEPLAYHEADSTYLE_H
|
||||
@@ -49,7 +49,6 @@ void TimelineView::AddClip(ClipBlock *clip)
|
||||
|
||||
// Set up clip with view parameters (clip item will automatically size its rect accordingly)
|
||||
clip_item->SetClip(clip);
|
||||
clip_item->SetTimebase(timebase_);
|
||||
clip_item->SetScale(scale_);
|
||||
|
||||
// Add to list of clip items that can be iterated through
|
||||
@@ -74,10 +73,6 @@ void TimelineView::SetTimebase(const rational &timebase)
|
||||
{
|
||||
timebase_ = timebase;
|
||||
|
||||
foreach (TimelineViewClipItem* item, clip_items_) {
|
||||
item->SetTimebase(timebase_);
|
||||
}
|
||||
|
||||
playhead_line_->SetTimebase(timebase_);
|
||||
}
|
||||
|
||||
@@ -113,7 +108,7 @@ void TimelineView::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
ghost->SetIn(clip->in());
|
||||
ghost->SetOut(clip->out());
|
||||
ghost->SetTimebase(timebase_);
|
||||
ghost->SetScale(scale_);
|
||||
|
||||
ghost->setPos(clip_item->pos());
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ void TimelineViewClipItem::SetClip(ClipBlock *clip)
|
||||
|
||||
void TimelineViewClipItem::UpdateRect()
|
||||
{
|
||||
if (clip_ == nullptr || !TimebaseIsValid()) {
|
||||
if (clip_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "timelineviewplayheaditem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QtMath>
|
||||
|
||||
TimelineViewPlayheadItem::TimelineViewPlayheadItem(QGraphicsItem *parent) :
|
||||
TimelineViewRect(parent)
|
||||
TimelineViewRect(parent),
|
||||
playhead_(0)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -17,6 +19,13 @@ void TimelineViewPlayheadItem::SetPlayhead(const int64_t &playhead)
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
void TimelineViewPlayheadItem::SetTimebase(const rational &timebase)
|
||||
{
|
||||
timebase_ = timebase;
|
||||
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
void TimelineViewPlayheadItem::UpdateRect()
|
||||
{
|
||||
double x = TimeToScreenCoord(rational(playhead_ * timebase_.numerator(), timebase_.denominator()));
|
||||
@@ -33,10 +42,10 @@ void TimelineViewPlayheadItem::paint(QPainter *painter, const QStyleOptionGraphi
|
||||
|
||||
// FIXME: Make adjustable through CSS
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(QColor(255, 255, 255, 128));
|
||||
painter->setBrush(style_.PlayheadHighlightColor());
|
||||
painter->drawRect(rect());
|
||||
|
||||
painter->setPen(Qt::red);
|
||||
painter->setPen(style_.PlayheadColor());
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawLine(QLineF(rect().topLeft(), rect().bottomLeft()));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef TIMELINEVIEWPLAYHEADITEM_H
|
||||
#define TIMELINEVIEWPLAYHEADITEM_H
|
||||
|
||||
#include "timelineplayhead.h"
|
||||
#include "timelineviewrect.h"
|
||||
|
||||
class TimelineViewPlayheadItem : public TimelineViewRect
|
||||
@@ -10,6 +11,8 @@ public:
|
||||
|
||||
void SetPlayhead(const int64_t& playhead);
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
protected:
|
||||
virtual void UpdateRect() override;
|
||||
|
||||
@@ -17,6 +20,10 @@ protected:
|
||||
|
||||
private:
|
||||
int64_t playhead_;
|
||||
|
||||
rational timebase_;
|
||||
|
||||
TimelinePlayhead style_;
|
||||
};
|
||||
|
||||
#endif // TIMELINEVIEWPLAYHEADITEM_H
|
||||
|
||||
@@ -7,26 +7,14 @@ TimelineViewRect::TimelineViewRect(QGraphicsItem* parent) :
|
||||
|
||||
}
|
||||
|
||||
void TimelineViewRect::SetTimebase(const rational &timebase)
|
||||
{
|
||||
timebase_ = timebase;
|
||||
timebase_dbl_ = timebase_.toDouble();
|
||||
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
void TimelineViewRect::SetScale(const double &scale)
|
||||
{
|
||||
scale_ = scale;
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
bool TimelineViewRect::TimebaseIsValid()
|
||||
{
|
||||
return timebase_.denominator() != 0;
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
double TimelineViewRect::TimeToScreenCoord(const rational &time)
|
||||
{
|
||||
return time.toDouble() / timebase_dbl_ * scale_;
|
||||
return time.toDouble() * scale_;
|
||||
}
|
||||
|
||||
@@ -10,21 +10,13 @@ class TimelineViewRect : public QGraphicsRectItem
|
||||
public:
|
||||
TimelineViewRect(QGraphicsItem* parent = nullptr);
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetScale(const double& scale);
|
||||
|
||||
protected:
|
||||
virtual void UpdateRect() = 0;
|
||||
|
||||
bool TimebaseIsValid();
|
||||
|
||||
double TimeToScreenCoord(const rational& time);
|
||||
|
||||
rational timebase_;
|
||||
|
||||
double timebase_dbl_;
|
||||
|
||||
double scale_;
|
||||
};
|
||||
|
||||
|
||||
@@ -78,7 +78,11 @@ void TimeRuler::SetScale(double d)
|
||||
|
||||
void TimeRuler::SetTimebase(const rational &r)
|
||||
{
|
||||
time_base_ = r;
|
||||
timebase_ = r;
|
||||
|
||||
timebase_dbl_ = timebase_.toDouble();
|
||||
|
||||
timebase_flipped_dbl_ = timebase_.flipped().toDouble();
|
||||
|
||||
update();
|
||||
}
|
||||
@@ -97,12 +101,10 @@ void TimeRuler::SetScroll(int s)
|
||||
update();
|
||||
}
|
||||
|
||||
void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
void TimeRuler::paintEvent(QPaintEvent *)
|
||||
{
|
||||
Q_UNUSED(e)
|
||||
|
||||
// Nothing to paint if the timebase is invalid
|
||||
if (time_base_.denominator() == 0) {
|
||||
if (timebase_.denominator() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,10 +115,10 @@ void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
|
||||
// Depending on the scale, we don't need all the lines drawn or else they'll start to become unhelpful
|
||||
// Determine an even number to divide the frame count by
|
||||
int rough_frames_in_second = qRound(time_base_.flipped().toDouble());
|
||||
int rough_frames_in_second = qRound(timebase_flipped_dbl_);
|
||||
int test_divider = 1;
|
||||
while (!((rough_frames_in_second%test_divider == 0 || test_divider > rough_frames_in_second)
|
||||
&& scale_ * test_divider >= minimum_gap_between_lines_)) {
|
||||
&& scale_ * test_divider * timebase_dbl_ >= minimum_gap_between_lines_)) {
|
||||
if (test_divider < rough_frames_in_second) {
|
||||
test_divider++;
|
||||
} else {
|
||||
@@ -124,7 +126,7 @@ void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
}
|
||||
}
|
||||
double reverse_divider = double(rough_frames_in_second) / double(test_divider);
|
||||
qreal real_divider = qMax(1.0, time_base_.flipped().toDouble() / reverse_divider);
|
||||
qreal real_divider = qMax(1.0, timebase_flipped_dbl_ / reverse_divider);
|
||||
|
||||
// Set where the loop ends (affected by text)
|
||||
int loop_start = - playhead_width_;
|
||||
@@ -136,8 +138,8 @@ void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
int text_y = 0;
|
||||
if (text_visible_) {
|
||||
QFontMetrics fm = p.fontMetrics();
|
||||
double width_of_second = time_base_.flipped().toDouble() * scale_;
|
||||
int average_text_width = QFontMetricsWidth(&fm, olive::timestamp_to_timecode(0, time_base_, kTimecodeDisplay));
|
||||
double width_of_second = scale_;
|
||||
int average_text_width = QFontMetricsWidth(&fm, olive::timestamp_to_timecode(0, timebase_, kTimecodeDisplay));
|
||||
half_average_text_width = average_text_width/2;
|
||||
while (width_of_second * text_skip < average_text_width) {
|
||||
text_skip++;
|
||||
@@ -166,21 +168,14 @@ void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
int line_halfsec_bottom = line_top + line_length / 3 * 2;
|
||||
int line_frame_bottom = line_top + line_length / 3;
|
||||
|
||||
int playhead_pos = -1;
|
||||
|
||||
for (int i=loop_start;i<loop_end;i++) {
|
||||
int64_t unit = ScreenToUnit(i);
|
||||
|
||||
// Queue a playhead draw
|
||||
if (unit == time_ && playhead_pos == -1) {
|
||||
playhead_pos = i;
|
||||
}
|
||||
|
||||
// Check if enough space has passed since the last line drawn
|
||||
if (qFloor(double(unit)/real_divider) > qFloor(double(last_unit)/real_divider)) {
|
||||
|
||||
// Determine if this unit is a whole second or not
|
||||
int sec = qFloor(double(unit) * time_base_.toDouble());
|
||||
int sec = qFloor(double(unit) * timebase_dbl_);
|
||||
|
||||
if (sec > last_sec) {
|
||||
// This line marks a second so we make it long
|
||||
@@ -190,7 +185,7 @@ void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
|
||||
// Try to draw text here
|
||||
if (text_visible_ && sec%text_skip == 0) {
|
||||
QString timecode_string = olive::timestamp_to_timecode(sec, time_base_, kTimecodeDisplay);
|
||||
QString timecode_string = olive::timestamp_to_timecode(sec, timebase_, kTimecodeDisplay);
|
||||
|
||||
int text_x = i;
|
||||
|
||||
@@ -219,10 +214,11 @@ void TimeRuler::paintEvent(QPaintEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
// If we found the playhead along here, draw it last
|
||||
if (playhead_pos >= 0) {
|
||||
// Draw the playhead if it's on screen at the moment
|
||||
int playhead_pos = qFloor(static_cast<double>(time_) * timebase_dbl_);
|
||||
if (playhead_pos + playhead_width_ >= 0 && playhead_pos - playhead_width_ < width()) {
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(Qt::red); // FIXME: Make configurable in CSS
|
||||
p.setBrush(style_.PlayheadColor());
|
||||
DrawPlayhead(&p, playhead_pos, height());
|
||||
}
|
||||
}
|
||||
@@ -250,16 +246,17 @@ void TimeRuler::DrawPlayhead(QPainter *p, int x, int y)
|
||||
QPoint(x, y),
|
||||
QPoint(x - half_width, y - half_text_height),
|
||||
QPoint(x - half_width, y - text_height_),
|
||||
QPoint(x + half_width, y - text_height_),
|
||||
QPoint(x + half_width, y - half_text_height)
|
||||
QPoint(x + 1 + half_width, y - text_height_),
|
||||
QPoint(x + 1 + half_width, y - half_text_height),
|
||||
QPoint(x + 1, y),
|
||||
};
|
||||
|
||||
p->drawPolygon(points, 5);
|
||||
p->drawPolygon(points, 6);
|
||||
}
|
||||
|
||||
double TimeRuler::ScreenToUnitFloat(int screen)
|
||||
{
|
||||
return (screen + scroll_) / scale_;
|
||||
return (screen + scroll_) / scale_ / timebase_dbl_;
|
||||
}
|
||||
|
||||
int64_t TimeRuler::ScreenToUnit(int screen)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "widget/timelineview/timelineplayhead.h"
|
||||
|
||||
class TimeRuler : public QWidget
|
||||
{
|
||||
@@ -77,10 +78,16 @@ private:
|
||||
|
||||
double scale_;
|
||||
|
||||
rational time_base_;
|
||||
rational timebase_;
|
||||
|
||||
double timebase_dbl_;
|
||||
|
||||
double timebase_flipped_dbl_;
|
||||
|
||||
int64_t time_;
|
||||
|
||||
TimelinePlayhead style_;
|
||||
|
||||
};
|
||||
|
||||
#endif // TIMERULER_H
|
||||
|
||||
Reference in New Issue
Block a user