From 7ea138038e8189f0c2f59f3561ff32e2b2668e46 Mon Sep 17 00:00:00 2001 From: Automatic Release Builder <build@flightgear.org> Date: Mon, 28 Sep 2020 16:18:32 +0100 Subject: [PATCH] First-run page for the launcher. Appears on first launch, gives us a chance to point out some policy things and where to get help. --- src/GUI/LauncherController.cxx | 14 ++++ src/GUI/LauncherController.hxx | 17 ++++ src/GUI/qml/Button.qml | 13 ++- src/GUI/qml/FirstRun.qml | 140 +++++++++++++++++++++++++++++++++ src/GUI/qml/Launcher.qml | 12 +++ src/GUI/qml/Style.qml | 1 + src/GUI/resources.qrc | 3 +- 7 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 src/GUI/qml/FirstRun.qml diff --git a/src/GUI/LauncherController.cxx b/src/GUI/LauncherController.cxx index 3ba248533..6354334b5 100644 --- a/src/GUI/LauncherController.cxx +++ b/src/GUI/LauncherController.cxx @@ -133,6 +133,20 @@ LauncherController::LauncherController(QObject *parent, QWindow* window) : const auto ws = static_cast<Qt::WindowState>(settings.value("window-state").toInt()); m_window->setWindowState(ws); } + + // count launches; we use this to trigger first-run and periodic notices + // in the UI. + m_launchCount = settings.value("launch-count", 0).toInt(); + settings.setValue("launch-count", m_launchCount + 1); + + std::ostringstream os; + string_list versionParts = simgear::strutils::split(FLIGHTGEAR_VERSION, "."); + if (versionParts.size() >= 2) { + // build a setting key like launch-count-2020-2 + QString versionedCountKey = QString::fromStdString("launch-count-" + versionParts.at(0) + "-" + versionParts.at(1)); + m_versionLaunchCount = settings.value(versionedCountKey, 0).toInt(); + settings.setValue(versionedCountKey, m_versionLaunchCount + 1); + } } void LauncherController::initQML() diff --git a/src/GUI/LauncherController.hxx b/src/GUI/LauncherController.hxx index 449a18cd1..915ccc1e9 100644 --- a/src/GUI/LauncherController.hxx +++ b/src/GUI/LauncherController.hxx @@ -91,6 +91,10 @@ class LauncherController : public QObject Q_PROPERTY(bool inAppMode READ inApp NOTIFY inAppChanged) Q_PROPERTY(bool aircraftGridMode READ aircraftGridMode WRITE setAircraftGridMode NOTIFY aircraftGridModeChanged) + + Q_PROPERTY(int launchCount READ launchCount CONSTANT); + Q_PROPERTY(int versionLaunchCount READ versionLaunchCount CONSTANT); + public: explicit LauncherController(QObject *parent, QWindow* win); @@ -202,6 +206,17 @@ public: { return m_inAppMode; } + + int launchCount() const + { + return m_launchCount; + } + + int versionLaunchCount() const + { + return m_versionLaunchCount; + } + signals: void selectedAircraftChanged(QUrl selectedAircraft); @@ -294,6 +309,8 @@ private: bool m_keepRunningInAppMode = false; bool m_appModeResult = true; bool m_aircraftGridMode; + int m_launchCount = 0; + int m_versionLaunchCount = 0; }; #endif // LAUNCHERCONTROLLER_HXX diff --git a/src/GUI/qml/Button.qml b/src/GUI/qml/Button.qml index 4731ae115..a447a5ff2 100644 --- a/src/GUI/qml/Button.qml +++ b/src/GUI/qml/Button.qml @@ -9,19 +9,26 @@ Rectangle { property bool enabled: true property bool destructiveAction: false - readonly property string __baseColor: destructiveAction ? Style.destructiveActionColor : Style.themeColor + readonly property string __baseColor: destructiveAction ? Style.destructiveActionColor : + (invertColor ? "white" : Style.themeColor) + + readonly property string __activeColor: invertColor ? Style.inverseActiveColor : Style.activeColor + readonly property string __textColor: invertColor ? Style.frameColor : "white" + signal clicked + property bool invertColor: false + width: Math.max(Style.strutSize * 2, buttonText.implicitWidth + radius * 2) height: buttonText.implicitHeight + (radius * 2) radius: Style.roundRadius - color: enabled ? (mouse.containsMouse ? Style.activeColor : __baseColor) : Style.disabledThemeColor + color: enabled ? (mouse.containsMouse ? __activeColor : __baseColor) : Style.disabledThemeColor Text { id: buttonText anchors.centerIn: parent - color: "white" + color: root.__textColor text: (mouse.containsMouse && hoverText != "") ? root.hoverText : root.text font.pixelSize: Style.baseFontPixelSize } diff --git a/src/GUI/qml/FirstRun.qml b/src/GUI/qml/FirstRun.qml new file mode 100644 index 000000000..01314c2cc --- /dev/null +++ b/src/GUI/qml/FirstRun.qml @@ -0,0 +1,140 @@ +import QtQuick 2.4 +import FlightGear 1.0 +import FlightGear.Launcher 1.0 +import "." + +Rectangle { + color: Style.themeColor + id: root + + Item { + id: imageClipFrame + clip: true + + height: root.height * 0.5 + anchors { + left: parent.left + right: parent.right + top: parent.top + } + + PreviewImage { + id: preview + + anchors.centerIn: parent + + // over-zoom the preview to fill the entire space available + readonly property double scale: Math.max(root.width / sourceSize.width, + imageClipFrame.height / sourceSize.height) + + width: height * aspectRatio + height: scale * sourceSize.height + + property var urlsList: _launcher.defaultSplashUrls() + imageUrl: urlsList[0] + } + + Text { + id: logoText + width: parent.width - Style.strutSize + + anchors { + top: parent.top + topMargin: Style.strutSize + } + + font.pointSize: Style.strutSize * 3 + font.italic: true + font.bold: true + + horizontalAlignment: Text.AlignHCenter + fontSizeMode: Text.Fit + text: "FlightGear " + _launcher.versionString + color: "white" + style: Text.Outline + styleColor: "black" + } + } + + + + Column { + anchors { + left: parent.left + right: parent.right + top: imageClipFrame.bottom + + margins: Style.strutSize + } + + spacing: Style.strutSize + + Text { + width: parent.width + font.pixelSize: Style.baseFontPixelSize * 1.5 + color: "white" + wrapMode: Text.WordWrap + + readonly property string forumLink: "href=\"http://forum.flightgear.org\""; + + text: qsTr("Welcome to FlightGear, the open-source flight simulator. " + + "Everything in this software is the work of volunteers; we hope " + + "you enjoy it. If you find problems, or would like to contribute, " + + "please <a %1>visit our user forum</a>.").arg(forumLink) + + onLinkActivated: { + Qt.openUrlExternally(link) + } + } + + Text { + width: parent.width + font.pixelSize: Style.baseFontPixelSize * 1.5 + color: "white" + wrapMode: Text.WordWrap + + readonly property string gplLink: "href=\"https://www.gnu.org/licenses/gpl-3.0.html\""; + + text: qsTr("FlightGear is Free software, licensed under the <a %1>GNU General Public License</a>. " + + "This means you are are free to use the software, customise it, or make fixes to it, so long as " + + "you share your changes with the community.").arg(gplLink) + + onLinkActivated: { + Qt.openUrlExternally(link) + } + } + + Text { + width: parent.width + font.pixelSize: Style.baseFontPixelSize * 1.5 + color: "white" + + wrapMode: Text.WordWrap + + text: qsTr("FlightGear can automatically report crashes and errors to the development team, " + + "which helps to improve the software for everyone. This reporting is anonymous but " + + "contains information such as the aircraft in use, your operating system and graphics driver. " + + "You can enable or disable this reporting in the 'Settings' page." + ) + } + + Item { + width: parent.width + height: childrenRect.height + + Button { + invertColor: true + text: qsTrId("Okay"); + anchors.right: parent.right + + onClicked: { + OverlayShared.globalOverlay.dismissOverlay(); + } + } + } + } // of column + + + + +} diff --git a/src/GUI/qml/Launcher.qml b/src/GUI/qml/Launcher.qml index fee70c143..ce51b4078 100644 --- a/src/GUI/qml/Launcher.qml +++ b/src/GUI/qml/Launcher.qml @@ -43,6 +43,18 @@ Item { Component.onCompleted: { _launcher.minimumWindowSize = Qt.size(Style.strutSize * 12, sidebar.minimumHeight); + + if (_launcher.versionLaunchCount == 0) { + popupOverlay.showOverlay(firstRun) + } + } + + Component { + id: firstRun + FirstRun { + width: root.width + height: root.height + } } Connections { diff --git a/src/GUI/qml/Style.qml b/src/GUI/qml/Style.qml index b2880c418..8e0ae5018 100644 --- a/src/GUI/qml/Style.qml +++ b/src/GUI/qml/Style.qml @@ -16,6 +16,7 @@ QtObject readonly property string destructiveActionColor: "#c62703" readonly property string activeColor: Qt.darker(themeColor) + readonly property string inverseActiveColor: "#2f2f2f" readonly property string inactiveThemeColor: "#9f9f9f" readonly property string disabledThemeColor: disabledTextColor diff --git a/src/GUI/resources.qrc b/src/GUI/resources.qrc index d1846bcec..d05560ad4 100644 --- a/src/GUI/resources.qrc +++ b/src/GUI/resources.qrc @@ -130,9 +130,10 @@ <file>qml/EnableDisableButton.qml</file> <file>qml/IconButton.qml</file> <file>qml/FavouriteToggleButton.qml</file> - <file>qml/VariantMenu.qml</file> + <file>qml/VariantMenu.qml</file> <file alias="favourite-icon-filled">assets/icons8-christmas-star-filled.png</file> <file alias="favourite-icon-outline">assets/icons8-christmas-star-outline.png</file> + <file>qml/FirstRun.qml</file> </qresource> <qresource prefix="/preview"> <file alias="close-icon">assets/preview-close.png</file>