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

3
import QtQuick          2.12
4
import QtQuick.Controls 1.2
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
34
    property real platformFontPointSize:    10
Don Gagne's avatar
Don Gagne committed
35

Ricardo de Almeida Gonzaga's avatar
Ricardo de Almeida Gonzaga committed
36
    /// 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
37 38
    /// 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
39
    property real defaultFontPixelHeight:   10
Don Gagne's avatar
Don Gagne committed
40

Ricardo de Almeida Gonzaga's avatar
Ricardo de Almeida Gonzaga committed
41
    /// 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
42 43
    /// 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
44
    property real defaultFontPixelWidth:    10
Don Gagne's avatar
Don Gagne committed
45

46 47 48
    /// QFontMetrics::descent for default font at default point size
    property real defaultFontDescent:       0

DoinLakeFlyer's avatar
DoinLakeFlyer committed
49 50 51
    /// The default amount of space in between controls in a dialog
    property real defaultDialogControlSpacing: defaultFontPixelHeight / 2

dogmaphobic's avatar
dogmaphobic committed
52 53 54
    property real smallFontPointSize:       10
    property real mediumFontPointSize:      10
    property real largeFontPointSize:       10
dogmaphobic's avatar
dogmaphobic committed
55

56
    property real toolbarHeight:            0
Don Gagne's avatar
Don Gagne committed
57

58 59 60
    readonly property real smallFontPointRatio:      0.75
    readonly property real mediumFontPointRatio:     1.25
    readonly property real largeFontPointRatio:      1.5
dogmaphobic's avatar
dogmaphobic committed
61

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

78 79 80 81 82 83 84
    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
85
    property bool isShortScreen:                    ((Screen.height / realPixelDensity) < 120) || (ScreenToolsController.isMobile && ((Screen.height / Screen.width) < 0.6))
86 87 88 89 90
    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
91

92
    // The implicit heights/widths for our custom control set
93 94 95 96 97 98 99
    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))
DonLakeFlyer's avatar
DonLakeFlyer committed
100
    property real comboBoxPadding:                  defaultFontPixelWidth
101
    property real implicitSliderHeight:             isMobile ? Math.max(defaultFontPixelHeight, minTouchPixels) : defaultFontPixelHeight
102 103
    // 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
104
    property real radioButtonIndicatorSize:         checkBoxIndicatorSize
105

Gus Grubba's avatar
Gus Grubba committed
106 107
    readonly property string normalFontFamily:      ScreenToolsController.normalFontFamily
    readonly property string demiboldFontFamily:    ScreenToolsController.boldFontFamily
108
    readonly property string fixedFontFamily:       ScreenToolsController.fixedFontFamily
109 110 111 112
    /* 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 {
113 114
        target: QGroundControl.settingsManager.appSettings.appFontPointSize
        onValueChanged: {
115
            _setBasePointSize(QGroundControl.settingsManager.appSettings.appFontPointSize.value)
116 117 118
        }
    }

119 120 121 122
    onRealPixelDensityChanged: {
        _setBasePointSize(defaultFontPointSize)
    }

123 124 125 126
    function printScreenStats() {
        console.log('ScreenTools: Screen.width: ' + Screen.width + ' Screen.height: ' + Screen.height + ' Screen.pixelDensity: ' + Screen.pixelDensity)
    }

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

Don Gagne's avatar
Don Gagne committed
132
    /// Returns the current y position of the mouse in global screen coordinates.
Don Gagne's avatar
Don Gagne committed
133 134 135 136
    function mouseY() {
        return ScreenToolsController.mouseY()
    }

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

156 157 158 159 160
    Text {
        id:     _defaultFont
        text:   "X"
    }

Don Gagne's avatar
Don Gagne committed
161
    Text {
162 163
        id:     _textMeasure
        text:   "X"
164
        font.family:    normalFontFamily
165 166 167
        property real   fontWidth:    contentWidth
        property real   fontHeight:   contentHeight
        Component.onCompleted: {
168 169 170 171 172 173 174 175
            //-- First, compute platform, default size
            if(ScreenToolsController.isMobile) {
                //-- Check iOS really tiny screens (iPhone 4s/5/5s)
                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.
                        platformFontPointSize = 12;  // This will be lowered in a future pull
176
                    } else {
177
                        platformFontPointSize = 14;
178
                    }
179 180 181
                } else if((Screen.width / realPixelDensity) < 120) {
                    platformFontPointSize = 11;
                // Other Android
182
                } else {
183
                    platformFontPointSize = 14;
184 185
                }
            } else {
186 187 188 189 190 191 192 193 194
                platformFontPointSize = _defaultFont.font.pointSize;
            }
            //-- See if we are using a custom size
            var _appFontPointSizeFact = QGroundControl.settingsManager.appSettings.appFontPointSize
            var baseSize = _appFontPointSizeFact.value
            //-- Sanity check
            if(baseSize < _appFontPointSizeFact.min || baseSize > _appFontPointSizeFact.max) {
                baseSize = platformFontPointSize;
                _appFontPointSizeFact.value = baseSize
195
            }
196 197
            //-- Set size saved in settings
            _screenTools._setBasePointSize(baseSize);
198
        }
Don Gagne's avatar
Don Gagne committed
199 200
    }
}