LCOV - code coverage report
Current view: top level - display - DisplayManager.cpp (source / functions) Hit Total Coverage
Test: filtered.info Lines: 135 154 87.7 %
Date: 2025-07-25 11:48:17 Functions: 15 17 88.2 %

          Line data    Source code
       1             : /*!
       2             :  * @file DisplayManager.cpp
       3             :  * @brief Implementation of the DisplayManager class for handling the display of
       4             :  * the cluster.
       5             :  * @version 0.1
       6             :  * @date 2025-01-31
       7             :  * @author Félix LE BIHAN (@Fle-bihh)
       8             :  * @author Tiago Pereira (@t-pereira06)
       9             :  * @author Ricardo Melo (@reomelo)
      10             :  * @author Michel Batista (@MicchelFAB)
      11             :  * @details This file contains the implementation of the DisplayManager class,
      12             :  * which is responsible for handling the display of the cluster.
      13             :  * @note This class is used to manage the display of the cluster.
      14             :  * @warning Ensure that the display labels are properly initialized in the UI
      15             :  * form.
      16             :  * @see DisplayManager.hpp
      17             :  * @copyright Copyright (c) 2025
      18             :  */
      19             : 
      20             : #include "DisplayManager.hpp"
      21             : #include <QDebug>
      22             : #include <QPushButton>
      23             : 
      24             : /*!
      25             :  * @brief Construct a new DisplayManager object.
      26             :  * @param ui The UI form for the cluster.
      27             :  * @param parent The parent QObject.
      28             :  * @details This constructor initializes the DisplayManager object with the
      29             :  * specified UI form.
      30             :  */
      31          16 : DisplayManager::DisplayManager(Ui::CarManager *ui, QObject *parent)
      32          16 :                 : QObject(parent), m_ui(ui) {
      33             :         // Ensure the labels are initialized
      34          16 :     if (!m_ui->speedLabel || !m_ui->timeLabel ||
      35          16 :                         !m_ui->temperatureLabel || !m_ui->batteryLabel) {
      36           0 :                 qDebug() << "Error: Labels not initialized in the UI form!";
      37           0 :                 return;
      38             :         }
      39             : 
      40          16 :         m_ui->speedLimit50Label->hide();
      41          16 :         m_ui->speedLimit80Label->hide();
      42             : 
      43             :         // Set initial values for the labels
      44          16 :         m_ui->speedLabel->setText("0");
      45          16 :         m_ui->timeLabel->setText("--:--:--");
      46          16 :         m_ui->temperatureLabel->setText("N/A");
      47          16 :         m_ui->batteryLabel->setText("--%");
      48          16 :         m_ui->speedMetricsLabel->setText("KM/H");
      49             : 
      50          16 :         setupWifiDropdown();
      51             : 
      52             :         // Directly connect button clicks to signals
      53          16 :         connect(m_ui->toggleDrivingModeButton, &QPushButton::clicked, this,
      54             :                                         &DisplayManager::drivingModeToggled);
      55          16 :         connect(m_ui->toggleMetricsButton, &QPushButton::clicked, this,
      56             :                                         &DisplayManager::clusterMetricsToggled);
      57             : 
      58          16 :         m_speed50Timer = new QTimer(this);
      59          16 :         m_speed50Timer->setSingleShot(true);
      60          16 :         connect(m_speed50Timer, &QTimer::timeout, m_ui->speedLimit50Label, &QWidget::hide);
      61             : 
      62          16 :         m_speed80Timer = new QTimer(this);
      63          16 :         m_speed80Timer->setSingleShot(true);
      64          16 :         connect(m_speed80Timer, &QTimer::timeout, m_ui->speedLimit80Label, &QWidget::hide);
      65             : }
      66             : 
      67             : /*!
      68             :  * @brief Updates the CAN bus data on the display.
      69             :  * @details This function updates the speed and RPM labels based on the CAN bus
      70             :  * data.
      71             :  * @param speed The current speed of the car.
      72             :  * @param rpm The current RPM of the car.
      73             :  */
      74           1 : void DisplayManager::updateCanBusData(float speed, int rpm) {
      75           1 :         m_ui->speedLabel->setText(QString::number(static_cast<int>(speed)));
      76           1 : }
      77             : 
      78             : /*!
      79             :  * @brief Updates the engine data on the display.
      80             :  * @details This function updates the direction label and blinker visibility
      81             :  * based on the engine data.
      82             :  * @param direction The current direction of the car.
      83             :  * @param steeringAngle The current steering angle of the car.
      84             :  */
      85           2 : void DisplayManager::updateEngineData(CarDirection direction,
      86             :                                                                                                                                                         int steeringAngle) {
      87             :         //QString directionText;
      88           2 :         switch (direction) {
      89           1 :         case CarDirection::Drive:
      90             :                 //directionText = "D";
      91           1 :                 m_ui->directionParkLabel->setStyleSheet("color: white; background: transparent;");
      92           1 :                 m_ui->directionReverseLabel->setStyleSheet("color: white; background: transparent;");
      93           1 :                 m_ui->directionNeutralLabel->setStyleSheet("color: white; background: transparent;");
      94           1 :                 m_ui->directionDriveLabel->setStyleSheet("color: green; background: transparent;");
      95             : 
      96           1 :                 m_ui->directionParkLabel->update();
      97           1 :                 m_ui->directionReverseLabel->update();
      98           1 :                 m_ui->directionNeutralLabel->update();
      99           1 :                 m_ui->directionDriveLabel->update();
     100           1 :                 break;
     101           1 :         case CarDirection::Reverse:
     102             :                 //directionText = "R";
     103           1 :                 m_ui->directionParkLabel->setStyleSheet("color: white; background: transparent;");
     104           1 :                 m_ui->directionReverseLabel->setStyleSheet("color: lightgreen; background: transparent;");
     105           1 :                 m_ui->directionNeutralLabel->setStyleSheet("color: white; background: transparent;");
     106           1 :                 m_ui->directionDriveLabel->setStyleSheet("color: white; background: transparent;");
     107             : 
     108           1 :                 m_ui->directionParkLabel->update();
     109           1 :                 m_ui->directionReverseLabel->update();
     110           1 :                 m_ui->directionNeutralLabel->update();
     111           1 :                 m_ui->directionDriveLabel->update();
     112           1 :                 break;
     113             :         }
     114           2 : }
     115             : 
     116             : /*!
     117             :  * @brief Updates the system time on the display.
     118             :  * @details This function updates the date, time, and weekday labels based on
     119             :  * the current system time.
     120             :  * @param currentMonth The current month.
     121             :  * @param currentTime The current time.
     122             :  * @param currentDay The current day of the week.
     123             :  */
     124           1 : void DisplayManager::updateSystemTime(const QString &currentMonth,
     125             :                                                                                                                                                         const QString &currentTime,
     126             :                                                                             const QString &currentDay) {
     127           1 :         m_ui->dateLabel->setText(currentMonth + " " + currentDay);
     128           1 :         m_ui->timeLabel->setText(currentTime);
     129           1 : }
     130             : 
     131           1 : QString DisplayManager::getWifiSSID() {
     132             :     // Linux: read active SSID using shell command
     133           2 :     QProcess proc;
     134           1 :     proc.start("iwgetid -r");  // Gets current SSID
     135           1 :     proc.waitForFinished();
     136           3 :     QString output = proc.readAllStandardOutput().trimmed();
     137           2 :     return output.isEmpty() ? "Not connected" : output;
     138             : }
     139             : 
     140           1 : QString DisplayManager::getLocalIPAddress() {
     141           2 :     const QList<QHostAddress> &addresses = QNetworkInterface::allAddresses();
     142           3 :     for (const QHostAddress &address : addresses) {
     143           3 :         if (address.protocol() == QAbstractSocket::IPv4Protocol && !address.isLoopback())
     144           1 :             return address.toString();
     145             :     }
     146           0 :     return "No IP";
     147             : }
     148             : 
     149          16 : void DisplayManager::setupWifiDropdown() {
     150          16 :     connect(m_ui->wifiToggleButton, &QToolButton::clicked, this, [=]() {
     151           0 :         QMenu* wifiMenu = new QMenu(m_ui->wifiToggleButton);
     152             : 
     153             :         // Fetch current data
     154           0 :         QString ssidText = getWifiSSID();
     155           0 :         QString ipText = getLocalIPAddress();
     156             : 
     157           0 :         wifiMenu->addAction("Connected to: " + ssidText);
     158           0 :         wifiMenu->addAction("IP Address: " + ipText);
     159             : 
     160           0 :         wifiMenu->setStyleSheet(
     161             :             "QMenu {"
     162             :             " background-color: rgba(30, 30, 30, 0.9);"
     163             :             " color: white;"
     164             :             " border: 1px solid rgba(255, 255, 255, 0.2);"
     165             :             " border-radius: 6px;"
     166             :             " padding: 6px;"
     167             :             " }"
     168             :         );
     169             : 
     170           0 :         QPoint pos = m_ui->wifiToggleButton->mapToGlobal(QPoint(0, m_ui->wifiToggleButton->height()));
     171           0 :         wifiMenu->exec(pos);
     172           0 :     });
     173          16 : }
     174             : 
     175             : /*!
     176             :  * @brief Updates the temperature on the display.
     177             :  * @details This function updates the temperature label based on the current
     178             :  * temperature.
     179             :  * @param temperature The current temperature.
     180             :  */
     181           1 : void DisplayManager::updateTemperature(const QString &temperature) {
     182           1 :         m_ui->temperatureLabel->setText(temperature);
     183           1 : }
     184             : 
     185             : /*!
     186             :  * @brief Updates the battery percentage on the display.
     187             :  * @details This function updates the battery percentage label and low battery
     188             :  * warning based on the current battery percentage.
     189             :  * @param batteryPercentage The current battery percentage.
     190             :  */
     191           1 : void DisplayManager::updateBatteryPercentage(float batteryPercentage) {
     192           1 :         m_ui->batteryLabel->setText(QString::number(static_cast<int>(batteryPercentage)) + "%");
     193           1 : }
     194             : 
     195             : /*!
     196             :  * @brief Updates the mileage on the display.
     197             :  * @details This function updates the mileage label based on the current
     198             :  * mileage.
     199             :  * @param mileage The current mileage.
     200             :  */
     201           1 : void DisplayManager::updateMileage(double mileage) {
     202           1 :         m_ui->mileageLabel->setText(QString::number(static_cast<int>(mileage)) +
     203             :                                                                                                                         " m");
     204           1 : }
     205             : 
     206             : /*!
     207             :  * @brief Updates the driving mode on the display.
     208             :  * @details This function updates the driving mode label based on the current
     209             :  * driving mode.
     210             :  * @param newMode The new driving mode.
     211             :  */
     212           2 : void DisplayManager::updateDrivingMode(DrivingMode newMode) {
     213           4 :         QString modeText;
     214           2 :         switch (newMode) {
     215           1 :         case DrivingMode::Manual:
     216           1 :                 modeText = "Manual";
     217           1 :                 m_ui->laneKeepingAssistLabel->show();
     218           1 :                 m_ui->laneDepartureWarningLabel->show();
     219             :                 // Stop blinking if active
     220           1 :                 if (m_blinkTimer) {
     221           0 :                         m_blinkTimer->stop();
     222           0 :                         m_blinkTimer->deleteLater();
     223           0 :                         m_blinkTimer = nullptr;
     224             :                 }
     225           1 :                 break;
     226           1 :         case DrivingMode::Automatic:
     227           1 :                 modeText = "Automatic";
     228           1 :                 m_ui->laneKeepingAssistLabel->hide();
     229           1 :                 if (!m_blinkTimer) {
     230           1 :                         m_blinkTimer = new QTimer(this);
     231           1 :                         connect(m_blinkTimer, &QTimer::timeout, this, [=]() {
     232           0 :                                 bool currentlyVisible = m_ui->laneDepartureWarningLabel->isVisible();
     233           0 :                                 m_ui->laneDepartureWarningLabel->setVisible(!currentlyVisible);
     234           0 :                         });
     235           1 :                         m_blinkTimer->start(150);  // Blink every 150ms
     236             :                 }
     237           1 :                 break;
     238             :         }
     239           2 :         m_ui->drivingModeLabel->setText(modeText);
     240           2 : }
     241             : 
     242             : /*!
     243             :  * @brief Updates the cluster theme on the display.
     244             :  * @details This function updates the cluster theme label based on the current
     245             :  * cluster theme.
     246             :  * @param newTheme The new cluster theme.
     247             :  */
     248           2 : void DisplayManager::updateClusterTheme(ClusterTheme newTheme) {
     249           4 :         QString themeText;
     250           2 :         switch (newTheme) {
     251           1 :         case ClusterTheme::Dark:
     252           1 :                 themeText = "Dark";
     253           1 :                 break;
     254           1 :         case ClusterTheme::Light:
     255           1 :                 themeText = "Light";
     256           1 :                 break;
     257             :         }
     258           2 : }
     259             : 
     260             : /*!
     261             :  * @brief Updates the cluster metrics on the display.
     262             :  * @details This function updates the cluster metrics label and speed metrics
     263             :  * label based on the current cluster metrics.
     264             :  * @param newMetrics The new cluster metrics.
     265             :  */
     266           2 : void DisplayManager::updateClusterMetrics(ClusterMetrics newMetrics) {
     267           2 :         QString metricsText;
     268           2 :         switch (newMetrics) {
     269           1 :         case ClusterMetrics::Kilometers:
     270           1 :                 metricsText = "km/h";
     271           1 :                 break;
     272           1 :         case ClusterMetrics::Miles:
     273           1 :                 metricsText = "mph";
     274           1 :                 break;
     275             :         }
     276           2 :         m_ui->speedMetricsLabel->setText(metricsText.toUpper());
     277           2 : }
     278             : 
     279           2 : void DisplayManager::updateSpeedLimitLabels(int speed) {
     280           2 :         if (speed == 50) {
     281           1 :                 m_ui->speedLimit80Label->hide();
     282           1 :                 m_ui->speedLimit50Label->show();
     283           1 :                 m_speed50Timer->start(3000);
     284           1 :         } else if (speed == 80) {
     285           1 :                 m_ui->speedLimit50Label->hide();
     286           1 :                 m_ui->speedLimit80Label->show();
     287           1 :                 m_speed80Timer->start(3000);
     288             :         }
     289           2 : }
     290             : 
     291           1 : void DisplayManager::displayInferenceImage(const QImage &image) {
     292           1 :         if (!m_ui->inferenceLabel)
     293           0 :                 return;
     294             : 
     295           2 :         QPixmap original = QPixmap::fromImage(image);
     296           2 :         QPixmap rounded(original.size());
     297           1 :         rounded.fill(Qt::transparent);
     298             : 
     299           2 :         QPainter painter(&rounded);
     300           1 :         painter.setRenderHint(QPainter::Antialiasing, true);
     301             : 
     302           2 :         QPainterPath path;
     303           1 :         path.addRoundedRect(original.rect(), 34, 34);
     304           1 :         painter.setClipPath(path);
     305           1 :         painter.drawPixmap(0, 0, original);
     306             : 
     307           1 :         m_ui->inferenceLabel->setPixmap(rounded);
     308             : }

Generated by: LCOV version 1.14