Source

Target

Commits (24)
Showing with 341 additions and 20 deletions
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
......@@ -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
......
......@@ -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)
......
......@@ -200,7 +200,9 @@ QValidator::State QQuickSpinBoxValidator::validate(QString &input, int &pos) con
bool ok = false;
qreal val = locale().toDouble(value, &ok);
if (ok) {
if (state == QValidator::Acceptable) {
if (state == QValidator::Acceptable ||
(state == QValidator::Intermediate && val >= 0 && val <= m_validator.top()) ||
(state == QValidator::Intermediate && val < 0 && val >= m_validator.bottom())) {
const_cast<QQuickSpinBoxValidator *>(this)->setValue(val);
if (input != textFromValue(val))
state = QValidator::Intermediate;
......
......@@ -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
......
......@@ -473,7 +473,7 @@ import QtQuick.Controls.Private 1.0
\endlist
*/
Item {
FocusScope {
id: root
/*! \qmlproperty int StackView::depth
......
......@@ -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
......
......@@ -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
}
}
......
......@@ -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;
}
"
}
}
}
......@@ -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
}
}
......@@ -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
......
src/controls/doc/images/qtquickcontrols-android.png

20.9 KB

src/controls/doc/images/qtquickcontrols-example-gallery-android-dark.png

25.2 KB

src/controls/doc/images/qtquickcontrols-example-gallery-android.png

25.7 KB

src/controls/doc/images/qtquickcontrols-example-gallery-osx.png

23.6 KB

src/controls/doc/images/qtquickcontrols-example-gallery.png

33.3 KB

......@@ -27,5 +27,6 @@
/*!
\group applicationwindow
\brief A window adding convenience for positioning items.
\title Application Window
*/
......@@ -27,5 +27,6 @@
/*!
\group controls
\brief Buttons and UI Controls.
\title Buttons and Controls
*/
......@@ -27,5 +27,6 @@
/*!
\group menus
\brief How to create a menu bar.
\title Menus
*/
......@@ -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}.
......