From bcb6a113aea3356ab935cb44a7990a5dcabb33c3 Mon Sep 17 00:00:00 2001 From: dogmaphobic Date: Tue, 28 Apr 2015 16:09:52 -0400 Subject: [PATCH] Mobile Menu Bar --- QGCCommon.pri | 5 +- src/QGCFileDialog.cc | 4 +- src/ui/MainWindow.cc | 8 ++- src/ui/MainWindow.h | 5 ++ src/ui/flightdisplay/FlightDisplay.qml | 47 ++++--------- src/ui/flightdisplay/QGCFlightDisplay.h | 4 ++ src/ui/toolbar/MainToolBar.cc | 9 +++ src/ui/toolbar/MainToolBar.h | 14 ++++ src/ui/toolbar/MainToolBar.qml | 91 ++++++++++++++++++++++++- 9 files changed, 148 insertions(+), 39 deletions(-) diff --git a/QGCCommon.pri b/QGCCommon.pri index d8ede623e..85510004b 100644 --- a/QGCCommon.pri +++ b/QGCCommon.pri @@ -32,7 +32,9 @@ linux { CONFIG += LinuxBuild } else : android-g++ { message("Android build") - CONFIG += AndroidBuild + CONFIG += AndroidBuild + DEFINES += __mobile__ + DEFINES += __android__ warning("Android build is experimental and not fully functional") } else { error("Unsuported Linux toolchain, only GCC 32- or 64-bit is supported") @@ -116,7 +118,6 @@ DEFINES += _TTY_NOWARN_ # AndroidBuild { - DEFINES += __android__ DEFINES += __STDC_LIMIT_MACROS } diff --git a/src/QGCFileDialog.cc b/src/QGCFileDialog.cc index fd9a9e04e..398017bb1 100644 --- a/src/QGCFileDialog.cc +++ b/src/QGCFileDialog.cc @@ -217,7 +217,9 @@ void QGCFileDialog::_validate(Options& options) Q_ASSERT(qgcApp()); Q_ASSERT_X(QThread::currentThread() == qgcApp()->thread(), "Threading issue", "QGCFileDialog can only be called from main thread"); -#ifndef __android__ +#ifdef __android__ + Q_UNUSED(options) +#else // On OSX native dialog can hang so we always use Qt dialogs options |= DontUseNativeDialog; #endif diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 74d08196b..eefc27135 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -181,12 +181,16 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) // Qt 4 on Ubuntu does place the native menubar correctly so on Linux we revert back to in-window menu bar. // TODO: Check that this is still necessary on Qt5 on Ubuntu + #ifdef Q_OS_LINUX -#ifndef __android__ menuBar()->setNativeMenuBar(false); #endif + + // On Mobile devices, we don't want any main menus at all. +#ifdef __mobile__ + menuBar()->setNativeMenuBar(false); #endif - + #ifdef UNITTEST_BUILD QAction* qmlTestAction = new QAction("Test QML palette and controls", NULL); connect(qmlTestAction, &QAction::triggered, this, &MainWindow::_showQmlTestWidget); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 16856c3f6..f4f993152 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -62,6 +62,7 @@ This file is part of the QGROUNDCONTROL project #include "MainToolBar.h" #include "LogCompressor.h" +#include "QGCFlightDisplay.h" #include "QGCMAVLinkInspector.h" #include "QGCMAVLinkLogPlayer.h" #include "MAVLinkDecoder.h" @@ -76,6 +77,7 @@ class QGCStatusBar; class Linecharts; class QGCDataPlot2D; class QGCUASFileViewMulti; +class QGCFlightDisplay; /** * @brief Main Application Window @@ -125,6 +127,9 @@ public: /// @brief Gets a pointer to the Main Tool Bar MainToolBar* getMainToolBar(void) { return _mainToolBar; } + + /// @brief Gets a pointer to the Main Flight Display + QGCFlightDisplay* getFlightDisplay() { return dynamic_cast(_flightView.data()); } QWidget* getCurrentViewWidget(void) { return _currentViewWidget; } diff --git a/src/ui/flightdisplay/FlightDisplay.qml b/src/ui/flightdisplay/FlightDisplay.qml index 2b5ab7a63..752b9b177 100644 --- a/src/ui/flightdisplay/FlightDisplay.qml +++ b/src/ui/flightdisplay/FlightDisplay.qml @@ -58,6 +58,13 @@ Item { return value ? "1" : "0"; } + Connections { + target: flightDisplay + onShowOptionsMenuChanged: { + contextMenu.popup(); + } + } + Component.onCompleted: { mapBackground.visible = getBool(flightDisplay.loadSetting("showMapBackground", "0")); @@ -609,39 +616,15 @@ Item { z: 70 } - // Button at upper left corner - Item { - id: optionsButton - x: __screenTools.pixelSizeFactor * (5) - y: __screenTools.pixelSizeFactor * (5) - width: __screenTools.pixelSizeFactor * (30) - height: __screenTools.pixelSizeFactor * (30) - opacity: 0.85 - z: 1000 - Image { - id: buttomImg - anchors.fill: parent - source: "/qml/buttonMore.svg" - mipmap: true - smooth: true - antialiasing: true - fillMode: Image.PreserveAspectFit - } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - if (mouse.button == Qt.LeftButton) - { - contextMenu.popup(); - } - // Experimental - if (mouse.button == Qt.RightButton) - { - optionsDialog.open(); - } + //- Context Menu + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: { + if (mouse.button == Qt.RightButton) + { + contextMenu.popup(); } } } - } diff --git a/src/ui/flightdisplay/QGCFlightDisplay.h b/src/ui/flightdisplay/QGCFlightDisplay.h index 40048473c..41103c6fe 100644 --- a/src/ui/flightdisplay/QGCFlightDisplay.h +++ b/src/ui/flightdisplay/QGCFlightDisplay.h @@ -53,6 +53,9 @@ public: ALTITUDEAMSL_CHANGED }; + /// @brief Invokes the Flight Display Options menu + void showOptionsMenu() { emit showOptionsMenuChanged(); } + Q_PROPERTY(float roll READ roll NOTIFY rollChanged) Q_PROPERTY(float pitch READ pitch NOTIFY pitchChanged) Q_PROPERTY(float heading READ heading NOTIFY headingChanged) @@ -103,6 +106,7 @@ signals: void latitudeChanged (); void longitudeChanged (); void mavPresentChanged (); + void showOptionsMenuChanged (); private slots: /** @brief Attitude from main autopilot / system state */ diff --git a/src/ui/toolbar/MainToolBar.cc b/src/ui/toolbar/MainToolBar.cc index ff09c7559..e41ea702a 100644 --- a/src/ui/toolbar/MainToolBar.cc +++ b/src/ui/toolbar/MainToolBar.cc @@ -34,6 +34,7 @@ This file is part of the QGROUNDCONTROL project #include "MainWindow.h" #include "UASMessageHandler.h" #include "UASMessageView.h" +#include "QGCFlightDisplay.h" MainToolBar::MainToolBar(QWidget* parent) : QGCQmlWidgetHolder(parent) @@ -156,6 +157,14 @@ void MainToolBar::onFlyView() MainWindow::instance()->loadFlightView(); } +void MainToolBar::onFlyViewMenu() +{ + QGCFlightDisplay* fdsp = MainWindow::instance()->getFlightDisplay(); + if(fdsp) { + fdsp->showOptionsMenu(); + } +} + void MainToolBar::onAnalyzeView() { setCurrentView(MainWindow::VIEW_ANALYZE); diff --git a/src/ui/toolbar/MainToolBar.h b/src/ui/toolbar/MainToolBar.h index a3868a5f5..0a45a6cdd 100644 --- a/src/ui/toolbar/MainToolBar.h +++ b/src/ui/toolbar/MainToolBar.h @@ -70,6 +70,7 @@ public: Q_INVOKABLE void onSetupView(); Q_INVOKABLE void onPlanView(); Q_INVOKABLE void onFlyView(); + Q_INVOKABLE void onFlyViewMenu(); Q_INVOKABLE void onAnalyzeView(); Q_INVOKABLE void onConnect(QString conf); Q_INVOKABLE void onDisconnect(QString conf); @@ -102,6 +103,9 @@ public: Q_PROPERTY(int remoteRSSI READ remoteRSSI NOTIFY remoteRSSIChanged) Q_PROPERTY(int telemetryRRSSI READ telemetryRRSSI NOTIFY telemetryRRSSIChanged) Q_PROPERTY(int telemetryLRSSI READ telemetryLRSSI NOTIFY telemetryLRSSIChanged) + Q_PROPERTY(bool isAndroid READ isAndroid CONSTANT) + Q_PROPERTY(bool isiOS READ isiOS CONSTANT) + Q_PROPERTY(bool isMobile READ isMobile CONSTANT) bool mavPresent () { return _mav != NULL; } int satelliteCount () { return _satelliteCount; } @@ -109,6 +113,16 @@ public: int telemetryRRSSI () { return _telemetryRRSSI; } int telemetryLRSSI () { return _telemetryLRSSI; } +#if defined (__android__) + bool isAndroid () { return true; } + bool isiOS () { return false; } + bool isMobile () { return true; } +#else + bool isAndroid () { return false; } + bool isiOS () { return false; } + bool isMobile () { return false; } +#endif + void setCurrentView (int currentView); void viewStateChanged (const QString& key, bool value); diff --git a/src/ui/toolbar/MainToolBar.qml b/src/ui/toolbar/MainToolBar.qml index 7f6c79b06..2c3a1ba91 100644 --- a/src/ui/toolbar/MainToolBar.qml +++ b/src/ui/toolbar/MainToolBar.qml @@ -43,7 +43,7 @@ Rectangle { property var qgcPal: QGCPalette { id: palette; colorGroupEnabled: true } property ScreenTools __screenTools: ScreenTools { } - property int cellSpacerSize: getProportionalDimmension(4) + property int cellSpacerSize: mainToolBar.isMobile ? getProportionalDimmension(6) : getProportionalDimmension(4) property int cellHeight: getProportionalDimmension(30) property var colorBlue: "#1a6eaa" @@ -133,6 +133,52 @@ Rectangle { return (mainToolBar.mavPresent && mainToolBar.heartbeatTimeout === 0 && mainToolBar.connectionCount > 0); } + //------------------------------------------------------------------------- + //-- Main menu for Mobile Devices + Menu { + id: maintMenu + ExclusiveGroup { id: mainMenuGroup } + MenuItem { + text: "Vehicle Setup" + checkable: true + exclusiveGroup: mainMenuGroup + checked: (mainToolBar.currentView === MainToolBar.ViewSetup) + onTriggered: + { + mainToolBar.onSetupView(); + } + } + MenuItem { + text: "Plan View" + checkable: true + checked: (mainToolBar.currentView === MainToolBar.ViewPlan) + exclusiveGroup: mainMenuGroup + onTriggered: + { + mainToolBar.onPlanView(); + } + } + MenuItem { + text: "Flight View" + checkable: true + checked: (mainToolBar.currentView === MainToolBar.ViewFly) + exclusiveGroup: mainMenuGroup + onTriggered: + { + mainToolBar.onFlyView(); + } + } + //-- Flight View Context Menu + MenuItem { + text: "Flight View Options..." + visible: (mainToolBar.currentView === MainToolBar.ViewFly) + onTriggered: + { + mainToolBar.onFlyViewMenu(); + } + } + } + Row { id: row1 height: cellHeight @@ -141,11 +187,14 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: getProportionalDimmension(10) + //--------------------------------------------------------------------- + //-- Main menu for Non Mobile Devices (Chevron Buttons) Row { id: row11 height: cellHeight spacing: -getProportionalDimmension(12) anchors.verticalCenter: parent.verticalCenter + visible: !mainToolBar.isMobile Connections { target: __screenTools onRepaintRequestedChanged: { @@ -216,12 +265,50 @@ Rectangle { } + //--------------------------------------------------------------------- + //-- Indicators Row { id: row12 height: cellHeight spacing: cellSpacerSize anchors.verticalCenter: parent.verticalCenter + //-- "Hamburger" menu for Mobile Devices + Item { + id: actionButton + visible: mainToolBar.isMobile + height: cellHeight + width: cellHeight + Image { + id: buttomImg + anchors.fill: parent + source: "/qml/buttonMore.svg" + mipmap: true + smooth: true + antialiasing: true + fillMode: Image.PreserveAspectFit + } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton + onClicked: { + if (mouse.button == Qt.LeftButton) + { + maintMenu.popup(); + } + } + } + } + + //-- Separator if Hamburger menu is visible + Rectangle { + visible: actionButton.visible + height: cellHeight + width: cellHeight + color: "#00000000" + anchors.verticalCenter: parent.verticalCenter + } + Rectangle { id: messages width: (mainToolBar.messageCount > 99) ? getProportionalDimmension(65) : getProportionalDimmension(60) @@ -462,7 +549,7 @@ Rectangle { QGCLabel { id: batteryText text: mainToolBar.batteryVoltage.toFixed(1) + 'V'; - font.pointSize: __screenTools.fontPointFactor * (12); + font.pointSize: __screenTools.fontPointFactor * (11); font.weight: Font.DemiBold anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right -- 2.22.0