@ -175,11 +175,62 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
}
ExperimentalButton : : ExperimentalButton ( QWidget * parent ) : QPushButton ( parent ) {
setVisible ( false ) ;
setFixedSize ( btn_size , btn_size ) ;
setCheckable ( true ) ;
params = Params ( ) ;
engage_img = loadPixmap ( " ../assets/img_chffr_wheel.png " , { img_size , img_size } ) ;
experimental_img = loadPixmap ( " ../assets/img_experimental.svg " , { img_size , img_size } ) ;
QObject : : connect ( this , & QPushButton : : toggled , [ = ] ( bool checked ) {
params . putBool ( " ExperimentalMode " , checked ) ;
} ) ;
}
void ExperimentalButton : : updateState ( const UIState & s ) {
const SubMaster & sm = * ( s . sm ) ;
// button is "visible" if engageable or enabled
const auto cs = sm [ " controlsState " ] . getControlsState ( ) ;
setVisible ( cs . getEngageable ( ) | | cs . getEnabled ( ) ) ;
// button is "checked" if experimental mode is enabled
setChecked ( sm [ " controlsState " ] . getControlsState ( ) . getExperimentalMode ( ) ) ;
// disable button when experimental mode is not available, or has not been confirmed for the first time
const auto cp = sm [ " carParams " ] . getCarParams ( ) ;
const bool experimental_mode_available = cp . getExperimentalLongitudinalAvailable ( ) ? params . getBool ( " ExperimentalLongitudinalEnabled " ) : cp . getOpenpilotLongitudinalControl ( ) ;
setEnabled ( params . getBool ( " ExperimentalModeConfirmed " ) & & experimental_mode_available ) ;
}
void ExperimentalButton : : paintEvent ( QPaintEvent * event ) {
QPainter p ( this ) ;
p . setRenderHint ( QPainter : : Antialiasing ) ;
QPoint center ( btn_size / 2 , btn_size / 2 ) ;
QPixmap img = isChecked ( ) ? experimental_img : engage_img ;
p . setOpacity ( 1.0 ) ;
p . setPen ( Qt : : NoPen ) ;
p . setBrush ( QColor ( 0 , 0 , 0 , 166 ) ) ;
p . drawEllipse ( center , btn_size / 2 , btn_size / 2 ) ;
p . setOpacity ( isDown ( ) ? 0.8 : 1.0 ) ;
p . drawPixmap ( ( btn_size - img_size ) / 2 , ( btn_size - img_size ) / 2 , img ) ;
}
AnnotatedCameraWidget : : AnnotatedCameraWidget ( VisionStreamType type , QWidget * parent ) : fps_filter ( UI_FREQ , 3 , 1. / UI_FREQ ) , CameraWidget ( " camerad " , type , true , parent ) {
pm = std : : make_unique < PubMaster , const std : : initializer_list < const char * > > ( { " uiDebug " } ) ;
engage_img = loadPixmap ( " ../assets/img_chffr_wheel.png " , { img_size , img_size } ) ;
experimental_img = loadPixmap ( " ../assets/img_experimental.svg " , { img_size - 5 , img_size - 5 } ) ;
QVBoxLayout * main_layout = new QVBoxLayout ( this ) ;
main_layout - > setMargin ( bdr_s ) ;
main_layout - > setSpacing ( 0 ) ;
experimental_btn = new ExperimentalButton ( this ) ;
main_layout - > addWidget ( experimental_btn , 0 , Qt : : AlignTop | Qt : : AlignRight ) ;
dm_img = loadPixmap ( " ../assets/img_driver_face.png " , { img_size , img_size } ) ;
}
@ -227,9 +278,11 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
setProperty ( " hideDM " , cs . getAlertSize ( ) ! = cereal : : ControlsState : : AlertSize : : NONE ) ;
setProperty ( " status " , s . status ) ;
// update engageability and DM icons at 2Hz
// update engageability/experimental mode button
experimental_btn - > updateState ( s ) ;
// update DM icons at 2Hz
if ( sm . frame % ( UI_FREQ / 2 ) = = 0 ) {
setProperty ( " engageable " , cs . getEngageable ( ) | | cs . getEnabled ( ) ) ;
setProperty ( " dmActive " , sm [ " driverMonitoringState " ] . getDriverMonitoringState ( ) . getIsActiveMode ( ) ) ;
setProperty ( " rightHandDM " , sm [ " driverMonitoringState " ] . getDriverMonitoringState ( ) . getIsRHD ( ) ) ;
}
@ -382,16 +435,9 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
configFont ( p , " Inter " , 66 , " Regular " ) ;
drawText ( p , rect ( ) . center ( ) . x ( ) , 290 , speedUnit , 200 ) ;
// engage-ability icon
if ( engageable ) {
SubMaster & sm = * ( uiState ( ) - > sm ) ;
drawIcon ( p , rect ( ) . right ( ) - radius / 2 - bdr_s * 2 , radius / 2 + int ( bdr_s * 1.5 ) ,
sm [ " controlsState " ] . getControlsState ( ) . getExperimentalMode ( ) ? experimental_img : engage_img , blackColor ( 166 ) , 1.0 ) ;
}
// dm icon
if ( ! hideDM ) {
int dm_icon_x = rightHandDM ? rect ( ) . right ( ) - radius / 2 - ( bdr_s * 2 ) : radius / 2 + ( bdr_s * 2 ) ;
int dm_icon_x = rightHandDM ? rect ( ) . right ( ) - btn_size / 2 - ( bdr_s * 2 ) : btn_size / 2 + ( bdr_s * 2 ) ;
drawIcon ( p , dm_icon_x , rect ( ) . bottom ( ) - footer_h / 2 ,
dm_img , blackColor ( 70 ) , dmActive ? 1.0 : 0.2 ) ;
}
@ -414,7 +460,7 @@ void AnnotatedCameraWidget::drawIcon(QPainter &p, int x, int y, QPixmap &img, QB
p . setOpacity ( 1.0 ) ; // bg dictates opacity of ellipse
p . setPen ( Qt : : NoPen ) ;
p . setBrush ( bg ) ;
p . drawEllipse ( x - radius / 2 , y - radius / 2 , radius , radius ) ;
p . drawEllipse ( x - btn_size / 2 , y - btn_size / 2 , btn_size , btn_size ) ;
p . setOpacity ( opacity ) ;
p . drawPixmap ( x - img . size ( ) . width ( ) / 2 , y - img . size ( ) . height ( ) / 2 , img ) ;
}