ScreenTools.qml 9.51 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

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

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

56
    property real realPixelDensity:  QGroundControl.corePlugin.options.devicePixelDensity != 0 ? QGroundControl.corePlugin.options.devicePixelDensity : Screen.pixelDensity
57 58 59 60 61 62 63 64 65 66 67 68 69 70

    property real realPixelRatio: {
        //-- If a plugin defines it, just use what it tells us
        if (QGroundControl.corePlugin.options.devicePixelRatio != 0)
            return QGroundControl.corePlugin.options.devicePixelRatio
        //-- Mobile is rather unreliable. They all return 1 for Screen.devicePixelRatio.
        if(isMobile) {
            //   Lets assume it's unlikely you have a tablet over 300mm wide
            if((Screen.width / Screen.pixelDensity * Screen.devicePixelRatio) > 300)
                return 2
        }
        //-- Use whatever the system tells us
        return Screen.devicePixelRatio
    }
71

Don Gagne's avatar
Don Gagne committed
72 73 74
    property bool isAndroid:        ScreenToolsController.isAndroid
    property bool isiOS:            ScreenToolsController.isiOS
    property bool isMobile:         ScreenToolsController.isMobile
Gus Grubba's avatar
Gus Grubba committed
75
    property bool isWindows:        ScreenToolsController.isWindows
76
    property bool isDebug:          ScreenToolsController.isDebug
77
    property bool isTinyScreen:     (Screen.width / realPixelDensity) < 120 // 120mm
78
    property bool isShortScreen:    ScreenToolsController.isMobile && ((Screen.height / Screen.width) < 0.6) // Nexus 7 for example
79
    property bool isHugeScreen:     Screen.width >= 1920*2
Don Gagne's avatar
Don Gagne committed
80

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

84
    // The implicit heights/widths for our custom control set
85 86 87 88 89 90 91 92 93 94
    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))
    property real implicitSliderHeight:             isMobile ? Math.max(defaultFontPixelHeight, minTouchPixels) : defaultFontPixelHeight
    property real checkBoxIndicatorSize:            Math.round(defaultFontPixelHeight * (isMobile ? 1.5 : 1.0))
    property real radioButtonIndicatorSize:         checkBoxIndicatorSize
95

96 97
    readonly property string normalFontFamily:      "opensans"
    readonly property string demiboldFontFamily:    "opensans-demibold"
98
    readonly property string fixedFontFamily:       ScreenToolsController.fixedFontFamily
99 100 101 102
    /* 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 {
103 104
        target: QGroundControl.settingsManager.appSettings.appFontPointSize
        onValueChanged: {
105
            if(ScreenToolsController.isDebug)
106
                _setBasePointSize(QGroundControl.settingsManager.appSettings.appFontPointSize.value)
107 108 109
        }
    }

110 111 112 113 114 115 116 117
    onRealPixelDensityChanged: {
        _setBasePointSize(defaultFontPointSize)
    }

    onRealPixelRatioChanged: {
        _setBasePointSize(defaultFontPointSize)
    }

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

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

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

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

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

Don Gagne's avatar
Don Gagne committed
155
    Text {
156 157
        id:     _textMeasure
        text:   "X"
158
        font.family:    normalFontFamily
159 160 161
        property real   fontWidth:    contentWidth
        property real   fontHeight:   contentHeight
        Component.onCompleted: {
162 163
            var _appFontPointSizeFact = QGroundControl.settingsManager.appSettings.appFontPointSize
            var baseSize = _appFontPointSizeFact.value
164
            //-- If this is the first time (not saved in settings)
165
            if(baseSize < _appFontPointSizeFact.min || baseSize > _appFontPointSizeFact.max) {
166 167
                //-- Init base size base on the platform
                if(ScreenToolsController.isMobile) {
168
                    //-- Check iOS really tiny screens (iPhone 4s/5/5s)
169 170 171 172 173 174
                    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 {
175
                            baseSize = 14;
176
                        }
177
                    } else if((Screen.width / realPixelDensity) < 120) {
178 179
                        baseSize = 11;
                    // Other Android
180
                    } else {
181
                        baseSize = 14;
182
                    }
183
                } else {
184
                    baseSize = _defaultFont.font.pointSize;
185
                }
186
                _appFontPointSizeFact.value = baseSize
187 188
                //-- Release build doesn't get signal
                if(!ScreenToolsController.isDebug)
Don Gagne's avatar
Don Gagne committed
189
                    _screenTools._setBasePointSize(baseSize);
190
            } else {
191
                //-- Set size saved in settings
Don Gagne's avatar
Don Gagne committed
192
                _screenTools._setBasePointSize(baseSize);
193
            }
194
        }
Don Gagne's avatar
Don Gagne committed
195 196
    }
}