Source

Target

Commits (6)
Showing with 166 additions and 53 deletions
...@@ -63,7 +63,6 @@ Item { ...@@ -63,7 +63,6 @@ Item {
Button { Button {
text: "Push me" text: "Push me"
style: ButtonStyle { } style: ButtonStyle { }
onClicked: colorDialog.open()
implicitWidth: columnWidth implicitWidth: columnWidth
} }
Button { Button {
......
...@@ -197,6 +197,14 @@ Control { ...@@ -197,6 +197,14 @@ Control {
anchors.horizontalCenter: !__horizontal ? parent.horizontalCenter : undefined anchors.horizontalCenter: !__horizontal ? parent.horizontalCenter : undefined
width: __panel.handleWidth width: __panel.handleWidth
height: __panel.handleHeight height: __panel.handleHeight
function updatePos() {
if (updateValueWhileDragging && !mouseArea.drag.active)
range.position = __horizontal ? x : y
}
onXChanged: updatePos();
onYChanged: updatePos();
} }
MouseArea { MouseArea {
...@@ -247,14 +255,6 @@ Control { ...@@ -247,14 +255,6 @@ Control {
} }
} }
// Range position normally follows handle, except when
// 'updateValueWhileDragging' is false.
Binding {
when: updateValueWhileDragging && !mouseArea.drag.active
target: range
property: "position"
value: __horizontal ? fakeHandle.x : fakeHandle.y
}
// During the drag, we simply ignore the position set from the range, this // During the drag, we simply ignore the position set from the range, this
// means that setting a value while dragging will not "interrupt" the // means that setting a value while dragging will not "interrupt" the
......
...@@ -470,7 +470,7 @@ ScrollView { ...@@ -470,7 +470,7 @@ ScrollView {
// Fills extra rows with alternate color // Fills extra rows with alternate color
Column { Column {
id: rowfiller id: rowfiller
property int rowHeight: listView.contentHeight/count property int rowHeight: count ? listView.contentHeight/count : height
property int paddedRowCount: height/rowHeight property int paddedRowCount: height/rowHeight
property int count: listView.count property int count: listView.count
y: listView.contentHeight y: listView.contentHeight
......
...@@ -608,6 +608,9 @@ ScrollView { ...@@ -608,6 +608,9 @@ ScrollView {
*/ */
property alias backgroundColor: colorRect.color property alias backgroundColor: colorRect.color
/*! \internal */
default property alias data: area.data
/*! \internal */ /*! \internal */
property int __documentMargin: 4 property int __documentMargin: 4
......
...@@ -29,19 +29,16 @@ ...@@ -29,19 +29,16 @@
\page qtquickcontrols-index.html \page qtquickcontrols-index.html
\title Qt Quick Controls \title Qt Quick Controls
\brief The Qt Quick Controls module provides a set of reusable Qt Quick UI components. \brief The Qt Quick Controls module provides a set of UI controls for Qt Quick.
The Qt Quick Controls module provides a set of reusable UI components to create The Qt Quick Controls module provides a set of controls that can be used to
classic desktop-style user interfaces using Qt Quick. build complete interfaces in Qt Quick.
The module is new in Qt 5.1 and requires \l{Qt Quick} 2.1. The module is new in Qt 5.1 and requires \l{Qt Quick} 2.1.
\note \l{Qt Quick Layouts} can be used to arrange Qt Quick Controls in a user interface. \image qtquickcontrols-example-gallery.png
\note The current focus is on desktop, but in the long term Qt Quick Controls \section1 Getting Started
are expected to be supported on mobile platforms too.
\section1 Getting started
The QML types can be imported into your application using the following import statement in your \c {.qml} file. The QML types can be imported into your application using the following import statement in your \c {.qml} file.
...@@ -49,6 +46,47 @@ ...@@ -49,6 +46,47 @@
import QtQuick.Controls 1.0 import QtQuick.Controls 1.0
\endcode \endcode
A basic example of a QML file that makes use of controls is shown here:
\code
import QtQuick.Controls 1.0
ApplicationWindow {
title: "My Application"
Button {
text: "Push Me"
anchors.centerIn: parent
}
}
\endcode
\section2 Setting Up Controls from C++
While we traditionally have used a QQuickView window to display QML files
in a C++ application, doing this means you can only set window properties from C++.
With Qt Quick Controls, declare an ApplicationWindow as the root item of your application and launch it by using the
QQmlApplicationEngine instead. This ensures that you can control top level window properties from QML.
A basic example of a source file that makes use of controls is shown here:
\code
#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine("main.qml");
return app.exec();
}
\endcode
\note We are using QApplication and not QGuiApplication in this example.
Though you can use QGuiApplication instead, doing this will eliminate platform-dependent styling.
This is because it is relying on the widget module to provide the native look and feel.
\section1 Application Window \section1 Application Window
Components used to describe the basic window properties of an application. Components used to describe the basic window properties of an application.
\annotatedlist applicationwindow \annotatedlist applicationwindow
......
...@@ -98,14 +98,62 @@ static inline void combineHints(qreal &current, qreal fallbackHint) ...@@ -98,14 +98,62 @@ static inline void combineHints(qreal &current, qreal fallbackHint)
current = fallbackHint; current = fallbackHint;
} }
static inline void combineSize(QSizeF &result, const QSizeF &fallbackSize)
{
combineHints(result.rwidth(), fallbackSize.width());
combineHints(result.rheight(), fallbackSize.height());
}
static inline void combineImplicitHints(QQuickLayoutAttached *info, Qt::SizeHint which, QSizeF *size)
{
if (!info) return;
Q_ASSERT(which == Qt::MinimumSize || which == Qt::MaximumSize);
const QSizeF constraint(which == Qt::MinimumSize
? QSizeF(info->minimumWidth(), info->minimumHeight())
: QSizeF(info->maximumWidth(), info->maximumHeight()));
if (!info->isExtentExplicitlySet(Qt::Horizontal, which))
combineHints(size->rwidth(), constraint.width());
if (!info->isExtentExplicitlySet(Qt::Vertical, which))
combineHints(size->rheight(), constraint.height());
}
/*! /*!
\internal \internal
Note: Can potentially return the attached QQuickLayoutAttached object through \a attachedInfo. Note: Can potentially return the attached QQuickLayoutAttached object through \a attachedInfo.
It is like this is because it enables it to be reused. It is like this is because it enables it to be reused.
The goal of this function is to return the effective minimum, preferred and maximum size hints
that the layout will use for this item.
This function takes care of gathering all explicitly set size hints, normalizes them so
that min < pref < max.
Further, the hints _not_explicitly_ set will then be initialized with the implicit size hints,
which is usually derived from the content of the layouts (or items).
The following table illustrates the preference of the properties used for measuring layout
items. If present, the USER properties will be preferred. If USER properties are not present,
the HINT properties will be preferred. Finally, the FALLBACK properties will be used as an
ultimate fallback.
Note that one can query if the value of Layout.minimumWidth or Layout.maximumWidth has been
explicitly or implicitly set with QQuickLayoutAttached::isExtentExplicitlySet(). This
determines if it should be used as a USER or as a HINT value.
| *Minimum* | *Preferred* | *Maximum* |
+----------------+----------------------+-----------------------+--------------------------+
|USER (explicit) | Layout.minimumWidth | Layout.preferredWidth | Layout.maximumWidth |
|HINT (implicit) | Layout.minimumWidth | implicitWidth | Layout.maximumWidth |
|FALLBACK | 0 | width | Number.POSITIVE_INFINITY |
+----------------+----------------------+-----------------------+--------------------------+
*/ */
void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **attachedInfo, bool useFallbackToWidthOrHeight) void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **attachedInfo, bool useFallbackToWidthOrHeight)
{ {
for (int i = 0; i < Qt::NSizeHints; ++i)
cachedSizeHints[i] = QSizeF();
QQuickLayoutAttached *info = attachedLayoutObject(item, false); QQuickLayoutAttached *info = attachedLayoutObject(item, false);
// First, retrieve the user-specified hints from the attached "Layout." properties // First, retrieve the user-specified hints from the attached "Layout." properties
if (info) { if (info) {
...@@ -123,16 +171,16 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c ...@@ -123,16 +171,16 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c
for (int i = 0; i < NSizes; ++i) { for (int i = 0; i < NSizes; ++i) {
SizeGetter getter = horGetters.call[i]; SizeGetter getter = horGetters.call[i];
Q_ASSERT(getter); Q_ASSERT(getter);
cachedSizeHints[i].setWidth((info->*getter)());
if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
cachedSizeHints[i].setWidth((info->*getter)());
getter = verGetters.call[i]; getter = verGetters.call[i];
Q_ASSERT(getter); Q_ASSERT(getter);
cachedSizeHints[i].setHeight((info->*getter)()); if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
cachedSizeHints[i].setHeight((info->*getter)());
} }
} else {
for (int i = 0; i < NSizes; ++i)
cachedSizeHints[i] = QSize();
} }
cachedSizeHints[Qt::MinimumDescent] = QSize(); //### FIXME when baseline support is added
QSizeF &minS = cachedSizeHints[Qt::MinimumSize]; QSizeF &minS = cachedSizeHints[Qt::MinimumSize];
QSizeF &prefS = cachedSizeHints[Qt::PreferredSize]; QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];
...@@ -144,23 +192,21 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c ...@@ -144,23 +192,21 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c
// to: [10, 10, 60] // to: [10, 10, 60]
normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth()); normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight()); normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
/*
The following table illustrates the preference of the properties used for measuring layout // All explicit values gathered, now continue to gather the implicit sizes
items. If present, the USER properties will be preferred. If USER properties are not present,
the HINT 1 properties will be preferred. Finally, the HINT 2 properties will be used as an //--- GATHER MAXIMUM SIZE HINTS ---
ultimate fallback. combineImplicitHints(info, Qt::MaximumSize, &maxS);
combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()));
| USER | HINT 1 | HINT 2 // implicit max or min sizes should not limit an explicitly set preferred size
-----+--------------------------------+-------------------+------- expandSize(maxS, prefS);
MIN | Layout.minimumWidth | | 0 expandSize(maxS, minS);
PREF | Layout.preferredWidth | implicitWidth | width
MAX | Layout.maximumWidth | | 1000000000 (-1)
-----+--------------------------------+-------------------+--------
Fixed | Layout.fillWidth | Expanding if layout, Fixed if item |
*/
//--- GATHER MINIMUM SIZE HINTS --- //--- GATHER MINIMUM SIZE HINTS ---
// They are always 0 combineImplicitHints(info, Qt::MinimumSize, &minS);
expandSize(minS, QSizeF(0,0));
boundSize(minS, prefS);
boundSize(minS, maxS);
//--- GATHER PREFERRED SIZE HINTS --- //--- GATHER PREFERRED SIZE HINTS ---
// First, from implicitWidth/Height // First, from implicitWidth/Height
...@@ -203,17 +249,12 @@ Fixed | Layout.fillWidth | Expanding if layout, Fixed if item | ...@@ -203,17 +249,12 @@ Fixed | Layout.fillWidth | Expanding if layout, Fixed if item |
item->blockSignals(false); item->blockSignals(false);
} }
} }
//--- GATHER MAXIMUM SIZE HINTS ---
combineHints(cachedSizeHints[Qt::MaximumSize].rwidth(), std::numeric_limits<qreal>::infinity());
combineHints(cachedSizeHints[Qt::MaximumSize].rheight(), std::numeric_limits<qreal>::infinity());
//--- GATHER DESCENT //--- GATHER DESCENT
// ### Not implemented // ### Not implemented
// Normalize again after the implicit hints have been gathered // Normalize again after the implicit hints have been gathered
expandSize(minS, QSizeF(0,0));
boundSize(minS, maxS);
expandSize(prefS, minS); expandSize(prefS, minS);
boundSize(prefS, maxS); boundSize(prefS, maxS);
......
...@@ -175,6 +175,22 @@ public: ...@@ -175,6 +175,22 @@ public:
qreal sizeHint(Qt::SizeHint which, Qt::Orientation orientation) const; qreal sizeHint(Qt::SizeHint which, Qt::Orientation orientation) const;
bool isExtentExplicitlySet(Qt::Orientation o, Qt::SizeHint whichSize) const
{
switch (whichSize) {
case Qt::MinimumSize:
return o == Qt::Horizontal ? m_isMinimumWidthSet : m_isMinimumHeightSet;
case Qt::MaximumSize:
return o == Qt::Horizontal ? m_isMaximumWidthSet : m_isMaximumHeightSet;
case Qt::PreferredSize:
return true; // Layout.preferredWidth is always explicitly set
case Qt::MinimumDescent: // Not supported
case Qt::NSizeHints:
return false;
}
return false;
}
signals: signals:
void minimumWidthChanged(); void minimumWidthChanged();
void minimumHeightChanged(); void minimumHeightChanged();
......
...@@ -459,6 +459,12 @@ Item { ...@@ -459,6 +459,12 @@ Item {
{ tag: "propagateMaximumWidth", layoutHints: [10, 20, -1], childHints: [11, 21, 30], expected:[10, 20, 30]}, { tag: "propagateMaximumWidth", layoutHints: [10, 20, -1], childHints: [11, 21, 30], expected:[10, 20, 30]},
{ tag: "propagateAll", layoutHints: [-1, -1, -1], childHints: [10, 20, 30], expected:[10, 20, 30]}, { tag: "propagateAll", layoutHints: [-1, -1, -1], childHints: [10, 20, 30], expected:[10, 20, 30]},
{ tag: "propagateCrazy", layoutHints: [-1, -1, -1], childHints: [40, 21, 30], expected:[30, 30, 30]}, { tag: "propagateCrazy", layoutHints: [-1, -1, -1], childHints: [40, 21, 30], expected:[30, 30, 30]},
{ tag: "expandMinToExplicitPref", layoutHints: [-1, 1, -1], childHints: [11, 21, 31], expected:[ 1, 1, 31]},
{ tag: "expandMaxToExplicitPref", layoutHints: [-1, 99, -1], childHints: [11, 21, 31], expected:[11, 99, 99]},
{ tag: "expandAllToExplicitMin", layoutHints: [99, -1, -1], childHints: [11, 21, 31], expected:[99, 99, 99]},
{ tag: "expandPrefToExplicitMin", layoutHints: [24, -1, -1], childHints: [11, 21, 31], expected:[24, 24, 31]},
{ tag: "boundPrefToExplicitMax", layoutHints: [-1, -1, 19], childHints: [11, 21, 31], expected:[11, 19, 19]},
{ tag: "boundAllToExplicitMax", layoutHints: [-1, -1, 9], childHints: [11, 21, 31], expected:[ 9, 9, 9]},
]; ];
} }
...@@ -468,22 +474,21 @@ Item { ...@@ -468,22 +474,21 @@ Item {
function test_sizeHint(data) { function test_sizeHint(data) {
var layout = layout_sizeHint_Component.createObject(container) var layout = layout_sizeHint_Component.createObject(container)
layout.Layout.minimumWidth = data.layoutHints[0]
layout.Layout.preferredWidth = data.layoutHints[1]
layout.Layout.maximumWidth = data.layoutHints[2]
var child = layout.children[0].children[0] var grid = layout.children[0]
grid.Layout.minimumWidth = data.layoutHints[0]
grid.Layout.preferredWidth = data.layoutHints[1]
grid.Layout.maximumWidth = data.layoutHints[2]
var child = grid.children[0]
if (data.implicitWidth !== undefined) { if (data.implicitWidth !== undefined) {
child.implicitWidth = data.implicitWidth child.implicitWidth = data.implicitWidth
} }
child.Layout.minimumWidth = data.childHints[0] child.Layout.minimumWidth = data.childHints[0]
child.Layout.preferredWidth = data.childHints[1] child.Layout.preferredWidth = data.childHints[1]
child.Layout.maximumWidth = data.childHints[2] child.Layout.maximumWidth = data.childHints[2]
var grid = layout.children[0] var effectiveSizeHintResult = [layout.Layout.minimumWidth, layout.implicitWidth, layout.Layout.maximumWidth]
var preferredWidth = layout.Layout.preferredWidth >= 0 ? layout.Layout.preferredWidth : layout.implicitWidth
var effectiveSizeHintResult = [layout.Layout.minimumWidth, preferredWidth, layout.Layout.maximumWidth]
compare(effectiveSizeHintResult, data.expected) compare(effectiveSizeHintResult, data.expected)
layout.destroy() layout.destroy()
} }
......
...@@ -282,5 +282,16 @@ Item { ...@@ -282,5 +282,16 @@ Item {
verify(control.value > 0.5) verify(control.value > 0.5)
control.destroy() control.destroy()
} }
function test_valueAndHandlePosition()
{
var slider = Qt.createQmlObject('import QtQuick.Controls 1.0; Slider {minimumValue: 0; maximumValue: 100; width: 100; height: 20; stepSize: 1}', container, '');
slider.forceActiveFocus()
slider.value = 0
compare(slider.__handlePos, 0)
slider.value = 50
compare(slider.__handlePos, 50)
slider.destroy()
}
} }
} }