summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/controls/ApplicationWindow.qml1
-rw-r--r--src/controls/ComboBox.qml48
-rw-r--r--src/controls/Menu.qml1
-rw-r--r--src/controls/MenuBar.qml1
-rw-r--r--src/controls/Private/AbstractCheckable.qml1
-rw-r--r--src/controls/Private/BasicButton.qml3
-rw-r--r--src/controls/Private/BasicTableView.qml2
-rw-r--r--src/controls/Private/Control.qml21
-rw-r--r--src/controls/Private/EditMenu.qml19
-rw-r--r--src/controls/Private/MenuContentItem.qml2
-rw-r--r--src/controls/Private/TreeViewItemDelegateLoader.qml1
-rw-r--r--src/controls/Private/qquickcontrolsettings.cpp5
-rw-r--r--src/controls/Private/qquickcontrolsettings_p.h2
-rw-r--r--src/controls/Private/qquicktreemodeladaptor.cpp52
-rw-r--r--src/controls/Private/qquicktreemodeladaptor_p.h6
-rw-r--r--src/controls/ScrollView.qml1
-rw-r--r--src/controls/SplitView.qml1
-rw-r--r--src/controls/StackView.qml1
-rw-r--r--src/controls/StackViewDelegate.qml1
-rw-r--r--src/controls/StatusBar.qml1
-rw-r--r--src/controls/Styles/Base/BasicTableViewStyle.qml8
-rw-r--r--src/controls/Styles/Base/ScrollViewStyle.qml1
-rw-r--r--src/controls/Styles/Base/TabViewStyle.qml1
-rw-r--r--src/controls/Styles/Base/TextAreaStyle.qml6
-rw-r--r--src/controls/Styles/Base/TextFieldStyle.qml6
-rw-r--r--src/controls/Styles/Base/TreeViewStyle.qml7
-rw-r--r--src/controls/Styles/Desktop/TableViewStyle.qml5
-rw-r--r--src/controls/Styles/Desktop/TreeViewStyle.qml4
-rw-r--r--src/controls/Styles/iOS/SliderStyle.qml50
-rw-r--r--src/controls/Tab.qml1
-rw-r--r--src/controls/TabView.qml1
-rw-r--r--src/controls/TableViewColumn.qml1
-rw-r--r--src/controls/TextArea.qml13
-rw-r--r--src/controls/TextField.qml4
-rw-r--r--src/controls/ToolBar.qml1
-rw-r--r--src/controls/TreeView.qml1
-rw-r--r--src/controls/controls.pro4
-rw-r--r--src/controls/doc/qtquickcontrols.qdocconf26
-rw-r--r--src/controls/doc/src/qtquickcontrols-overview.qdoc4
-rw-r--r--src/controls/doc/src/qtquickcontrols-tableview.qdoc1
-rw-r--r--src/controls/doc/src/qtquickcontrols-treeview.qdoc18
-rw-r--r--src/controls/doc/src/qtquickcontrolsstyles-index.qdoc11
-rw-r--r--src/controls/doc/src/qtquickcontrolsstyles-tableviewstyle.qdoc1
-rw-r--r--src/controls/doc/src/qtquickcontrolsstyles-treeviewstyle.qdoc1
-rw-r--r--src/controls/plugin.cpp5
-rw-r--r--src/controls/qquickaction.cpp1
-rw-r--r--src/controls/qquickaction_p.h6
-rw-r--r--src/controls/qquickmenu.cpp4
-rw-r--r--src/controls/qquickmenu_p.h4
-rw-r--r--src/controls/qquickmenuitem.cpp2
-rw-r--r--src/controls/qquickpopupwindow.cpp1
-rw-r--r--src/controls/qquickstack.cpp1
-rw-r--r--src/dialogs/dialogs.pro2
-rw-r--r--src/dialogs/plugin.cpp6
-rw-r--r--src/extras/extras.pro2
-rw-r--r--src/layouts/layouts.pro2
-rw-r--r--src/layouts/plugin.cpp2
-rw-r--r--src/layouts/qquickgridlayoutengine.cpp255
-rw-r--r--src/layouts/qquickgridlayoutengine_p.h14
-rw-r--r--src/layouts/qquicklayout.cpp340
-rw-r--r--src/layouts/qquicklayout_p.h21
-rw-r--r--src/layouts/qquicklinearlayout.cpp61
-rw-r--r--src/layouts/qquicklinearlayout_p.h12
-rw-r--r--src/layouts/qquickstacklayout.cpp333
-rw-r--r--src/layouts/qquickstacklayout_p.h105
-rw-r--r--src/widgets/qquickqfiledialog.cpp1
-rw-r--r--src/widgets/widgets.pro2
67 files changed, 1106 insertions, 422 deletions
diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml
index 4c30664d..fa2d1b51 100644
--- a/src/controls/ApplicationWindow.qml
+++ b/src/controls/ApplicationWindow.qml
@@ -45,6 +45,7 @@ import QtQuick.Controls.Private 1.0
\since 5.1
\inqmlmodule QtQuick.Controls
\ingroup applicationwindow
+ \ingroup controls
\brief Provides a top-level application window.
\image applicationwindow.png
diff --git a/src/controls/ComboBox.qml b/src/controls/ComboBox.qml
index a2eff0b6..4e29dfe9 100644
--- a/src/controls/ComboBox.qml
+++ b/src/controls/ComboBox.qml
@@ -145,6 +145,50 @@ Control {
*/
property alias editText: input.text
+ /*! \qmlproperty enumeration ComboBox::inputMethodHints
+ \since QtQuick.Controls 1.5
+ Provides hints to the input method about the expected content of the combo box and how it
+ should operate.
+
+ The value is a bit-wise combination of flags or \c Qt.ImhNone if no hints are set.
+
+ Flags that alter behavior are:
+
+ \list
+ \li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords.
+ \li Qt.ImhSensitiveData - Typed text should not be stored by the active input method
+ in any persistent storage like predictive user dictionary.
+ \li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case
+ when a sentence ends.
+ \li Qt.ImhPreferNumbers - Numbers are preferred (but not required).
+ \li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required).
+ \li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required).
+ \li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing.
+
+ \li Qt.ImhDate - The text editor functions as a date field.
+ \li Qt.ImhTime - The text editor functions as a time field.
+ \endlist
+
+ Flags that restrict input (exclusive flags) are:
+
+ \list
+ \li Qt.ImhDigitsOnly - Only digits are allowed.
+ \li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign.
+ \li Qt.ImhUppercaseOnly - Only upper case letter input is allowed.
+ \li Qt.ImhLowercaseOnly - Only lower case letter input is allowed.
+ \li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed.
+ \li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed.
+ \li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed.
+ \endlist
+
+ Masks:
+
+ \list
+ \li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used.
+ \endlist
+ */
+ property alias inputMethodHints: input.inputMethodHints
+
/*! This property specifies whether the combobox should gain active focus when pressed.
The default value is \c false. */
property bool activeFocusOnPress: false
@@ -511,6 +555,8 @@ Control {
onTextRoleChanged: popup.resolveTextValue(textRole)
+ ExclusiveGroup { id: eg }
+
Menu {
id: popup
objectName: "popup"
@@ -536,8 +582,6 @@ Control {
__minimumWidth: comboBox.width
__visualItem: comboBox
- property ExclusiveGroup eg: ExclusiveGroup { id: eg }
-
property bool modelIsArray: false
Instantiator {
diff --git a/src/controls/Menu.qml b/src/controls/Menu.qml
index 037fa550..d485cb65 100644
--- a/src/controls/Menu.qml
+++ b/src/controls/Menu.qml
@@ -44,6 +44,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup menus
+ \ingroup controls
\brief Provides a menu component for use as a context menu, popup menu, or
as part of a menu bar.
diff --git a/src/controls/MenuBar.qml b/src/controls/MenuBar.qml
index 444185cc..a16635ff 100644
--- a/src/controls/MenuBar.qml
+++ b/src/controls/MenuBar.qml
@@ -44,6 +44,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup applicationwindow
+ \ingroup controls
\brief Provides a horizontal menu bar.
\image menubar.png
diff --git a/src/controls/Private/AbstractCheckable.qml b/src/controls/Private/AbstractCheckable.qml
index 42abebe5..bca626e0 100644
--- a/src/controls/Private/AbstractCheckable.qml
+++ b/src/controls/Private/AbstractCheckable.qml
@@ -41,7 +41,6 @@ import QtQuick.Controls.Private 1.0
/*!
\qmltype AbstractCheckable
\inqmlmodule QtQuick.Controls
- \ingroup controls
\brief An abstract representation of a checkable control with a label
\qmlabstract
\internal
diff --git a/src/controls/Private/BasicButton.qml b/src/controls/Private/BasicButton.qml
index 1756a296..346cd419 100644
--- a/src/controls/Private/BasicButton.qml
+++ b/src/controls/Private/BasicButton.qml
@@ -38,6 +38,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Private 1.0
import QtQuick.Controls.Styles 1.1
+import QtQuick.Window 2.2
/*!
\qmltype BasicButton
@@ -206,7 +207,7 @@ Control {
Timer {
interval: 1000
- running: behavior.containsMouse && !pressed && tooltip.length
+ running: behavior.containsMouse && !pressed && tooltip.length && behavior.Window.visibility !== Window.Hidden
onTriggered: Tooltip.showText(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
}
}
diff --git a/src/controls/Private/BasicTableView.qml b/src/controls/Private/BasicTableView.qml
index 27635bc9..5fd21167 100644
--- a/src/controls/Private/BasicTableView.qml
+++ b/src/controls/Private/BasicTableView.qml
@@ -94,6 +94,7 @@ ScrollView {
property Component itemDelegate: __style ? __style.itemDelegate : null
/*! \qmlproperty Component BasicTableView::rowDelegate
+ \keyword basictableview-rowdelegate
This property defines a delegate to draw a row.
@@ -116,6 +117,7 @@ ScrollView {
property Component rowDelegate: __style ? __style.rowDelegate : null
/*! \qmlproperty Component BasicTableView::headerDelegate
+ \keyword basictableview-headerdelegate
This property defines a delegate to draw a header.
diff --git a/src/controls/Private/Control.qml b/src/controls/Private/Control.qml
index f4733cc5..4b965482 100644
--- a/src/controls/Private/Control.qml
+++ b/src/controls/Private/Control.qml
@@ -72,19 +72,20 @@ FocusScope {
property alias __styleData: styleLoader.styleData
Loader {
+ id: styleLoader
+ sourceComponent: style
+ property Item __control: root
+ property QtObject styleData: null
+ onStatusChanged: {
+ if (status === Loader.Error)
+ console.error("Failed to load Style for", root)
+ }
+ }
+
+ Loader {
id: panelLoader
anchors.fill: parent
sourceComponent: __style ? __style.panel : null
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
- Loader {
- id: styleLoader
- sourceComponent: style
- property Item __control: root
- property QtObject styleData: null
- onStatusChanged: {
- if (status === Loader.Error)
- console.error("Failed to load Style for", root)
- }
- }
}
}
diff --git a/src/controls/Private/EditMenu.qml b/src/controls/Private/EditMenu.qml
index 51abe758..a70e8407 100644
--- a/src/controls/Private/EditMenu.qml
+++ b/src/controls/Private/EditMenu.qml
@@ -45,8 +45,9 @@ Loader {
property Item selectionHandle
property Flickable flickable
property Component defaultMenu: item && item.defaultMenu ? item.defaultMenu : null
- property Menu menuInstance: null
+ property QtObject menuInstance: null
property MouseArea mouseArea
+ property QtObject style: __style
Connections {
target: control
@@ -67,6 +68,18 @@ Loader {
return menuInstance;
}
- source: Qt.resolvedUrl(Qt.platform.os === "ios" ? "EditMenu_ios.qml"
- : Qt.platform.os === "android" ? "" : "EditMenu_base.qml")
+ function syncStyle() {
+ if (!style)
+ return;
+
+ if (style.__editMenu)
+ sourceComponent = style.__editMenu;
+ else {
+ // todo: get ios/android/base menus from style as well
+ source = (Qt.resolvedUrl(Qt.platform.os === "ios" ? "EditMenu_ios.qml"
+ : Qt.platform.os === "android" ? "" : "EditMenu_base.qml"));
+ }
+ }
+ onStyleChanged: syncStyle();
+ Component.onCompleted: syncStyle();
}
diff --git a/src/controls/Private/MenuContentItem.qml b/src/controls/Private/MenuContentItem.qml
index a0b346c4..e3be2e44 100644
--- a/src/controls/Private/MenuContentItem.qml
+++ b/src/controls/Private/MenuContentItem.qml
@@ -174,7 +174,7 @@ Loader {
id: menuItemLoader
Accessible.role: opts.type === MenuItemType.Item || opts.type === MenuItemType.Menu ?
- Accessible.MenuItem : Acccessible.NoRole
+ Accessible.MenuItem : Accessible.NoRole
Accessible.name: StyleHelpers.removeMnemonics(opts.text)
Accessible.checkable: opts.checkable
Accessible.checked: opts.checked
diff --git a/src/controls/Private/TreeViewItemDelegateLoader.qml b/src/controls/Private/TreeViewItemDelegateLoader.qml
index c4e13729..8b8801fc 100644
--- a/src/controls/Private/TreeViewItemDelegateLoader.qml
+++ b/src/controls/Private/TreeViewItemDelegateLoader.qml
@@ -98,6 +98,7 @@ TableViewItemDelegateLoader {
visible: itemDelegateLoader.width > __itemIndentation
sourceComponent: __style && __style.__branchDelegate || null
anchors.right: parent.item ? parent.item.left : undefined
+ anchors.rightMargin: __style.__indentation > width ? (__style.__indentation - width) / 2 : 0
anchors.verticalCenter: parent.verticalCenter
property QtObject styleData: itemDelegateLoader.styleData
onLoaded: if (__rowItem) __rowItem.branchDecoration = item
diff --git a/src/controls/Private/qquickcontrolsettings.cpp b/src/controls/Private/qquickcontrolsettings.cpp
index 55850bf0..8483830b 100644
--- a/src/controls/Private/qquickcontrolsettings.cpp
+++ b/src/controls/Private/qquickcontrolsettings.cpp
@@ -98,6 +98,9 @@ bool QQuickControlSettings::isMobile() const
#if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX) || defined(Q_OS_WINRT)
return true;
#else
+ if (qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_MOBILE")) {
+ return true;
+ }
return false;
#endif
}
@@ -112,7 +115,7 @@ QString QQuickControlSettings::makeStyleComponentPath(const QString &controlStyl
return styleDirPath + QStringLiteral("/") + controlStyleName;
}
-QUrl QQuickControlSettings::makeStyleComponentUrl(const QString &controlStyleName, QString styleDirPath)
+QUrl QQuickControlSettings::makeStyleComponentUrl(const QString &controlStyleName, const QString &styleDirPath)
{
QString styleFilePath = makeStyleComponentPath(controlStyleName, styleDirPath);
diff --git a/src/controls/Private/qquickcontrolsettings_p.h b/src/controls/Private/qquickcontrolsettings_p.h
index 1b99fd3e..6a4e8c6a 100644
--- a/src/controls/Private/qquickcontrolsettings_p.h
+++ b/src/controls/Private/qquickcontrolsettings_p.h
@@ -90,7 +90,7 @@ private:
void findStyle(QQmlEngine *engine, const QString &styleName);
bool resolveCurrentStylePath();
QString makeStyleComponentPath(const QString &controlStyleName, const QString &styleDirPath);
- QUrl makeStyleComponentUrl(const QString &controlStyleName, QString styleDirPath);
+ QUrl makeStyleComponentUrl(const QString &controlStyleName, const QString &styleDirPath);
struct StyleData
{
diff --git a/src/controls/Private/qquicktreemodeladaptor.cpp b/src/controls/Private/qquicktreemodeladaptor.cpp
index 87b2808e..666fafc9 100644
--- a/src/controls/Private/qquicktreemodeladaptor.cpp
+++ b/src/controls/Private/qquicktreemodeladaptor.cpp
@@ -120,6 +120,29 @@ void QQuickTreeModelAdaptor::clearModelData()
endResetModel();
}
+const QModelIndex &QQuickTreeModelAdaptor::rootIndex() const
+{
+ return m_rootIndex;
+}
+
+void QQuickTreeModelAdaptor::setRootIndex(const QModelIndex &idx)
+{
+ if (m_rootIndex == idx)
+ return;
+
+ if (m_model)
+ clearModelData();
+ m_rootIndex = idx;
+ if (m_model)
+ showModelTopLevelItems();
+ emit rootIndexChanged();
+}
+
+void QQuickTreeModelAdaptor::resetRootIndex()
+{
+ setRootIndex(QModelIndex());
+}
+
QHash<int, QByteArray> QQuickTreeModelAdaptor::roleNames() const
{
if (!m_model)
@@ -180,7 +203,7 @@ bool QQuickTreeModelAdaptor::setData(const QModelIndex &index, const QVariant &v
int QQuickTreeModelAdaptor::itemIndex(const QModelIndex &index) const
{
// This is basically a plagiarism of QTreeViewPrivate::viewIndex()
- if (!index.isValid() || m_items.isEmpty())
+ if (!index.isValid() || index == m_rootIndex || m_items.isEmpty())
return -1;
const int totalCount = m_items.count();
@@ -226,7 +249,7 @@ bool QQuickTreeModelAdaptor::isVisible(const QModelIndex &index)
bool QQuickTreeModelAdaptor::childrenVisible(const QModelIndex &index)
{
- return (!index.isValid() && !m_items.isEmpty())
+ return (index == m_rootIndex && !m_items.isEmpty())
|| (m_expandedItems.contains(index) && isVisible(index));
}
@@ -302,21 +325,21 @@ void QQuickTreeModelAdaptor::showModelTopLevelItems(bool doInsertRows)
if (!m_model)
return;
- if (m_model->hasChildren(QModelIndex()) && m_model->canFetchMore(QModelIndex()))
- m_model->fetchMore(QModelIndex());
- const long topLevelRowCount = m_model->rowCount();
+ if (m_model->hasChildren(m_rootIndex) && m_model->canFetchMore(m_rootIndex))
+ m_model->fetchMore(m_rootIndex);
+ const long topLevelRowCount = m_model->rowCount(m_rootIndex);
if (topLevelRowCount == 0)
return;
- showModelChildItems(TreeItem(), 0, topLevelRowCount - 1, doInsertRows);
+ showModelChildItems(TreeItem(m_rootIndex), 0, topLevelRowCount - 1, doInsertRows);
}
void QQuickTreeModelAdaptor::showModelChildItems(const TreeItem &parentItem, int start, int end, bool doInsertRows, bool doExpandPendingRows)
{
const QModelIndex &parentIndex = parentItem.index;
- int rowIdx = parentIndex.isValid() ? itemIndex(parentIndex) + 1 : 0;
+ int rowIdx = parentIndex.isValid() && parentIndex != m_rootIndex ? itemIndex(parentIndex) + 1 : 0;
Q_ASSERT(rowIdx == 0 || parentItem.expanded);
- if (parentIndex.isValid() && (rowIdx == 0 || !parentItem.expanded))
+ if (parentIndex.isValid() && parentIndex != m_rootIndex && (rowIdx == 0 || !parentItem.expanded))
return;
if (m_model->rowCount(parentIndex) == 0) {
@@ -603,8 +626,11 @@ void QQuickTreeModelAdaptor::modelRowsInserted(const QModelIndex & parent, int s
ASSERT_CONSISTENCY();
return;
}
- } else if (parent.isValid()) {
+ } else if (parent == m_rootIndex) {
item = TreeItem(parent);
+ } else {
+ ASSERT_CONSISTENCY();
+ return;
}
showModelChildItems(item, start, end);
ASSERT_CONSISTENCY();
@@ -612,10 +638,8 @@ void QQuickTreeModelAdaptor::modelRowsInserted(const QModelIndex & parent, int s
void QQuickTreeModelAdaptor::modelRowsAboutToBeRemoved(const QModelIndex & parent, int start, int end)
{
- Q_UNUSED(start);
- Q_UNUSED(end);
ASSERT_CONSISTENCY();
- if (!parent.isValid() || childrenVisible(parent)) {
+ if (parent == m_rootIndex || childrenVisible(parent)) {
const QModelIndex &smi = m_model->index(start, 0, parent);
int startIndex = itemIndex(smi);
const QModelIndex &emi = m_model->index(end, 0, parent);
@@ -756,9 +780,9 @@ bool QQuickTreeModelAdaptor::testConsistency(bool dumpOnFail) const
}
return true;
}
- QModelIndex parent;
+ QModelIndex parent = m_rootIndex;
QStack<QModelIndex> ancestors;
- QModelIndex idx = m_model->index(0, 0);
+ QModelIndex idx = m_model->index(0, 0, parent);
for (int i = 0; i < m_items.count(); i++) {
bool isConsistent = true;
const TreeItem &item = m_items.at(i);
diff --git a/src/controls/Private/qquicktreemodeladaptor_p.h b/src/controls/Private/qquicktreemodeladaptor_p.h
index 2297c365..3eefbe77 100644
--- a/src/controls/Private/qquicktreemodeladaptor_p.h
+++ b/src/controls/Private/qquicktreemodeladaptor_p.h
@@ -61,6 +61,7 @@ class QQuickTreeModelAdaptor : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
+ Q_PROPERTY(QModelIndex rootIndex READ rootIndex WRITE setRootIndex RESET resetRootIndex NOTIFY rootIndexChanged)
struct TreeItem;
@@ -68,6 +69,9 @@ public:
explicit QQuickTreeModelAdaptor(QObject *parent = 0);
QAbstractItemModel *model() const;
+ const QModelIndex &rootIndex() const;
+ void setRootIndex(const QModelIndex &idx);
+ void resetRootIndex();
enum {
DepthRole = Qt::UserRole - 4,
@@ -110,6 +114,7 @@ public:
signals:
void modelChanged(QAbstractItemModel *model);
+ void rootIndexChanged();
void expanded(const QModelIndex &index);
void collapsed(const QModelIndex &index);
@@ -149,6 +154,7 @@ private:
};
QPointer<QAbstractItemModel> m_model;
+ QPersistentModelIndex m_rootIndex;
QList<TreeItem> m_items;
QSet<QPersistentModelIndex> m_expandedItems;
QList<TreeItem *> m_itemsToExpand;
diff --git a/src/controls/ScrollView.qml b/src/controls/ScrollView.qml
index 5c21848f..74d5ee7d 100644
--- a/src/controls/ScrollView.qml
+++ b/src/controls/ScrollView.qml
@@ -44,6 +44,7 @@ import QtQuick.Controls.Styles 1.1
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup views
+ \ingroup controls
\brief Provides a scrolling view within another Item.
\image scrollview.png
diff --git a/src/controls/SplitView.qml b/src/controls/SplitView.qml
index 41c50329..c2e361ac 100644
--- a/src/controls/SplitView.qml
+++ b/src/controls/SplitView.qml
@@ -45,6 +45,7 @@ import QtQuick.Window 2.1
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup views
+ \ingroup controls
\brief Lays out items with a draggable splitter between each item.
\image splitview.png
diff --git a/src/controls/StackView.qml b/src/controls/StackView.qml
index 26772781..c76459ff 100644
--- a/src/controls/StackView.qml
+++ b/src/controls/StackView.qml
@@ -42,6 +42,7 @@ import QtQuick.Controls.Private 1.0
\qmltype StackView
\inherits Item
\ingroup views
+ \ingroup controls
\inqmlmodule QtQuick.Controls
\since 5.1
diff --git a/src/controls/StackViewDelegate.qml b/src/controls/StackViewDelegate.qml
index c837c281..a1dacb21 100644
--- a/src/controls/StackViewDelegate.qml
+++ b/src/controls/StackViewDelegate.qml
@@ -39,6 +39,7 @@ import QtQuick 2.2
/*!
\qmltype StackViewDelegate
\inqmlmodule QtQuick.Controls
+ \ingroup controls
\since 5.1
\brief A delegate used by StackView for loading transitions.
diff --git a/src/controls/StatusBar.qml b/src/controls/StatusBar.qml
index f151a3ac..468d3587 100644
--- a/src/controls/StatusBar.qml
+++ b/src/controls/StatusBar.qml
@@ -43,6 +43,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup applicationwindow
+ \ingroup controls
\brief Contains status information in your app.
The common way of using StatusBar is in relation to \l ApplicationWindow.
diff --git a/src/controls/Styles/Base/BasicTableViewStyle.qml b/src/controls/Styles/Base/BasicTableViewStyle.qml
index 973d09c0..c8d817c9 100644
--- a/src/controls/Styles/Base/BasicTableViewStyle.qml
+++ b/src/controls/Styles/Base/BasicTableViewStyle.qml
@@ -94,7 +94,8 @@ ScrollViewStyle {
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: styleData.textAlignment
- anchors.leftMargin: 12
+ anchors.leftMargin: horizontalAlignment === Text.AlignLeft ? 12 : 1
+ anchors.rightMargin: horizontalAlignment === Text.AlignRight ? 8 : 1
text: styleData.value
elide: Text.ElideRight
color: textColor
@@ -137,8 +138,9 @@ ScrollViewStyle {
Text {
id: label
objectName: "label"
- width: parent.width - x
- x: styleData.depth && styleData.column === 0 ? 0 : 8
+ width: parent.width - x - (horizontalAlignment === Text.AlignRight ? 8 : 1)
+ x: (styleData.hasOwnProperty("depth") && styleData.column === 0) ? 0 :
+ horizontalAlignment === Text.AlignRight ? 1 : 8
horizontalAlignment: styleData.textAlignment
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 1
diff --git a/src/controls/Styles/Base/ScrollViewStyle.qml b/src/controls/Styles/Base/ScrollViewStyle.qml
index ed72951f..09bc7da3 100644
--- a/src/controls/Styles/Base/ScrollViewStyle.qml
+++ b/src/controls/Styles/Base/ScrollViewStyle.qml
@@ -43,6 +43,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls.Styles
\since 5.1
\ingroup viewsstyling
+ \ingroup controlsstyling
\brief Provides custom styling for ScrollView
*/
Style {
diff --git a/src/controls/Styles/Base/TabViewStyle.qml b/src/controls/Styles/Base/TabViewStyle.qml
index 4842c39a..94cc1240 100644
--- a/src/controls/Styles/Base/TabViewStyle.qml
+++ b/src/controls/Styles/Base/TabViewStyle.qml
@@ -43,6 +43,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls.Styles
\since 5.1
\ingroup viewsstyling
+ \ingroup controlsstyling
\brief Provides custom styling for TabView
\qml
diff --git a/src/controls/Styles/Base/TextAreaStyle.qml b/src/controls/Styles/Base/TextAreaStyle.qml
index 678d365d..1da52227 100644
--- a/src/controls/Styles/Base/TextAreaStyle.qml
+++ b/src/controls/Styles/Base/TextAreaStyle.qml
@@ -146,4 +146,10 @@ ScrollViewStyle {
\since QtQuick.Controls.Styles 1.3
*/
property Component __cursorDelegate
+
+ /*! \internal
+ The delegate for the cut/copy/paste menu.
+ \since QtQuick.Controls.Styles 1.4
+ */
+ property Component __editMenu
}
diff --git a/src/controls/Styles/Base/TextFieldStyle.qml b/src/controls/Styles/Base/TextFieldStyle.qml
index e9247416..b5e024b4 100644
--- a/src/controls/Styles/Base/TextFieldStyle.qml
+++ b/src/controls/Styles/Base/TextFieldStyle.qml
@@ -209,4 +209,10 @@ Style {
\since QtQuick.Controls.Styles 1.3
*/
property Component __cursorDelegate
+
+ /*! \internal
+ The delegate for the cut/copy/paste menu.
+ \since QtQuick.Controls.Styles 1.4
+ */
+ property Component __editMenu
}
diff --git a/src/controls/Styles/Base/TreeViewStyle.qml b/src/controls/Styles/Base/TreeViewStyle.qml
index b8f03f65..e90542fe 100644
--- a/src/controls/Styles/Base/TreeViewStyle.qml
+++ b/src/controls/Styles/Base/TreeViewStyle.qml
@@ -43,10 +43,10 @@ BasicTableViewStyle {
readonly property TreeView control: __control
- property int indentation: 12
+ property int indentation: 16
property Component branchDelegate: Item {
- width: 16
+ width: indentation
height: 16
Text {
visible: styleData.column === 0 && styleData.hasChildren
@@ -54,8 +54,9 @@ BasicTableViewStyle {
color: !control.activeFocus || styleData.selected ? styleData.textColor : "#666"
font.pointSize: 10
renderType: Text.NativeRendering
+ style: Text.PlainText
anchors.centerIn: parent
- anchors.verticalCenterOffset: styleData.isExpanded ? 2 : 0
+ anchors.verticalCenterOffset: 2
}
}
diff --git a/src/controls/Styles/Desktop/TableViewStyle.qml b/src/controls/Styles/Desktop/TableViewStyle.qml
index f5199f3f..1ead1b34 100644
--- a/src/controls/Styles/Desktop/TableViewStyle.qml
+++ b/src/controls/Styles/Desktop/TableViewStyle.qml
@@ -96,7 +96,10 @@ ScrollViewStyle {
font: __styleitem.font
anchors.left: parent.left
anchors.right: parent.right
- anchors.leftMargin: styleData["depth"] && styleData.column === 0 ? 0 : 8
+ anchors.leftMargin: styleData.hasOwnProperty("depth") && styleData.column === 0 ? 0 :
+ horizontalAlignment === Text.AlignRight ? 1 : 8
+ anchors.rightMargin: (styleData.hasOwnProperty("depth") && styleData.column === 0)
+ || horizontalAlignment !== Text.AlignRight ? 1 : 8
horizontalAlignment: styleData.textAlignment
anchors.verticalCenter: parent.verticalCenter
elide: styleData.elideMode
diff --git a/src/controls/Styles/Desktop/TreeViewStyle.qml b/src/controls/Styles/Desktop/TreeViewStyle.qml
index 1901c40c..6424ed0e 100644
--- a/src/controls/Styles/Desktop/TreeViewStyle.qml
+++ b/src/controls/Styles/Desktop/TreeViewStyle.qml
@@ -56,12 +56,12 @@ Desktop.TableViewStyle {
hasFocus: __styleitem.active
Component.onCompleted: {
- implicitWidth = si.pixelMetric("treeviewindentation")
+ root.__indentation = si.pixelMetric("treeviewindentation")
+ implicitWidth = root.__indentation
implicitHeight = implicitWidth
var rect = si.subControlRect("dummy");
width = rect.width
height = rect.height
- root.__indentation = width
}
}
}
diff --git a/src/controls/Styles/iOS/SliderStyle.qml b/src/controls/Styles/iOS/SliderStyle.qml
index 3d39ce2b..8a87f809 100644
--- a/src/controls/Styles/iOS/SliderStyle.qml
+++ b/src/controls/Styles/iOS/SliderStyle.qml
@@ -34,6 +34,54 @@
**
****************************************************************************/
+import QtQuick 2.3
import QtQuick.Controls.Styles 1.3
-SliderStyle { }
+SliderStyle {
+ groove: Rectangle {
+ implicitWidth: 20
+ implicitHeight: 2
+
+ color: "#a8a8a8"
+ radius: 45.0
+
+ Rectangle {
+ width: styleData.handlePosition
+ height: parent.height
+ color: "#0a60ff"
+ radius: parent.radius
+ }
+ }
+
+ handle: Item {
+ width: 29
+ height: 32
+
+ Rectangle {
+ y: 3
+ width: 29
+ height: 29
+ radius: 90.0
+
+ color: "#d6d6d6"
+ opacity: 0.2
+ }
+
+ Rectangle {
+ width: 29
+ height: 29
+ radius: 90.0
+
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#e2e2e2" }
+ GradientStop { position: 1.0; color: "#d6d6d6" }
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: 1
+ radius: parent.radius
+ }
+ }
+ }
+}
diff --git a/src/controls/Tab.qml b/src/controls/Tab.qml
index f5d02cf3..07a4cd9e 100644
--- a/src/controls/Tab.qml
+++ b/src/controls/Tab.qml
@@ -41,6 +41,7 @@ import QtQuick 2.2
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup viewaddons
+ \ingroup controls
\brief Tab represents the content of a tab in a TabView.
A Tab item inherits from Loader and provides a similar
diff --git a/src/controls/TabView.qml b/src/controls/TabView.qml
index bd043be9..f7a8324a 100644
--- a/src/controls/TabView.qml
+++ b/src/controls/TabView.qml
@@ -43,6 +43,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup views
+ \ingroup controls
\brief A control that allows the user to select one of multiple stacked items.
\image tabview.png
diff --git a/src/controls/TableViewColumn.qml b/src/controls/TableViewColumn.qml
index 9bcdfe6d..3f5a8468 100644
--- a/src/controls/TableViewColumn.qml
+++ b/src/controls/TableViewColumn.qml
@@ -41,6 +41,7 @@ import QtQuick 2.2
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup viewitems
+ \ingroup controls
\brief Used to define columns in a \l TableView or in a \l TreeView.
\image tableview.png
diff --git a/src/controls/TextArea.qml b/src/controls/TextArea.qml
index 23360f06..87b13e0d 100644
--- a/src/controls/TextArea.qml
+++ b/src/controls/TextArea.qml
@@ -34,7 +34,7 @@
**
****************************************************************************/
-import QtQuick 2.2
+import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Private 1.0
@@ -423,6 +423,16 @@ ScrollView {
signal linkHovered(string link)
/*!
+ \qmlsignal TextArea::editingFinished()
+ \since QtQuick.Controls 1.5
+
+ This signal is emitted when the text area loses focus.
+
+ The corresponding handler is \c onEditingFinished.
+ */
+ signal editingFinished()
+
+ /*!
\qmlproperty string TextArea::hoveredLink
\since QtQuick.Controls 1.1
@@ -819,6 +829,7 @@ ScrollView {
onLinkActivated: area.linkActivated(link)
onLinkHovered: area.linkHovered(link)
+ onEditingFinished: area.editingFinished()
function activate() {
if (activeFocusOnPress) {
diff --git a/src/controls/TextField.qml b/src/controls/TextField.qml
index 589869d3..0c8a0df6 100644
--- a/src/controls/TextField.qml
+++ b/src/controls/TextField.qml
@@ -34,7 +34,7 @@
**
****************************************************************************/
-import QtQuick 2.2
+import QtQuick 2.6
import QtQuick.Controls 1.2
import QtQuick.Controls.Private 1.0
@@ -660,6 +660,8 @@ Control {
Keys.forwardTo: textfield
+ EnterKey.type: control.EnterKey.type
+
onAccepted: textfield.accepted()
onEditingFinished: textfield.editingFinished()
diff --git a/src/controls/ToolBar.qml b/src/controls/ToolBar.qml
index 48f62f16..f5d0a994 100644
--- a/src/controls/ToolBar.qml
+++ b/src/controls/ToolBar.qml
@@ -43,6 +43,7 @@ import QtQuick.Controls.Private 1.0
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup applicationwindow
+ \ingroup controls
\brief Contains ToolButton and related controls.
\image toolbar.png
diff --git a/src/controls/TreeView.qml b/src/controls/TreeView.qml
index c97930f3..637c46c3 100644
--- a/src/controls/TreeView.qml
+++ b/src/controls/TreeView.qml
@@ -44,6 +44,7 @@ BasicTableView {
id: root
property var model: null
+ property alias rootIndex: modelAdaptor.rootIndex
readonly property var currentIndex: modelAdaptor.mapRowToModelIndex(__currentRow)
property ItemSelectionModel selection: null
diff --git a/src/controls/controls.pro b/src/controls/controls.pro
index 7dd176f0..f725b1ce 100644
--- a/src/controls/controls.pro
+++ b/src/controls/controls.pro
@@ -1,6 +1,8 @@
+requires(contains(QT_CONFIG, accessibility))
+
TARGET = qtquickcontrolsplugin
TARGETPATH = QtQuick/Controls
-IMPORT_VERSION = 1.4
+IMPORT_VERSION = 1.5
QT += qml quick quick-private qml-private gui-private core-private
diff --git a/src/controls/doc/qtquickcontrols.qdocconf b/src/controls/doc/qtquickcontrols.qdocconf
index e8aa0422..33df123f 100644
--- a/src/controls/doc/qtquickcontrols.qdocconf
+++ b/src/controls/doc/qtquickcontrols.qdocconf
@@ -17,16 +17,22 @@ qhp.QtQuickControls.filterAttributes = qtquickcontrols $QT_VERSION qtrefdoc
qhp.QtQuickControls.customFilters.Qt.name = QtQuickControls $QT_VERSION
qhp.QtQuickControls.customFilters.Qt.filterAttributes = qtquickcontrols $QT_VERSION
-qhp.QtQuickControls.subprojects = qtquickcontrolsqmltypes qtquickcontrolsstyles
-
-qhp.QtQuickControls.subprojects.qtquickcontrolsqmltypes.title = Controls QML Types
-qhp.QtQuickControls.subprojects.qtquickcontrolsqmltypes.indexTitle = Qt Quick Controls QML Types
-qhp.QtQuickControls.subprojects.qtquickcontrolsqmltypes.selectors = qmlclass # cannot choose qmltypes from a specific group QTBUG-32985
-qhp.QtQuickControls.subprojects.qtquickcontrolsqmltypes.sortPages = true
-
-qhp.QtQuickControls.subprojects.qtquickcontrolsstyles.title = Qt Quick Controls Styles Structure
-qhp.QtQuickControls.subprojects.qtquickcontrolsstyles.indexTitle = Qt Quick Controls Styles Structure
-qhp.QtQuickControls.subprojects.qtquickcontrolsstyles.type = manual
+qhp.QtQuickControls.subprojects = qqcqmltypes qqcstylesqmltypes qqcexamples
+
+qhp.QtQuickControls.subprojects.qqcqmltypes.title = Controls QML Types
+qhp.QtQuickControls.subprojects.qqcqmltypes.indexTitle = Qt Quick Controls QML Types
+qhp.QtQuickControls.subprojects.qqcqmltypes.selectors = group:controls
+qhp.QtQuickControls.subprojects.qqcqmltypes.sortPages = true
+
+qhp.QtQuickControls.subprojects.qqcstylesqmltypes.title = Controls Styles QML Types
+qhp.QtQuickControls.subprojects.qqcstylesqmltypes.indexTitle = Qt Quick Controls Styles QML Types
+qhp.QtQuickControls.subprojects.qqcstylesqmltypes.selectors = group:controlsstyling
+qhp.QtQuickControls.subprojects.qqcstylesqmltypes.sortPages = true
+
+qhp.QtQuickControls.subprojects.qqcexamples.title = Examples and Tutorials
+qhp.QtQuickControls.subprojects.qqcexamples.indexTitle = Qt Quick Controls Examples
+qhp.QtQuickControls.subprojects.qqcexamples.selectors = doc:example group:stylingtutorials
+qhp.QtQuickControls.subprojects.qqcexamples.sortpages = true
depends = qtcore qtdoc qtgui qtwidgets qtqml qtquick qtquicklayouts qtquickdialogs qtquickextras
diff --git a/src/controls/doc/src/qtquickcontrols-overview.qdoc b/src/controls/doc/src/qtquickcontrols-overview.qdoc
index 45a4557a..f549d0c8 100644
--- a/src/controls/doc/src/qtquickcontrols-overview.qdoc
+++ b/src/controls/doc/src/qtquickcontrols-overview.qdoc
@@ -126,6 +126,10 @@
forgotten. This is a known limitation and a workaround is to add potentially missing imports in
one of the qml files of the application using the controls.
+ \section2 Testing Desktop and Mobile behavior of the controls
+ You can test how the controls on your application or style will behave on
+ a mobile platform by setting the environment variable \e QT_QUICK_CONTROLS_MOBILE, to force a behavior optimized for mobile devices.
+
\section1 Related information
\list
diff --git a/src/controls/doc/src/qtquickcontrols-tableview.qdoc b/src/controls/doc/src/qtquickcontrols-tableview.qdoc
index 15b99c18..a9c6d22a 100644
--- a/src/controls/doc/src/qtquickcontrols-tableview.qdoc
+++ b/src/controls/doc/src/qtquickcontrols-tableview.qdoc
@@ -31,6 +31,7 @@
\inherits BasicTableView
\since 5.1
\ingroup views
+ \ingroup controls
\brief Provides a list view with scroll bars, styling and header sections.
\image tableview.png
diff --git a/src/controls/doc/src/qtquickcontrols-treeview.qdoc b/src/controls/doc/src/qtquickcontrols-treeview.qdoc
index fb186059..8188e955 100644
--- a/src/controls/doc/src/qtquickcontrols-treeview.qdoc
+++ b/src/controls/doc/src/qtquickcontrols-treeview.qdoc
@@ -31,6 +31,7 @@
\inherits BasicTableView
\since 5.5
\ingroup views
+ \ingroup controls
\brief Provides a tree view with scroll bars, styling and header sections.
\image treeview.png
@@ -63,8 +64,8 @@
the model role they attach to. Each property in the model will
then be shown in their corresponding column.
- You can customize the look by overriding the \l {TreeView::itemDelegate}{itemDelegate},
- \l {TreeView::rowDelegate}{rowDelegate}, or \l {TreeView::headerDelegate}{headerDelegate} properties.
+ You can customize the look by overriding the \l [QML]{TreeView::}{itemDelegate},
+ \l {basictableview-rowdelegate}{rowDelegate}, or \l {basictableview-headerdelegate}{headerDelegate} properties.
The view itself does not provide sorting. This has to
be done on the model itself. However you can provide sorting
@@ -142,6 +143,19 @@
*/
/*!
+ \qmlproperty QModelIndex TreeView::rootIndex
+ The model index of the root item in the tree view. The root item is the
+ parent item to the view's top-level items. Only items descending from the
+ root item will be visible in the view.
+
+ Its default value is an invalid QModelIndex, which means the whole
+ model data is shown by the tree view (assigning \c undefined to this
+ proprety resets it to its default value.)
+
+ \since QtQuick.Controls 1.5
+*/
+
+/*!
\qmlproperty QModelIndex TreeView::currentIndex
The model index of the current row in the tree view.
*/
diff --git a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc
index 94eb6fb4..792f064c 100644
--- a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc
+++ b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc
@@ -125,17 +125,6 @@
*/
/*!
- \page qtquickcontrolsstyles-structure.html
- \title Qt Quick Controls Styles Structure
- \list
- \li \l{Qt Quick Controls Styles}
- \list
- \li \l{Qt Quick Controls Styles QML Types}{Styles QMl Types}
- \endlist
- \endlist
-*/
-
-/*!
\qmlmodule QtQuick.Controls.Styles 1.4
\title Qt Quick Controls Styles QML Types
\ingroup qmlmodules
diff --git a/src/controls/doc/src/qtquickcontrolsstyles-tableviewstyle.qdoc b/src/controls/doc/src/qtquickcontrolsstyles-tableviewstyle.qdoc
index 0b5012f1..c781f903 100644
--- a/src/controls/doc/src/qtquickcontrolsstyles-tableviewstyle.qdoc
+++ b/src/controls/doc/src/qtquickcontrolsstyles-tableviewstyle.qdoc
@@ -31,6 +31,7 @@
\inherits BasicTableViewStyle
\since 5.1
\ingroup viewsstyling
+ \ingroup controlsstyling
\brief Provides custom styling for TableView
*/
diff --git a/src/controls/doc/src/qtquickcontrolsstyles-treeviewstyle.qdoc b/src/controls/doc/src/qtquickcontrolsstyles-treeviewstyle.qdoc
index 3f4508f4..e98b6cae 100644
--- a/src/controls/doc/src/qtquickcontrolsstyles-treeviewstyle.qdoc
+++ b/src/controls/doc/src/qtquickcontrolsstyles-treeviewstyle.qdoc
@@ -31,6 +31,7 @@
\inherits BasicTableViewStyle
\since 5.5
\ingroup viewsstyling
+ \ingroup controlsstyling
\brief Provides custom styling for TreeView
*/
diff --git a/src/controls/plugin.cpp b/src/controls/plugin.cpp
index 8ab956c6..e1afeef2 100644
--- a/src/controls/plugin.cpp
+++ b/src/controls/plugin.cpp
@@ -112,7 +112,10 @@ static const struct {
{ "TextArea", 1, 3 },
- { "TreeView", 1, 4 }
+ { "TreeView", 1, 4 },
+
+ { "TextArea", 1, 5 },
+ { "TreeView", 1, 5 }
};
void QtQuickControlsPlugin::registerTypes(const char *uri)
diff --git a/src/controls/qquickaction.cpp b/src/controls/qquickaction.cpp
index 90a1fd67..6add916d 100644
--- a/src/controls/qquickaction.cpp
+++ b/src/controls/qquickaction.cpp
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
\qmltype Action
\instantiates QQuickAction
\ingroup applicationwindow
+ \ingroup controls
\inqmlmodule QtQuick.Controls
\brief Action provides an abstract user interface action that can be bound to items
diff --git a/src/controls/qquickaction_p.h b/src/controls/qquickaction_p.h
index 1828cc9e..e3b9c852 100644
--- a/src/controls/qquickaction_p.h
+++ b/src/controls/qquickaction_p.h
@@ -104,7 +104,7 @@ public:
QIcon icon() const { return m_icon; }
QVariant iconVariant() const { return QVariant(m_icon); }
- void setIcon(QIcon icon) { m_icon = icon; emit iconChanged(); }
+ void setIcon(const QIcon &icon) { m_icon = icon; emit iconChanged(); }
bool event(QEvent *e);
@@ -116,12 +116,12 @@ Q_SIGNALS:
void toggled(bool checked);
void textChanged();
- void shortcutChanged(QVariant shortcut);
+ void shortcutChanged(const QVariant &shortcut);
void iconChanged();
void iconNameChanged();
void iconSourceChanged();
- void tooltipChanged(QString arg);
+ void tooltipChanged(const QString &arg);
void enabledChanged();
void checkableChanged();
diff --git a/src/controls/qquickmenu.cpp b/src/controls/qquickmenu.cpp
index beabe65b..fec24189 100644
--- a/src/controls/qquickmenu.cpp
+++ b/src/controls/qquickmenu.cpp
@@ -695,12 +695,12 @@ int QQuickMenu::indexOfMenuItem(QQuickMenuBase *item) const
}
}
-QQuickMenuItem *QQuickMenu::addItem(QString title)
+QQuickMenuItem *QQuickMenu::addItem(const QString &title)
{
return insertItem(m_itemsCount, title);
}
-QQuickMenuItem *QQuickMenu::insertItem(int index, QString title)
+QQuickMenuItem *QQuickMenu::insertItem(int index, const QString &title)
{
QQuickMenuItem *item = new QQuickMenuItem(this);
item->setText(title);
diff --git a/src/controls/qquickmenu_p.h b/src/controls/qquickmenu_p.h
index a626179a..1c51fe71 100644
--- a/src/controls/qquickmenu_p.h
+++ b/src/controls/qquickmenu_p.h
@@ -77,8 +77,8 @@ public:
enum MenuType { DefaultMenu = 0, EditMenu };
Q_INVOKABLE void popup();
- Q_INVOKABLE QQuickMenuItem *addItem(QString);
- Q_INVOKABLE QQuickMenuItem *insertItem(int, QString);
+ Q_INVOKABLE QQuickMenuItem *addItem(const QString &);
+ Q_INVOKABLE QQuickMenuItem *insertItem(int, const QString &);
Q_INVOKABLE void addSeparator();
Q_INVOKABLE void insertSeparator(int);
diff --git a/src/controls/qquickmenuitem.cpp b/src/controls/qquickmenuitem.cpp
index be15a435..0702d398 100644
--- a/src/controls/qquickmenuitem.cpp
+++ b/src/controls/qquickmenuitem.cpp
@@ -135,6 +135,7 @@ void QQuickMenuBase::setVisualItem(QQuickItem *item)
\instantiates QQuickMenuSeparator
\inqmlmodule QtQuick.Controls
\ingroup menus
+ \ingroup controls
\brief MenuSeparator provides a separator for items inside a menu.
\image menu.png
@@ -284,6 +285,7 @@ void QQuickMenuText::updateIcon()
\qmltype MenuItem
\instantiates QQuickMenuItem
\ingroup menus
+ \ingroup controls
\inqmlmodule QtQuick.Controls
\brief MenuItem provides an item to add in a menu or a menu bar.
diff --git a/src/controls/qquickpopupwindow.cpp b/src/controls/qquickpopupwindow.cpp
index a8f45167..59cfe22b 100644
--- a/src/controls/qquickpopupwindow.cpp
+++ b/src/controls/qquickpopupwindow.cpp
@@ -67,6 +67,7 @@ void QQuickPopupWindow::show()
if (QWindow *tp = transientParent()) {
if (m_parentItem) {
QPointF pos = m_parentItem->mapToItem(m_parentItem->window()->contentItem(), QPointF(posx, posy));
+ pos += tp->mapFromGlobal(m_parentItem->window()->mapToGlobal(QPoint()));
posx = pos.x();
posy = pos.y();
}
diff --git a/src/controls/qquickstack.cpp b/src/controls/qquickstack.cpp
index 16031656..3524b9ef 100644
--- a/src/controls/qquickstack.cpp
+++ b/src/controls/qquickstack.cpp
@@ -42,6 +42,7 @@ QT_BEGIN_NAMESPACE
\qmltype Stack
\instantiates QQuickStack
\inqmlmodule QtQuick.Controls
+ \ingroup controls
\brief Provides attached properties for items pushed onto a StackView.
The Stack type provides attached properties for items pushed onto a \l StackView.
diff --git a/src/dialogs/dialogs.pro b/src/dialogs/dialogs.pro
index b0b9db2d..9daaa6e6 100644
--- a/src/dialogs/dialogs.pro
+++ b/src/dialogs/dialogs.pro
@@ -1,3 +1,5 @@
+requires(contains(QT_CONFIG, accessibility))
+
CXX_MODULE = qml
TARGET = dialogplugin
TARGETPATH = QtQuick/Dialogs
diff --git a/src/dialogs/plugin.cpp b/src/dialogs/plugin.cpp
index 7fac166d..65740024 100644
--- a/src/dialogs/plugin.cpp
+++ b/src/dialogs/plugin.cpp
@@ -175,7 +175,7 @@ public:
protected:
template <class WrapperType>
- void registerWidgetOrQmlImplementation(QDir widgetsDir, QDir qmlDir,
+ void registerWidgetOrQmlImplementation(const QDir &widgetsDir, const QDir &qmlDir,
const char *qmlName, const char *uri, bool hasTopLevelWindows, int versionMajor, int versionMinor) {
qCDebug(lcRegistration) << qmlName << uri << ": QML in" << qmlDir.absolutePath()
<< "using resources?" << m_useResources << "; widgets in" << widgetsDir.absolutePath();
@@ -191,7 +191,7 @@ protected:
}
template <class WrapperType>
- bool registerWidgetImplementation(QDir widgetsDir, QDir qmlDir,
+ bool registerWidgetImplementation(const QDir &widgetsDir, const QDir &qmlDir,
const char *qmlName, const char *uri, bool hasTopLevelWindows, int versionMajor, int versionMinor)
{
@@ -223,7 +223,7 @@ protected:
}
template <class WrapperType>
- void registerQmlImplementation(QDir qmlDir, const char *qmlName, const char *uri , int versionMajor, int versionMinor)
+ void registerQmlImplementation(const QDir &qmlDir, const char *qmlName, const char *uri , int versionMajor, int versionMinor)
{
qCDebug(lcRegistration) << "Register QML version for" << qmlName << "with uri:" << uri;
diff --git a/src/extras/extras.pro b/src/extras/extras.pro
index 2ebd8f81..4363ce00 100644
--- a/src/extras/extras.pro
+++ b/src/extras/extras.pro
@@ -1,3 +1,5 @@
+requires(contains(QT_CONFIG, accessibility))
+
TARGET = qtquickextrasplugin
TARGETPATH = QtQuick/Extras
IMPORT_VERSION = 1.4
diff --git a/src/layouts/layouts.pro b/src/layouts/layouts.pro
index 3ef18f85..f7a73b7e 100644
--- a/src/layouts/layouts.pro
+++ b/src/layouts/layouts.pro
@@ -10,12 +10,14 @@ QMAKE_DOCS = $$PWD/doc/qtquicklayouts.qdocconf
SOURCES += plugin.cpp \
qquicklayout.cpp \
qquicklinearlayout.cpp \
+ qquickstacklayout.cpp \
qquickgridlayoutengine.cpp \
qquicklayoutstyleinfo.cpp
HEADERS += \
qquicklayout_p.h \
qquicklinearlayout_p.h \
+ qquickstacklayout_p.h \
qquickgridlayoutengine_p.h \
qquicklayoutstyleinfo_p.h
diff --git a/src/layouts/plugin.cpp b/src/layouts/plugin.cpp
index fa72fa8d..6a670539 100644
--- a/src/layouts/plugin.cpp
+++ b/src/layouts/plugin.cpp
@@ -37,6 +37,7 @@
#include <QtQml/qqmlextensionplugin.h>
#include "qquicklinearlayout_p.h"
+#include "qquickstacklayout_p.h"
QT_BEGIN_NAMESPACE
@@ -54,6 +55,7 @@ public:
qmlRegisterType<QQuickRowLayout>(uri, 1, 0, "RowLayout");
qmlRegisterType<QQuickColumnLayout>(uri, 1, 0, "ColumnLayout");
qmlRegisterType<QQuickGridLayout>(uri, 1, 0, "GridLayout");
+ qmlRegisterType<QQuickStackLayout>(uri, 1, 3, "StackLayout");
qmlRegisterUncreatableType<QQuickLayout>(uri, 1, 0, "Layout",
QStringLiteral("Do not create objects of type Layout"));
qmlRegisterUncreatableType<QQuickLayout>(uri, 1, 2, "Layout",
diff --git a/src/layouts/qquickgridlayoutengine.cpp b/src/layouts/qquickgridlayoutengine.cpp
index 553f45d0..2c08eec1 100644
--- a/src/layouts/qquickgridlayoutengine.cpp
+++ b/src/layouts/qquickgridlayoutengine.cpp
@@ -40,261 +40,6 @@
QT_BEGIN_NAMESPACE
-/*
- The layout engine assumes:
- 1. minimum <= preferred <= maximum
- 2. descent is within minimum and maximum bounds (### verify)
-
- This function helps to ensure that by the following rules (in the following order):
- 1. If minimum > maximum, set minimum = maximum
- 2. Make sure preferred is not outside the [minimum,maximum] range.
- 3. If descent > minimum, set descent = minimum (### verify if this is correct, it might
- need some refinements to multiline texts)
-
- If any values are "not set" (i.e. negative), they will be left untouched, so that we
- know which values needs to be fetched from the implicit hints (not user hints).
- */
-static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
-{
- if (minimum >= 0 && maximum >= 0 && minimum > maximum)
- minimum = maximum;
-
- if (preferred >= 0) {
- if (minimum >= 0 && preferred < minimum) {
- preferred = minimum;
- } else if (maximum >= 0 && preferred > maximum) {
- preferred = maximum;
- }
- }
-
- if (minimum >= 0 && descent > minimum)
- descent = minimum;
-}
-
-static void boundSize(QSizeF &result, const QSizeF &size)
-{
- if (size.width() >= 0 && size.width() < result.width())
- result.setWidth(size.width());
- if (size.height() >= 0 && size.height() < result.height())
- result.setHeight(size.height());
-}
-
-static void expandSize(QSizeF &result, const QSizeF &size)
-{
- if (size.width() >= 0 && size.width() > result.width())
- result.setWidth(size.width());
- if (size.height() >= 0 && size.height() > result.height())
- result.setHeight(size.height());
-}
-
-static inline void combineHints(qreal &current, qreal fallbackHint)
-{
- if (current < 0)
- 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
- Note: Can potentially return the attached QQuickLayoutAttached object through \a attachedInfo.
-
- 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.
-
- Fractional size hints will be ceiled to the closest integer. This is in order to give some
- slack when the items are snapped to the pixel grid.
-
- | *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)
-{
- for (int i = 0; i < Qt::NSizeHints; ++i)
- cachedSizeHints[i] = QSizeF();
- QQuickLayoutAttached *info = attachedLayoutObject(item, false);
- // First, retrieve the user-specified hints from the attached "Layout." properties
- if (info) {
- struct Getters {
- SizeGetter call[NSizes];
- };
-
- static Getters horGetters = {
- {&QQuickLayoutAttached::minimumWidth, &QQuickLayoutAttached::preferredWidth, &QQuickLayoutAttached::maximumWidth},
- };
-
- static Getters verGetters = {
- {&QQuickLayoutAttached::minimumHeight, &QQuickLayoutAttached::preferredHeight, &QQuickLayoutAttached::maximumHeight}
- };
- for (int i = 0; i < NSizes; ++i) {
- SizeGetter getter = horGetters.call[i];
- Q_ASSERT(getter);
-
- if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
- cachedSizeHints[i].setWidth(qCeil((info->*getter)()));
-
- getter = verGetters.call[i];
- Q_ASSERT(getter);
- if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
- cachedSizeHints[i].setHeight(qCeil((info->*getter)()));
- }
- }
-
- QSizeF &minS = cachedSizeHints[Qt::MinimumSize];
- QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];
- QSizeF &maxS = cachedSizeHints[Qt::MaximumSize];
- QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent];
-
- // For instance, will normalize the following user-set hints
- // from: [10, 5, 60]
- // to: [10, 10, 60]
- normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
- normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
-
- // All explicit values gathered, now continue to gather the implicit sizes
-
- //--- GATHER MAXIMUM SIZE HINTS ---
- combineImplicitHints(info, Qt::MaximumSize, &maxS);
- combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()));
- // implicit max or min sizes should not limit an explicitly set preferred size
- expandSize(maxS, prefS);
- expandSize(maxS, minS);
-
- //--- GATHER MINIMUM SIZE HINTS ---
- combineImplicitHints(info, Qt::MinimumSize, &minS);
- expandSize(minS, QSizeF(0,0));
- boundSize(minS, prefS);
- boundSize(minS, maxS);
-
- //--- GATHER PREFERRED SIZE HINTS ---
- // First, from implicitWidth/Height
- qreal &prefWidth = prefS.rwidth();
- qreal &prefHeight = prefS.rheight();
- if (prefWidth < 0 && item->implicitWidth() > 0)
- prefWidth = qCeil(item->implicitWidth());
- if (prefHeight < 0 && item->implicitHeight() > 0)
- prefHeight = qCeil(item->implicitHeight());
-
- // If that fails, make an ultimate fallback to width/height
-
- if (!info && (prefWidth < 0 || prefHeight < 0))
- info = attachedLayoutObject(item);
-
- if (useFallbackToWidthOrHeight && info) {
- /* This block is a bit hacky, but if we want to support using width/height
- as preferred size hints in layouts, (which we think most people expect),
- we only want to use the initial width.
- This is because the width will change due to layout rearrangement, and the preferred
- width should return the same value, regardless of the current width.
- We therefore store the width in the implicitWidth attached property.
- Since the layout listens to changes of implicitWidth, (it will
- basically cause an invalidation of the layout), we have to disable that
- notification while we set the implicit width (and height).
-
- Only use this fallback the first time the size hint is queried. Otherwise, we might
- end up picking a width that is different than what was specified in the QML.
- */
- if (prefWidth < 0 || prefHeight < 0) {
- item->blockSignals(true);
- if (prefWidth < 0) {
- prefWidth = item->width();
- item->setImplicitWidth(prefWidth);
- }
- if (prefHeight < 0) {
- prefHeight = item->height();
- item->setImplicitHeight(prefHeight);
- }
- item->blockSignals(false);
- }
- }
-
-
-
- // Normalize again after the implicit hints have been gathered
- expandSize(prefS, minS);
- boundSize(prefS, maxS);
-
- //--- GATHER DESCENT
- // Minimum descent is only applicable for the effective minimum height,
- // so we gather the descent last.
- const qreal minimumDescent = minS.height() - item->baselineOffset();
- descentS.setHeight(minimumDescent);
-
- if (info) {
- QMarginsF margins = info->qMargins();
- QSizeF extraMargins(margins.left() + margins.right(), margins.top() + margins.bottom());
- minS += extraMargins;
- prefS += extraMargins;
- maxS += extraMargins;
- descentS += extraMargins;
- }
- if (attachedInfo)
- *attachedInfo = info;
-}
-
-/*!
- \internal
-
- Assumes \a info is set (if the object has an attached property)
- */
-QLayoutPolicy::Policy QQuickGridLayoutItem::effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info)
-{
- bool fillExtent = false;
- bool isSet = false;
- if (info) {
- if (orientation == Qt::Horizontal) {
- isSet = info->isFillWidthSet();
- if (isSet) fillExtent = info->fillWidth();
- } else {
- isSet = info->isFillHeightSet();
- if (isSet) fillExtent = info->fillHeight();
- }
- }
- if (!isSet && qobject_cast<QQuickLayout*>(item))
- fillExtent = true;
- return fillExtent ? QLayoutPolicy::Preferred : QLayoutPolicy::Fixed;
-
-}
-
void QQuickGridLayoutEngine::setAlignment(QQuickItem *quickItem, Qt::Alignment alignment)
{
if (QQuickGridLayoutItem *item = findLayoutItem(quickItem)) {
diff --git a/src/layouts/qquickgridlayoutengine_p.h b/src/layouts/qquickgridlayoutengine_p.h
index a94ef934..ce7285bf 100644
--- a/src/layouts/qquickgridlayoutengine_p.h
+++ b/src/layouts/qquickgridlayoutengine_p.h
@@ -64,23 +64,18 @@ public:
: QGridLayoutItem(row, column, rowSpan, columnSpan, alignment), m_item(item), sizeHintCacheDirty(true), useFallbackToWidthOrHeight(true) {}
- typedef qreal (QQuickLayoutAttached::*SizeGetter)() const;
-
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
Q_UNUSED(constraint); // Quick Layouts does not support constraint atm
return effectiveSizeHints()[which];
}
- static void effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **info, bool useFallbackToWidthOrHeight);
- static QLayoutPolicy::Policy effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info);
-
QSizeF *effectiveSizeHints() const
{
if (!sizeHintCacheDirty)
return cachedSizeHints;
- effectiveSizeHints_helper(m_item, cachedSizeHints, 0, useFallbackToWidthOrHeight);
+ QQuickLayout::effectiveSizeHints_helper(m_item, cachedSizeHints, 0, useFallbackToWidthOrHeight);
useFallbackToWidthOrHeight = false;
sizeHintCacheDirty = false;
@@ -103,7 +98,7 @@ public:
QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const
{
- return effectiveSizePolicy_helper(m_item, orientation, attachedLayoutObject(m_item, false));
+ return QQuickLayout::effectiveSizePolicy_helper(m_item, orientation, attachedLayoutObject(m_item, false));
}
void setGeometry(const QRectF &rect)
@@ -112,8 +107,7 @@ public:
const QRectF r = info ? rect.marginsRemoved(info->qMargins()) : rect;
const QSizeF oldSize(m_item->width(), m_item->height());
const QSizeF newSize = r.size();
- QPointF topLeft(qCeil(r.x()), qCeil(r.y()));
- m_item->setPosition(topLeft);
+ m_item->setPosition(r.topLeft());
if (newSize == oldSize) {
if (QQuickLayout *lay = qobject_cast<QQuickLayout *>(m_item)) {
if (lay->arrangementIsDirty())
@@ -135,7 +129,7 @@ private:
class QQuickGridLayoutEngine : public QGridLayoutEngine {
public:
- QQuickGridLayoutEngine() : QGridLayoutEngine(Qt::AlignVCenter) { }
+ QQuickGridLayoutEngine() : QGridLayoutEngine(Qt::AlignVCenter, true /*snapToPixelGrid*/) { }
int indexOf(QQuickItem *item) const {
for (int i = 0; i < q_items.size(); ++i) {
diff --git a/src/layouts/qquicklayout.cpp b/src/layouts/qquicklayout.cpp
index 759ad6f2..d812c112 100644
--- a/src/layouts/qquicklayout.cpp
+++ b/src/layouts/qquicklayout.cpp
@@ -38,6 +38,7 @@
#include <QEvent>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qnumeric.h>
+#include <QtCore/qmath.h>
#include <limits>
/*!
@@ -684,9 +685,6 @@ QQuickItem *QQuickLayoutAttached::item() const
}
-
-
-
QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent)
: QQuickItem(dd, parent),
m_dirty(false)
@@ -695,7 +693,7 @@ QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent)
QQuickLayout::~QQuickLayout()
{
-
+ d_func()->m_isReady = false;
}
QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object)
@@ -710,7 +708,11 @@ void QQuickLayout::updatePolish()
void QQuickLayout::componentComplete()
{
- QQuickItem::componentComplete();
+ Q_D(QQuickLayout);
+ d->m_disableRearrange = true;
+ QQuickItem::componentComplete(); // will call our geometryChanged(), (where isComponentComplete() == true)
+ d->m_disableRearrange = false;
+ d->m_isReady = true;
}
void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
@@ -726,9 +728,337 @@ void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
}
}
+bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const
+{
+ Q_D(const QQuickLayout);
+ bool ignoreItem = true;
+ QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
+ if (childPrivate->explicitVisible) {
+ effectiveSizeHints_helper(child, sizeHints, &info, true);
+ QSizeF effectiveMaxSize = sizeHints[Qt::MaximumSize];
+ if (!effectiveMaxSize.isNull()) {
+ QSizeF &prefS = sizeHints[Qt::PreferredSize];
+ if (effectiveSizePolicy_helper(child, Qt::Horizontal, info) == QLayoutPolicy::Fixed)
+ effectiveMaxSize.setWidth(prefS.width());
+ if (effectiveSizePolicy_helper(child, Qt::Vertical, info) == QLayoutPolicy::Fixed)
+ effectiveMaxSize.setHeight(prefS.height());
+ }
+ ignoreItem = effectiveMaxSize.isNull();
+ }
+
+ if (ignoreItem)
+ d->m_ignoredItems << child;
+ return ignoreItem;
+}
+
+void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ if (change == ItemChildAddedChange) {
+ QQuickItem *item = value.item;
+ QObject::connect(item, SIGNAL(implicitWidthChanged()), this, SLOT(invalidateSenderItem()));
+ QObject::connect(item, SIGNAL(implicitHeightChanged()), this, SLOT(invalidateSenderItem()));
+ QObject::connect(item, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(invalidateSenderItem()));
+ if (isReady())
+ updateLayoutItems();
+ } else if (change == ItemChildRemovedChange) {
+ QQuickItem *item = value.item;
+ QObject::disconnect(item, SIGNAL(implicitWidthChanged()), this, SLOT(invalidateSenderItem()));
+ QObject::disconnect(item, SIGNAL(implicitHeightChanged()), this, SLOT(invalidateSenderItem()));
+ QObject::disconnect(item, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(invalidateSenderItem()));
+ if (isReady())
+ updateLayoutItems();
+ }
+ QQuickItem::itemChange(change, value);
+}
+
+void QQuickLayout::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickLayout);
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ if (d->m_disableRearrange || !isReady() || !newGeometry.isValid())
+ return;
+
+ quickLayoutDebug() << "QQuickStackLayout::geometryChanged" << newGeometry << oldGeometry;
+ rearrange(newGeometry.size());
+}
+
+void QQuickLayout::invalidateSenderItem()
+{
+ if (!isReady())
+ return;
+ QQuickItem *item = static_cast<QQuickItem *>(sender());
+ Q_ASSERT(item);
+ invalidate(item);
+}
+
+bool QQuickLayout::isReady() const
+{
+ return d_func()->m_isReady;
+}
+
void QQuickLayout::rearrange(const QSizeF &/*size*/)
{
m_dirty = false;
}
+
+/*
+ The layout engine assumes:
+ 1. minimum <= preferred <= maximum
+ 2. descent is within minimum and maximum bounds (### verify)
+
+ This function helps to ensure that by the following rules (in the following order):
+ 1. If minimum > maximum, set minimum = maximum
+ 2. Clamp preferred to be between the [minimum,maximum] range.
+ 3. If descent > minimum, set descent = minimum (### verify if this is correct, it might
+ need some refinements to multiline texts)
+
+ If any values are "not set" (i.e. negative), they will be left untouched, so that we
+ know which values needs to be fetched from the implicit hints (not user hints).
+ */
+static void normalizeHints(qreal &minimum, qreal &preferred, qreal &maximum, qreal &descent)
+{
+ if (minimum >= 0 && maximum >= 0 && minimum > maximum)
+ minimum = maximum;
+
+ if (preferred >= 0) {
+ if (minimum >= 0 && preferred < minimum) {
+ preferred = minimum;
+ } else if (maximum >= 0 && preferred > maximum) {
+ preferred = maximum;
+ }
+ }
+
+ if (minimum >= 0 && descent > minimum)
+ descent = minimum;
+}
+
+static void boundSize(QSizeF &result, const QSizeF &size)
+{
+ if (size.width() >= 0 && size.width() < result.width())
+ result.setWidth(size.width());
+ if (size.height() >= 0 && size.height() < result.height())
+ result.setHeight(size.height());
+}
+
+static void expandSize(QSizeF &result, const QSizeF &size)
+{
+ if (size.width() >= 0 && size.width() > result.width())
+ result.setWidth(size.width());
+ if (size.height() >= 0 && size.height() > result.height())
+ result.setHeight(size.height());
+}
+
+static inline void combineHints(qreal &current, qreal fallbackHint)
+{
+ if (current < 0)
+ 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());
+}
+
+typedef qreal (QQuickLayoutAttached::*SizeGetter)() const;
+
+/*!
+ \internal
+ Note: Can potentially return the attached QQuickLayoutAttached object through \a attachedInfo.
+
+ 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.
+
+ Fractional size hints will be ceiled to the closest integer. This is in order to give some
+ slack when the items are snapped to the pixel grid.
+
+ | *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 QQuickLayout::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);
+ // First, retrieve the user-specified hints from the attached "Layout." properties
+ if (info) {
+ struct Getters {
+ SizeGetter call[NSizes];
+ };
+
+ static Getters horGetters = {
+ {&QQuickLayoutAttached::minimumWidth, &QQuickLayoutAttached::preferredWidth, &QQuickLayoutAttached::maximumWidth},
+ };
+
+ static Getters verGetters = {
+ {&QQuickLayoutAttached::minimumHeight, &QQuickLayoutAttached::preferredHeight, &QQuickLayoutAttached::maximumHeight}
+ };
+ for (int i = 0; i < NSizes; ++i) {
+ SizeGetter getter = horGetters.call[i];
+ Q_ASSERT(getter);
+
+ if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
+ cachedSizeHints[i].setWidth((info->*getter)());
+
+ getter = verGetters.call[i];
+ Q_ASSERT(getter);
+ if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
+ cachedSizeHints[i].setHeight((info->*getter)());
+ }
+ }
+
+ QSizeF &minS = cachedSizeHints[Qt::MinimumSize];
+ QSizeF &prefS = cachedSizeHints[Qt::PreferredSize];
+ QSizeF &maxS = cachedSizeHints[Qt::MaximumSize];
+ QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent];
+
+ // For instance, will normalize the following user-set hints
+ // from: [10, 5, 60]
+ // to: [10, 10, 60]
+ normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth());
+ normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight());
+
+ // All explicit values gathered, now continue to gather the implicit sizes
+
+ //--- GATHER MAXIMUM SIZE HINTS ---
+ combineImplicitHints(info, Qt::MaximumSize, &maxS);
+ combineSize(maxS, QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()));
+ // implicit max or min sizes should not limit an explicitly set preferred size
+ expandSize(maxS, prefS);
+ expandSize(maxS, minS);
+
+ //--- GATHER MINIMUM SIZE HINTS ---
+ combineImplicitHints(info, Qt::MinimumSize, &minS);
+ expandSize(minS, QSizeF(0,0));
+ boundSize(minS, prefS);
+ boundSize(minS, maxS);
+
+ //--- GATHER PREFERRED SIZE HINTS ---
+ // First, from implicitWidth/Height
+ qreal &prefWidth = prefS.rwidth();
+ qreal &prefHeight = prefS.rheight();
+ if (prefWidth < 0 && item->implicitWidth() > 0)
+ prefWidth = qCeil(item->implicitWidth());
+ if (prefHeight < 0 && item->implicitHeight() > 0)
+ prefHeight = qCeil(item->implicitHeight());
+
+ // If that fails, make an ultimate fallback to width/height
+
+ if (!info && (prefWidth < 0 || prefHeight < 0))
+ info = attachedLayoutObject(item);
+
+ if (useFallbackToWidthOrHeight && info) {
+ /* This block is a bit hacky, but if we want to support using width/height
+ as preferred size hints in layouts, (which we think most people expect),
+ we only want to use the initial width.
+ This is because the width will change due to layout rearrangement, and the preferred
+ width should return the same value, regardless of the current width.
+ We therefore store the width in the implicitWidth attached property.
+ Since the layout listens to changes of implicitWidth, (it will
+ basically cause an invalidation of the layout), we have to disable that
+ notification while we set the implicit width (and height).
+
+ Only use this fallback the first time the size hint is queried. Otherwise, we might
+ end up picking a width that is different than what was specified in the QML.
+ */
+ if (prefWidth < 0 || prefHeight < 0) {
+ item->blockSignals(true);
+ if (prefWidth < 0) {
+ prefWidth = item->width();
+ item->setImplicitWidth(prefWidth);
+ }
+ if (prefHeight < 0) {
+ prefHeight = item->height();
+ item->setImplicitHeight(prefHeight);
+ }
+ item->blockSignals(false);
+ }
+ }
+
+
+
+ // Normalize again after the implicit hints have been gathered
+ expandSize(prefS, minS);
+ boundSize(prefS, maxS);
+
+ //--- GATHER DESCENT
+ // Minimum descent is only applicable for the effective minimum height,
+ // so we gather the descent last.
+ const qreal minimumDescent = minS.height() - item->baselineOffset();
+ descentS.setHeight(minimumDescent);
+
+ if (info) {
+ QMarginsF margins = info->qMargins();
+ QSizeF extraMargins(margins.left() + margins.right(), margins.top() + margins.bottom());
+ minS += extraMargins;
+ prefS += extraMargins;
+ maxS += extraMargins;
+ descentS += extraMargins;
+ }
+ if (attachedInfo)
+ *attachedInfo = info;
+}
+
+/*!
+ \internal
+
+ Assumes \a info is set (if the object has an attached property)
+ */
+QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info)
+{
+ bool fillExtent = false;
+ bool isSet = false;
+ if (info) {
+ if (orientation == Qt::Horizontal) {
+ isSet = info->isFillWidthSet();
+ if (isSet) fillExtent = info->fillWidth();
+ } else {
+ isSet = info->isFillHeightSet();
+ if (isSet) fillExtent = info->fillHeight();
+ }
+ }
+ if (!isSet && qobject_cast<QQuickLayout*>(item))
+ fillExtent = true;
+ return fillExtent ? QLayoutPolicy::Preferred : QLayoutPolicy::Fixed;
+
+}
+
+
+
QT_END_NAMESPACE
diff --git a/src/layouts/qquicklayout_p.h b/src/layouts/qquicklayout_p.h
index 37f6ca00..d613f5bd 100644
--- a/src/layouts/qquicklayout_p.h
+++ b/src/layouts/qquicklayout_p.h
@@ -40,6 +40,7 @@
#include <QPointer>
#include <QQuickItem>
#include <private/qquickitem_p.h>
+#include <QtGui/private/qlayoutpolicy_p.h>
QT_BEGIN_NAMESPACE
@@ -81,6 +82,16 @@ public:
virtual void rearrange(const QSizeF &);
bool arrangementIsDirty() const { return m_dirty; }
+
+ static void effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **info, bool useFallbackToWidthOrHeight);
+ static QLayoutPolicy::Policy effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info);
+ bool shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const;
+
+ void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ bool isReady() const;
+
+
protected:
void updatePolish() Q_DECL_OVERRIDE;
@@ -90,6 +101,9 @@ protected:
NOrientations
};
+protected slots:
+ void invalidateSenderItem();
+
private:
bool m_dirty;
@@ -102,6 +116,13 @@ private:
class QQuickLayoutPrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickLayout)
+public:
+ QQuickLayoutPrivate() : m_isReady(false), m_disableRearrange(true) {}
+
+protected:
+ unsigned m_isReady : 1;
+ unsigned m_disableRearrange : 1;
+ mutable QSet<QQuickItem *> m_ignoredItems;
};
diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp
index 0b9c6f54..cbd32976 100644
--- a/src/layouts/qquicklinearlayout.cpp
+++ b/src/layouts/qquicklinearlayout.cpp
@@ -323,7 +323,6 @@ void QQuickGridLayoutBase::setAlignment(QQuickItem *item, Qt::Alignment alignmen
QQuickGridLayoutBase::~QQuickGridLayoutBase()
{
Q_D(QQuickGridLayoutBase);
- d->m_isReady = false;
/* Avoid messy deconstruction, should give:
* Faster deconstruction
@@ -341,12 +340,8 @@ QQuickGridLayoutBase::~QQuickGridLayoutBase()
void QQuickGridLayoutBase::componentComplete()
{
- Q_D(QQuickGridLayoutBase);
quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::componentComplete()" << parent();
- d->m_disableRearrange = true;
- QQuickLayout::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true)
- d->m_isReady = true;
- d->m_disableRearrange = false;
+ QQuickLayout::componentComplete();
updateLayoutItems();
QQuickItem *par = parentItem();
@@ -469,10 +464,6 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v
QQuickItem *item = value.item;
QObject::connect(item, SIGNAL(destroyed()), this, SLOT(onItemDestroyed()));
QObject::connect(item, SIGNAL(visibleChanged()), this, SLOT(onItemVisibleChanged()));
- QObject::connect(item, SIGNAL(implicitWidthChanged()), this, SLOT(invalidateSenderItem()));
- QObject::connect(item, SIGNAL(implicitHeightChanged()), this, SLOT(invalidateSenderItem()));
- QObject::connect(item, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(invalidateSenderItem()));
-
if (isReady())
updateLayoutItems();
} else if (change == ItemChildRemovedChange) {
@@ -480,9 +471,6 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v
QQuickItem *item = value.item;
QObject::disconnect(item, SIGNAL(destroyed()), this, SLOT(onItemDestroyed()));
QObject::disconnect(item, SIGNAL(visibleChanged()), this, SLOT(onItemVisibleChanged()));
- QObject::disconnect(item, SIGNAL(implicitWidthChanged()), this, SLOT(invalidateSenderItem()));
- QObject::disconnect(item, SIGNAL(implicitHeightChanged()), this, SLOT(invalidateSenderItem()));
- QObject::disconnect(item, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(invalidateSenderItem()));
if (isReady())
updateLayoutItems();
}
@@ -490,16 +478,6 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v
QQuickLayout::itemChange(change, value);
}
-void QQuickGridLayoutBase::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_D(QQuickGridLayoutBase);
- QQuickLayout::geometryChanged(newGeometry, oldGeometry);
- if (d->m_disableRearrange || !isReady() || !newGeometry.isValid())
- return;
- quickLayoutDebug() << "QQuickGridLayoutBase::geometryChanged" << newGeometry << oldGeometry;
- rearrange(newGeometry.size());
-}
-
void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem)
{
Q_D(QQuickGridLayoutBase);
@@ -508,11 +486,6 @@ void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem)
d->engine.removeRows(index, 1, d->orientation);
}
-bool QQuickGridLayoutBase::isReady() const
-{
- return d_func()->m_isReady;
-}
-
void QQuickGridLayoutBase::onItemVisibleChanged()
{
if (!isReady())
@@ -535,15 +508,6 @@ void QQuickGridLayoutBase::onItemDestroyed()
}
}
-void QQuickGridLayoutBase::invalidateSenderItem()
-{
- if (!isReady())
- return;
- QQuickItem *item = static_cast<QQuickItem *>(sender());
- Q_ASSERT(item);
- invalidate(item);
-}
-
void QQuickGridLayoutBase::rearrange(const QSizeF &size)
{
Q_D(QQuickGridLayoutBase);
@@ -578,29 +542,6 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
}
}
-bool QQuickGridLayoutBase::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints)
-{
- Q_D(QQuickGridLayoutBase);
- bool ignoreItem = true;
- QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
- if (childPrivate->explicitVisible) {
- QQuickGridLayoutItem::effectiveSizeHints_helper(child, sizeHints, &info, true);
- QSizeF effectiveMaxSize = sizeHints[Qt::MaximumSize];
- if (!effectiveMaxSize.isNull()) {
- QSizeF &prefS = sizeHints[Qt::PreferredSize];
- if (QQuickGridLayoutItem::effectiveSizePolicy_helper(child, Qt::Horizontal, info) == QLayoutPolicy::Fixed)
- effectiveMaxSize.setWidth(prefS.width());
- if (QQuickGridLayoutItem::effectiveSizePolicy_helper(child, Qt::Vertical, info) == QLayoutPolicy::Fixed)
- effectiveMaxSize.setHeight(prefS.height());
- }
- ignoreItem = effectiveMaxSize.isNull();
- }
-
- if (ignoreItem)
- d->m_ignoredItems << child;
- return ignoreItem;
-}
-
/**********************************
**
** QQuickGridLayout
diff --git a/src/layouts/qquicklinearlayout_p.h b/src/layouts/qquicklinearlayout_p.h
index b6483c4e..e3522bce 100644
--- a/src/layouts/qquicklinearlayout_p.h
+++ b/src/layouts/qquicklinearlayout_p.h
@@ -39,7 +39,6 @@
#include "qquicklayout_p.h"
#include "qquickgridlayoutengine_p.h"
-#include <QtCore/qset.h>
QT_BEGIN_NAMESPACE
@@ -83,8 +82,6 @@ protected:
void rearrange(const QSizeF &size) Q_DECL_OVERRIDE;
virtual void insertLayoutItems() {}
void itemChange(ItemChange change, const ItemChangeData &data) Q_DECL_OVERRIDE;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- bool shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints);
signals:
Q_REVISION(1) void layoutDirectionChanged();
@@ -92,11 +89,9 @@ signals:
protected slots:
void onItemVisibleChanged();
void onItemDestroyed();
- void invalidateSenderItem();
private:
void removeGridItem(QGridLayoutItem *gridItem);
- bool isReady() const;
Q_DECLARE_PRIVATE(QQuickGridLayoutBase)
};
@@ -107,9 +102,7 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate
Q_DECLARE_PUBLIC(QQuickGridLayoutBase)
public:
- QQuickGridLayoutBasePrivate() : m_disableRearrange(true)
- , m_isReady(false)
- , m_rearranging(false)
+ QQuickGridLayoutBasePrivate() : m_rearranging(false)
, m_updateAfterRearrange(false)
, m_layoutDirection(Qt::LeftToRight)
{}
@@ -122,14 +115,11 @@ public:
QQuickGridLayoutEngine engine;
Qt::Orientation orientation;
- unsigned m_disableRearrange : 1;
- unsigned m_isReady : 1;
unsigned m_rearranging : 1;
unsigned m_updateAfterRearrange : 1;
QVector<QQuickItem *> m_invalidateAfterRearrange;
Qt::LayoutDirection m_layoutDirection : 2;
- QSet<QQuickItem *> m_ignoredItems;
QQuickLayoutStyleInfo *styleInfo;
};
diff --git a/src/layouts/qquickstacklayout.cpp b/src/layouts/qquickstacklayout.cpp
new file mode 100644
index 00000000..66513bfd
--- /dev/null
+++ b/src/layouts/qquickstacklayout.cpp
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Layouts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstacklayout_p.h"
+#include <limits>
+
+/*!
+ \qmltype StackLayout
+ \instantiates QQuickStackLayout
+ \inherits Item
+ \inqmlmodule QtQuick.Layouts
+ \ingroup layouts
+ \brief The StackLayout class provides a stack of items where
+ only one item is visible at a time.
+
+ The current visible item can be modified by setting the \l currentIndex property.
+ The index corresponds to the order of the StackLayout's children.
+
+ In contrast to most other layouts, child Items' \l{Layout::fillWidth}{Layout.fillWidth} and \l{Layout::fillHeight}{Layout.fillHeight} properties
+ default to \c true. As a consequence, child items are by default filled to match the size of the StackLayout as long as their
+ \l{Layout::maximumWidth}{Layout.maximumWidth} or \l{Layout::maximumHeight}{Layout.maximumHeight} does not prevent it.
+
+ Items are added to the layout by reparenting the item to the layout. Similarly, removal is done by reparenting the item from the layout.
+ Both of these operations will affect the layout's \l count property.
+
+ The following code will create a StackLayout where only the 'plum' rectangle is visible.
+ \code
+ StackLayout {
+ id: layout
+ anchors.fill: parent
+ currentIndex: 1
+ Rectangle {
+ color: 'teal'
+ implicitWidth: 200
+ implicitHeight: 200
+ }
+ Rectangle {
+ color: 'plum'
+ implicitWidth: 300
+ implicitHeight: 200
+ }
+ }
+ \endcode
+
+ Items in a StackLayout support these attached properties:
+ \list
+ \li \l{Layout::minimumWidth}{Layout.minimumWidth}
+ \li \l{Layout::minimumHeight}{Layout.minimumHeight}
+ \li \l{Layout::preferredWidth}{Layout.preferredWidth}
+ \li \l{Layout::preferredHeight}{Layout.preferredHeight}
+ \li \l{Layout::maximumWidth}{Layout.maximumWidth}
+ \li \l{Layout::maximumHeight}{Layout.maximumHeight}
+ \li \l{Layout::fillWidth}{Layout.fillWidth}
+ \li \l{Layout::fillHeight}{Layout.fillHeight}
+ \endlist
+
+ Read more about attached properties \l{QML Object Attributes}{here}.
+ \sa ColumnLayout
+ \sa GridLayout
+ \sa RowLayout
+ \sa StackView
+*/
+
+QQuickStackLayout::QQuickStackLayout(QQuickItem *parent) :
+ QQuickLayout(*new QQuickStackLayoutPrivate, parent)
+{
+}
+
+/*!
+ \qmlproperty int StackLayout::count
+
+ This property holds the number of items that belong to the layout.
+
+ Only items that are children of the StackLayout will be candidates for layouting.
+*/
+int QQuickStackLayout::count() const
+{
+ Q_D(const QQuickStackLayout);
+ return d->count;
+}
+
+/*!
+ \qmlproperty int StackLayout::currentIndex
+
+ This property holds the index of the child item that is currently visible in the StackLayout.
+ By default it will be \c -1 for an empty layout, otherwise the default is \c 0 (referring to the first item).
+*/
+int QQuickStackLayout::currentIndex() const
+{
+ Q_D(const QQuickStackLayout);
+ return d->currentIndex;
+}
+
+void QQuickStackLayout::setCurrentIndex(int index)
+{
+ Q_D(QQuickStackLayout);
+ if (index != d->currentIndex) {
+ QQuickItem *prev = itemAt(d->currentIndex);
+ QQuickItem *next = itemAt(index);
+ d->currentIndex = index;
+ d->explicitCurrentIndex = true;
+ if (prev)
+ prev->setVisible(false);
+ if (next)
+ next->setVisible(true);
+
+ if (isComponentComplete()) {
+ rearrange(QSizeF(width(), height()));
+ emit currentIndexChanged();
+ }
+ }
+}
+
+void QQuickStackLayout::componentComplete()
+{
+ QQuickLayout::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true)
+
+ updateLayoutItems();
+
+ QQuickItem *par = parentItem();
+ if (qobject_cast<QQuickLayout*>(par))
+ return;
+
+ rearrange(QSizeF(width(), height()));
+}
+
+QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const
+{
+ QSizeF &askingFor = m_cachedSizeHints[whichSizeHint];
+ if (!askingFor.isValid()) {
+ QSizeF &minS = m_cachedSizeHints[Qt::MinimumSize];
+ QSizeF &prefS = m_cachedSizeHints[Qt::PreferredSize];
+ QSizeF &maxS = m_cachedSizeHints[Qt::MaximumSize];
+
+ minS = QSizeF(0,0);
+ prefS = QSizeF(0,0);
+ maxS = QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity());
+
+ const int count = itemCount();
+ m_cachedItemSizeHints.resize(count);
+ for (int i = 0; i < count; ++i) {
+ SizeHints &hints = m_cachedItemSizeHints[i];
+ QQuickStackLayout::collectItemSizeHints(itemAt(i), hints.array);
+ minS = minS.expandedTo(hints.min());
+ prefS = prefS.expandedTo(hints.pref());
+ //maxS = maxS.boundedTo(hints.max()); // Can be resized to be larger than any of its items.
+ // This is the same as QStackLayout does it.
+ // Not sure how descent makes sense here...
+ }
+ }
+ return askingFor;
+}
+
+int QQuickStackLayout::indexOf(QQuickItem *childItem) const
+{
+ if (childItem) {
+ int indexOfItem = 0;
+ foreach (QQuickItem *item, childItems()) {
+ if (shouldIgnoreItem(item))
+ continue;
+ if (childItem == item)
+ return indexOfItem;
+ ++indexOfItem;
+ }
+ }
+ return -1;
+}
+
+QQuickItem *QQuickStackLayout::itemAt(int index) const
+{
+ foreach (QQuickItem *item, childItems()) {
+ if (shouldIgnoreItem(item))
+ continue;
+ if (index == 0)
+ return item;
+ --index;
+ }
+ return 0;
+}
+
+int QQuickStackLayout::itemCount() const
+{
+ int count = 0;
+ foreach (QQuickItem *item, childItems()) {
+ if (shouldIgnoreItem(item))
+ continue;
+ ++count;
+ }
+ return count;
+}
+
+void QQuickStackLayout::setAlignment(QQuickItem * /*item*/, Qt::Alignment /*align*/)
+{
+ // ### Do we have to respect alignment?
+}
+
+void QQuickStackLayout::invalidate(QQuickItem *childItem)
+{
+ Q_D(QQuickStackLayout);
+ if (d->m_ignoredItems.contains(childItem)) {
+ // If an invalid item gets a valid size, it should be included, as it was added to the layout
+ updateLayoutItems();
+ return;
+ }
+
+ const int indexOfChild = indexOf(childItem);
+ if (indexOfChild >= 0 && indexOfChild < m_cachedItemSizeHints.count()) {
+ m_cachedItemSizeHints[indexOfChild].min() = QSizeF();
+ m_cachedItemSizeHints[indexOfChild].pref() = QSizeF();
+ m_cachedItemSizeHints[indexOfChild].max() = QSizeF();
+ }
+
+ for (int i = 0; i < Qt::NSizeHints; ++i)
+ m_cachedSizeHints[i] = QSizeF();
+ QQuickLayout::invalidate(this);
+
+ QQuickLayoutAttached *info = attachedLayoutObject(this);
+
+ const QSizeF min = sizeHint(Qt::MinimumSize);
+ const QSizeF pref = sizeHint(Qt::PreferredSize);
+ const QSizeF max = sizeHint(Qt::MaximumSize);
+
+ const bool old = info->setChangesNotificationEnabled(false);
+ info->setMinimumImplicitSize(min);
+ info->setMaximumImplicitSize(max);
+ info->setChangesNotificationEnabled(old);
+ if (pref.width() == implicitWidth() && pref.height() == implicitHeight()) {
+ // In case setImplicitSize does not emit implicit{Width|Height}Changed
+ if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(parentItem()))
+ parentLayout->invalidate(this);
+ } else {
+ setImplicitSize(pref.width(), pref.height());
+ }
+}
+
+void QQuickStackLayout::updateLayoutItems()
+{
+ Q_D(QQuickStackLayout);
+ d->m_ignoredItems.clear();
+ const int count = itemCount();
+ int oldIndex = d->currentIndex;
+ if (!d->explicitCurrentIndex)
+ d->currentIndex = (count > 0 ? 0 : -1);
+
+ if (d->currentIndex != oldIndex)
+ emit currentIndexChanged();
+
+ if (count != d->count) {
+ d->count = count;
+ emit countChanged();
+ }
+ for (int i = 0; i < count; ++i)
+ itemAt(i)->setVisible(d->currentIndex == i);
+
+ invalidate();
+}
+
+void QQuickStackLayout::rearrange(const QSizeF &newSize)
+{
+ Q_D(QQuickStackLayout);
+ if (newSize.isNull() || !newSize.isValid())
+ return;
+ (void)sizeHint(Qt::PreferredSize); // Make sure m_cachedItemSizeHints are valid
+
+ if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.count())
+ return;
+ QQuickStackLayout::SizeHints &hints = m_cachedItemSizeHints[d->currentIndex];
+ QQuickItem *item = itemAt(d->currentIndex);
+ Q_ASSERT(item);
+ item->setPosition(QPointF(0,0)); // ### respect alignment?
+ item->setSize(newSize.expandedTo(hints.min()).boundedTo(hints.max()));
+ QQuickLayout::rearrange(newSize);
+}
+
+void QQuickStackLayout::collectItemSizeHints(QQuickItem *item, QSizeF *sizeHints)
+{
+ QQuickLayoutAttached *info = 0;
+ QQuickLayout::effectiveSizeHints_helper(item, sizeHints, &info, true);
+ if (!info)
+ return;
+ if (info->isFillWidthSet() && !info->fillWidth()) {
+ const qreal pref = sizeHints[Qt::PreferredSize].width();
+ sizeHints[Qt::MinimumSize].setWidth(pref);
+ sizeHints[Qt::MaximumSize].setWidth(pref);
+ }
+
+ if (info->isFillHeightSet() && !info->fillHeight()) {
+ const qreal pref = sizeHints[Qt::PreferredSize].height();
+ sizeHints[Qt::MinimumSize].setHeight(pref);
+ sizeHints[Qt::MaximumSize].setHeight(pref);
+ }
+}
+
+bool QQuickStackLayout::shouldIgnoreItem(QQuickItem *item) const
+{
+ const bool ignored = QQuickItemPrivate::get(item)->isTransparentForPositioner();
+ if (ignored)
+ d_func()->m_ignoredItems << item;
+ return ignored;
+}
diff --git a/src/layouts/qquickstacklayout_p.h b/src/layouts/qquickstacklayout_p.h
new file mode 100644
index 00000000..92121400
--- /dev/null
+++ b/src/layouts/qquickstacklayout_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Layouts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTACKLAYOUT_H
+#define QQUICKSTACKLAYOUT_H
+
+#include <qquicklayout_p.h>
+
+class QQuickStackLayoutPrivate;
+
+class QQuickStackLayout : public QQuickLayout
+{
+ Q_OBJECT
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+
+public:
+ explicit QQuickStackLayout(QQuickItem *parent = 0);
+ int count() const;
+ int currentIndex() const;
+ void setCurrentIndex(int index);
+
+ void componentComplete() Q_DECL_OVERRIDE;
+ QSizeF sizeHint(Qt::SizeHint whichSizeHint) const Q_DECL_OVERRIDE;
+ void setAlignment(QQuickItem *item, Qt::Alignment align) Q_DECL_OVERRIDE;
+ void invalidate(QQuickItem *childItem = 0) Q_DECL_OVERRIDE;
+ void updateLayoutItems() Q_DECL_OVERRIDE;
+ void rearrange(const QSizeF &) Q_DECL_OVERRIDE;
+
+ // iterator
+ Q_INVOKABLE QQuickItem *itemAt(int index) const Q_DECL_OVERRIDE;
+ int itemCount() const Q_DECL_OVERRIDE;
+ int indexOf(QQuickItem *item) const;
+
+
+
+signals:
+ void currentIndexChanged();
+ void countChanged();
+
+public slots:
+
+private:
+ static void collectItemSizeHints(QQuickItem *item, QSizeF *sizeHints);
+ bool shouldIgnoreItem(QQuickItem *item) const;
+ Q_DECLARE_PRIVATE(QQuickStackLayout)
+
+ QList<QQuickItem*> m_items;
+
+ typedef struct {
+ inline QSizeF &min() { return array[Qt::MinimumSize]; }
+ inline QSizeF &pref() { return array[Qt::PreferredSize]; }
+ inline QSizeF &max() { return array[Qt::MaximumSize]; }
+ QSizeF array[Qt::NSizeHints];
+ } SizeHints;
+
+ mutable QVector<SizeHints> m_cachedItemSizeHints;
+ mutable QSizeF m_cachedSizeHints[Qt::NSizeHints];
+};
+
+class QQuickStackLayoutPrivate : public QQuickLayoutPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickStackLayout)
+public:
+ QQuickStackLayoutPrivate() : count(0), currentIndex(-1), explicitCurrentIndex(false) {}
+private:
+ int count;
+ int currentIndex;
+ bool explicitCurrentIndex;
+};
+
+#endif // QQUICKSTACKLAYOUT_H
diff --git a/src/widgets/qquickqfiledialog.cpp b/src/widgets/qquickqfiledialog.cpp
index 90d1ef9e..7ebebf1f 100644
--- a/src/widgets/qquickqfiledialog.cpp
+++ b/src/widgets/qquickqfiledialog.cpp
@@ -209,6 +209,7 @@ void QFileDialogHelper::fileSelected(const QString& path)
void QFileDialogHelper::filesSelected(const QStringList& paths)
{
QList<QUrl> pathUrls;
+ pathUrls.reserve(paths.count());
foreach (const QString &path, paths)
pathUrls << QUrl::fromLocalFile(path);
emit QPlatformFileDialogHelper::filesSelected(pathUrls);
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index 53208380..2e3c8164 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -1,3 +1,5 @@
+requires(contains(QT_CONFIG, accessibility))
+
CXX_MODULE = qml
TARGET = widgetsplugin
TARGETPATH = QtQuick/PrivateWidgets