mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-23 06:38:07 +00:00
feat(mainWindow): use new search bar
This commit is contained in:
parent
d53a4f20f5
commit
aa790dc0cf
5 changed files with 156 additions and 55 deletions
|
|
@ -31,6 +31,7 @@
|
|||
<file>ui/components/form/TransparentComboBox.qml</file>
|
||||
<file>ui/components/form/SmallButton.qml</file>
|
||||
<file>ui/components/form/DarkButton.qml</file>
|
||||
<file>ui/components/invertedMouseArea/InvertedMouseArea.qml</file>
|
||||
<file>ui/scripts/utils.js</file>
|
||||
<file>ui/views/newCall.qml</file>
|
||||
<file>ui/views/manageAccounts.qml</file>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
86
tests/ui/components/invertedMouseArea/InvertedMouseArea.qml
Normal file
86
tests/ui/components/invertedMouseArea/InvertedMouseArea.qml
Normal file
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue