|
|
|
@ -33,11 +33,9 @@ VideoWidget::VideoWidget(QWidget *parent) : QFrame(parent) { |
|
|
|
|
main_layout->addLayout(createPlaybackController()); |
|
|
|
|
|
|
|
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); |
|
|
|
|
|
|
|
|
|
QObject::connect(can, &AbstractStream::paused, this, &VideoWidget::updatePlayBtnState); |
|
|
|
|
QObject::connect(can, &AbstractStream::resume, this, &VideoWidget::updatePlayBtnState); |
|
|
|
|
QObject::connect(can, &AbstractStream::updated, this, &VideoWidget::updateState); |
|
|
|
|
QObject::connect(&settings, &Settings::changed, this, &VideoWidget::updatePlayBtnState); |
|
|
|
|
|
|
|
|
|
updatePlayBtnState(); |
|
|
|
|
setWhatsThis(tr(R"( |
|
|
|
@ -131,10 +129,15 @@ QWidget *VideoWidget::createCameraWidget() { |
|
|
|
|
QWidget *w = new QWidget(this); |
|
|
|
|
QVBoxLayout *l = new QVBoxLayout(w); |
|
|
|
|
l->setContentsMargins(0, 0, 0, 0); |
|
|
|
|
l->setSpacing(0); |
|
|
|
|
|
|
|
|
|
l->addWidget(camera_tab = new TabBar(w)); |
|
|
|
|
camera_tab->setAutoHide(true); |
|
|
|
|
camera_tab->setExpanding(false); |
|
|
|
|
|
|
|
|
|
QStackedLayout *stacked = new QStackedLayout(); |
|
|
|
|
stacked->setStackingMode(QStackedLayout::StackAll); |
|
|
|
|
stacked->addWidget(cam_widget = new CameraWidget("camerad", can->visionStreamType(), false)); |
|
|
|
|
stacked->addWidget(cam_widget = new CameraWidget("camerad", VISION_STREAM_ROAD, false)); |
|
|
|
|
cam_widget->setMinimumHeight(MIN_VIDEO_HEIGHT); |
|
|
|
|
cam_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); |
|
|
|
|
stacked->addWidget(alert_label = new InfoLabel(this)); |
|
|
|
@ -146,11 +149,34 @@ QWidget *VideoWidget::createCameraWidget() { |
|
|
|
|
setMaximumTime(can->totalSeconds()); |
|
|
|
|
QObject::connect(slider, &QSlider::sliderReleased, [this]() { can->seekTo(slider->currentSecond()); }); |
|
|
|
|
QObject::connect(slider, &Slider::updateMaximumTime, this, &VideoWidget::setMaximumTime, Qt::QueuedConnection); |
|
|
|
|
QObject::connect(cam_widget, &CameraWidget::clicked, []() { can->pause(!can->isPaused()); }); |
|
|
|
|
QObject::connect(static_cast<ReplayStream*>(can), &ReplayStream::qLogLoaded, slider, &Slider::parseQLog); |
|
|
|
|
QObject::connect(cam_widget, &CameraWidget::clicked, []() { can->pause(!can->isPaused()); }); |
|
|
|
|
QObject::connect(cam_widget, &CameraWidget::vipcAvailableStreamsUpdated, this, &VideoWidget::vipcAvailableStreamsUpdated); |
|
|
|
|
QObject::connect(camera_tab, &QTabBar::currentChanged, [this](int index) { |
|
|
|
|
if (index != -1) cam_widget->setStreamType((VisionStreamType)camera_tab->tabData(index).toInt()); |
|
|
|
|
}); |
|
|
|
|
return w; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VideoWidget::vipcAvailableStreamsUpdated(std::set<VisionStreamType> streams) { |
|
|
|
|
static const QString stream_names[] = { |
|
|
|
|
[VISION_STREAM_ROAD] = "Road camera", |
|
|
|
|
[VISION_STREAM_WIDE_ROAD] = "Wide road camera", |
|
|
|
|
[VISION_STREAM_DRIVER] = "Driver camera"}; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < streams.size(); ++i) { |
|
|
|
|
if (camera_tab->count() <= i) { |
|
|
|
|
camera_tab->addTab(QString()); |
|
|
|
|
} |
|
|
|
|
int type = *std::next(streams.begin(), i); |
|
|
|
|
camera_tab->setTabText(i, stream_names[type]); |
|
|
|
|
camera_tab->setTabData(i, type); |
|
|
|
|
} |
|
|
|
|
while (camera_tab->count() > streams.size()) { |
|
|
|
|
camera_tab->removeTab(camera_tab->count() - 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void VideoWidget::loopPlaybackClicked() { |
|
|
|
|
auto replay = qobject_cast<ReplayStream *>(can)->getReplay(); |
|
|
|
|
if (replay->hasFlag(REPLAY_FLAG_NO_LOOP)) { |
|
|
|
@ -172,12 +198,8 @@ void VideoWidget::updateTimeRange(double min, double max, bool is_zoomed) { |
|
|
|
|
skip_to_end_btn->setEnabled(!is_zoomed); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!is_zoomed) { |
|
|
|
|
min = 0; |
|
|
|
|
max = maximum_time; |
|
|
|
|
} |
|
|
|
|
slider->setTimeRange(min, max); |
|
|
|
|
is_zoomed ? slider->setTimeRange(min, max) |
|
|
|
|
: slider->setTimeRange(0, maximum_time); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString VideoWidget::formatTime(double sec, bool include_milliseconds) { |
|
|
|
@ -262,7 +284,7 @@ void Slider::paintEvent(QPaintEvent *ev) { |
|
|
|
|
double min = minimum() / factor; |
|
|
|
|
double max = maximum() / factor; |
|
|
|
|
|
|
|
|
|
for (auto [begin, end, type] : qobject_cast<ReplayStream *>(can)->getTimeline()) { |
|
|
|
|
for (auto [begin, end, type] : qobject_cast<ReplayStream *>(can)->getReplay()->getTimeline()) { |
|
|
|
|
if (begin > max || end < min) |
|
|
|
|
continue; |
|
|
|
|
r.setLeft(((std::max(min, begin) - min) / (max - min)) * width()); |
|
|
|
@ -282,8 +304,7 @@ void Slider::paintEvent(QPaintEvent *ev) { |
|
|
|
|
void Slider::mousePressEvent(QMouseEvent *e) { |
|
|
|
|
QSlider::mousePressEvent(e); |
|
|
|
|
if (e->button() == Qt::LeftButton && !isSliderDown()) { |
|
|
|
|
int value = minimum() + ((maximum() - minimum()) * e->x()) / width(); |
|
|
|
|
setValue(value); |
|
|
|
|
setValue(minimum() + ((maximum() - minimum()) * e->x()) / width()); |
|
|
|
|
emit sliderReleased(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -294,7 +315,7 @@ void Slider::mouseMoveEvent(QMouseEvent *e) { |
|
|
|
|
QPixmap thumb = thumbnail(seconds); |
|
|
|
|
if (!thumb.isNull()) { |
|
|
|
|
int x = std::clamp(pos - thumb.width() / 2, THUMBNAIL_MARGIN, width() - thumb.width() - THUMBNAIL_MARGIN + 1); |
|
|
|
|
int y = -thumb.height() - THUMBNAIL_MARGIN - 6; |
|
|
|
|
int y = -thumb.height() - THUMBNAIL_MARGIN; |
|
|
|
|
thumbnail_label.showPixmap(mapToParent(QPoint(x, y)), utils::formatSeconds(seconds), thumb, alertInfo(seconds)); |
|
|
|
|
} else { |
|
|
|
|
thumbnail_label.hide(); |
|
|
|
|