File indexing completed on 2024-10-27 04:24:10

0001 #pragma once
0002 
0003 #include <QObject>
0004 #include <QRect>
0005 #include <QList>
0006 
0007 #include "mauiman_export.h"
0008 
0009 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0010 #define QT5_BASE
0011 #include <QTouchDevice>
0012 class QInputInfoManager;
0013 #else
0014 #define QT6_BASE
0015 class QInputDevice;
0016 #endif
0017 
0018 class QDBusInterface;
0019 namespace MauiMan
0020 {
0021     class SettingsStore;
0022 
0023     /**
0024      * @brief The FormFactoInfo class contains information about the input devices available in the current system.
0025      */
0026     class MAUIMAN_EXPORT FormFactorInfo : public QObject
0027     {
0028         Q_OBJECT
0029         /**
0030          * The best fitted mode according to the available input devices and the screen size.
0031          */
0032         Q_PROPERTY(uint bestMode READ bestMode NOTIFY bestModeChanged FINAL)
0033         
0034         /**
0035          * The system preferred mode. This is picked up from the env var `QT_QUICK_CONTROLS_MOBILE`
0036          */
0037         Q_PROPERTY(uint defaultMode READ defaultMode CONSTANT FINAL)
0038 
0039         /**
0040          * Whether the device has a physical keyboard.
0041          */
0042         Q_PROPERTY(bool hasKeyboard READ hasKeyboard NOTIFY hasKeyboardChanged FINAL)
0043         
0044         /**
0045          * Whether the device has a touch screen.
0046          */
0047         Q_PROPERTY(bool hasTouchscreen READ hasTouchscreen NOTIFY hasTouchscreenChanged FINAL)
0048         
0049         /**
0050          * Whether the device has a physical mouse.
0051          */
0052         Q_PROPERTY(bool hasMouse READ hasMouse  NOTIFY hasMouseChanged FINAL)
0053         
0054         /**
0055          * Whether the device has a trackpad or touchpad 
0056          */
0057         Q_PROPERTY(bool hasTouchpad READ hasTouchpad NOTIFY hasTouchpadChanged)
0058 
0059         /**
0060          * The size of the main screen.
0061          */
0062         Q_PROPERTY(QRect screenSize READ screenSize NOTIFY screenSizeChanged)
0063         
0064         /**
0065          * The current orientation of the main screen.
0066          */
0067         Q_PROPERTY(Qt::ScreenOrientation screenOrientation READ screenOrientation NOTIFY screenOrientationChanged)
0068 
0069     public:
0070         /**
0071          * @brief The possible form factor modes the system can have based on the device capabilities.
0072          */
0073         enum Mode
0074         {
0075             /**
0076              * Is a desktop when the screen size if relative big, has a physical keyboard, mouse.
0077              */
0078             Desktop = 0,
0079             
0080             /**
0081              * Is a tablet when the devices has a relative big screen size, and it is a touch screen. There is not mouse present.
0082              */
0083             Tablet,
0084             
0085             /**
0086              * Is a mobile phone, the the screen size is small, has a touch screen and not peripheral input devices such as a a keyboard or mouse.
0087              */
0088             Phone
0089         };
0090 
0091         struct DefaultValues
0092         {
0093             [[nodiscard]] static uint getDefaultMode()
0094             {
0095 
0096                 #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(UBUNTU_TOUCH)
0097                 return MauiMan::FormFactorInfo::Mode::Phone;
0098                 #else
0099 
0100                 return QByteArrayList{"1", "true"}.contains(qgetenv("QT_QUICK_CONTROLS_MOBILE")) ? MauiMan::FormFactorInfo::Mode::Phone : MauiMan::FormFactorInfo::Mode::Desktop;
0101                 #endif
0102             }
0103 
0104             [[nodiscard]] static bool getHasTouchScreen()
0105             {
0106 
0107                 #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(UBUNTU_TOUCH)
0108                 return true;
0109                 #else
0110 
0111                 return false;
0112                 #endif
0113             }
0114 
0115             static inline const uint defaultMode = DefaultValues::getDefaultMode();
0116             static inline const bool hasTouchscreen = DefaultValues::getHasTouchScreen();
0117         } ;
0118 
0119         explicit FormFactorInfo(QObject *parent);
0120 
0121         [[nodiscard]] uint bestMode() const;
0122 
0123         [[nodiscard]] uint defaultMode() const;
0124 
0125         [[nodiscard]] bool hasKeyboard() const;
0126 
0127         [[nodiscard]] bool hasTouchscreen() const;
0128 
0129         [[nodiscard]] bool hasMouse() const;
0130 
0131         [[nodiscard]] bool hasTouchpad() const;
0132 
0133         [[nodiscard]] QRect screenSize();
0134         [[nodiscard]] Qt::ScreenOrientation screenOrientation();
0135 
0136     private:
0137         uint m_bestMode = FormFactorInfo::DefaultValues::defaultMode;
0138 
0139         uint m_defaultMode = FormFactorInfo::DefaultValues::defaultMode;
0140 
0141         bool m_hasKeyboard = true;
0142 
0143         bool m_hasTouchscreen = FormFactorInfo::DefaultValues::hasTouchscreen;
0144 
0145         bool m_hasMouse = true;
0146         bool m_hasTouchpad = true;
0147 
0148         QRect m_screenSize;
0149         Qt::ScreenOrientation m_screenOrientation;
0150 
0151         #ifdef QT5_BASE
0152         void checkInputs(const QInputInfoManager *inputManager);
0153         #elif defined QT6_BASE
0154         void checkInputs(const QList<const QInputDevice *> &devices);
0155         #endif
0156         void findBestMode();
0157 
0158     Q_SIGNALS:
0159         void bestModeChanged(uint bestMode);
0160         void defaultModeChanged(uint defaultMode);
0161 
0162         void hasKeyboardChanged(bool hasKeyboard);
0163         void hasTouchscreenChanged(bool hasTouchscreen);
0164         void hasMouseChanged(bool hasMouse);
0165         void hasTouchpadChanged(bool hasTouchpad);
0166 
0167         void screenSizeChanged(QRect screenSize);
0168         void screenOrientationChanged(Qt::ScreenOrientation screenOrientation);
0169     };
0170 
0171     /**
0172      * @brief The FormFactorManager class exposes all the system form factor properties.
0173      */
0174     class MAUIMAN_EXPORT FormFactorManager : public FormFactorInfo
0175     {
0176         Q_OBJECT
0177         /**
0178          * The preferred mode to display information. The possible values are:
0179          * - 0 Desktop 
0180          * - 1 Tablet
0181          * - 2 Phone
0182          */
0183         Q_PROPERTY(uint preferredMode READ preferredMode WRITE setPreferredMode NOTIFY preferredModeChanged FINAL)
0184 
0185     public:
0186         explicit FormFactorManager(QObject *parent = nullptr);
0187 
0188         [[nodiscard]] uint preferredMode() const;
0189         void setPreferredMode(uint preferredMode);
0190 
0191     private Q_SLOTS:
0192         void onPreferredModeChanged(uint preferredMode);
0193 
0194     private:
0195         #if !defined Q_OS_ANDROID
0196         QDBusInterface *m_interface = nullptr;
0197         #endif
0198         MauiMan::SettingsStore *m_settings;
0199         FormFactorInfo *m_info;
0200 
0201         uint m_preferredMode;
0202 
0203         void sync(const QString &key, const QVariant &value);
0204         void setConnections();
0205         void loadSettings();
0206 
0207     Q_SIGNALS:
0208         void preferredModeChanged(uint preferredMode);
0209 
0210     };
0211 }