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 }