ScreenTools.qml 9.99 KB
Newer Older
Don Gagne's avatar
Don Gagne committed
1 2
pragma Singleton

3 4
import QtQuick 2.3
import QtQuick.Controls 1.2
dogmaphobic's avatar
dogmaphobic committed
5
import QtQuick.Window 2.2
Don Gagne's avatar
Don Gagne committed
6

7
import QGroundControl                       1.0
Don Gagne's avatar
Don Gagne committed
8 9
import QGroundControl.ScreenToolsController 1.0

Don Gagne's avatar
Don Gagne committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*!
 The ScreenTools Singleton provides information on QGC's standard font metrics. It also provides information on screen
 size which can be used to adjust user interface for varying available screen real estate.

 QGC has four standard font sizes: default, small, medium and large. The QGC controls use the default font for display and you should use this font
 for most text within the system that is drawn using something other than a standard QGC control. The small font is smaller than the default font.
 The medium and large fonts are larger than the default font.

 Usage:

        import QGroundControl.ScreenTools 1.0

        Rectangle {
            anchors.fill:       parent
            anchors.margins:    ScreenTools.defaultFontPixelWidth
            ...
        }
*/
Don Gagne's avatar
Don Gagne committed
28
Item {
29 30
    id: _screenTools

Don Gagne's avatar
Don Gagne committed
31
    //-- The point and pixel font size values are computed at runtime
32

dogmaphobic's avatar
dogmaphobic committed
33
    property real defaultFontPointSize:     10
Don Gagne's avatar
Don Gagne committed
34

Ricardo de Almeida Gonzaga's avatar
Ricardo de Almeida Gonzaga committed
35
    /// You can use this property to position ui elements in a screen resolution independent manner. Using fixed positioning values should not
Don Gagne's avatar
Don Gagne committed
36 37
    /// be done. All positioning should be done using anchors or a ratio of the defaultFontPixelHeight and defaultFontPixelWidth values. This way
    /// your ui elements will reposition themselves appropriately on varying screen sizes and resolutions.
dogmaphobic's avatar
dogmaphobic committed
38
    property real defaultFontPixelHeight:   10
Don Gagne's avatar
Don Gagne committed
39

Ricardo de Almeida Gonzaga's avatar
Ricardo de Almeida Gonzaga committed
40
    /// You can use this property to position ui elements in a screen resolution independent manner. Using fixed positioning values should not
Don Gagne's avatar
Don Gagne committed
41 42
    /// be done. All positioning should be done using anchors or a ratio of the defaultFontPixelHeight and defaultFontPixelWidth values. This way
    /// your ui elements will reposition themselves appropriately on varying screen sizes and resolutions.
dogmaphobic's avatar
dogmaphobic committed
43
    property real defaultFontPixelWidth:    10
Don Gagne's avatar
Don Gagne committed
44

dogmaphobic's avatar
dogmaphobic committed
45 46 47
    property real smallFontPointSize:       10
    property real mediumFontPointSize:      10
    property real largeFontPointSize:       10
dogmaphobic's avatar
dogmaphobic committed
48

49
    property real toolbarHeight:            0
Don Gagne's avatar
Don Gagne committed
50

51 52 53
    readonly property real smallFontPointRatio:      0.75
    readonly property real mediumFontPointRatio:     1.25
    readonly property real largeFontPointRatio:      1.5
dogmaphobic's avatar
dogmaphobic committed
54

55
    property real realPixelDensity: {
56
        //-- If a plugin defines it, just use what it tells us
57 58 59
        if(QGroundControl.corePlugin.options.devicePixelDensity != 0) {
            return QGroundControl.corePlugin.options.devicePixelDensity
        }
60 61
        //-- Android is rather unreliable
        if(isAndroid) {
62 63 64 65
            // Lets assume it's unlikely you have a tablet over 300mm wide
            if((Screen.width / Screen.pixelDensity) > 300) {
                return Screen.pixelDensity * 2
            }
66
        }
67
        //-- Let's use what the system tells us
68
        return Screen.pixelDensity
69
    }
70

71 72 73 74 75 76 77
    property bool isAndroid:                        ScreenToolsController.isAndroid
    property bool isiOS:                            ScreenToolsController.isiOS
    property bool isMobile:                         ScreenToolsController.isMobile
    property bool isWindows:                        ScreenToolsController.isWindows
    property bool isDebug:                          ScreenToolsController.isDebug
    property bool isMac:                            ScreenToolsController.isMacOS
    property bool isTinyScreen:                     (Screen.width / realPixelDensity) < 120 // 120mm
78
    property bool isShortScreen:                    ((Screen.height / realPixelDensity) < 120) || (ScreenToolsController.isMobile && ((Screen.height / Screen.width) < 0.6))
79 80 81 82 83
    property bool isHugeScreen:                     (Screen.width / realPixelDensity) >= (23.5 * 25.4) // 27" monitor
    property bool isSerialAvailable:                ScreenToolsController.isSerialAvailable

    readonly property real minTouchMillimeters:     10      ///< Minimum touch size in millimeters
    property real minTouchPixels:                   0       ///< Minimum touch size in pixels
84

85
    // The implicit heights/widths for our custom control set
86 87 88 89 90 91 92
    property real implicitButtonWidth:              Math.round(defaultFontPixelWidth *  (isMobile ? 7.0 : 5.0))
    property real implicitButtonHeight:             Math.round(defaultFontPixelHeight * (isMobile ? 2.0 : 1.6))
    property real implicitCheckBoxHeight:           Math.round(defaultFontPixelHeight * (isMobile ? 2.0 : 1.0))
    property real implicitRadioButtonHeight:        implicitCheckBoxHeight
    property real implicitTextFieldHeight:          Math.round(defaultFontPixelHeight * (isMobile ? 2.0 : 1.6))
    property real implicitComboBoxHeight:           Math.round(defaultFontPixelHeight * (isMobile ? 2.0 : 1.6))
    property real implicitComboBoxWidth:            Math.round(defaultFontPixelWidth *  (isMobile ? 7.0 : 5.0))
93
    property real comboBoxPadding:                  Math.round(defaultFontPixelWidth *  (isShortScreen ? 1 : 0.5))
94
    property real implicitSliderHeight:             isMobile ? Math.max(defaultFontPixelHeight, minTouchPixels) : defaultFontPixelHeight
95 96
    // It's not possible to centralize an even number of pixels, checkBoxIndicatorSize should be an odd number to allow centralization
    property real checkBoxIndicatorSize:            2 * Math.floor(defaultFontPixelHeight * (isMobile ? 1.5 : 1.0) / 2) + 1
97
    property real radioButtonIndicatorSize:         checkBoxIndicatorSize
98

Gus Grubba's avatar
Gus Grubba committed
99 100
    readonly property string normalFontFamily:      ScreenToolsController.normalFontFamily
    readonly property string demiboldFontFamily:    ScreenToolsController.boldFontFamily
101
    readonly property string fixedFontFamily:       ScreenToolsController.fixedFontFamily
102 103 104 105
    /* This mostly works but for some reason, reflowWidths() in SetupView doesn't change size.
       I've disabled (in release builds) until I figure out why. Changes require a restart for now.
    */
    Connections {
106 107
        target: QGroundControl.settingsManager.appSettings.appFontPointSize
        onValueChanged: {
108
            if(ScreenToolsController.isDebug)
109
                _setBasePointSize(QGroundControl.settingsManager.appSettings.appFontPointSize.value)
110 111 112
        }
    }

113 114 115 116
    onRealPixelDensityChanged: {
        _setBasePointSize(defaultFontPointSize)
    }

117 118 119 120
    function printScreenStats() {
        console.log('ScreenTools: Screen.width: ' + Screen.width + ' Screen.height: ' + Screen.height + ' Screen.pixelDensity: ' + Screen.pixelDensity)
    }

Don Gagne's avatar
Don Gagne committed
121
    /// Returns the current x position of the mouse in global screen coordinates.
Don Gagne's avatar
Don Gagne committed
122 123 124 125
    function mouseX() {
        return ScreenToolsController.mouseX()
    }

Don Gagne's avatar
Don Gagne committed
126
    /// Returns the current y position of the mouse in global screen coordinates.
Don Gagne's avatar
Don Gagne committed
127 128 129 130
    function mouseY() {
        return ScreenToolsController.mouseY()
    }

Don Gagne's avatar
Don Gagne committed
131 132
    /// \private
    function _setBasePointSize(pointSize) {
133 134
        _textMeasure.font.pointSize = pointSize
        defaultFontPointSize    = pointSize
135 136
        defaultFontPixelHeight  = Math.round(_textMeasure.fontHeight/2.0)*2
        defaultFontPixelWidth   = Math.round(_textMeasure.fontWidth/2.0)*2
137 138 139
        smallFontPointSize      = defaultFontPointSize  * _screenTools.smallFontPointRatio
        mediumFontPointSize     = defaultFontPointSize  * _screenTools.mediumFontPointRatio
        largeFontPointSize      = defaultFontPointSize  * _screenTools.largeFontPointRatio
140
        minTouchPixels          = Math.round(minTouchMillimeters * realPixelDensity)
141
        if (minTouchPixels / Screen.height > 0.15) {
142
            // If using physical sizing takes up too much of the vertical real estate fall back to font based sizing
143 144
            minTouchPixels      = defaultFontPixelHeight * 3
        }
145
        toolbarHeight           = isMobile ? minTouchPixels : defaultFontPixelHeight * 3
146
        toolbarHeight           = toolbarHeight * QGroundControl.corePlugin.options.toolbarHeightMultiplier
147 148
    }

149 150 151 152 153
    Text {
        id:     _defaultFont
        text:   "X"
    }

Don Gagne's avatar
Don Gagne committed
154
    Text {
155 156
        id:     _textMeasure
        text:   "X"
157
        font.family:    normalFontFamily
158 159 160
        property real   fontWidth:    contentWidth
        property real   fontHeight:   contentHeight
        Component.onCompleted: {
161 162
            var _appFontPointSizeFact = QGroundControl.settingsManager.appSettings.appFontPointSize
            var baseSize = _appFontPointSizeFact.value
163
            //-- If this is the first time (not saved in settings)
164
            if(baseSize < _appFontPointSizeFact.min || baseSize > _appFontPointSizeFact.max) {
165 166
                //-- Init base size base on the platform
                if(ScreenToolsController.isMobile) {
167
                    //-- Check iOS really tiny screens (iPhone 4s/5/5s)
168 169 170 171 172 173
                    if(ScreenToolsController.isiOS) {
                        if(ScreenToolsController.isiOS && Screen.width < 570) {
                            // For iPhone 4s size we don't fit with additional tweaks to fit screen,
                            // we will just drop point size to make things fit. Correct size not yet determined.
                            baseSize = 12;  // This will be lowered in a future pull
                        } else {
174
                            baseSize = 14;
175
                        }
176
                    } else if((Screen.width / realPixelDensity) < 120) {
177 178
                        baseSize = 11;
                    // Other Android
179
                    } else {
180
                        baseSize = 14;
181
                    }
182
                } else {
183
                    baseSize = _defaultFont.font.pointSize;
184
                }
185
                _appFontPointSizeFact._setIgnoreQGCRebootRequired(true)
186
                _appFontPointSizeFact.value = baseSize
187
                _appFontPointSizeFact._setIgnoreQGCRebootRequired(false)
188 189
                //-- Release build doesn't get signal
                if(!ScreenToolsController.isDebug)
Don Gagne's avatar
Don Gagne committed
190
                    _screenTools._setBasePointSize(baseSize);
191
            } else {
192
                //-- Set size saved in settings
Don Gagne's avatar
Don Gagne committed
193
                _screenTools._setBasePointSize(baseSize);
194
            }
195
        }
Don Gagne's avatar
Don Gagne committed
196 197
    }
}