@ -152,7 +152,6 @@ QWidget *VideoWidget::createCameraWidget() {
QObject : : connect ( slider , & QSlider : : sliderReleased , [ this ] ( ) { can - > seekTo ( slider - > currentSecond ( ) ) ; } ) ;
QObject : : connect ( slider , & QSlider : : sliderReleased , [ this ] ( ) { can - > seekTo ( slider - > currentSecond ( ) ) ; } ) ;
QObject : : connect ( can , & AbstractStream : : paused , cam_widget , [ c = cam_widget ] ( ) { c - > showPausedOverlay ( ) ; } ) ;
QObject : : connect ( can , & AbstractStream : : paused , cam_widget , [ c = cam_widget ] ( ) { c - > showPausedOverlay ( ) ; } ) ;
QObject : : connect ( can , & AbstractStream : : resume , cam_widget , [ c = cam_widget ] ( ) { c - > update ( ) ; } ) ;
QObject : : connect ( can , & AbstractStream : : eventsMerged , this , [ this ] ( ) { slider - > update ( ) ; } ) ;
QObject : : connect ( can , & AbstractStream : : eventsMerged , this , [ this ] ( ) { slider - > update ( ) ; } ) ;
QObject : : connect ( cam_widget , & CameraWidget : : clicked , [ ] ( ) { can - > pause ( ! can - > isPaused ( ) ) ; } ) ;
QObject : : connect ( cam_widget , & CameraWidget : : clicked , [ ] ( ) { can - > pause ( ! can - > isPaused ( ) ) ; } ) ;
QObject : : connect ( cam_widget , & CameraWidget : : vipcAvailableStreamsUpdated , this , & VideoWidget : : vipcAvailableStreamsUpdated ) ;
QObject : : connect ( cam_widget , & CameraWidget : : vipcAvailableStreamsUpdated , this , & VideoWidget : : vipcAvailableStreamsUpdated ) ;
@ -160,7 +159,7 @@ QWidget *VideoWidget::createCameraWidget() {
if ( index ! = - 1 ) cam_widget - > setStreamType ( ( VisionStreamType ) camera_tab - > tabData ( index ) . toInt ( ) ) ;
if ( index ! = - 1 ) cam_widget - > setStreamType ( ( VisionStreamType ) camera_tab - > tabData ( index ) . toInt ( ) ) ;
} ) ;
} ) ;
QObject : : connect ( static_cast < ReplayStream * > ( can ) , & ReplayStream : : qLogLoaded , cam_widget , & StreamCameraView : : parseQLog , Qt : : QueuedConnection ) ;
QObject : : connect ( static_cast < ReplayStream * > ( can ) , & ReplayStream : : qLogLoaded , cam_widget , & StreamCameraView : : parseQLog , Qt : : QueuedConnection ) ;
slider - > installEventFilter ( cam_widget ) ;
slider - > installEventFilter ( this ) ;
return w ;
return w ;
}
}
@ -222,8 +221,24 @@ void VideoWidget::updatePlayBtnState() {
play_toggle_action - > setToolTip ( can - > isPaused ( ) ? tr ( " Play " ) : tr ( " Pause " ) ) ;
play_toggle_action - > setToolTip ( can - > isPaused ( ) ? tr ( " Play " ) : tr ( " Pause " ) ) ;
}
}
// Slider
void VideoWidget : : showThumbnail ( double seconds ) {
cam_widget - > thumbnail_dispaly_time = seconds ;
slider - > thumbnail_dispaly_time = seconds ;
cam_widget - > update ( ) ;
slider - > update ( ) ;
}
bool VideoWidget : : eventFilter ( QObject * obj , QEvent * event ) {
if ( event - > type ( ) = = QEvent : : MouseMove ) {
auto [ min_sec , max_sec ] = can - > timeRange ( ) . value_or ( std : : make_pair ( can - > minSeconds ( ) , can - > maxSeconds ( ) ) ) ;
showThumbnail ( min_sec + static_cast < QMouseEvent * > ( event ) - > pos ( ) . x ( ) * ( max_sec - min_sec ) / slider - > width ( ) ) ;
} else if ( event - > type ( ) = = QEvent : : Leave ) {
showThumbnail ( - 1 ) ;
}
return false ;
}
// Slider
Slider : : Slider ( QWidget * parent ) : QSlider ( Qt : : Horizontal , parent ) {
Slider : : Slider ( QWidget * parent ) : QSlider ( Qt : : Horizontal , parent ) {
setMouseTracking ( true ) ;
setMouseTracking ( true ) ;
}
}
@ -265,6 +280,14 @@ void Slider::paintEvent(QPaintEvent *ev) {
opt . subControls = QStyle : : SC_SliderHandle ;
opt . subControls = QStyle : : SC_SliderHandle ;
opt . sliderPosition = value ( ) ;
opt . sliderPosition = value ( ) ;
style ( ) - > drawComplexControl ( QStyle : : CC_Slider , & opt , & p ) ;
style ( ) - > drawComplexControl ( QStyle : : CC_Slider , & opt , & p ) ;
if ( thumbnail_dispaly_time > = 0 ) {
int left = ( thumbnail_dispaly_time - min ) * width ( ) / ( max - min ) - 1 ;
QRect rc ( left , rect ( ) . top ( ) + 1 , 2 , rect ( ) . height ( ) - 2 ) ;
p . setBrush ( palette ( ) . highlight ( ) ) ;
p . setPen ( Qt : : NoPen ) ;
p . drawRoundedRect ( rc , 1.5 , 1.5 ) ;
}
}
}
void Slider : : mousePressEvent ( QMouseEvent * e ) {
void Slider : : mousePressEvent ( QMouseEvent * e ) {
@ -276,7 +299,6 @@ void Slider::mousePressEvent(QMouseEvent *e) {
}
}
// StreamCameraView
// StreamCameraView
StreamCameraView : : StreamCameraView ( std : : string stream_name , VisionStreamType stream_type , QWidget * parent )
StreamCameraView : : StreamCameraView ( std : : string stream_name , VisionStreamType stream_type , QWidget * parent )
: CameraWidget ( stream_name , stream_type , parent ) {
: CameraWidget ( stream_name , stream_type , parent ) {
fade_animation = new QPropertyAnimation ( this , " overlayOpacity " ) ;
fade_animation = new QPropertyAnimation ( this , " overlayOpacity " ) ;
@ -298,6 +320,7 @@ void StreamCameraView::parseQLog(std::shared_ptr<LogReader> qlog) {
QPixmap generated_thumb = generateThumbnail ( thumb , can - > toSeconds ( thumb_data . getTimestampEof ( ) ) ) ;
QPixmap generated_thumb = generateThumbnail ( thumb , can - > toSeconds ( thumb_data . getTimestampEof ( ) ) ) ;
std : : lock_guard lock ( mutex ) ;
std : : lock_guard lock ( mutex ) ;
thumbnails [ thumb_data . getTimestampEof ( ) ] = generated_thumb ;
thumbnails [ thumb_data . getTimestampEof ( ) ] = generated_thumb ;
big_thumbnails [ thumb_data . getTimestampEof ( ) ] = thumb ;
}
}
}
}
} ) ;
} ) ;
@ -308,12 +331,15 @@ void StreamCameraView::paintGL() {
CameraWidget : : paintGL ( ) ;
CameraWidget : : paintGL ( ) ;
QPainter p ( this ) ;
QPainter p ( this ) ;
if ( auto alert = getReplay ( ) - > findAlertAtTime ( can - > currentSec ( ) ) ) {
bool scrubbing = false ;
drawAlert ( p , rect ( ) , * alert ) ;
if ( thumbnail_dispaly_time > = 0 ) {
scrubbing = can - > isPaused ( ) ;
scrubbing ? drawScrubThumbnail ( p ) : drawThumbnail ( p ) ;
}
}
if ( thumbnail_pt_ ) {
if ( auto alert = getReplay ( ) - > findAlertAtTime ( scrubbing ? thumbnail_dispaly_time : can - > currentSec ( ) ) ) {
drawThumbnail ( p ) ;
drawAlert ( p , rect ( ) , * alert ) ;
}
}
if ( can - > isPaused ( ) ) {
if ( can - > isPaused ( ) ) {
p . setPen ( QColor ( 200 , 200 , 200 , static_cast < int > ( 255 * fade_animation - > currentValue ( ) . toFloat ( ) ) ) ) ;
p . setPen ( QColor ( 200 , 200 , 200 , static_cast < int > ( 255 * fade_animation - > currentValue ( ) . toFloat ( ) ) ) ) ;
p . setFont ( QFont ( font ( ) . family ( ) , 16 , QFont : : Bold ) ) ;
p . setFont ( QFont ( font ( ) . family ( ) , 16 , QFont : : Bold ) ) ;
@ -333,25 +359,37 @@ QPixmap StreamCameraView::generateThumbnail(QPixmap thumb, double seconds) {
return scaled ;
return scaled ;
}
}
void StreamCameraView : : drawThumbnail ( QPainter & p ) {
void StreamCameraView : : drawScrubThumbnail ( QPainter & p ) {
int pos = std : : clamp ( thumbnail_pt_ - > x ( ) , 0 , width ( ) ) ;
p . fillRect ( rect ( ) , Qt : : black ) ;
auto [ min_sec , max_sec ] = can - > timeRange ( ) . value_or ( std : : make_pair ( can - > minSeconds ( ) , can - > maxSeconds ( ) ) ) ;
auto it = big_thumbnails . lowerBound ( can - > toMonoTime ( thumbnail_dispaly_time ) ) ;
double seconds = min_sec + pos * ( max_sec - min_sec ) / width ( ) ;
if ( it ! = big_thumbnails . end ( ) ) {
QPixmap scaled_thumb = it . value ( ) . scaled ( rect ( ) . size ( ) , Qt : : KeepAspectRatio , Qt : : SmoothTransformation ) ;
QRect thumb_rect ( rect ( ) . center ( ) - scaled_thumb . rect ( ) . center ( ) , scaled_thumb . size ( ) ) ;
p . drawPixmap ( thumb_rect . topLeft ( ) , scaled_thumb ) ;
drawTime ( p , thumb_rect , thumbnail_dispaly_time ) ;
}
}
auto it = thumbnails . lowerBound ( can - > toMonoTime ( seconds ) ) ;
void StreamCameraView : : drawThumbnail ( QPainter & p ) {
auto it = thumbnails . lowerBound ( can - > toMonoTime ( thumbnail_dispaly_time ) ) ;
if ( it ! = thumbnails . end ( ) ) {
if ( it ! = thumbnails . end ( ) ) {
const QPixmap & thumb = it . value ( ) ;
const QPixmap & thumb = it . value ( ) ;
auto [ min_sec , max_sec ] = can - > timeRange ( ) . value_or ( std : : make_pair ( can - > minSeconds ( ) , can - > maxSeconds ( ) ) ) ;
int pos = ( thumbnail_dispaly_time - min_sec ) * width ( ) / ( max_sec - min_sec ) ;
int x = std : : clamp ( pos - thumb . width ( ) / 2 , THUMBNAIL_MARGIN , width ( ) - thumb . width ( ) - THUMBNAIL_MARGIN + 1 ) ;
int x = std : : clamp ( pos - thumb . width ( ) / 2 , THUMBNAIL_MARGIN , width ( ) - thumb . width ( ) - THUMBNAIL_MARGIN + 1 ) ;
int y = height ( ) - thumb . height ( ) - THUMBNAIL_MARGIN ;
int y = height ( ) - thumb . height ( ) - THUMBNAIL_MARGIN ;
p . drawPixmap ( x , y , thumb ) ;
p . drawPixmap ( x , y , thumb ) ;
p . setPen ( QPen ( palette ( ) . color ( QPalette : : BrightText ) , 2 ) ) ;
drawTime ( p , QRect { x , y , thumb . width ( ) , thumb . height ( ) } , thumbnail_dispaly_time ) ;
p . setFont ( QFont ( font ( ) . family ( ) , 10 ) ) ;
p . drawText ( x , y , thumb . width ( ) , thumb . height ( ) - THUMBNAIL_MARGIN ,
Qt : : AlignHCenter | Qt : : AlignBottom , QString : : number ( seconds , ' f ' , 3 ) ) ;
}
}
}
}
void StreamCameraView : : drawTime ( QPainter & p , const QRect & rect , double seconds ) {
p . setPen ( palette ( ) . color ( QPalette : : BrightText ) ) ;
p . setFont ( QFont ( font ( ) . family ( ) , 10 ) ) ;
p . drawText ( rect . adjusted ( 0 , 0 , 0 , - THUMBNAIL_MARGIN ) , Qt : : AlignHCenter | Qt : : AlignBottom , QString : : number ( seconds , ' f ' , 3 ) ) ;
}
void StreamCameraView : : drawAlert ( QPainter & p , const QRect & rect , const Timeline : : Entry & alert ) {
void StreamCameraView : : drawAlert ( QPainter & p , const QRect & rect , const Timeline : : Entry & alert ) {
p . setPen ( QPen ( palette ( ) . color ( QPalette : : BrightText ) , 2 ) ) ;
p . setPen ( QPen ( palette ( ) . color ( QPalette : : BrightText ) , 2 ) ) ;
QColor color = timeline_colors [ int ( alert . type ) ] ;
QColor color = timeline_colors [ int ( alert . type ) ] ;
@ -364,14 +402,3 @@ void StreamCameraView::drawAlert(QPainter &p, const QRect &rect, const Timeline:
p . fillRect ( text_rect . left ( ) , r . top ( ) , text_rect . width ( ) , r . height ( ) , color ) ;
p . fillRect ( text_rect . left ( ) , r . top ( ) , text_rect . width ( ) , r . height ( ) , color ) ;
p . drawText ( text_rect , Qt : : AlignTop | Qt : : AlignHCenter | Qt : : TextWordWrap , text ) ;
p . drawText ( text_rect , Qt : : AlignTop | Qt : : AlignHCenter | Qt : : TextWordWrap , text ) ;
}
}
bool StreamCameraView : : eventFilter ( QObject * , QEvent * event ) {
if ( event - > type ( ) = = QEvent : : MouseMove ) {
thumbnail_pt_ = static_cast < QMouseEvent * > ( event ) - > pos ( ) ;
update ( ) ;
} else if ( event - > type ( ) = = QEvent : : Leave ) {
thumbnail_pt_ = std : : nullopt ;
update ( ) ;
}
return false ;
}