@ -31,9 +31,12 @@ static Replay *getReplay() {
VideoWidget : : VideoWidget ( QWidget * parent ) : QFrame ( parent ) {
setFrameStyle ( QFrame : : StyledPanel | QFrame : : Plain ) ;
auto main_layout = new QVBoxLayout ( this ) ;
main_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
main_layout - > setSpacing ( 0 ) ;
if ( ! can - > liveStreaming ( ) )
main_layout - > addWidget ( createCameraWidget ( ) ) ;
main_layout - > addLayout ( createPlaybackController ( ) ) ;
createPlaybackController ( ) ;
setSizePolicy ( QSizePolicy : : Preferred , QSizePolicy : : Maximum ) ;
QObject : : connect ( can , & AbstractStream : : paused , this , & VideoWidget : : updatePlayBtnState ) ;
@ -65,15 +68,19 @@ VideoWidget::VideoWidget(QWidget *parent) : QFrame(parent) {
timeline_colors [ ( int ) TimelineType : : AlertCritical ] . name ( ) ) ) ;
}
QHBoxLayout * VideoWidget : : createPlaybackController ( ) {
QHBoxLayout * layout = new QHBoxLayout ( ) ;
layout - > addWidget ( seek_backward_btn = new ToolButton ( " rewind " , tr ( " Seek backward " ) ) ) ;
layout - > addWidget ( play_btn = new ToolButton ( " play " , tr ( " Play " ) ) ) ;
layout - > addWidget ( seek_forward_btn = new ToolButton ( " fast-forward " , tr ( " Seek forward " ) ) ) ;
void VideoWidget : : createPlaybackController ( ) {
QToolBar * toolbar = new QToolBar ( this ) ;
layout ( ) - > addWidget ( toolbar ) ;
int icon_size = style ( ) - > pixelMetric ( QStyle : : PM_SmallIconSize ) ;
toolbar - > setIconSize ( { icon_size , icon_size } ) ;
toolbar - > addAction ( utils : : icon ( " rewind " ) , tr ( " Seek backward " ) , [ ] ( ) { can - > seekTo ( can - > currentSec ( ) - 1 ) ; } ) ;
play_toggle_action = toolbar - > addAction ( utils : : icon ( " play " ) , tr ( " Play " ) , [ ] ( ) { can - > pause ( ! can - > isPaused ( ) ) ; } ) ;
toolbar - > addAction ( utils : : icon ( " fast-forward " ) , tr ( " Seek forward " ) , [ ] ( ) { can - > seekTo ( can - > currentSec ( ) + 1 ) ; } ) ;
if ( can - > liveStreaming ( ) ) {
layout - > addWidget ( skip_to_end_btn = new ToolButton ( " skip-end " , tr ( " Skip to the end " ) , this ) ) ;
QObject : : connect ( skip_to_end_btn , & QToolButton : : clicked , [ this ] ( ) {
skip_to_end_action = toolbar - > addAction ( utils : : icon ( " skip-end " ) , tr ( " Skip to the end " ) , this , [ this ] ( ) {
// set speed to 1.0
speed_btn - > menu ( ) - > actions ( ) [ 7 ] - > setChecked ( true ) ;
can - > pause ( false ) ;
@ -81,53 +88,48 @@ QHBoxLayout *VideoWidget::createPlaybackController() {
} ) ;
}
layout - > addWidget ( time_btn = new QToolButton ) ;
time_btn - > setToolTip ( settings . absolute_time ? tr ( " Elapsed time " ) : tr ( " Absolute time " ) ) ;
time_btn - > setAutoRaise ( true ) ;
layout - > addStretch ( 0 ) ;
time_display_action = toolbar - > addAction ( " " , this , [ this ] ( ) {
settings . absolute_time = ! settings . absolute_time ;
time_display_action - > setToolTip ( settings . absolute_time ? tr ( " Elapsed time " ) : tr ( " Absolute time " ) ) ;
updateState ( ) ;
} ) ;
QWidget * spacer = new QWidget ( ) ;
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
toolbar - > addWidget ( spacer ) ;
if ( ! can - > liveStreaming ( ) ) {
layout - > addWidget ( loop_btn = new ToolButton ( " repeat " , tr ( " Loop playback " ) ) ) ;
QObject : : connect ( loop_btn , & QToolButton : : clicked , this , & VideoWidget : : loopPlaybackClicked ) ;
toolbar - > addAction ( utils : : icon ( " repeat " ) , tr ( " Loop playback " ) , this , & VideoWidget : : loopPlaybackClicked ) ;
}
// speed selector
layout - > addWidget ( speed_btn = new QToolButton ( this ) ) ;
speed_btn - > setAutoRaise ( true ) ;
createSpeedDropdown ( toolbar ) ;
}
void VideoWidget : : createSpeedDropdown ( QToolBar * toolbar ) {
toolbar - > addWidget ( speed_btn = new QToolButton ( this ) ) ;
speed_btn - > setMenu ( new QMenu ( speed_btn ) ) ;
speed_btn - > setPopupMode ( QToolButton : : InstantPopup ) ;
QActionGroup * speed_group = new QActionGroup ( this ) ;
speed_group - > setExclusive ( true ) ;
int max_width = 0 ;
QFont font = speed_btn - > font ( ) ;
font . setBold ( true ) ;
speed_btn - > setFont ( font ) ;
QFontMetrics fm ( font ) ;
for ( float speed : { 0.01 , 0.02 , 0.05 , 0.1 , 0.2 , 0.5 , 0.8 , 1. , 2. , 3. , 5. } ) {
QString name = QString ( " %1x " ) . arg ( speed ) ;
max_width = std : : max ( max_width , fm . width ( name ) + fm . horizontalAdvance ( QLatin1Char ( ' ' ) ) * 2 ) ;
QAction * act = new QAction ( name , speed_group ) ;
act - > setCheckable ( true ) ;
QObject : : connect ( act , & QAction : : toggled , [ this , speed ] ( ) {
auto act = speed_btn - > menu ( ) - > addAction ( QString ( " %1x " ) . arg ( speed ) , this , [ this , speed ] ( ) {
can - > setSpeed ( speed ) ;
speed_btn - > setText ( QString ( " %1x " ) . arg ( speed ) ) ;
} ) ;
speed_btn - > menu ( ) - > addAction ( act ) ;
if ( speed = = 1.0 ) act - > setChecked ( true ) ;
speed_group - > addAction ( act ) ;
act - > setCheckable ( true ) ;
if ( speed = = 1.0 ) {
act - > setChecked ( true ) ;
act - > trigger ( ) ;
}
}
speed_btn - > setMinimumWidth ( max_width + style ( ) - > pixelMetric ( QStyle : : PM_MenuButtonIndicator ) ) ;
QObject : : connect ( play_btn , & QToolButton : : clicked , [ ] ( ) { can - > pause ( ! can - > isPaused ( ) ) ; } ) ;
QObject : : connect ( seek_backward_btn , & QToolButton : : clicked , [ ] ( ) { can - > seekTo ( can - > currentSec ( ) - 1 ) ; } ) ;
QObject : : connect ( seek_forward_btn , & QToolButton : : clicked , [ ] ( ) { can - > seekTo ( can - > currentSec ( ) + 1 ) ; } ) ;
QObject : : connect ( time_btn , & QToolButton : : clicked , [ this ] ( ) {
settings . absolute_time = ! settings . absolute_time ;
time_btn - > setToolTip ( settings . absolute_time ? tr ( " Elapsed time " ) : tr ( " Absolute time " ) ) ;
updateState ( ) ;
} ) ;
return layout ;
QFont font = speed_btn - > font ( ) ;
font . setBold ( true ) ;
speed_btn - > setFont ( font ) ;
speed_btn - > setMinimumWidth ( speed_btn - > fontMetrics ( ) . width ( " 0.05x " ) + style ( ) - > pixelMetric ( QStyle : : PM_MenuButtonIndicator ) ) ;
}
QWidget * VideoWidget : : createCameraWidget ( ) {
@ -180,13 +182,13 @@ void VideoWidget::vipcAvailableStreamsUpdated(std::set<VisionStreamType> streams
void VideoWidget : : loopPlaybackClicked ( ) {
bool is_looping = getReplay ( ) - > loop ( ) ;
getReplay ( ) - > setLoop ( ! is_looping ) ;
loop_btn - > setIcon ( ! is_looping ? " repeat " : " repeat-1 " ) ;
qobject_cast < QAction * > ( sender ( ) ) - > setIcon ( utils : : i con ( ! is_looping ? " repeat " : " repeat-1 " ) ) ;
}
void VideoWidget : : timeRangeChanged ( ) {
const auto time_range = can - > timeRange ( ) ;
if ( can - > liveStreaming ( ) ) {
skip_to_end_bt n - > setEnabled ( ! time_range . has_value ( ) ) ;
skip_to_end_actio n - > setEnabled ( ! time_range . has_value ( ) ) ;
return ;
}
time_range ? slider - > setTimeRange ( time_range - > first , time_range - > second )
@ -208,16 +210,16 @@ void VideoWidget::updateState() {
if ( camera_tab - > count ( ) = = 0 ) { // No streams available
cam_widget - > update ( ) ; // Manually refresh to show alert events
}
time_bt n - > setText ( QString ( " %1 / %2 " ) . arg ( formatTime ( can - > currentSec ( ) , true ) ,
time_display_actio n - > setText ( QString ( " %1 / %2 " ) . arg ( formatTime ( can - > currentSec ( ) , true ) ,
formatTime ( slider - > maximum ( ) / slider - > factor ) ) ) ;
} else {
time_bt n - > setText ( formatTime ( can - > currentSec ( ) , true ) ) ;
time_display_actio n - > setText ( formatTime ( can - > currentSec ( ) , true ) ) ;
}
}
void VideoWidget : : updatePlayBtnState ( ) {
play_b tn - > setIcon ( can - > isPaused ( ) ? " play " : " pause " ) ;
play_b tn - > setToolTip ( can - > isPaused ( ) ? tr ( " Play " ) : tr ( " Pause " ) ) ;
play_toggle_actio n - > setIcon ( utils : : i con ( can - > isPaused ( ) ? " play " : " pause " ) ) ;
play_toggle_actio n - > setToolTip ( can - > isPaused ( ) ? tr ( " Play " ) : tr ( " Pause " ) ) ;
}
// Slider
@ -228,8 +230,12 @@ Slider::Slider(QWidget *parent) : QSlider(Qt::Horizontal, parent) {
void Slider : : paintEvent ( QPaintEvent * ev ) {
QPainter p ( this ) ;
QRect r = rect ( ) . adjusted ( 0 , 4 , 0 , - 4 ) ;
QStyleOptionSlider opt ;
initStyleOption ( & opt ) ;
QRect r = style ( ) - > subControlRect ( QStyle : : CC_Slider , & opt , QStyle : : SC_SliderGroove , this ) ;
p . fillRect ( r , timeline_colors [ ( int ) TimelineType : : None ] ) ;
double min = minimum ( ) / factor ;
double max = maximum ( ) / factor ;
@ -254,8 +260,6 @@ void Slider::paintEvent(QPaintEvent *ev) {
}
}
QStyleOptionSlider opt ;
opt . initFrom ( this ) ;
opt . minimum = minimum ( ) ;
opt . maximum = maximum ( ) ;
opt . subControls = QStyle : : SC_SliderHandle ;