Skip to content

Commit

Permalink
Update MobileUI
Browse files Browse the repository at this point in the history
  • Loading branch information
emericg committed Sep 3, 2024
1 parent b815629 commit db2318e
Show file tree
Hide file tree
Showing 10 changed files with 470 additions and 128 deletions.
135 changes: 74 additions & 61 deletions qml/MobileApplication.qml
Original file line number Diff line number Diff line change
Expand Up @@ -35,72 +35,90 @@ ApplicationWindow {
property int screenPaddingRight: 0
property int screenPaddingBottom: 0

onScreenOrientationChanged: handleSafeAreas()
onScreenOrientationFullChanged: handleSafeAreas()
onVisibilityChanged: handleSafeAreas()

function handleSafeAreas() {
// safe areas are only taken into account when using maximized geometry / full screen mode
if (appWindow.visibility === Window.FullScreen ||
appWindow.flags & Qt.MaximizeUsingFullscreenGeometryHint) {
MobileUI {
id: mobileUI

statusbarColor: "transparent"
statusbarTheme: Theme.themeStatusbar
navbarColor: {
if (appContent.state === "Tutorial") return Theme.colorHeader
return Theme.colorBackground
}

screenPaddingStatusbar = mobileUI.statusbarHeight
screenPaddingNavbar = mobileUI.navbarHeight
Component.onCompleted: handleSafeAreas()

screenPaddingTop = mobileUI.safeAreaTop
screenPaddingLeft = mobileUI.safeAreaLeft
screenPaddingRight = mobileUI.safeAreaRight
screenPaddingBottom = mobileUI.safeAreaBottom
function handleSafeAreas() {
// safe areas handling is a work in progress /!\
// safe areas are only taken into account when using maximized geometry / full screen mode

// hacks
if (Qt.platform.os === "android") {
if (appWindow.visibility === Window.FullScreen) {
screenPaddingStatusbar = 0
screenPaddingNavbar = 0
mobileUI.refreshUI() // hack

if (appWindow.visibility === Window.FullScreen ||
appWindow.flags & Qt.MaximizeUsingFullscreenGeometryHint) {

screenPaddingStatusbar = mobileUI.statusbarHeight
screenPaddingNavbar = mobileUI.navbarHeight

screenPaddingTop = mobileUI.safeAreaTop
screenPaddingLeft = mobileUI.safeAreaLeft
screenPaddingRight = mobileUI.safeAreaRight
screenPaddingBottom = mobileUI.safeAreaBottom

// hacks
if (Qt.platform.os === "android") {
if (appWindow.visibility === Window.FullScreen) {
screenPaddingStatusbar = 0
screenPaddingNavbar = 0
}
if (appWindow.flags & Qt.MaximizeUsingFullscreenGeometryHint) {
if (mobileUI.isPhone) {
if (Screen.orientation === Qt.LandscapeOrientation) {
screenPaddingLeft = screenPaddingStatusbar
screenPaddingRight = screenPaddingNavbar
screenPaddingNavbar = 0
} else if (Screen.orientation === Qt.InvertedLandscapeOrientation) {
screenPaddingLeft = screenPaddingNavbar
screenPaddingRight = screenPaddingStatusbar
screenPaddingNavbar = 0
}
}
}
}
}
// hacks
if (Qt.platform.os === "ios") {
if (appWindow.visibility === Window.FullScreen) {
screenPaddingStatusbar = 0
// hacks
if (Qt.platform.os === "ios") {
if (appWindow.visibility === Window.FullScreen) {
screenPaddingStatusbar = 0
}
}
} else {
screenPaddingStatusbar = 0
screenPaddingNavbar = 0
screenPaddingTop = 0
screenPaddingLeft = 0
screenPaddingRight = 0
screenPaddingBottom = 0
}
} else {
screenPaddingStatusbar = 0
screenPaddingNavbar = 0
screenPaddingTop = 0
screenPaddingLeft = 0
screenPaddingRight = 0
screenPaddingBottom = 0
}
/*
console.log("> handleSafeAreas()")
console.log("- window mode: " + appWindow.visibility)
console.log("- window flags: " + appWindow.flags)
console.log("- screen dpi: " + Screen.devicePixelRatio)
console.log("- screen width: " + Screen.width)
console.log("- screen width avail: " + Screen.desktopAvailableWidth)
console.log("- screen height: " + Screen.height)
console.log("- screen height avail: " + Screen.desktopAvailableHeight)
console.log("- screen orientation (full): " + Screen.orientation)
console.log("- screen orientation (primary): " + Screen.primaryOrientation)
console.log("- screenSizeStatusbar: " + screenPaddingStatusbar)
console.log("- screenSizeNavbar: " + screenPaddingNavbar)
console.log("- screenPaddingTop: " + screenPaddingTop)
console.log("- screenPaddingLeft: " + screenPaddingLeft)
console.log("- screenPaddingRight: " + screenPaddingRight)
console.log("- screenPaddingBottom: " + screenPaddingBottom)
console.log("> handleSafeAreas()")
console.log("- window mode: " + appWindow.visibility)
console.log("- window flags: " + appWindow.flags)
console.log("- screen dpi: " + Screen.devicePixelRatio)
console.log("- screen width: " + Screen.width)
console.log("- screen width avail: " + Screen.desktopAvailableWidth)
console.log("- screen height: " + Screen.height)
console.log("- screen height avail: " + Screen.desktopAvailableHeight)
console.log("- screen orientation (full): " + Screen.orientation)
console.log("- screen orientation (primary): " + Screen.primaryOrientation)
console.log("- screenSizeStatusbar: " + screenPaddingStatusbar)
console.log("- screenSizeNavbar: " + screenPaddingNavbar)
console.log("- screenPaddingTop: " + screenPaddingTop)
console.log("- screenPaddingLeft: " + screenPaddingLeft)
console.log("- screenPaddingRight: " + screenPaddingRight)
console.log("- screenPaddingBottom: " + screenPaddingBottom)
*/
}

MobileUI {
id: mobileUI
property bool isLoading: true

statusbarTheme: Theme.themeStatusbar
navbarColor: {
if (isLoading) return "white"
if (appContent.state === "Tutorial") return Theme.colorHeader
return Theme.colorBackground
}
}

Expand All @@ -116,11 +134,6 @@ ApplicationWindow {

// Events handling /////////////////////////////////////////////////////////

Component.onCompleted: {
handleSafeAreas()
mobileUI.isLoading = false
}

Connections {
target: ThemeEngine
function onCurrentThemeChanged() {
Expand Down
61 changes: 55 additions & 6 deletions src/thirdparty/MobileUI/MobileUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@
#include "MobileUI.h"
#include "MobileUI_private.h"

#include <QGuiApplication>
#include <QQmlEngine>
#include <QScreen>

/* ************************************************************************** */

bool MobileUI::isPhone = false;
bool MobileUI::isTablet = false;

bool MobileUIPrivate::areRefreshSlotsConnected = false;

MobileUI::Theme MobileUIPrivate::deviceTheme = MobileUI::Light;
Expand All @@ -54,6 +59,23 @@ void MobileUI::registerQML()

/* ************************************************************************** */

MobileUI::MobileUI(QObject *parent) : QObject(parent)
{
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
QScreen *screen = qApp->primaryScreen();
if (screen)
{
double screenSizeInch = std::sqrt(std::pow(screen->physicalSize().width(), 2.0) +
std::pow(screen->physicalSize().height(), 2.0)) / (2.54 * 10.0);

if (screenSizeInch < 7.0) MobileUI::isPhone = true;
else MobileUI::isTablet = true;
}
#endif
}

/* ************************************************************************** */

MobileUI::Theme MobileUI::getDeviceTheme()
{
return static_cast<MobileUI::Theme>(MobileUIPrivate::getDeviceTheme());
Expand All @@ -68,8 +90,11 @@ QColor MobileUI::getStatusbarColor()

void MobileUI::setStatusbarColor(const QColor &color)
{
MobileUIPrivate::statusbarColor = color;
MobileUIPrivate::setColor_statusbar(color);
if (color.isValid())
{
MobileUIPrivate::statusbarColor = color;
MobileUIPrivate::setColor_statusbar(color);
}
}

MobileUI::Theme MobileUI::getStatusbarTheme()
Expand All @@ -92,8 +117,11 @@ QColor MobileUI::getNavbarColor()

void MobileUI::setNavbarColor(const QColor &color)
{
MobileUIPrivate::navbarColor = color;
MobileUIPrivate::setColor_navbar(color);
if (color.isValid())
{
MobileUIPrivate::navbarColor = color;
MobileUIPrivate::setColor_navbar(color);
}
}

MobileUI::Theme MobileUI::getNavbarTheme()
Expand All @@ -111,9 +139,13 @@ void MobileUI::setNavbarTheme(const MobileUI::Theme theme)

void MobileUI::refreshUI()
{
MobileUIPrivate::setColor_statusbar(MobileUIPrivate::statusbarColor);
if (MobileUIPrivate::statusbarColor.isValid())
MobileUIPrivate::setColor_statusbar(MobileUIPrivate::statusbarColor);

if (MobileUIPrivate::navbarColor.isValid())
MobileUIPrivate::setColor_navbar(MobileUIPrivate::navbarColor);

MobileUIPrivate::setTheme_statusbar(MobileUIPrivate::statusbarTheme);
MobileUIPrivate::setColor_navbar(MobileUIPrivate::navbarColor);
MobileUIPrivate::setTheme_navbar(MobileUIPrivate::navbarTheme);
}

Expand Down Expand Up @@ -175,9 +207,26 @@ void MobileUI::setScreenAlwaysOn(const bool value)

/* ************************************************************************** */

int MobileUI::getScreenBrightness()
{
return MobileUIPrivate::getScreenBrightness();
}

void MobileUI::setScreenBrightness(const int value)
{
return MobileUIPrivate::setScreenBrightness(value);
}

/* ************************************************************************** */

void MobileUI::vibrate()
{
MobileUIPrivate::vibrate();
}

void MobileUI::backToHomeScreen()
{
MobileUIPrivate::backToHomeScreen();
}

/* ************************************************************************** */
51 changes: 46 additions & 5 deletions src/thirdparty/MobileUI/MobileUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class MobileUI : public QObject

Q_PROPERTY(Theme deviceTheme READ getDeviceTheme NOTIFY devicethemeUpdated)

Q_PROPERTY(bool isPhone READ isDevicePhone CONSTANT)
Q_PROPERTY(bool isTablet READ isDeviceTablet CONSTANT)

Q_PROPERTY(QColor statusbarColor READ getStatusbarColor WRITE setStatusbarColor NOTIFY statusbarUpdated)
Q_PROPERTY(Theme statusbarTheme READ getStatusbarTheme WRITE setStatusbarTheme NOTIFY statusbarUpdated)
Q_PROPERTY(int statusbarHeight READ getStatusbarHeight NOTIFY statusbarUpdated)
Expand All @@ -51,6 +54,7 @@ class MobileUI : public QObject

Q_PROPERTY(bool screenAlwaysOn READ getScreenAlwaysOn WRITE setScreenAlwaysOn NOTIFY screenUpdated)
Q_PROPERTY(ScreenOrientation screenOrientation READ getScreenOrientation WRITE setScreenOrientation NOTIFY screenUpdated)
Q_PROPERTY(int screenBrightness READ getScreenBrightness WRITE setScreenBrightness NOTIFY screenUpdated)

Q_SIGNALS:
void devicethemeUpdated();
Expand All @@ -60,10 +64,16 @@ class MobileUI : public QObject
void screenUpdated();

public:
explicit MobileUI(QObject *parent = nullptr) : QObject(parent) {}
MobileUI(QObject *parent = nullptr);

static void registerQML();

static bool isPhone;
static bool isTablet;

static bool isDevicePhone() { return MobileUI::isPhone; }
static bool isDeviceTablet() { return MobileUI::isTablet; }

// Device theme ////////////////////////////////////////////////////////////

enum Theme {
Expand All @@ -74,7 +84,6 @@ class MobileUI : public QObject

/*!
* \brief Get the theme currently in effect on this device.
* \note Not available yet on iOS.
* \return see MobileUI::Theme enum.
*/
static MobileUI::Theme getDeviceTheme();
Expand Down Expand Up @@ -123,6 +132,10 @@ class MobileUI : public QObject
};
Q_ENUM(ScreenOrientation)

/*!
* \brief Get orientation lock (if set).
* \return See MobileUI::ScreenOrientation enum.
*/
MobileUI::ScreenOrientation getScreenOrientation();

/*!
Expand All @@ -136,22 +149,50 @@ class MobileUI : public QObject
*/
Q_INVOKABLE static void setScreenOrientation(const MobileUI::ScreenOrientation orientation);

/*!
* \brief Get screensaver lock (if set).
* \return on or off.
*/
static bool getScreenAlwaysOn();

/*!
* \brief Lock screensaver.
* \param value: on or off
* \param value: on or off.
*/
Q_INVOKABLE static void setScreenAlwaysOn(const bool value);

/*!
* \brief Get screen brightness set for the current app (on Android) or system wide (on iOS).
* \return screen brightness, from 0 to 100.
*
* If brightness has not been set for the current app, this function will
* return the OS wide brightness level.
*/
static int getScreenBrightness();

/*!
* \brief Set screen brightness for the current app (on Android) or system wide (on iOS).
* \param value: screen brightness, from 0 to 100.
*/
Q_INVOKABLE static void setScreenBrightness(const int value);

// Other helpers ///////////////////////////////////////////////////////////

/*!
* \brief Trigger an haptic feedback.
*
* On Android the "android.permission.VIBRATE" must be added to the manifest.
* \note iPads don't support haptic feedbacks.
* \note On Android the "android.permission.VIBRATE" must be added to the manifest.
*/
Q_INVOKABLE static void vibrate();

/*!
* \brief Go back to Android home screen.
*
* You can use this method to bypass the default behavior for the Android
* back button, which is to kill the application instead of doing what every
* single Android application does, going back to the home screen...
*/
Q_INVOKABLE static void backToHomeScreen();
};

/* ************************************************************************** */
Expand Down
2 changes: 1 addition & 1 deletion src/thirdparty/MobileUI/MobileUI.pri
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ android {
}
} else: ios {
LIBS += -framework UIKit
OBJECTIVE_SOURCES += $${PWD}/MobileUI_ios.mm
SOURCES += $${PWD}/MobileUI_ios.mm
} else {
SOURCES += $${PWD}/MobileUI_dummy.cpp
}
Loading

0 comments on commit db2318e

Please sign in to comment.