diff --git a/dist/changes-5.4.0 b/dist/changes-5.4.0 new file mode 100644 index 0000000000000000000000000000000000000000..abbd528182a569b4e5888207fad27faf77fee9a7 --- /dev/null +++ b/dist/changes-5.4.0 @@ -0,0 +1,191 @@ +Qt 5.4 introduces many new features and improvements as well as bugfixes +over the 5.3.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.4 + +The Qt version 5.4 series is binary compatible with the 5.3.x series. +Applications compiled for 5.3 will continue to run with 5.4. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + + - Introduced a native Android style + - Added text selection handles to all editable controls on Android and iOS + - Added translation support to dialogs + - Made all controls and dialogs use native text rendering on mobile + platforms + +**************************************************************************** +* Examples * +**************************************************************************** + + - Revised the Qt Quick Controls Gallery and Table View examples to be more + mobile friendly + - Removed the Split View example - a similar snippet is available in the + detailed description section of SplitView documentation + - Made the Styles tab of the former Gallery example a standalone example + +**************************************************************************** +* Controls * +**************************************************************************** + + - ApplicationWindow: + * Introduced ApplicationWindowStyle for styling the window background + + - Button: + * Added support for mnemonics + + - Calendar: + * Added navigationBarVisible property + * Added pressAndHold(date) signal + + - CheckBox: + * Added support for mnemonics + + - ComboBox: + * Added inputMethodComposing property + + - Menu: + * Fixed key navigation on Windows + + - RadioButton: + * Added support for mnemonics + + - ScrollView: + * Added horizontalScrollBarPolicy and verticalScrollBarPolicy properties + + - Slider: + * [QTBUG-39099] Fixed the step size used on increase/decrease key press + * Made the hovered property follow the hovered state of the handle + instead of the whole groove + + - SpinBox: + * Added inputMethodComposing property + + - SplitView: + * [QTBUG-35281] Added addItem() method + + - StackView: + * Changed the linear slide with a smooth animation + + - Switch: + * Added pressed property + * Added clicked() signal + + - TableView: + * Added pressAndHold(int row) signal + * Fixed support for Keys-attached property + * [QTBUG-41444] Fixed leaking of key events + * Made focused and selected rows to be raised above other rows + + - TabView: + * [QTBUG-38425] Added contentItem property + + - TextArea: + * [QTBUG-38324] Added contentWidth and contentHeight properties + * Added cursorRectangle property + * Added inputMethodComposing property + * Made selection persistent + + - TextField: + * Added cursorRectangle property + * Added selectByMouse property + * Added inputMethodComposing property + * [QTBUG-38282] Added support for sticky VKB with Qt.ImhMultiLine + + - ToolButton: + * Added support for mnemonics + +**************************************************************************** +* Dialogs * +**************************************************************************** + + - Fixed deployment dependencies + - [QTBUG-41844] Fixed centering of dialogs over parent windows + - [QTBUG-41734] Fixed several sizing problems + - [QTBUG-38578] Fixed dynamically created dialogs + + - I18n: + * Added translation support + + - ColorDialog: + * Fixed rendering on non-windowing platforms + + - FileDialog: + * Fixed array key navigation to always navigate the file list + * Replaced icons with scalable ones from an icon font + * [QTBUG-39231] Added sideBarVisible property and button + * [QTBUG-39435] Fixed Save As and directory-choosing scenarios + + - FontDialog: + * [QTBUG-39365] Added support for key navigation + + - Dialog: + * Focus is given to the contentItem automatically + +**************************************************************************** +* Layouts * +**************************************************************************** + + - Increased the default spacing on mobile platforms + - [QTBUG-39045] Fixed a crash when removing children from hidden layouts + +**************************************************************************** +* Styles * +**************************************************************************** + + - Introduced ApplicationWindowStyle + + - ComboBoxStyle: + * Added font property + * Added textColor, selectionColor and selectedTextColor properties + + - MenuBarStyle: + * Added font property + + - MenuStyle: + * Added font property + * Added styleData.pressed context property + + - SpinBoxStyle: + * Added font property + + - TableViewStyle: + * Added styleData.pressed context property for itemDelegate & rowDelegate + * Added styleData.hasActiveFocus context property for itemDelegate + + - TabViewStyle: + * Added styleData.pressed context property for tab + + - ToolBarStyle: + * Added menuButton property + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + - Introduced a native Android style + - [QTBUG-38934] Added text selection handles to all editable controls + +iOS +--- + - [QTBUG-38934] Added text selection handles to all editable controls + - Made ComboBox open a native selection menu + - Added edit menu (cut, copy, paste) support to all editable controls + - Added text cursor and scroll bar styling + +Windows +------- + - Fixed Menu key navigation diff --git a/src/controls/Private/ScrollBar.qml b/src/controls/Private/ScrollBar.qml index 82750412197f2f267cfa3de840282032dc0195fc..3bd0a16405c2ce6a264201f69d91c1c1c7763492 100644 --- a/src/controls/Private/ScrollBar.qml +++ b/src/controls/Private/ScrollBar.qml @@ -102,7 +102,7 @@ Item { onExited: if (!pressed) __panel.activeControl = "none" onMouseXChanged: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY) hoverEnabled: !Settings.hasTouchScreen - enabled: !Settings.hasTouchScreen // TODO: touch on desktop? + enabled: !Settings.isMobile || !Settings.hasTouchScreen // ### Not ideal, but will usually behave as expected... preventStealing: true property var pressedX property var pressedY diff --git a/src/controls/Private/TextInputWithHandles.qml b/src/controls/Private/TextInputWithHandles.qml index 726b6863e202421d2adb7c4fed80557e28d9a0c2..75ca947f7619eaa04e23534aa03944806588f639 100644 --- a/src/controls/Private/TextInputWithHandles.qml +++ b/src/controls/Private/TextInputWithHandles.qml @@ -54,7 +54,7 @@ TextInput { property alias editMenu: editMenu cursorDelegate: __style && __style.__cursorDelegate ? __style.__cursorDelegate : null - selectByMouse: control.selectByMouse && (!cursorHandle.delegate || !selectionHandle.delegate) + selectByMouse: control.selectByMouse && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate) // force re-evaluation when selection moves: // - cursorRectangle changes => content scrolled @@ -137,7 +137,7 @@ TextInput { editor: input parent: control control: input.control - active: control.selectByMouse + active: control.selectByMouse && Settings.isMobile maximum: cursorHandle.position - 1 property var mappedPos: parent.mapFromItem(editor, editor.selectionRectangle.x, editor.selectionRectangle.y) @@ -163,7 +163,7 @@ TextInput { editor: input parent: control control: input.control - active: control.selectByMouse + active: control.selectByMouse && Settings.isMobile minimum: input.hasSelection ? selectionHandle.position + 1 : -1 property var mappedPos: parent.mapFromItem(editor, editor.cursorRectangle.x, editor.cursorRectangle.y) diff --git a/src/controls/Slider.qml b/src/controls/Slider.qml index 89c1e7236daa98183788ce92c6253a35033c4fe8..d0644b4ccb6c03068ccd8332b9c239676a16a2ca 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -167,6 +167,8 @@ Control { \l stepSize property. The default value is \c false. + + \note This property may be ignored on some platforms when using the native style (e.g. Android). */ property bool tickmarksEnabled: false diff --git a/src/controls/Styles/Android/SwitchStyle.qml b/src/controls/Styles/Android/SwitchStyle.qml index 4c36c918e6de467e6466485de9c4f62c7e0fdb1c..6e9260c352b99a2a7b4138ca492d688abcf5f03a 100644 --- a/src/controls/Styles/Android/SwitchStyle.qml +++ b/src/controls/Styles/Android/SwitchStyle.qml @@ -79,18 +79,26 @@ SwitchStyle { Item { id: thumb + readonly property bool hideText: AndroidStyle.styleDef.switchStyle.Switch_showText === false + x: control.checked ? max : min - FontMetrics { - id: metrics + TextMetrics { + id: onMetrics + font: label.font + text: panel.styleDef.Switch_textOn + } + + TextMetrics { + id: offMetrics font: label.font + text: panel.styleDef.Switch_textOff } - readonly property real maxTextWidth: Math.max(metrics.boundingRect(panel.styleDef.Switch_textOn).width, - metrics.boundingRect(panel.styleDef.Switch_textOff).width) + readonly property real maxTextWidth: Math.max(onMetrics.width, offMetrics.width) implicitWidth: Math.max(loader.implicitWidth, maxTextWidth + 2 * panel.styleDef.Switch_thumbTextPadding) - implicitHeight: Math.max(loader.implicitHeight, metrics.height) + implicitHeight: Math.max(loader.implicitHeight, onMetrics.height, offMetrics.height) anchors.top: parent.top anchors.bottom: parent.bottom @@ -120,6 +128,7 @@ SwitchStyle { LabelStyle { id: label + visible: !thumb.hideText text: control.checked ? panel.styleDef.Switch_textOn : panel.styleDef.Switch_textOff pressed: control.pressed diff --git a/src/controls/Styles/Android/drawables/AnimationDrawable.qml b/src/controls/Styles/Android/drawables/AnimationDrawable.qml index a522bfa7ce509a3f222859ae8196106f7c123810..12d576ff421f4fbcfee1b237844ba01b9febc0d5 100644 --- a/src/controls/Styles/Android/drawables/AnimationDrawable.qml +++ b/src/controls/Styles/Android/drawables/AnimationDrawable.qml @@ -49,14 +49,17 @@ Drawable { property int currentFrame: 0 readonly property int frameCount: styleDef.frames ? styleDef.frames.length : 0 readonly property var frameDef: styleDef.frames ? styleDef.frames[currentFrame] : undefined + readonly property alias running: timer.running + property bool oneshot: styleDef.oneshot Timer { + id: timer repeat: true running: root.frameCount && root.visible && Qt.application.active interval: root.frameDef ? root.frameDef.duration : 0 onTriggered: { var frame = root.currentFrame + 1 - repeat = !root.styleDef.oneshot || frame < root.frameCount - 1 + repeat = !root.oneshot || frame < root.frameCount - 1 root.currentFrame = frame % root.frameCount } } diff --git a/src/controls/Styles/Android/drawables/ImageDrawable.qml b/src/controls/Styles/Android/drawables/ImageDrawable.qml index 1e71a389a36ff23d21b3a092c17d965d964350f2..4b41b2f21c4e218c27259dca77f6df4a7a2304ee 100644 --- a/src/controls/Styles/Android/drawables/ImageDrawable.qml +++ b/src/controls/Styles/Android/drawables/ImageDrawable.qml @@ -52,5 +52,33 @@ Drawable { anchors.fill: parent fillMode: Image.TileHorizontally source: AndroidStyle.filePath(styleDef.path) + + layer.enabled: !!styleDef && !!styleDef.tintList + layer.effect: ShaderEffect { + property variant source: image + property color color: AndroidStyle.colorValue(styleDef.tintList[state]) + state: { + var states = [] + if (pressed) states.push("PRESSED") + if (enabled) states.push("ENABLED") + if (focused) states.push("FOCUSED") + if (selected) states.push("SELECTED") + if (window_focused) states.push("WINDOW_FOCUSED") + if (!states.length) + states.push("EMPTY") + return states.join("_") + "_STATE_SET" + } + // QtGraphicalEffects/ColorOverlay: + fragmentShader: " + varying mediump vec2 qt_TexCoord0; + uniform highp float qt_Opacity; + uniform lowp sampler2D source; + uniform highp vec4 color; + void main() { + highp vec4 pixelColor = texture2D(source, qt_TexCoord0); + gl_FragColor = vec4(mix(pixelColor.rgb/max(pixelColor.a, 0.00390625), color.rgb/max(color.a, 0.00390625), color.a) * pixelColor.a, pixelColor.a) * qt_Opacity; + } + " + } } } diff --git a/src/controls/Styles/Android/drawables/StateDrawable.qml b/src/controls/Styles/Android/drawables/StateDrawable.qml index d446542d95ebe221fd6564cc62b0c36045fcf782..862ab9ae64c3c2a0914819bb446e7319cc302b8a 100644 --- a/src/controls/Styles/Android/drawables/StateDrawable.qml +++ b/src/controls/Styles/Android/drawables/StateDrawable.qml @@ -46,10 +46,12 @@ Drawable { implicitWidth: Math.max(loader.implicitWidth, styleDef.width || 0) implicitHeight: Math.max(loader.implicitHeight, styleDef.height || 0) + property int prevMatch: 0 + DrawableLoader { id: loader anchors.fill: parent - styleDef: bestStateMatch() + visible: !animation.active focused: root.focused pressed: root.pressed checked: root.checked @@ -65,17 +67,70 @@ Drawable { clippables: root.clippables } - function bestStateMatch () { + Loader { + id: animation + property var animDef + active: false + anchors.fill: parent + sourceComponent: AnimationDrawable { + anchors.fill: parent + styleDef: animDef + focused: root.focused + pressed: root.pressed + checked: root.checked + selected: root.selected + accelerated: root.accelerated + window_focused: root.window_focused + index: root.index + level: root.level + levelId: root.levelId + orientations: root.orientations + duration: root.duration + excludes: root.excludes + clippables: root.clippables + + oneshot: true + onRunningChanged: if (!running) animation.active = false + } + } + + onStyleDefChanged: resolveState() + Component.onCompleted: resolveState() + + // In order to be able to find appropriate transition paths between + // various states, the following states must be allowed to change in + // batches. For example, button-like controls could have a transition + // path from pressed+checked to unpressed+unchecked. We must let both + // properties change before we try to find the transition path. + onEnabledChanged: resolver.start() + onFocusedChanged: resolver.start() + onPressedChanged: resolver.start() + onCheckedChanged: resolver.start() + onSelectedChanged: resolver.start() + onAcceleratedChanged: resolver.start() + onWindow_focusedChanged: resolver.start() + + Timer { + id: resolver + interval: 15 + onTriggered: resolveState() + } + + function resolveState () { if (styleDef && styleDef.stateslist) { var bestMatch = 0 var highestScore = -1 var stateslist = styleDef.stateslist + var transitions = [] for (var i = 0; i < stateslist.length; ++i) { var score = 0 var state = stateslist[i] + if (state.transition) + transitions.push(i) + for (var s in state.states) { if (s === "pressed") score += (pressed === state.states[s]) ? 1 : -10 @@ -98,8 +153,21 @@ Drawable { highestScore = score } } - return stateslist[bestMatch].drawable + + if (prevMatch != bestMatch) { + for (var t = 0; t < transitions.length; ++t) { + var transition = stateslist[transitions[t]].transition + if ((transition.from == prevMatch && transition.to == bestMatch) || + (transition.reverse && transition.from == bestMatch && transition.to == prevMatch)) { + animation.animDef = stateslist[transitions[t]].drawable + animation.active = true + break + } + } + prevMatch = bestMatch + } + + loader.styleDef = stateslist[bestMatch].drawable } - return undefined } } diff --git a/src/controls/TextArea.qml b/src/controls/TextArea.qml index 691bf13e1f5b43076fc530ad4df1cbd94b2d4356..1c19a300f83b2151f967e5bdcb60f8a6895444d9 100644 --- a/src/controls/TextArea.qml +++ b/src/controls/TextArea.qml @@ -770,7 +770,7 @@ ScrollView { wrapMode: TextEdit.WordWrap textMargin: __style && __style.textMargin !== undefined ? __style.textMargin : 4 - selectByMouse: area.selectByMouse && (!cursorHandle.delegate || !selectionHandle.delegate) + selectByMouse: area.selectByMouse && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate) readOnly: false Keys.forwardTo: area @@ -885,7 +885,7 @@ ScrollView { control: area z: 1 // above scrollbars parent: Qt.platform.os === "ios" ? editor : __scroller // no clip - active: area.selectByMouse + active: area.selectByMouse && Settings.isMobile delegate: __style.__selectionHandle maximum: cursorHandle.position - 1 @@ -921,7 +921,7 @@ ScrollView { control: area z: 1 // above scrollbars parent: Qt.platform.os === "ios" ? editor : __scroller // no clip - active: area.selectByMouse + active: area.selectByMouse && Settings.isMobile delegate: __style.__cursorHandle minimum: edit.hasSelection ? selectionHandle.position + 1 : -1 diff --git a/src/controls/doc/images/qtquickcontrols-android.png b/src/controls/doc/images/qtquickcontrols-android.png deleted file mode 100644 index 8877c09cd2af74bb82bbc51135fa6a4d27d04ed1..0000000000000000000000000000000000000000 Binary files a/src/controls/doc/images/qtquickcontrols-android.png and /dev/null differ diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery-android.png b/src/controls/doc/images/qtquickcontrols-example-gallery-android.png new file mode 100644 index 0000000000000000000000000000000000000000..11ba2cc0c6324e2e3a9d135895f42344875e6ad6 Binary files /dev/null and b/src/controls/doc/images/qtquickcontrols-example-gallery-android.png differ diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery-osx.png b/src/controls/doc/images/qtquickcontrols-example-gallery-osx.png new file mode 100644 index 0000000000000000000000000000000000000000..492dc36e5a206d0f6774813dcabb9703d3396381 Binary files /dev/null and b/src/controls/doc/images/qtquickcontrols-example-gallery-osx.png differ diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery.png b/src/controls/doc/images/qtquickcontrols-example-gallery.png deleted file mode 100644 index a88eab793eabb3f62b178e1a4d209c018f6e54e2..0000000000000000000000000000000000000000 Binary files a/src/controls/doc/images/qtquickcontrols-example-gallery.png and /dev/null differ diff --git a/src/controls/doc/src/applicationwindow.qdoc b/src/controls/doc/src/applicationwindow.qdoc index f9e2d97fe10f0b1761276efb1d57b9c1b4e4013c..45b66e30bb13ab49c55a40f02443787249127191 100644 --- a/src/controls/doc/src/applicationwindow.qdoc +++ b/src/controls/doc/src/applicationwindow.qdoc @@ -27,5 +27,6 @@ /*! \group applicationwindow + \brief A window adding convenience for positioning items. \title Application Window */ diff --git a/src/controls/doc/src/controls.qdoc b/src/controls/doc/src/controls.qdoc index d1e4d0524ba8a4f2f51a530e7145c470a9577ce5..fa2a800cadf80d14c3c7f2aaed151f56cee82af0 100644 --- a/src/controls/doc/src/controls.qdoc +++ b/src/controls/doc/src/controls.qdoc @@ -27,5 +27,6 @@ /*! \group controls + \brief Buttons and UI Controls. \title Buttons and Controls */ diff --git a/src/controls/doc/src/menus.qdoc b/src/controls/doc/src/menus.qdoc index 75f5ba2c69107c0a07eb4e2d8e7149cbfef5879b..8a6a8032cb59c5adf8e47bacb3cedce5d4151369 100644 --- a/src/controls/doc/src/menus.qdoc +++ b/src/controls/doc/src/menus.qdoc @@ -27,5 +27,6 @@ /*! \group menus + \brief How to create a menu bar. \title Menus */ diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index 4e6fccb08696b0efd2aa60fe6bb4348f5a5c93e6..29c8d2b55241eedaec8a5e1dc46473e3ec031b71 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -40,7 +40,22 @@ \title Qt Quick Controls - Gallery \ingroup qtquickcontrols_examples \brief A collection of components for a classic desktop-style UI. - \image qtquickcontrols-example-gallery.png + + \raw HTML + <div class="table"><table style="background:transparent; border:0px"> + <tr><td style="border:0px"> + \endraw + \image qtquickcontrols-example-gallery-osx.png + \caption OS X + \raw HTML + </td><td style="border:0px"> + \endraw + \image qtquickcontrols-example-gallery-android.png + \caption Android - Nexus 5 + \raw HTML + </td></tr> + </table></div> + \endraw This example project demonstrates the various UI components provided by \l{Qt Quick Controls}. diff --git a/src/controls/doc/src/qtquickcontrols-overview.qdoc b/src/controls/doc/src/qtquickcontrols-overview.qdoc index 09f5318d0f95cd2201764b38be285a08801cfbe1..651edc66dd2e1fb1184232c2ea99786efd892425 100644 --- a/src/controls/doc/src/qtquickcontrols-overview.qdoc +++ b/src/controls/doc/src/qtquickcontrols-overview.qdoc @@ -61,7 +61,7 @@ For an overview of the controls provided by \l{Qt Quick Controls}, you can look at the \l{Qt Quick Controls - Gallery}{Gallery} example. - \image qtquickcontrols-example-gallery.png + \image qtquickcontrols-example-gallery-osx.png \section1 Setting Up Controls from C++ diff --git a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc index fdf64cf5a325520e68e67e6ffe2f9b8ed0281d25..2d8524454c7d28c5ca24e6affc46ef5afc3c7e1d 100644 --- a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc +++ b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc @@ -37,7 +37,7 @@ Qt 5.4 introduced a native Android style for Qt Quick Controls. - \image qtquickcontrols-android.png + \image qtquickcontrols-example-gallery-android.png \note The Android style requires Android 3.0 (API level 11) or later. diff --git a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc index 74c750a5a97f90011cfe27e79edf0ffb56dfb2c4..7548d7429e6a340e42ce1621638d5c765bd93427 100644 --- a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc +++ b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc @@ -40,6 +40,7 @@ /*! \group controlsstyling + \brief Provides custom styling for Buttons and UI Controls. \title Styling Controls */ diff --git a/src/controls/qquickmenu.cpp b/src/controls/qquickmenu.cpp index c2e7bc30ab422e80131179e9be50486ebad23c26..1a125135c0ab4b5de9657dedcc05a1601de44e5a 100644 --- a/src/controls/qquickmenu.cpp +++ b/src/controls/qquickmenu.cpp @@ -414,6 +414,7 @@ void QQuickMenu::__popup(const QRectF &targetRect, int atItemIndex, MenuType men } globalTargetRect = visualItem()->mapRectToScene(globalTargetRect); } + globalTargetRect.translate(renderOffset); m_platformMenu->setMenuType(QPlatformMenu::MenuType(menuType)); m_platformMenu->showPopup(parentWindow, globalTargetRect.toRect(), atItem ? atItem->platformItem() : 0); } else { diff --git a/src/dialogs/doc/src/qtquickdialogs-index.qdoc b/src/dialogs/doc/src/qtquickdialogs-index.qdoc index 5a1223b04dbd13f334b8b4a3e3952d2181b95e7b..ab0bc31a184ac0c298d3fdbf220978a1217471fe 100644 --- a/src/dialogs/doc/src/qtquickdialogs-index.qdoc +++ b/src/dialogs/doc/src/qtquickdialogs-index.qdoc @@ -27,6 +27,7 @@ /*! \group dialogs + \brief Dialog components \title Dialogs */