diff --git a/demo/FullScreenDialogDemo.qml b/demo/FullScreenDialogDemo.qml new file mode 100644 index 00000000..e48ba296 --- /dev/null +++ b/demo/FullScreenDialogDemo.qml @@ -0,0 +1,107 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.2 as QuickControls +import QtQuick.Layouts 1.1 +import Material 0.1 +import Material.Extras 0.1 + +Item { + + FullScreenDialog { + id: searchDialog + title: qsTr("Search") + positiveButtonText: qsTr("Search") + + Column { + width: parent.width + spacing: Units.dp(16) + + TextField { + id: searchText + placeholderText: qsTr("Search for") + floatingLabel: true + Layout.fillWidth: true + } + + Item { + width: parent.width + height: Units.dp(72) + + Ink { + anchors.fill: parent + z: -1 + } + + RowLayout { + anchors.fill: parent + anchors.topMargin: Units.dp(16) + anchors.bottomMargin: Units.dp(16) + + ColumnLayout { + spacing: Units.dp(3) + + Label { + text: qsTr("Case sensitive") + + Layout.fillWidth: true + + elide: Text.ElideRight + style: "subheading" + } + + Label { + Layout.fillWidth: true + + text: caseSwitch.checked ? qsTr("Ignore the case") : qsTr("Match the case") + color: Theme.light.subTextColor + elide: Text.ElideRight + wrapMode: Text.WordWrap + style: "body1" + } + } + + Switch { + id: caseSwitch + anchors.verticalCenter: parent.verticalCenter + } + } + } + + RowLayout { + width: parent.width + height: Units.dp(72) + + Label { + text: qsTr("Whole words only") + + Layout.fillWidth: true + + elide: Text.ElideRight + style: "subheading" + } + + Switch { + id: wholeWordSwitch + anchors.verticalCenter: parent.verticalCenter + } + } + } + } + + Column { + anchors.centerIn: parent + spacing: Units.dp(20) + + Button { + text: "Show full-screen dialog" + anchors.horizontalCenter: parent.horizontalCenter + elevation: 1 + onClicked: { + searchDialog.show() + } + } + } + + Snackbar { + id: dialogSnackBar + } +} diff --git a/demo/main.qml b/demo/main.qml index a4d1726d..a17b457a 100644 --- a/demo/main.qml +++ b/demo/main.qml @@ -26,7 +26,7 @@ ApplicationWindow { ] property var compoundComponents: [ - "Bottom Sheet", "Dialog", "Forms", "List Items", "Page Stack", "Time Picker", "Date Picker" + "Bottom Sheet", "Dialog", "Full-Screen Dialog", "Forms", "List Items", "Page Stack", "Time Picker", "Date Picker" ] property var sections: [ basicComponents, styles, compoundComponents ] @@ -248,9 +248,9 @@ ApplicationWindow { // selectedComponent will always be valid, as it defaults to the first component source: { if (navDrawer.enabled) { - return Qt.resolvedUrl("%1Demo.qml").arg(demo.selectedComponent.replace(" ", "")) + return Qt.resolvedUrl("%1Demo.qml").arg(demo.selectedComponent.replace(/[\s-]/g, "")) } else { - return Qt.resolvedUrl("%1Demo.qml").arg(selectedComponent.replace(" ", "")) + return Qt.resolvedUrl("%1Demo.qml").arg(selectedComponent.replace(/[\s-]/g, "")) } } } diff --git a/modules/Material/ApplicationWindow.qml b/modules/Material/ApplicationWindow.qml index 50c702fb..993f9478 100644 --- a/modules/Material/ApplicationWindow.qml +++ b/modules/Material/ApplicationWindow.qml @@ -113,6 +113,11 @@ Controls.ApplicationWindow { clientSideDecorations: app.clientSideDecorations } + OverlayLayer { + id: fullDialogOverlayLayer + objectName: "fullDialogOverlayLayer" + } + OverlayLayer { id: dialogOverlayLayer objectName: "dialogOverlayLayer" diff --git a/modules/Material/FullScreenDialog.qml b/modules/Material/FullScreenDialog.qml new file mode 100644 index 00000000..b8a8bd0e --- /dev/null +++ b/modules/Material/FullScreenDialog.qml @@ -0,0 +1,238 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.1 +import Material 0.1 +import Material.Extras 0.1 + +/*! + \qmltype FullScreenDialog + \inqmlmodule Material 0.1 + + \brief Full-screen dialogs group complex tasks that require explicit + action, such as save or create, before changes are committed or + discarded, as in a calendar entry. + */ +PopupBase { + id: dialog + + overlayLayer: "fullDialogOverlayLayer" + overlayColor: Qt.rgba(0, 0, 0, 0.3) + dismissOnTap: false + + opacity: showing ? 1 : 0 + visible: opacity > 0 + + readonly property int _minimumWidth: 640 + readonly property int _minimumHeight: 1280 + readonly property real _rw: 1.25 + readonly property real _rh: 1.12 + + onVisibleChanged: { + // orientation > 1 means landscape, orientation < 1 means portrait + var orientation = parent.width / parent.height + if (orientation >= 1 /*landscape*/) { + if (Units.dp(parent.width) <= _minimumWidth) { + width = parent.width + } else { + width = parent.width / 2 + } + height = parent.height + } else { + if (Units.dp(parent.height) < _minimumHeight) { + width = parent.width + height = parent.height + } else { + width = parent.width / _rw + height = parent.height / _rh + } + } + } + + property int contentMargins: Units.dp(16) + + /*! + \qmlproperty color titleBarColor + + The color of the title bar. By default, it uses the application's primary color. + */ + property color titleBarColor: Theme.primaryColor + + property alias title: titleLabel.text + + /*! + \qmlproperty Button negativeButton + + The negative button, displayed as the leftmost button on the right of the dialog buttons. + This is usually used to dismiss the dialog. + */ + property alias negativeButton: negativeButton + + /*! + \qmlproperty Button primaryButton + + The primary button, displayed as the rightmost button in the dialog buttons row. This is + usually used to accept the dialog's action. + */ + property alias positiveButton: positiveButton + + property string positiveButtonText: "Ok" + property alias positiveButtonEnabled: positiveButton.enabled + + default property alias dialogContent: column.data + + signal accepted() + signal rejected() + + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Keys.onPressed: { + if (event.key === Qt.Key_Escape) { + closeKeyPressed(event) + } + } + + Keys.onReleased: { + if (event.key === Qt.Key_Back) { + closeKeyPressed(event) + } + } + + function closeKeyPressed(event) { + if (dialog.showing) { + if (dialog.dismissOnTap) { + dialog.close() + } + event.accepted = true + } + } + + function show() { + open() + } + + View { + id: dialogContainer + + anchors.fill: parent + elevation: 5 + + MouseArea { + anchors.fill: parent + propagateComposedEvents: false + + onClicked: { + mouse.accepted = false + } + } + + View { + id: headerView + + anchors { + left: parent.left + right: parent.right + top: parent.top + } + + backgroundColor: titleBarColor + elevation: content.atYBeginning ? 0 : 1 + fullWidth: true + height: Units.dp(56) + + IconButton { + id: negativeButton + + anchors { + verticalCenter: titleLabel.verticalCenter + left: parent.left + leftMargin: Units.dp(16) + } + + iconName: "navigation/close" + color: Theme.lightDark(titleBarColor, Theme.light.iconColor, + Theme.dark.iconColor) + + onClicked: { + close() + rejected(); + } + } + + Label { + id: titleLabel + + anchors { + left: parent.left + right: positiveButton.left + top: parent.top + leftMargin: Units.dp(72) + rightMargin: Units.dp(16) + topMargin: Units.dp(16) + } + + wrapMode: Text.Wrap + style: "title" + visible: text != "" + color: Theme.lightDark(titleBarColor, Theme.light.textColor, + Theme.dark.textColor) + } + + Button { + id: positiveButton + text: positiveButtonText + + anchors { + verticalCenter: titleLabel.verticalCenter + right: parent.right + rightMargin: Units.dp(16) + } + + textColor: Theme.lightDark(titleBarColor, Theme.light.textColor, + Theme.dark.textColor) + + onClicked: { + close() + accepted(); + } + } + } + + Flickable { + id: content + + clip: true + anchors { + left: parent.left + right: parent.right + top: headerView.bottom + bottom: parent.bottom + bottomMargin: Units.dp(16) + } + interactive: contentHeight + Units.dp(8) > height + bottomMargin: 0 + + Column { + id: column + anchors { + left: parent.left + right: parent.right + top: parent.top + bottom: parent.bottom + margins: contentMargins + } + + spacing: Units.dp(16) + } + } + + Scrollbar { + flickableItem: content + } + } +} diff --git a/modules/Material/qmldir b/modules/Material/qmldir index 399da227..eaa41f1f 100644 --- a/modules/Material/qmldir +++ b/modules/Material/qmldir @@ -13,6 +13,7 @@ CheckBox 0.1 CheckBox.qml DatePicker 0.2 DatePicker.qml Dialog 0.1 Dialog.qml Dropdown 0.1 Dropdown.qml +FullScreenDialog 0.1 FullScreenDialog.qml Icon 0.1 Icon.qml IconButton 0.1 IconButton.qml Ink 0.1 Ink.qml