From a9790cc158955cb6774e662432bddcbd66274130 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Fri, 3 Jan 2020 17:41:32 -0500 Subject: Rework to raise navigation app and improve behavior Add callback to raise navigation app via homescreen and hook it up to the "Go" button handling. Additionally, testing of this addition revealed that the result list and information panel state is fragile and easily gotten into a bad state with respect to repaints when raising the navigation app. To fix this, the code has been reworked to change InfoPanel into an actual widget and keep it and the result list widget around; manipulating their visibilty rather than recreating them and forcing whole-window repaints. As well, a slight delay is used before raising the navigation app to let all repaints finish. Ideally this would not be required, but the app likely needs a more significant rewrite to fix it. Bug-AGL: SPEC-3079 Signed-off-by: Scott Murray Change-Id: Id8dce33e2a2135179644305a88b340ecd1d7d3c5 --- InfoPanel.cpp | 35 +++++++++++-------- InfoPanel.h | 5 +-- InfoPanelLabel.cpp | 2 +- MainApp.cpp | 99 +++++++++++++++++++++++++----------------------------- MainApp.h | 12 +++++-- main.cpp | 27 ++++++++++----- 6 files changed, 99 insertions(+), 81 deletions(-) diff --git a/InfoPanel.cpp b/InfoPanel.cpp index bc57e34..81cf317 100644 --- a/InfoPanel.cpp +++ b/InfoPanel.cpp @@ -22,22 +22,30 @@ #define LABEL_IMG_HEIGHT 220 #define LABEL_REVIEWS_HEIGHT 24 -InfoPanel::InfoPanel(QWidget *parent, Business & business, QRect rect): - nameLabel(parent, rect), - imageLabel(parent, rect), - addressLabel(parent, rect), - phoneLabel(parent, rect), - imgRatingLabel(parent, rect), - nbReviewsLabel(parent, rect), - btnsBackground(parent, rect), - cancelButton("Cancel", parent), - goButton("Go !", parent), +InfoPanel::InfoPanel(QWidget *parent, QRect rect): + QWidget(parent), + nameLabel(this, rect), + imageLabel(this, rect), + addressLabel(this, rect), + phoneLabel(this, rect), + imgRatingLabel(this, rect), + nbReviewsLabel(this, rect), + btnsBackground(this, rect), + cancelButton("Cancel", this), + goButton("Go !", this), networkManager(parent) +{ + setGeometry(rect); + setVisible(false); +} + +void InfoPanel::populateInfo(Business & business) { int y = 0; QPixmap pixmap; bool isImageDownloaded = false; QFont font, fontBold; + QRect rect = this->geometry(); font = nameLabel.font(); font.setPointSize(FONT_SIZE); @@ -110,12 +118,11 @@ InfoPanel::InfoPanel(QWidget *parent, Business & business, QRect rect): cancelButton.setStyleSheet(BTN_STYLE); cancelButton.setFont(font); cancelButton.setMinimumSize(QSize(rect.width()/4, 50)); - cancelButton.setGeometry(QRect(rect.x()+rect.width()/8, rect.y()+y-60, rect.width()/4, 50)); - cancelButton.setVisible(true); + //cancelButton.setGeometry(QRect(rect.x()+rect.width()/8, rect.y()+y-60, rect.width()/4, 50)); + cancelButton.setGeometry(QRect(rect.width()/8, y-60, rect.width()/4, 50)); goButton.setStyleSheet(BTN_STYLE); goButton.setFont(font); goButton.setMinimumSize(QSize(rect.width()/4, 50)); - goButton.setGeometry(QRect(rect.x()+rect.width()*5/8, rect.y()+y-60, rect.width()/4, 50)); - goButton.setVisible(true); + goButton.setGeometry(QRect(rect.width()*5/8, y-60, rect.width()/4, 50)); } diff --git a/InfoPanel.h b/InfoPanel.h index 0602c9f..e6e3048 100644 --- a/InfoPanel.h +++ b/InfoPanel.h @@ -9,13 +9,14 @@ #include "Business.h" #include "InfoPanelLabel.h" -class InfoPanel +class InfoPanel : public QWidget { public: - InfoPanel(QWidget *parent, Business & business, QRect rect); + InfoPanel(QWidget *parent, QRect rect); virtual ~InfoPanel(){} QPushButton * getCancelButton() { return &cancelButton; } QPushButton * getGoButton() { return &goButton; } + void populateInfo(Business & business); private: InfoPanelLabel nameLabel; diff --git a/InfoPanelLabel.cpp b/InfoPanelLabel.cpp index c87e7e5..1dd5dda 100644 --- a/InfoPanelLabel.cpp +++ b/InfoPanelLabel.cpp @@ -13,7 +13,7 @@ void InfoPanelLabel::Init(int pos, int height, const QString &text, QFont *font) setFont(*font); } setStyleSheet("QLabel { background-color : white; color : #FFFFFF; }"); - setGeometry(QRect(rect.x(), rect.y()+pos, rect.width(), height)); + setGeometry(QRect(0, pos, rect.width(), height)); /* if text is too big, align left so that we can at least read the beginning : */ if (this->text().length() > 0 && this->fontMetrics().width(this->text()) >= rect.width()) diff --git a/MainApp.cpp b/MainApp.cpp index f4c858d..10492f7 100644 --- a/MainApp.cpp +++ b/MainApp.cpp @@ -80,7 +80,6 @@ MainApp::MainApp(Navigation *navigation):QMainWindow(Q_NULLPTR, Qt::FramelessWin lineEdit.setGeometry(QRect(LEFT_OFFSET + searchBtn.width() + SPACER, 0, lineEdit.width(), lineEdit.height())); lineEdit.setVisible(false); - QFile file(NAVI_CONFIG_FILEPATH); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -150,8 +149,6 @@ void MainApp::DisplayLineEdit(bool display) { mutex.lock(); - this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB)); - if (display) { lineEdit.setVisible(true); @@ -162,13 +159,11 @@ void MainApp::DisplayLineEdit(bool display) if (pResultList) { pResultList->removeEventFilter(this); - delete pResultList; - pResultList = NULL; + pResultList->setVisible(false); } if (pInfoPanel) { - delete pInfoPanel; - pInfoPanel = NULL; + pInfoPanel->setVisible(false); } lineEdit.setText(tr("")); lineEdit.setVisible(false); @@ -193,7 +188,7 @@ void MainApp::UpdateAglSurfaces() system(cmd); } -void MainApp::DisplayResultList(bool display, bool RefreshDisplay) +void MainApp::DisplayResultList(bool display) { mutex.lock(); @@ -215,32 +210,25 @@ void MainApp::DisplayResultList(bool display, bool RefreshDisplay) //font.setPointSize(FONT_SIZE_LIST); //pResultList->setFont(font); pResultList->installEventFilter(this); - } - pResultList->setGeometry(QRect( LEFT_OFFSET+searchBtn.width()+SPACER, searchBtn.height()+SPACER, - DISPLAY_WIDTH, DISPLAY_HEIGHT)); - if (RefreshDisplay) - { - this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB)); + pResultList->setGeometry(QRect(LEFT_OFFSET + searchBtn.width() + SPACER, + searchBtn.height() + SPACER, + DISPLAY_WIDTH, + DISPLAY_HEIGHT)); } pResultList->setVisible(true); pResultList->setFocus(); + pResultList->update(); } else { if (pResultList) { pResultList->removeEventFilter(this); - pResultList->deleteLater(); - pResultList = NULL; + pResultList->setVisible(false); + pResultList->update(); } - lineEdit.setFocus(); - - if (RefreshDisplay) - { - this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB)); - } } mutex.unlock(); @@ -251,7 +239,8 @@ void MainApp::textChanged(const QString & text) TRACE_INFO("New text is: %s", qPrintable(text)); /* do not handle text input if info panel is displayed: */ - if (pInfoPanel) return; + if (pInfoPanel && pInfoPanel->isVisible()) + return; mutex.lock(); @@ -308,7 +297,7 @@ void MainApp::itemClicked() mutex.lock(); if (isInfoScreen) { - DisplayInformation(true, false); + DisplayInformation(true); } else { @@ -521,7 +510,7 @@ bool MainApp::eventFilter(QObject *obj, QEvent *ev) { case Qt::Key_Escape: TRACE_DEBUG("Escape !"); - DisplayInformation(false, false); + DisplayInformation(false); DisplayResultList(true); FillResultList(Businesses, currentIndex); break; @@ -577,9 +566,20 @@ void MainApp::SetDestination(int index) SetWayPoints(0); mutex.unlock(); + + if (navWinRaiseCb) { + // Attempt to let any outstanding repaints finish by flushing + // and then waiting slightly before raising the nav window. + // It's currently unclear why repaints can be missed if this + // is not done. + qApp->processEvents(); + + //TRACE_DEBUG("Calling nav window raise callback"); + QTimer::singleShot(100, this, SLOT(callNavWinRaiseCb())); + } } -void MainApp::DisplayInformation(bool display, bool RefreshDisplay) +void MainApp::DisplayInformation(bool display) { mutex.lock(); if (display) @@ -603,18 +603,20 @@ void MainApp::DisplayInformation(bool display, bool RefreshDisplay) /* select the first selected item : */ currentIndex = pResultList->indexOfTopLevelItem(*SelectedItems.begin()); - /* Resize window: */ - DisplayResultList(false, false); + /* Hide results */ + DisplayResultList(false); /* Display info for the selected item: */ - QRect rect( LEFT_OFFSET+searchBtn.width()+SPACER, searchBtn.height()+SPACER, - DISPLAY_WIDTH, DISPLAY_HEIGHT); - pInfoPanel = new InfoPanel(this, Businesses[currentIndex], rect); - - if (RefreshDisplay) - { - this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB)); + if (!pInfoPanel) { + QRect rect(LEFT_OFFSET + searchBtn.width() + SPACER, + searchBtn.height(), + DISPLAY_WIDTH, + DISPLAY_HEIGHT); + pInfoPanel = new InfoPanel(this, rect); } + pInfoPanel->populateInfo(Businesses[currentIndex]); + pInfoPanel->setVisible(true); + pInfoPanel->update(); connect(pInfoPanel->getGoButton(), SIGNAL(clicked(bool)), this, SLOT(goClicked())); connect(pInfoPanel->getCancelButton(), SIGNAL(clicked(bool)), this, SLOT(cancelClicked())); @@ -623,17 +625,12 @@ void MainApp::DisplayInformation(bool display, bool RefreshDisplay) { if (pInfoPanel) { + pInfoPanel->setVisible(false); pInfoPanel->getGoButton()->disconnect(); pInfoPanel->getCancelButton()->disconnect(); - delete pInfoPanel; - pInfoPanel = NULL; + pInfoPanel->update(); } lineEdit.setFocus(); - - if (RefreshDisplay) - { - this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB)); - } } mutex.unlock(); @@ -666,8 +663,6 @@ void MainApp::networkReplySearch(QNetworkReply* reply) return; } - - currentIndex = 0; Businesses.clear(); ParseJsonBusinessList(buf.data(), Businesses); @@ -883,28 +878,24 @@ int MainApp::StartMonitoringUserInput() void MainApp::SetWayPoints(uint32_t myRoute) { /* set the destination : */ + naviapi->broadcastStatus("stop"); naviapi->sendWaypoint(this->destinationLatitude, this->destinationLongitude); - - /* reset search: */ - currentSearchingText = tr(""); - currentSearchedText = tr(""); - currentIndex = 0; - Businesses.clear(); } void MainApp::goClicked() { TRACE_DEBUG("Go clicked !"); + DisplayInformation(false); + DisplayResultList(true); + SetDestination(currentIndex); - DisplayLineEdit(false); } void MainApp::cancelClicked() { TRACE_DEBUG("Cancel clicked !"); - DisplayInformation(false, false); - DisplayResultList(true, false); - FillResultList(Businesses, currentIndex); + DisplayInformation(false); + DisplayResultList(true); } void MainApp::getAllSessions_reply(const std::map< uint32_t, std::string >& allSessions) diff --git a/MainApp.h b/MainApp.h index 7d0b9de..909f68c 100644 --- a/MainApp.h +++ b/MainApp.h @@ -14,6 +14,8 @@ #include +typedef void (*NavWinRaiseCb_t)(void); + class MainApp: public QMainWindow { Q_OBJECT @@ -25,6 +27,7 @@ class MainApp: public QMainWindow int StartMonitoringUserInput(); void setInfoScreen(bool val) { isInfoScreen = val; } void setKeyboard(bool val) { isKeyboard = val; } + void setNavWindowRaiseCallback(NavWinRaiseCb_t val) { navWinRaiseCb = val; } private: void ParseJsonBusinessList(const char* buf, std::vector & Output); @@ -33,12 +36,13 @@ class MainApp: public QMainWindow void SetDestination(int index = 0); bool IsCoordinatesConsistent(Business & business); void DisplayLineEdit(bool display = true); - void DisplayResultList(bool display, bool RefreshDisplay = true); - void DisplayInformation(bool display, bool RefreshDisplay = true); + void DisplayResultList(bool display); + void DisplayInformation(bool display); int FillResultList(std::vector & list, int focusIndex = 0); void SetWayPoints(uint32_t myRoute); Navigation *naviapi; + NavWinRaiseCb_t navWinRaiseCb = nullptr; QNetworkAccessManager networkManager; QPushButton searchBtn; QLineEdit lineEdit; @@ -81,6 +85,10 @@ class MainApp: public QMainWindow void UpdateAglSurfaces(); void goClicked(); void cancelClicked(); + void callNavWinRaiseCb() { + if(navWinRaiseCb) + navWinRaiseCb(); + } void positionGot(); diff --git a/main.cpp b/main.cpp index 2f360f3..8bf8b51 100644 --- a/main.cpp +++ b/main.cpp @@ -12,21 +12,29 @@ using namespace std; -QLibWindowmanager* qwm; -LibHomeScreen* hs; -QString graphic_role; -MainApp *mainapp; +static QLibWindowmanager* qwm; +static LibHomeScreen* hs; +static QString graphic_role; +static MainApp *mainapp; -void SyncDrawHandler(json_object *object) +static void SyncDrawHandler(json_object *object) { qwm->endDraw(graphic_role); } -void TapShortcutHandler(json_object *object) +static void ShowWindowHandler(json_object *object) { qwm->activateWindow(graphic_role); } +// Callback to drive raising navigation app +static void NavWindowRaiseHandler(void) +{ + if (hs) { + hs->showWindow("navigation", nullptr); + } +} + int main(int argc, char *argv[], char *env[]) { int opt; @@ -65,12 +73,15 @@ int main(int argc, char *argv[], char *env[]) hs->init(port, token.c_str()); - hs->set_event_handler(LibHomeScreen::Event_TapShortcut, TapShortcutHandler); + hs->set_event_handler(LibHomeScreen::Event_ShowWindow, ShowWindowHandler); - //force setting + // force setting mainapp->setInfoScreen(true); mainapp->setKeyboard(true); + // hook up callback to start/raise navigation app + mainapp->setNavWindowRaiseCallback(NavWindowRaiseHandler); + /* then, authenticate connexion to POI service: */ if (mainapp->AuthenticatePOI(credentialsFile) < 0) { -- cgit 1.2.3-korg