waveformview: show in/out points in waveformview

Moved drawing routines to the base class that is used by both TimeRuler
and WaveformView
This commit is contained in:
itsmattkc
2020-03-15 18:21:14 +11:00
parent a6fb0c7e2b
commit 50061e4e55
10 changed files with 146 additions and 97 deletions
+91
View File
@@ -1,15 +1,23 @@
#include "seekablewidget.h"
#include <QMouseEvent>
#include <QPainter>
#include <QtMath>
#include "common/qtutils.h"
SeekableWidget::SeekableWidget(QWidget* parent) :
TimelineScaledWidget(parent),
time_(0),
timeline_points_(nullptr),
scroll_(0)
{
QFontMetrics fm = fontMetrics();
text_height_ = fm.height();
// Set width of playhead marker
playhead_width_ = QFontMetricsWidth(fm, "H");
}
void SeekableWidget::ConnectTimelinePoints(TimelinePoints *points)
@@ -108,3 +116,86 @@ void SeekableWidget::SeekToScreenPoint(int screen)
emit TimeChanged(timestamp);
}
void SeekableWidget::DrawTimelinePoints(QPainter* p, int marker_bottom)
{
if (!timeline_points()) {
return;
}
// Draw in/out workarea
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());
}
// Draw markers
if (marker_bottom > 0 && !timeline_points()->markers()->list().isEmpty()) {
int marker_top = marker_bottom - text_height_;
// FIXME: Hardcoded marker colors
p->setPen(Qt::black);
p->setBrush(Qt::green);
foreach (TimelineMarker* marker, timeline_points()->markers()->list()) {
int marker_left = TimeToScreen(marker->time().in());
int marker_right = TimeToScreen(marker->time().out());
if (marker_left >= width() || marker_right < 0) {
continue;
}
if (marker->time().length() == 0) {
// Single point in time marker
DrawPlayhead(p, marker_left, marker_bottom);
} else {
// Marker range
int rect_left = qMax(0, marker_left);
int rect_right = qMin(width(), marker_right);
QRect marker_rect(rect_left, marker_top, rect_right - rect_left, marker_bottom - marker_top);
p->drawRect(marker_rect);
if (!marker->name().isEmpty()) {
p->drawText(marker_rect, marker->name());
}
}
}
}
}
void SeekableWidget::DrawPlayhead(QPainter *p, int x, int y)
{
int half_width = playhead_width_ / 2;
if (x + half_width < 0 || x - half_width > width()) {
return;
}
p->setRenderHint(QPainter::Antialiasing);
int half_text_height = text_height() / 3;
QPoint points[] = {
QPoint(x, y),
QPoint(x - half_width, y - half_text_height),
QPoint(x - half_width, y - 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, 6);
p->setRenderHint(QPainter::Antialiasing, false);
}
+16
View File
@@ -31,6 +31,8 @@ protected:
virtual void ScaleChangedEvent(const double&) override;
void DrawTimelinePoints(QPainter *p, int marker_bottom = 0);
TimelinePoints* timeline_points() const;
double ScreenToUnitFloat(int screen);
@@ -42,6 +44,16 @@ protected:
int TimeToScreen(const rational& time);
void DrawPlayhead(QPainter* p, int x, int y);
inline const int& text_height() const {
return text_height_;
}
inline const int& playhead_width() const {
return playhead_width_;
}
inline const QColor& GetPlayheadColor() const
{
return style_.GetPlayheadColor();
@@ -67,6 +79,10 @@ private:
int scroll_;
int text_height_;
int playhead_width_;
};
#endif // SEEKABLEWIDGET_H
+14 -87
View File
@@ -39,16 +39,12 @@ TimeRuler::TimeRuler(bool text_visible, bool cache_status_visible, QWidget* pare
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
// Text height is used to calculate widget height
text_height_ = fm.height();
cache_status_height_ = text_height_ / 4;
cache_status_height_ = text_height() / 4;
// Get the "minimum" space allowed between two line markers on the ruler (in screen pixels)
// Mediocre but reliable way of scaling UI objects by font/DPI size
minimum_gap_between_lines_ = QFontMetricsWidth(fm, "H");
// Set width of playhead marker
playhead_width_ = minimum_gap_between_lines_;
// Text visibility affects height, so we set that here
UpdateHeight();
}
@@ -93,65 +89,17 @@ void TimeRuler::paintEvent(QPaintEvent *)
// Draw timeline points if connected
if (timeline_points()) {
int marker_bottom = height() - text_height();
// Draw in/out workarea
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());
if (show_cache_status_) {
marker_bottom -= cache_status_height_;
}
// Draw markers
if (!timeline_points()->markers()->list().isEmpty()) {
int marker_bottom = height() - text_height_;
if (show_cache_status_) {
marker_bottom -= cache_status_height_;
}
if (text_visible_) {
marker_bottom -= cache_status_height_;
}
int marker_top = marker_bottom - text_height_;
// FIXME: Hardcoded marker colors
p.setPen(Qt::black);
p.setBrush(Qt::green);
foreach (TimelineMarker* marker, timeline_points()->markers()->list()) {
int marker_left = TimeToScreen(marker->time().in());
int marker_right = TimeToScreen(marker->time().out());
if (marker_left >= width() || marker_right < 0) {
continue;
}
if (marker->time().length() == 0) {
// Single point in time marker
DrawPlayhead(&p, marker_left, marker_bottom);
} else {
// Marker range
int rect_left = qMax(0, marker_left);
int rect_right = qMin(width(), marker_right);
QRect marker_rect(rect_left, marker_top, rect_right - rect_left, marker_bottom - marker_top);
p.drawRect(marker_rect);
if (!marker->name().isEmpty()) {
p.drawText(marker_rect, marker->name());
}
}
}
if (text_visible_) {
marker_bottom -= cache_status_height_;
}
DrawTimelinePoints(&p, marker_bottom);
}
double width_of_frame = timebase_dbl() * GetScale();
@@ -325,11 +273,9 @@ void TimeRuler::paintEvent(QPaintEvent *)
// Draw the playhead if it's on screen at the moment
int playhead_pos = UnitToScreen(GetTime());
if (playhead_pos + playhead_width_ >= 0 && playhead_pos - playhead_width_ < width()) {
p.setPen(Qt::NoPen);
p.setBrush(GetPlayheadColor());
DrawPlayhead(&p, playhead_pos, line_bottom);
}
p.setPen(Qt::NoPen);
p.setBrush(GetPlayheadColor());
DrawPlayhead(&p, playhead_pos, line_bottom);
}
void TimeRuler::TimebaseChangedEvent(const rational &tb)
@@ -339,25 +285,6 @@ void TimeRuler::TimebaseChangedEvent(const rational &tb)
update();
}
void TimeRuler::DrawPlayhead(QPainter *p, int x, int y)
{
p->setRenderHint(QPainter::Antialiasing);
int half_text_height = text_height_ / 3;
int half_width = playhead_width_ / 2;
QPoint points[] = {
QPoint(x, y),
QPoint(x - half_width, y - half_text_height),
QPoint(x - half_width, y - 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, 6);
}
int TimeRuler::CacheStatusHeight() const
{
return fontMetrics().height() / 4;
@@ -365,11 +292,11 @@ int TimeRuler::CacheStatusHeight() const
void TimeRuler::UpdateHeight()
{
int height = text_height_;
int height = text_height();
// Add text height
if (text_visible_) {
height += text_height_;
height += text_height();
}
// Add cache status height
@@ -378,7 +305,7 @@ void TimeRuler::UpdateHeight()
}
// Add marker height
height += text_height_;
height += text_height();
setFixedHeight(height);
}
-6
View File
@@ -50,18 +50,12 @@ protected:
private:
void UpdateHeight();
void DrawPlayhead(QPainter* p, int x, int y);
int CacheStatusHeight() const;
int text_height_;
int cache_status_height_;
int minimum_gap_between_lines_;
int playhead_width_;
bool text_visible_;
bool centered_text_;