diff --git a/autoapp/UI/MainWindow.cpp b/autoapp/UI/MainWindow.cpp index 44bd961..2936a26 100644 --- a/autoapp/UI/MainWindow.cpp +++ b/autoapp/UI/MainWindow.cpp @@ -17,29 +17,157 @@ */ #include +#include +#include +#include +#include +#include +#include + #include "autoapp/UI/MainWindow.hpp" #include "ui_mainwindow.h" namespace autoapp { -namespace ui -{ + namespace ui + { -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui_(new Ui::MainWindow) -{ - ui_->setupUi(this); - connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); - connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); - connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor); - connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog); + MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui_(new Ui::MainWindow), webSocket(new QWebSocket), + reconnectTimer(new QTimer(this)), + metadataTimer(new QTimer(this)), + shuttingDown(false) + { + ui_->setupUi(this); + connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); + connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); + connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor); + connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog); + + // BT NOW PLAYING UPDATE + connect(metadataTimer, &QTimer::timeout, this, &MainWindow::updateNowPlaying); + metadataTimer->start(1000); // refresh every 5 seconds + + // RADIO WEBSOCKET STUFF + reconnectTimer->setSingleShot(true); + reconnectTimer->setInterval(3000); + + connect(reconnectTimer, &QTimer::timeout, this, &MainWindow::connectWebSocket); + + connect(webSocket, &QWebSocket::connected, this, [this]() + { + qDebug() << "WebSocket connected"; + webSocket->sendTextMessage(QStringLiteral("Hello from MainWindow WebSocket!")); }); + + connect(webSocket, &QWebSocket::textMessageReceived, this, [this](const QString &message) + { + qDebug() << "Message received:" << message; + handleIncomingMessage(message); }); + + connect(webSocket, &QWebSocket::disconnected, this, [this]() + { + qDebug() << "WebSocket disconnected"; + if (!shuttingDown) { + qDebug() << "Attempting to reconnect in 3 seconds..."; + reconnectTimer->start(); + } }); + + connect(webSocket, QOverload::of(&QWebSocket::error), + this, [this](QAbstractSocket::SocketError) + { qDebug() << "WebSocket error:" << webSocket->errorString(); }); + + connectWebSocket(); + } + + MainWindow::~MainWindow() + { + shuttingDown = true; + webSocket->abort(); + webSocket->deleteLater(); + delete ui_; + } + + } } -MainWindow::~MainWindow() +void f1x::openauto::autoapp::ui::MainWindow::updateBtNowPlaying() { - delete ui_; + QDBusInterface manager( + "org.bluez", + "/", + "org.freedesktop.DBus.ObjectManager", + QDBusConnection::systemBus()); + + if (!manager.isValid()) + { + qDebug() << "Failed to connect to BlueZ D-Bus"; + return; + } + + QDBusReply reply = manager.call("GetManagedObjects"); + + if (!reply.isValid()) + { + qDebug() << "D-Bus call failed:" << reply.error().message(); + return; + } + + QVariantMap allObjects = reply.value(); + + for (auto it = allObjects.begin(); it != allObjects.end(); ++it) + { + QString path = it.key(); + QVariantMap interfaces = it.value().toMap(); + + if (interfaces.contains("org.bluez.MediaPlayer1")) + { + qDebug() << "Found MediaPlayer at:" << path; + + QDBusInterface mediaPlayer( + "org.bluez", + path, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + + QDBusReply trackReply = mediaPlayer.call("Get", "org.bluez.MediaPlayer1", "Track"); + if (trackReply.isValid()) + { + QVariantMap track = trackReply.value().toMap(); + QString artist = track["Artist"].toString(); + QString title = track["Title"].toString(); + QString album = track["Album"].toString(); + + QString status = statusReply.value().toString(); + + qDebug() << "Now playing:" << artist << "-" << title << "from" << album; + qDebug() << "Status:" << status; + + if (status == "Playing") + { + ui_->stackedWidget->setCurrentIndex(0); + ui_->btSongName->setText(title); + ui_->btArtistName->setText(artist); + ui_->btAlbumName->setText(album); + } + else + { + ui_->stackedWidget->setCurrentIndex(1); + } + } + break; + } + } } +void f1x::openauto::autoapp::ui::MainWindow::connectWebSocket() +{ + QUrl url(QStringLiteral("ws://127.0.0.1:5000")); // Change to your real server + qDebug() << "Connecting to WebSocket:" << url; + webSocket->open(url); } + +void f1x::openauto::autoapp::ui::MainWindow::handleIncomingMessage(const QString &message) +{ + // Your custom message processing logic here + qDebug() << "[Handler] Processing message:" << message; } diff --git a/autoapp/UI/mainwindow.ui b/autoapp/UI/mainwindow.ui index 2ef2c5b..a89e95e 100644 --- a/autoapp/UI/mainwindow.ui +++ b/autoapp/UI/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 800 - 480 + 1046 + 571 @@ -18,231 +18,477 @@ color: rgb(238, 238, 236); - - - - 290 - 30 - 281 - 41 - - - - <html><head/><body><p><span style=" font-size:22pt; font-weight:600; font-style:italic; color:#3465a4;">Waiting for device...</span></p></body></html> - - - - - - 180 - 20 - 101 - 101 - - - - <html><head/><body><p><img src=":/ico_androidauto.png"/></p></body></html> - - - - - - 630 - 330 - 161 - 41 - - - - Settings - - - false - - - false - - - - - - 630 - 380 - 161 - 41 - - - - Exit - - - false - - - - - - 340 - 70 - 301 - 31 - - - - <html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html> - - - - - - 10 - 440 - 271 - 31 - - - - <html><head/><body><p><a href="https://github.com/f1xpl/openauto"><span style=" text-decoration: underline; color:#007af4;">https://github.com/f1xpl/openauto</span></a></p></body></html> - - - - - - 30 - 170 - 31 - 41 - - - - <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> - - - - - - 80 - 130 - 531 - 101 - - - - <html><head/><body><p align="center"><span style=" color:#ef2929;">WARNING!</span></p><p><span style=" color:#ef2929;">Distraction may cause accidents. Do not attempt to operate while driving. Always concentrate on driving and obey Traffic Regulations. You assume total responsibility and risk for using this software.</span></p></body></html> - - - true - - - - - - 80 - 240 - 531 - 121 - - - - <html><head/><body><p><span style=" color:#ef2929;">This software is not certified by Google Inc. It is created for R&amp;D purposes and may not work as expected by the original authors. Do not use while driving.</span></p><p><span style=" color:#ef2929;">You use this software at your own risk.</span></p></body></html> - - - true - - - - - - 30 - 270 - 31 - 41 - - - - <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> - - - - - - 410 - 440 - 21 - 31 - - - - <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> - - - - - - 440 - 440 - 351 - 31 - - - - <html><head/><body><p><span style=" font-style:italic;">AndroidAuto is registered trademark of Google Inc.</span></p></body></html> - - - - - - 630 - 230 - 161 - 41 - - - - Toggle cursor - - - false - - - false - - - - - - 630 - 280 - 161 - 41 - - - - Wireless connection - - - false - - - false - - - - - - 50 - 370 - 551 - 61 - - - - <html><head/><body><p align="center"><span style=" font-weight:600;">If you are looking for a Raspberry PI compatible 12V power supply equipped with an ignition switch, visit </span><a href="https://bluewavestudio.io/"><span style=" text-decoration: underline; color:#007af4;">https://bluewavestudio.io</span></a></p></body></html> - - - true - - + + + + + + 1024 + 500 + + + + + 1024 + 500 + + + + 1 + + + + + + 0 + 0 + 1021 + 500 + + + + + 0 + 500 + + + + + 1024 + 500 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 16777215 + 300 + + + + + + + + 200 + 200 + + + + + 200 + 200 + + + + + + + :/bluetooth.png + + + true + + + + + + + + 16777215 + 300 + + + + + 10 + + + + + + + + 60 + 60 + + + + + + + :/song.png + + + true + + + + + + + + 24 + + + + Lorem Ipsum Dorem + + + + + + + + + + + + 60 + 60 + + + + + 60 + 60 + + + + + + + :/artist.png + + + true + + + + + + + + 16 + + + + Example Artist + + + + + + + + + + + + 60 + 60 + + + + + + + :/album.png + + + true + + + + + + + + 16 + + + + Example Album + + + + + + + + + + + + + + + + 16777215 + 50 + + + + + 24 + + + + ABCD,EFGH + + + + + + + + + + + + + + 0 + 0 + 1024 + 550 + + + + + 0 + 550 + + + + + 1024 + 550 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 200 + 200 + + + + + 200 + 200 + + + + + + + :/radio.png + + + true + + + + + + + + + + + + 40 + + + + ABCD,EFGH + + + + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + + 20 + + + + 0 + + + + + + + + + + 16777215 + 50 + + + + + 16 + + + + Tuner List + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 1024 + 30 + + + + + 1024 + 50 + + + + + 0 + 30 + + + + + 5 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Exit + + + false + + + + + + + Settings + + + false + + + false + + + + + + + Wireless connection + + + false + + + false + + + + + + + Toggle cursor + + + false + + + false + + + + + + + @@ -251,6 +497,8 @@ color: rgb(238, 238, 236); pushButtonSettings pushButtonExit - + + + diff --git a/autoapp/assets/album.png b/autoapp/assets/album.png new file mode 100644 index 0000000..e5f6937 Binary files /dev/null and b/autoapp/assets/album.png differ diff --git a/autoapp/assets/artist.png b/autoapp/assets/artist.png new file mode 100644 index 0000000..cb26ce9 Binary files /dev/null and b/autoapp/assets/artist.png differ diff --git a/autoapp/assets/bluetooth.png b/autoapp/assets/bluetooth.png new file mode 100644 index 0000000..1ed25ee Binary files /dev/null and b/autoapp/assets/bluetooth.png differ diff --git a/autoapp/assets/radio.png b/autoapp/assets/radio.png new file mode 100644 index 0000000..4940987 Binary files /dev/null and b/autoapp/assets/radio.png differ diff --git a/autoapp/assets/resources.qrc b/autoapp/assets/resources.qrc index c159d57..f004a66 100644 --- a/autoapp/assets/resources.qrc +++ b/autoapp/assets/resources.qrc @@ -1,9 +1,14 @@ - - ico_androidauto.png - ico_warning.png - ico_setting.png - ico_info.png - aa_video.qml - + + radio.png + album.png + artist.png + bluetooth.png + song.png + ico_androidauto.png + ico_warning.png + ico_setting.png + ico_info.png + aa_video.qml + diff --git a/autoapp/assets/song.png b/autoapp/assets/song.png new file mode 100644 index 0000000..38b3183 Binary files /dev/null and b/autoapp/assets/song.png differ diff --git a/include/autoapp/UI/MainWindow.hpp b/include/autoapp/UI/MainWindow.hpp index 52e3c62..7c16f60 100644 --- a/include/autoapp/UI/MainWindow.hpp +++ b/include/autoapp/UI/MainWindow.hpp @@ -20,33 +20,42 @@ #include #include +#include namespace Ui { -class MainWindow; + class MainWindow; } namespace autoapp { -namespace ui -{ + namespace ui + { -class MainWindow : public QMainWindow -{ - Q_OBJECT -public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow() override; + class MainWindow : public QMainWindow + { + Q_OBJECT + public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; -signals: - void exit(); - void openSettings(); - void toggleCursor(); - void openConnectDialog(); + signals: + void exit(); + void openSettings(); + void toggleCursor(); + void openConnectDialog(); -private: - Ui::MainWindow* ui_; -}; + private slots: + void connectWebSocket(); + void handleIncomingMessage(const QString &message); + void updateBtNowPlaying(); -} + private: + Ui::MainWindow *ui_; + QWebSocket *webSocket; + QTimer *reconnectTimer; + bool shuttingDown; + }; + + } }