From aa790dc0cf3473e86d76c6e84eba62a0f137a39d Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 23 Sep 2016 10:43:03 +0200 Subject: [PATCH] feat(mainWindow): use new search bar --- tests/resources.qrc | 1 + tests/ui/components/collapse/Collapse.qml | 21 ++--- .../invertedMouseArea/InvertedMouseArea.qml | 86 ++++++++++++++++++ tests/ui/components/searchBox/SearchBox.qml | 89 ++++++++++--------- tests/ui/views/mainWindow/mainWindow.qml | 14 ++- 5 files changed, 156 insertions(+), 55 deletions(-) create mode 100644 tests/ui/components/invertedMouseArea/InvertedMouseArea.qml diff --git a/tests/resources.qrc b/tests/resources.qrc index 7682af02b..427e93006 100644 --- a/tests/resources.qrc +++ b/tests/resources.qrc @@ -31,6 +31,7 @@ ui/components/form/TransparentComboBox.qml ui/components/form/SmallButton.qml ui/components/form/DarkButton.qml + ui/components/invertedMouseArea/InvertedMouseArea.qml ui/scripts/utils.js ui/views/newCall.qml ui/views/manageAccounts.qml diff --git a/tests/ui/components/collapse/Collapse.qml b/tests/ui/components/collapse/Collapse.qml index c514ce280..def381519 100644 --- a/tests/ui/components/collapse/Collapse.qml +++ b/tests/ui/components/collapse/Collapse.qml @@ -1,5 +1,6 @@ import QtQuick 2.7 +import 'qrc:/ui/components/form' import 'qrc:/ui/components/image' // =================================================================== @@ -9,21 +10,21 @@ Item { signal collapsed (bool collapsed) - function updateCollapse () { + function collapse () { isCollapsed = !isCollapsed collapsed(isCollapsed) rotate.start() } - Icon { - anchors.fill: parent - id: backgroundImage - icon: 'collapse' - - MouseArea { - anchors.fill: parent - onClicked: updateCollapse() + ActionButton { + anchors.centerIn: parent + background: Rectangle { + color: 'transparent' } + icon: 'collapse' + iconSize: 32 + id: button + onClicked: collapse() } RotationAnimation { @@ -32,7 +33,7 @@ Item { from: isCollapsed ? 0 : 180 id: rotate property: 'rotation' - target: backgroundImage + target: button to: isCollapsed ? 180 : 0 } } diff --git a/tests/ui/components/invertedMouseArea/InvertedMouseArea.qml b/tests/ui/components/invertedMouseArea/InvertedMouseArea.qml new file mode 100644 index 000000000..211f999e0 --- /dev/null +++ b/tests/ui/components/invertedMouseArea/InvertedMouseArea.qml @@ -0,0 +1,86 @@ +import QtQuick 2.0 + +// =================================================================== +// Helper to handle button click outside a component. +// =================================================================== + +Item { + property var mouseArea + + signal pressed + + function createMouseArea () { + if (mouseArea == null) { + mouseArea = builder.createObject(this) + } + + mouseArea.parent = (function () { + // Search root. + var p = item + + while (p.parent != null) { + p = p.parent + } + + return p + })() + } + + function deleteMouseArea () { + if (mouseArea != null) { + mouseArea.destroy() + mouseArea = null + } + } + + function isInItem (point) { + return ( + point.x >= item.x && + point.y >= item.y && + point.x <= item.x + item.width && + point.y <= item.y + item.height + ) + } + + id: item + + onEnabledChanged: { + deleteMouseArea() + + if (enabled) { + createMouseArea() + } + } + + Component { + id: builder + + MouseArea { + anchors.fill: parent + propagateComposedEvents: true + z: 9999999999 // Ugly! But it's necessary in some cases... + + onPressed: { + // Propagate event. + mouse.accepted = false + + if (!isInItem( + mapToItem(item.parent, mouse.x, mouse.y) + )) { + // Outside!!! + item.pressed() + } + } + } + } + + // It's necessary to use a `enabled` variable. + // See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal + // + // The creation order of components in a view is undefined, + // so the mouse area mustt be created only when `enabled == true`. + // + // In the first view render, `enabled` must equal false. + Component.onCompleted: enabled && createMouseArea() + Component.onDestruction: deleteMouseArea() +} diff --git a/tests/ui/components/searchBox/SearchBox.qml b/tests/ui/components/searchBox/SearchBox.qml index 9012246ff..d0150a199 100644 --- a/tests/ui/components/searchBox/SearchBox.qml +++ b/tests/ui/components/searchBox/SearchBox.qml @@ -2,6 +2,7 @@ import QtGraphicalEffects 1.0 import QtQuick 2.7 import QtQuick.Controls 2.0 +import 'qrc:/ui/components/invertedMouseArea' import 'qrc:/ui/components/popup' // =================================================================== @@ -10,68 +11,70 @@ Item { property alias placeholderText: searchField.placeholderText property alias maxMenuHeight: menu.maxMenuHeight + signal menuClosed () + signal menuOpened () + signal searchTextChanged (string text) + implicitHeight: searchField.height function hideMenu () { menu.hide() shadow.visible = false + searchField.focus = false + menuClosed() } function showMenu () { menu.show() shadow.visible = true + menuOpened() } - TextField { - signal searchTextChanged (string text) + Item { + implicitHeight: searchField.height + menu.height + width: parent.width - anchors.fill: parent - background: Rectangle { - implicitHeight: 30 - } - id: searchField - - Keys.onEscapePressed: focus = false - - onActiveFocusChanged: { - // Menu is hidden if `TextField` AND `FocusScope` focus - // are lost. - if (activeFocus) { - showMenu() - } else if (!scope.activeFocus) { - hideMenu() + TextField { + background: Rectangle { + implicitHeight: 30 } + id: searchField + width: parent.width + + Keys.onEscapePressed: hideMenu() + + onActiveFocusChanged: activeFocus && showMenu() + onTextChanged: searchTextChanged(text) } - onTextChanged: searchTextChanged(text) - } - - // Handle focus from content. (Buttons...) - FocusScope { - anchors.top: searchField.bottom - id: scope - z: 999 // Menu must be above any component. - - Keys.onEscapePressed: focus = false - - onActiveFocusChanged: !searchField.activeFocus && - !activeFocus && - hideMenu() DropDownMenu { + anchors.top: searchField.bottom id: menu width: searchField.width + z: 999 // Menu must be above any component. + + Keys.onEscapePressed: hideMenu() + } + + DropShadow { + anchors.fill: searchField + color: "#80000000" + horizontalOffset: 2 + id: shadow + radius: 8.0 + samples: 15 + source: searchField + verticalOffset: 2 + visible: false + } + + InvertedMouseArea { + enabled: menu.visible + height: parent.height + parent: parent + width: parent.width + + onPressed: hideMenu() } } - - DropShadow { - anchors.fill: searchField - color: "#80000000" - horizontalOffset: 2 - id: shadow - radius: 8.0 - samples: 15 - source: searchField - verticalOffset: 2 - visible: false - } } diff --git a/tests/ui/views/mainWindow/mainWindow.qml b/tests/ui/views/mainWindow/mainWindow.qml index 7a9a5933c..751dac15f 100644 --- a/tests/ui/views/mainWindow/mainWindow.qml +++ b/tests/ui/views/mainWindow/mainWindow.qml @@ -15,7 +15,7 @@ ApplicationWindow { id: mainWindow maximumHeight: 70 minimumHeight: 70 - minimumWidth: 700 + minimumWidth: 780 title: 'Linphone' visible: true @@ -64,8 +64,17 @@ ApplicationWindow { // Search. SearchBox { Layout.fillWidth: true - maxMenuHeight: mainWindow.height - 100 + maxMenuHeight: 300 // See Hick's law for good choice. placeholderText: qsTr('mainSearchBarPlaceholder') + + onMenuClosed: content.enabled = true + + onMenuOpened: { + if (!collapse.isCollapsed) { + collapse.collapse() + } + content.enabled = false + } } // Start conference. @@ -79,6 +88,7 @@ ApplicationWindow { RowLayout { anchors.fill: parent + id: content spacing: 0 // Main menu.