diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index 3a5253ead..95fea44ca 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -427,8 +427,6 @@ Window { id: contactsListPanel CallContactsLists { Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("Transfert d'appel") - sideMargin: 10 * DefaultStyle.dp - topMargin: 15 * DefaultStyle.dp groupCallVisible: false searchBarColor: DefaultStyle.grey_0 searchBarBorderColor: DefaultStyle.grey_200 @@ -745,28 +743,27 @@ Window { id: addParticipantComp AddParticipantsLayout { id: addParticipantLayout - titleLayout.visible: false onSelectedParticipantsCountChanged: { if (participantsStack.Control.StackView.status === Control.StackView.Active && Control.StackView.visible) { rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné").arg(selectedParticipants.length).arg(selectedParticipants.length > 1 ? "s" : "") } participantsStack.selectedParticipants = selectedParticipants } - onValidateRequested: { - conferenceInfoGui.core.resetParticipants(contactList.selectedContacts) - returnRequested() - } Connections { target: participantsStack onCurrentItemChanged: { if (participantsStack.currentItem == addParticipantLayout) { rightPanel.headerTitleText = qsTr("Ajouter des participants") - rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné").arg(addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length > 1 ? "s" : "") + rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length > 1 ? "s" : "") } } onParticipantAdded: { addParticipantLayout.clearSelectedParticipants() } + onValidateRequested: { + conferenceInfoGui.core.resetParticipants(contactList.selectedContacts) + returnRequested() + } } } } @@ -1115,6 +1112,27 @@ Window { else mainWindow.call.core.lStartRecording() } } + MenuButton { + checkable: true + icon.source: mainWindow.call.core.speakerMuted ? AppIcons.speakerSlash : AppIcons.speaker + icon.width: 32 * DefaultStyle.dp + icon.height: 32 * DefaultStyle.dp + contentImageColor: down + ? DefaultStyle.main1_500_main + : mainWindow.call && mainWindow.call.core.speakerMuted + ? DefaultStyle.danger_500main + : DefaultStyle.main2_500main + text: mainWindow.call && mainWindow.call.core.speakerMuted ? qsTr("Activer le son") : qsTr("Désactiver le son") + textColor: down + ? DefaultStyle.main1_500_main + :mainWindow.call && mainWindow.call.core.speakerMuted + ? DefaultStyle.danger_500main + : DefaultStyle.main2_500main + Layout.fillWidth: true + onCheckedChanged: { + if (mainWindow.call) mainWindow.call.core.lSetSpeakerMuted(!mainWindow.call.core.speakerMuted) + } + } MenuButton { Layout.fillWidth: true icon.source: AppIcons.settings diff --git a/Linphone/view/App/Layout/MainLayout.qml b/Linphone/view/App/Layout/MainLayout.qml index e38cbac09..fe31ebcd0 100644 --- a/Linphone/view/App/Layout/MainLayout.qml +++ b/Linphone/view/App/Layout/MainLayout.qml @@ -167,7 +167,7 @@ Item { shadowOpacity: 0.1 } } - Control.ScrollBar { + ScrollBar { id: scrollbar height: parent.height anchors.right: listPopup.right diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index ca80930d5..acd4f396d 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -69,6 +69,7 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Item/RadioButton.qml view/Item/RectangleTest.qml view/Item/RoundedBackgroundControl.qml + view/Item/ScrollBar.qml view/Item/SearchBar.qml view/Item/Slider.qml view/Item/Switch.qml diff --git a/Linphone/view/Item/Call/CallContactsLists.qml b/Linphone/view/Item/Call/CallContactsLists.qml index f284e790e..6044f6f77 100644 --- a/Linphone/view/Item/Call/CallContactsLists.qml +++ b/Linphone/view/Item/Call/CallContactsLists.qml @@ -8,13 +8,12 @@ import UtilsCpp 1.0 Item { id: mainItem - property int sideMargin: 25 * DefaultStyle.dp - property int topMargin: 5 * DefaultStyle.dp property bool groupCallVisible property color searchBarColor: DefaultStyle.grey_100 property color searchBarBorderColor: "transparent" signal callButtonPressed(string address) signal groupCallCreationRequested() + property NumericPad numPad clip: true Popup { @@ -25,7 +24,7 @@ Item { } underlineColor: DefaultStyle.main1_500_main anchors.centerIn: parent - width: parent.width - 30 * DefaultStyle.dp + width: parent.width modal: true leftPadding: 15 * DefaultStyle.dp rightPadding: 15 * DefaultStyle.dp @@ -41,9 +40,7 @@ Item { weight: 800 * DefaultStyle.dp } } - Item { - Layout.fillWidth: true - } + Item{Layout.fillWidth: true} Button { Layout.preferredWidth: 24 * DefaultStyle.dp Layout.preferredHeight: 24 * DefaultStyle.dp @@ -110,24 +107,9 @@ Item { } } - - Control.ScrollBar { - id: contactsScrollbar - active: true - interactive: true - policy: Control.ScrollBar.AsNeeded - // Layout.fillWidth: true - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.right: parent.right - // x: mainItem.x + mainItem.width - width - // anchors.left: control.right - } - Control.Control { id: listLayout anchors.fill: parent - anchors.topMargin: mainItem.topMargin background: Item { anchors.fill: parent } @@ -139,23 +121,31 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.maximumWidth: mainItem.width - Layout.leftMargin: mainItem.sideMargin - Layout.rightMargin: mainItem.sideMargin + Layout.rightMargin: 39 * DefaultStyle.dp color: mainItem.searchBarColor borderColor: mainItem.searchBarBorderColor placeholderText: qsTr("Rechercher un contact") - numericPad: numPad + numericPad: mainItem.numPad } Control.ScrollView { Layout.fillWidth: true Layout.fillHeight: true - Layout.leftMargin: mainItem.sideMargin Layout.topMargin: 25 * DefaultStyle.dp - rightPadding: mainItem.sideMargin - contentWidth: width - mainItem.sideMargin + contentWidth: width contentHeight: content.height clip: true - Control.ScrollBar.vertical: contactsScrollbar + Control.ScrollBar.vertical: ScrollBar { + active: true + interactive: true + policy: Control.ScrollBar.AsNeeded + // Layout.fillWidth: true + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: 8 * DefaultStyle.dp + // x: mainItem.x + mainItem.width - width + // anchors.left: control.right + } ColumnLayout { id: content @@ -241,6 +231,7 @@ Item { id: contactList Layout.fillWidth: true Layout.preferredHeight: contentHeight + Control.ScrollBar.vertical.visible: false contactMenuVisible: false model: MagicSearchProxy { searchText: searchBar.text.length === 0 ? "*" : searchBar.text @@ -248,7 +239,7 @@ Item { onSelectedContactChanged: { if (selectedContact) { if (selectedContact.core.allAddresses.length > 1) { - startCallPopup.selectedContact = selectedContact + startCallPopup.contact = selectedContact startCallPopup.open() } else { @@ -279,6 +270,7 @@ Item { contactMenuVisible: false Layout.fillWidth: true Layout.fillHeight: true + Control.ScrollBar.vertical.visible: false Layout.preferredHeight: contentHeight initialHeadersVisible: false displayNameCapitalization: false @@ -290,7 +282,7 @@ Item { onSelectedContactChanged: { if (selectedContact) { if (selectedContact.core.allAddresses.length > 1) { - startCallPopup.selectedContact = selectedContact + startCallPopup.contact = selectedContact startCallPopup.open() } else { @@ -326,19 +318,4 @@ Item { } } } - - Item { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - height: numPad.implicitHeight - NumericPad { - id: numPad - width: parent.width - onLaunchCall: { - UtilsCpp.createCall(searchBar.text + "@sip.linphone.org") - // TODO : auto completion instead of sip linphone - } - } - } } diff --git a/Linphone/view/Item/Contact/ContactsList.qml b/Linphone/view/Item/Contact/ContactsList.qml index 89b3c5603..710a4b85d 100644 --- a/Linphone/view/Item/Contact/ContactsList.qml +++ b/Linphone/view/Item/Contact/ContactsList.qml @@ -1,5 +1,6 @@ import QtQuick 2.7 import QtQuick.Layouts 1.3 +import QtQuick.Controls as Control import Linphone import UtilsCpp 1.0 @@ -9,7 +10,7 @@ ListView { height: contentHeight visible: contentHeight > 0 clip: true - rightMargin: 5 * DefaultStyle.dp + // rightMargin: 5 * DefaultStyle.dp property string searchBarText @@ -67,11 +68,19 @@ ListView { searchText: searchBarText.length === 0 ? "*" : searchBarText } + Control.ScrollBar.vertical: ScrollBar { + id: scrollbar + active: true + interactive: true + // anchors.top: parent.top + // anchors.bottom: parent.bottom + // anchors.right: parent.right + } delegate: Item { id: itemDelegate height: display ? 56 * DefaultStyle.dp : 0 - width: mainItem.width + width: mainItem.width - scrollbar.width - 12 * DefaultStyle.dp property var previousItem : mainItem.model.count > 0 && index > 0 ? mainItem.model.getAt(index-1) : null property var previousDisplayName: previousItem ? previousItem.core.displayName : "" property var displayName: modelData.core.displayName @@ -103,7 +112,7 @@ ListView { anchors.left: initial.visible ? initial.right : parent.left anchors.leftMargin: 10 * DefaultStyle.dp anchors.right: parent.right - anchors.rightMargin: 10 * DefaultStyle.dp + // anchors.rightMargin: 10 * DefaultStyle.dp anchors.verticalCenter: parent.verticalCenter spacing: 10 * DefaultStyle.dp z: 1 @@ -141,7 +150,7 @@ ListView { // visible: mainItem.actionLayoutVisible || friendPopup.visible // anchors.fill: parent anchors.right: parent.right - anchors.rightMargin: 10 * DefaultStyle.dp + // anchors.rightMargin: 10 * DefaultStyle.dp anchors.verticalCenter: parent.verticalCenter RowLayout{ visible: mainItem.actionLayoutVisible diff --git a/Linphone/view/Item/Meeting/MeetingSetUp.qml b/Linphone/view/Item/Meeting/MeetingSetUp.qml index 8aff18773..03d101307 100644 --- a/Linphone/view/Item/Meeting/MeetingSetUp.qml +++ b/Linphone/view/Item/Meeting/MeetingSetUp.qml @@ -31,58 +31,6 @@ ColumnLayout { startDate.calendar.selectedDate = mainItem.conferenceInfoGui.core.dateTime } - RowLayout { - Button { - background: Item{} - icon.source: AppIcons.leftArrow - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: mainItem.returnRequested() - } - TextInput { - visible: !mainItem.isCreation - Component.onCompleted: text = conferenceInfoGui.core.subject - color: DefaultStyle.main2_600 - font { - pixelSize: 20 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - Layout.fillWidth: true - onActiveFocusChanged: if(activeFocus==true) selectAll() - onEditingFinished: mainItem.conferenceInfoGui.core.subject = text - } - Text { - visible: mainItem.isCreation - text: qsTr("Nouvelle réunion") - color: DefaultStyle.main2_700 - font { - pixelSize: 22 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - Layout.fillWidth: true - } - Button { - topPadding: 6 * DefaultStyle.dp - bottomPadding: 6 * DefaultStyle.dp - leftPadding: 12 * DefaultStyle.dp - rightPadding: 12 * DefaultStyle.dp - text: mainItem.isCreation ? qsTr("Créer") : qsTr("Save") - textSize: 13 * DefaultStyle.dp - onClicked: { - if (mainItem.conferenceInfoGui.core.subject.length === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) - } else if (mainItem.conferenceInfoGui.core.duration <= 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) - } else if (mainItem.conferenceInfoGui.core.participantCount === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) - } else { - mainItem.conferenceInfoGui.core.save() - } - } - } - } component CheckableButton: Button { id: checkableButton checkable: true @@ -115,8 +63,8 @@ ColumnLayout { Layout.fillWidth: true Layout.topMargin: 20 * DefaultStyle.dp Layout.bottomMargin: 20 * DefaultStyle.dp - Layout.alignment: Qt.AlignHCenter - spacing: 20 * DefaultStyle.dp + // Layout.alignment: Qt.AlignHCenter + spacing: 18 * DefaultStyle.dp CheckableButton { Layout.preferredWidth: 151 * DefaultStyle.dp icon.source: AppIcons.usersThree diff --git a/Linphone/view/Item/NumericPad.qml b/Linphone/view/Item/NumericPad.qml index c2f9d35f0..09cf982e9 100644 --- a/Linphone/view/Item/NumericPad.qml +++ b/Linphone/view/Item/NumericPad.qml @@ -5,17 +5,17 @@ import QtQuick.Effects import Linphone Control.Popup { - clip: true id: mainItem signal buttonPressed(string text) signal launchCall() signal wipe() property bool closeButtonVisible: true closePolicy: Control.Popup.CloseOnEscape - leftPadding: closeButton.width - rightPadding: closeButton.width - rightInset: closeButton.width - topPadding: closeButton.height + leftPadding: 72 * DefaultStyle.dp + rightPadding: 72 * DefaultStyle.dp + topPadding: 41 * DefaultStyle.dp + bottomPadding: 18 * DefaultStyle.dp + // topPadding: closeButton.height + 4 * DefaultStyle.dp background: Item { anchors.fill: parent Rectangle { @@ -24,16 +24,15 @@ Control.Popup { color: DefaultStyle.grey_100 radius: 20 * DefaultStyle.dp } - // MultiEffect { - // id: effect - // anchors.fill: parent - // source: numPadBackground - // shadowEnabled: true - // shadowColor: DefaultStyle.grey_1000 - // shadowOpacity: 0.1 - // shadowVerticalOffset: -200 * DefaultStyle.dp - // shadowBlur: 1 - // } + MultiEffect { + id: effect + anchors.fill: parent + source: numPadBackground + shadowEnabled: true + shadowColor: DefaultStyle.grey_1000 + shadowOpacity: 0.1 + shadowBlur: 1 + } Rectangle { width: parent.width height: parent.height / 2 @@ -61,9 +60,8 @@ Control.Popup { } contentItem: Layout.GridLayout { columns: 3 - columnSpacing: 3 - Layout.Layout.fillWidth: true - Layout.Layout.fillHeight: true + columnSpacing: 40 * DefaultStyle.dp + rowSpacing: 10 * DefaultStyle.dp Repeater { model: 9 Button { diff --git a/Linphone/view/Item/ScrollBar.qml b/Linphone/view/Item/ScrollBar.qml new file mode 100644 index 000000000..e5d24ca06 --- /dev/null +++ b/Linphone/view/Item/ScrollBar.qml @@ -0,0 +1,16 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 as Control +import QtQuick.Effects +import QtQuick.Layouts +import Linphone + +Control.ScrollBar { + id: mainItem + padding: 0 + background: Item{} + contentItem: Rectangle { + implicitWidth: 6 + radius: 32 * DefaultStyle.dp + color: "#D9D9D9" + } +} \ No newline at end of file diff --git a/Linphone/view/Item/SearchBar.qml b/Linphone/view/Item/SearchBar.qml index bf0ea0572..051a5a5c2 100644 --- a/Linphone/view/Item/SearchBar.qml +++ b/Linphone/view/Item/SearchBar.qml @@ -7,6 +7,7 @@ import Linphone Rectangle { id: mainItem property string placeholderText: "" + property color placeholderTextColor: DefaultStyle.main2_400 property int textInputWidth: 350 * DefaultStyle.dp property color borderColor: "transparent" property string text: textField.text @@ -52,6 +53,7 @@ Rectangle { anchors.right: clearTextButton.left anchors.verticalCenter: parent.verticalCenter placeholderText: mainItem.placeholderText + placeholderTextColor: mainItem.placeholderTextColor width: mainItem.width - dialerButton.width echoMode: (mainItem.hidden && !dialerButton.checked) ? TextInput.Password : TextInput.Normal font { diff --git a/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml b/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml index 84ce7b118..2c1074444 100644 --- a/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml +++ b/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml @@ -7,78 +7,22 @@ import UtilsCpp 1.0 ColumnLayout { id: mainItem - spacing: 10 * DefaultStyle.dp - property string title - property string validateButtonText property string placeHolderText: qsTr("Rechercher des contacts") - property color titleColor: DefaultStyle.main2_700 property list selectedParticipants: contactList.selectedContacts property int selectedParticipantsCount: selectedParticipants.length - property alias titleLayout: titleLayout property ConferenceInfoGui conferenceInfoGui property bool nameGroupCall: false readonly property string groupName: groupCallName.text - signal returnRequested() - signal validateRequested() // Layout.preferredWidth: 362 * DefaultStyle.dp function clearSelectedParticipants() { contactList.selectedContacts.clear() } - - RowLayout { - id: titleLayout - Layout.fillWidth: true - Button { - background: Item{} - icon.source: AppIcons.leftArrow - contentImageColor: DefaultStyle.main1_500_main - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: mainItem.returnRequested() - } - ColumnLayout { - spacing: 0 - Text { - text: mainItem.title - color: mainItem.titleColor - maximumLineCount: 1 - font { - pixelSize: 18 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - Layout.fillWidth: true - } - Text { - text: qsTr("%1 participant%2 sélectionné").arg(mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount > 1 ? "s" : "") - color: DefaultStyle.main2_500main - maximumLineCount: 1 - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp - } - Layout.fillWidth: true - } - } - Button { - Layout.preferredWidth: 70 * DefaultStyle.dp - topPadding: 6 * DefaultStyle.dp - bottomPadding: 6 * DefaultStyle.dp - enabled: contactList.selectedContacts.length != 0 - // leftPadding: 12 * DefaultStyle.dp - // rightPadding: 12 * DefaultStyle.dp - text: mainItem.validateButtonText - textSize: 13 * DefaultStyle.dp - onClicked: { - mainItem.validateRequested() - } - } - } + ColumnLayout { visible: mainItem.nameGroupCall - spacing: 0 + spacing: 5 * DefaultStyle.dp + Layout.rightMargin: 38 * DefaultStyle.dp RowLayout { Text { font.pixelSize: 13 * DefaultStyle.dp @@ -101,7 +45,7 @@ ColumnLayout { ListView { id: participantList Layout.fillWidth: true - // Layout.fillHeight: true + Layout.topMargin: 15 * DefaultStyle.dp Layout.preferredHeight: contentHeight Layout.maximumHeight: mainItem.height / 3 width: mainItem.width @@ -109,7 +53,7 @@ ColumnLayout { clip: true delegate: Item { height: 56 * DefaultStyle.dp - width: participantList.width + width: participantList.width - scrollbar.implicitWidth - 12 * DefaultStyle.dp RowLayout { anchors.fill: parent Avatar { @@ -138,13 +82,26 @@ ColumnLayout { } } } + Control.ScrollBar.vertical: ScrollBar { + id: scrollbar + active: true + interactive: true + policy: Control.ScrollBar.AsNeeded + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: 8 * DefaultStyle.dp + } } SearchBar { id: searchbar Layout.fillWidth: true + Layout.topMargin: 21 * DefaultStyle.dp + Layout.rightMargin: 28 * DefaultStyle.dp placeholderText: mainItem.placeHolderText } Text { + Layout.topMargin: 21 * DefaultStyle.dp text: qsTr("Contacts") font { pixelSize: 16 * DefaultStyle.dp @@ -156,6 +113,8 @@ ColumnLayout { visible: contentHeight > 0 || searchbar.text.length > 0 Layout.fillWidth: true Layout.fillHeight: true + Layout.topMargin: 8 * DefaultStyle.dp + Layout.rightMargin: 8 * DefaultStyle.dp Layout.preferredHeight: contentHeight multiSelectionEnabled: true contactMenuVisible: false @@ -188,6 +147,7 @@ ColumnLayout { } } } + } Item { Layout.fillHeight: true diff --git a/Linphone/view/Page/Main/CallPage.qml b/Linphone/view/Page/Main/CallPage.qml index efdae2404..a786bd0c7 100644 --- a/Linphone/view/Page/Main/CallPage.qml +++ b/Linphone/view/Page/Main/CallPage.qml @@ -14,6 +14,7 @@ AbstractMainPage { property var selectedRowHistoryGui signal listViewUpdated() + //Group call properties property ConferenceInfoGui confInfoGui property AccountProxy accounts: AccountProxy{id: accountProxy} property AccountGui account: accountProxy.defaultAccount @@ -21,6 +22,8 @@ AbstractMainPage { onStateChanged: console.log(state) property bool isRegistered: account ? account.core.registrationState == LinphoneEnums.RegistrationState.Ok : false onIsRegisteredChanged: console.log(isRegistered) + property int selectedParticipantsCount + signal startGroupCallRequested() Connections { enabled: confInfoGui @@ -62,366 +65,438 @@ AbstractMainPage { Layout.fillWidth: true Layout.fillHeight: true + Loader { + id: titleLoader + anchors.left: parent.left + anchors.right: parent.right + } + Control.StackView { id: listStackView clip: true initialItem: historyListItem - anchors.fill: parent - property int leftMargin: 45 * DefaultStyle.dp - property int rightMargin: 39 * DefaultStyle.dp + anchors.top: titleLoader.bottom + anchors.topMargin: 18 * DefaultStyle.dp + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.leftMargin: 45 * DefaultStyle.dp } - Component { - id: historyListItem + Item { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 402 * DefaultStyle.dp + NumericPad { + id: numericPad + width: parent.width + height: parent.height + onLaunchCall: { + UtilsCpp.createCall(searchBar.text + "@sip.linphone.org") + // TODO : auto completion instead of sip linphone + } + } + } + } - ColumnLayout { - spacing: 30 * DefaultStyle.dp - property alias listView: historyListView - RowLayout { - spacing: 16 * DefaultStyle.dp - Layout.fillWidth: true - Layout.leftMargin: listStackView.leftMargin - Layout.rightMargin: listStackView.rightMargin - Text { - text: qsTr("Appels") - color: DefaultStyle.main2_700 - font.pixelSize: 29 * DefaultStyle.dp - font.weight: 800 * DefaultStyle.dp - } - Item { - Layout.fillWidth: true - } - PopupButton { - id: removeHistory - width: 24 * DefaultStyle.dp - height: 24 * DefaultStyle.dp - popup.x: 0 - popup.padding: 10 * DefaultStyle.dp - popup.contentItem: Button { - background: Item{} - contentItem: RowLayout { - EffectImage { - imageSource: AppIcons.trashCan - width: 24 * DefaultStyle.dp - height: 24 * DefaultStyle.dp - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - fillMode: Image.PreserveAspectFit - colorizationColor: DefaultStyle.danger_500main - } - Text { - text: qsTr("Supprimer l’historique") - color: DefaultStyle.danger_500main - font { - pixelSize: 14 * DefaultStyle.dp - weight: 400 * DefaultStyle.dp - } - } - } - Connections { - target: deleteHistoryPopup - onAccepted: { - historyListView.model.removeAllEntries() - } - } - onClicked: { - removeHistory.close() - deleteHistoryPopup.open() + Component { + id: historyListTitle + RowLayout { + spacing: 16 * DefaultStyle.dp + Text { + text: qsTr("Appels") + Layout.leftMargin: 45 * DefaultStyle.dp + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item { + Layout.fillWidth: true + } + PopupButton { + id: removeHistory + width: 24 * DefaultStyle.dp + height: 24 * DefaultStyle.dp + popup.x: 0 + popup.padding: 10 * DefaultStyle.dp + popup.contentItem: Button { + background: Item{} + contentItem: RowLayout { + EffectImage { + imageSource: AppIcons.trashCan + width: 24 * DefaultStyle.dp + height: 24 * DefaultStyle.dp + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + fillMode: Image.PreserveAspectFit + colorizationColor: DefaultStyle.danger_500main + } + Text { + text: qsTr("Supprimer l’historique") + color: DefaultStyle.danger_500main + font { + pixelSize: 14 * DefaultStyle.dp + weight: 400 * DefaultStyle.dp } } } - Button { - background: Item {} - icon.source: AppIcons.newCall - Layout.preferredWidth: 28 * DefaultStyle.dp - Layout.preferredHeight: 28 * DefaultStyle.dp - icon.width: 28 * DefaultStyle.dp - icon.height: 28 * DefaultStyle.dp - onClicked: { - console.debug("[CallPage]User: create new call") - listStackView.push(newCallItem) + Connections { + target: deleteHistoryPopup + onAccepted: { + historyListView.model.removeAllEntries() } } + onClicked: { + removeHistory.close() + deleteHistoryPopup.open() + } } - ColumnLayout { - SearchBar { - id: searchBar - Layout.fillWidth: true - Layout.leftMargin: listStackView.leftMargin - Layout.rightMargin: listStackView.rightMargin - placeholderText: qsTr("Rechercher un appel") - } - RowLayout { - Layout.topMargin: 30 * DefaultStyle.dp - spacing: 0 - Control.Control { - id: listLayout - Layout.fillWidth: true - Layout.fillHeight: true - Layout.leftMargin: listStackView.leftMargin - Layout.rightMargin: listStackView.rightMargin - (scrollbar.visible? scrollbar.width : 0) + } + Button { + background: Item {} + icon.source: AppIcons.newCall + Layout.preferredWidth: 28 * DefaultStyle.dp + Layout.preferredHeight: 28 * DefaultStyle.dp + Layout.rightMargin: 39 * DefaultStyle.dp + icon.width: 28 * DefaultStyle.dp + icon.height: 28 * DefaultStyle.dp + onClicked: { + console.debug("[CallPage]User: create new call") + listStackView.push(newCallItem) + } + } + } + } + Component { + id: historyListItem + ColumnLayout { + Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle + property alias listView: historyListView + SearchBar { + id: searchBar + Layout.fillWidth: true + Layout.rightMargin: 39 * DefaultStyle.dp + placeholderText: qsTr("Rechercher un appel") + } + Item { + Layout.topMargin: 38 * DefaultStyle.dp + Layout.fillWidth: true + Layout.fillHeight: true + Control.Control { + id: listLayout + anchors.fill: parent + anchors.rightMargin: 39 * DefaultStyle.dp - background: Rectangle { - anchors.fill: parent + background: Item{} + ColumnLayout { + anchors.fill: parent + ColumnLayout { + Text { + text: qsTr("Aucun appel") + font { + pixelSize: 16 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + visible: historyListView.count === 0 + Layout.alignment: Qt.AlignHCenter } - ColumnLayout { - anchors.fill: parent - ColumnLayout { - Text { - text: qsTr("Aucun appel") - font { - pixelSize: 16 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - visible: historyListView.count === 0 - Layout.alignment: Qt.AlignHCenter - } - ListView { - id: historyListView - clip: true - Layout.fillWidth: true - Layout.fillHeight: true - model: CallHistoryProxy { - filterText: searchBar.text - } - - currentIndex: -1 - flickDeceleration: 10000 - spacing: 10 * DefaultStyle.dp + ListView { + id: historyListView + clip: true + Layout.fillWidth: true + Layout.fillHeight: true + model: CallHistoryProxy { + filterText: searchBar.text + } + + currentIndex: -1 + flickDeceleration: 10000 + spacing: 10 * DefaultStyle.dp - delegate: Item { - width:historyListView.width - height: 56 * DefaultStyle.dp - anchors.topMargin: 5 * DefaultStyle.dp - anchors.bottomMargin: 5 * DefaultStyle.dp + delegate: Item { + width:historyListView.width + height: 56 * DefaultStyle.dp + anchors.topMargin: 5 * DefaultStyle.dp + anchors.bottomMargin: 5 * DefaultStyle.dp + RowLayout { + z: 1 + anchors.fill: parent + Item { + Layout.preferredWidth: historyAvatar.width + Layout.preferredHeight: historyAvatar.height + Layout.leftMargin: 5 * DefaultStyle.dp + MultiEffect { + source: historyAvatar + anchors.fill: historyAvatar + shadowEnabled: true + shadowBlur: 1 + shadowColor: DefaultStyle.grey_900 + shadowOpacity: 0.1 + } + Avatar { + id: historyAvatar + address: modelData.core.remoteAddress + width: 45 * DefaultStyle.dp + height: 45 * DefaultStyle.dp + } + } + ColumnLayout { + Layout.fillHeight: true + Layout.fillWidth: true + spacing: 5 * DefaultStyle.dp + Text { + id: friendAddress + Layout.fillWidth: true + maximumLineCount: 1 + property var remoteAddress: modelData ? UtilsCpp.getDisplayName(modelData.core.remoteAddress) : null + text: remoteAddress ? remoteAddress.value : "" + font { + pixelSize: 14 * DefaultStyle.dp + weight: 400 * DefaultStyle.dp + } + } RowLayout { - z: 1 - anchors.fill: parent - Item { - Layout.preferredWidth: historyAvatar.width - Layout.preferredHeight: historyAvatar.height - Layout.leftMargin: 5 * DefaultStyle.dp - MultiEffect { - source: historyAvatar - anchors.fill: historyAvatar - shadowEnabled: true - shadowBlur: 1 - shadowColor: DefaultStyle.grey_900 - shadowOpacity: 0.1 - } - Avatar { - id: historyAvatar - address: modelData.core.remoteAddress - width: 45 * DefaultStyle.dp - height: 45 * DefaultStyle.dp - } - } - ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - spacing: 5 * DefaultStyle.dp - Text { - id: friendAddress - Layout.fillWidth: true - maximumLineCount: 1 - property var remoteAddress: modelData ? UtilsCpp.getDisplayName(modelData.core.remoteAddress) : null - text: remoteAddress ? remoteAddress.value : "" - font { - pixelSize: 14 * DefaultStyle.dp - weight: 400 * DefaultStyle.dp - } - } - RowLayout { - spacing: 3 * DefaultStyle.dp - EffectImage { - id: statusIcon - imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined + spacing: 3 * DefaultStyle.dp + EffectImage { + id: statusIcon + imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined + || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere + || modelData.core.status === LinphoneEnums.CallStatus.Aborted + || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted + ? AppIcons.arrowElbow + : modelData.core.isOutgoing + ? AppIcons.arrowUpRight + : AppIcons.arrowDownLeft + colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined + || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere + || modelData.core.status === LinphoneEnums.CallStatus.Aborted + || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted + || modelData.core.status === LinphoneEnums.CallStatus.Missed + ? DefaultStyle.danger_500main + : modelData.core.isOutgoing + ? DefaultStyle.info_500_main + : DefaultStyle.success_500main + Layout.preferredWidth: 12 * DefaultStyle.dp + Layout.preferredHeight: 12 * DefaultStyle.dp + transform: Rotation { + angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted - || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted - ? AppIcons.arrowElbow - : modelData.core.isOutgoing - ? AppIcons.arrowUpRight - : AppIcons.arrowDownLeft - colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined - || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere - || modelData.core.status === LinphoneEnums.CallStatus.Aborted - || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted - || modelData.core.status === LinphoneEnums.CallStatus.Missed - ? DefaultStyle.danger_500main - : modelData.core.isOutgoing - ? DefaultStyle.info_500_main - : DefaultStyle.success_500main - Layout.preferredWidth: 12 * DefaultStyle.dp - Layout.preferredHeight: 12 * DefaultStyle.dp - transform: Rotation { - angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined - || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere - || modelData.core.status === LinphoneEnums.CallStatus.Aborted - || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 - origin { - x: statusIcon.width/2 - y: statusIcon.height/2 - } - } - } - Text { - // text: modelData.core.date - text: UtilsCpp.formatDateElapsedTime(modelData.core.date) - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp - } + || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 + origin { + x: statusIcon.width/2 + y: statusIcon.height/2 } } } - Button { - Layout.rightMargin: 5 * DefaultStyle.dp - padding: 0 - background: Item { - visible: false - } - icon.source: AppIcons.phone - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: { - var addr = UtilsCpp.generateLinphoneSipAddress(modelData.core.remoteAddress) - UtilsCpp.createCall(addr) + Text { + // text: modelData.core.date + text: UtilsCpp.formatDateElapsedTime(modelData.core.date) + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp } } } - MouseArea { - hoverEnabled: true - anchors.fill: parent - Rectangle { - anchors.fill: parent - opacity: 0.1 - color: DefaultStyle.main2_500main - visible: parent.containsMouse - } - Rectangle { - anchors.fill: parent - visible: historyListView.currentIndex === model.index - color: DefaultStyle.main2_100 - } - onPressed: { - historyListView.currentIndex = model.index - } + } + Button { + Layout.rightMargin: 5 * DefaultStyle.dp + padding: 0 + background: Item { + visible: false + } + icon.source: AppIcons.phone + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + onClicked: { + var addr = UtilsCpp.generateLinphoneSipAddress(modelData.core.remoteAddress) + UtilsCpp.createCall(addr) } } - onCurrentIndexChanged: { - positionViewAtIndex(currentIndex, ListView.Visible) - mainItem.selectedRowHistoryGui = model.getAt(currentIndex) + } + MouseArea { + hoverEnabled: true + anchors.fill: parent + Rectangle { + anchors.fill: parent + opacity: 0.1 + color: DefaultStyle.main2_500main + visible: parent.containsMouse } - onCountChanged: mainItem.selectedRowHistoryGui = model.getAt(currentIndex) - onVisibleChanged: { - if (!visible) currentIndex = -1 + Rectangle { + anchors.fill: parent + visible: historyListView.currentIndex === model.index + color: DefaultStyle.main2_100 } - - Connections { - target: mainItem - onListViewUpdated: { - historyListView.model.updateView() - } + onPressed: { + historyListView.currentIndex = model.index } - Control.ScrollBar.vertical: scrollbar } } - } - } - Control.ScrollBar { - id: scrollbar - active: true - policy: Control.ScrollBar.AlwaysOn //Control.ScrollBar.AsNeeded - Layout.fillHeight: true - Layout.rightMargin: 8 * DefaultStyle.dp - Rectangle{// TODO: change colors of scrollbar! - anchors.fill: parent - color: 'red' - opacity:0.2 + onCurrentIndexChanged: { + positionViewAtIndex(currentIndex, ListView.Visible) + mainItem.selectedRowHistoryGui = model.getAt(currentIndex) + } + onCountChanged: mainItem.selectedRowHistoryGui = model.getAt(currentIndex) + onVisibleChanged: { + if (!visible) currentIndex = -1 + } + + Connections { + target: mainItem + onListViewUpdated: { + historyListView.model.updateView() + } + } + Control.ScrollBar.vertical: scrollbar } } } } + ScrollBar { + id: scrollbar + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: 8 * DefaultStyle.dp + active: true + policy: Control.ScrollBar.AsNeeded + } } } - Component { - id: newCallItem + } + + Component { + id: newCallTitle + RowLayout { + Button { + Layout.leftMargin: 45 * DefaultStyle.dp + background: Item { + } + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.source: AppIcons.leftArrow + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + onClicked: { + console.debug("[CallPage]User: return to call history") + listStackView.pop() + } + } + Text { + text: qsTr("Nouvel appel") + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item { + Layout.fillWidth: true + } + } + } + Component { + id: newCallItem + CallContactsLists { + Control.StackView.onActivated: titleLoader.sourceComponent = newCallTitle + numPad: numericPad + groupCallVisible: true + searchBarColor: DefaultStyle.grey_100 + + onCallButtonPressed: (address) => { + UtilsCpp.createCall(UtilsCpp.generateLinphoneSipAddress(address)) + // var window = UtilsCpp.getCallsWindow() + } + onGroupCallCreationRequested: { + console.log("groupe call requetsed") + listStackView.push(groupCallItem) + } + } + } + + Component { + id: groupCallTitle + RowLayout { + Button { + background: Item{} + icon.source: AppIcons.leftArrow + contentImageColor: DefaultStyle.main1_500_main + Layout.leftMargin: 21 * DefaultStyle.dp + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + onClicked: listStackView.pop() + } ColumnLayout { - spacing: 30 * DefaultStyle.dp - RowLayout { - Layout.leftMargin: listStackView.leftMargin - Layout.rightMargin: listStackView.rightMargin - Button { - background: Item { - } - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - icon.source: AppIcons.leftArrow - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - onClicked: { - console.debug("[CallPage]User: return to call history") - listStackView.pop() - } + spacing: 3 * DefaultStyle.dp + Text { + text: qsTr("Appel de groupe") + color: DefaultStyle.main1_500_main + maximumLineCount: 1 + font { + pixelSize: 18 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp } - Text { - text: qsTr("Nouvel appel") - color: DefaultStyle.main2_700 - font.pixelSize: 29 * DefaultStyle.dp - font.weight: 800 * DefaultStyle.dp - } - Item { - Layout.fillWidth: true - } - } - CallContactsLists { Layout.fillWidth: true - Layout.fillHeight: true - groupCallVisible: true - searchBarColor: DefaultStyle.grey_100 - - onCallButtonPressed: (address) => { - UtilsCpp.createCall(UtilsCpp.generateLinphoneSipAddress(address)) - // var window = UtilsCpp.getCallsWindow() - } - onGroupCallCreationRequested: { - console.log("groupe call requetsed") - listStackView.push(groupCallItem) + } + Text { + text: qsTr("%1 participant%2 sélectionné").arg(mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount > 1 ? "s" : "") + color: DefaultStyle.main2_500main + maximumLineCount: 1 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp } + Layout.fillWidth: true + } + } + Button { + enabled: mainItem.selectedParticipantsCount.length != 0 + Layout.rightMargin: 21 * DefaultStyle.dp + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + leftPadding: 12 * DefaultStyle.dp + rightPadding: 12 * DefaultStyle.dp + text: qsTr("Lancer") + textSize: 13 * DefaultStyle.dp + onClicked: { + mainItem.startGroupCallRequested() } } } - Component { - id: groupCallItem - // RowLayout { - AddParticipantsLayout { - Control.StackView.onActivated: mainItem.confInfoGui = Qt.createQmlObject('import Linphone - ConferenceInfoGui{ - }', mainItem) - Layout.leftMargin: 21 * DefaultStyle.dp - title: qsTr("Appel de groupe") - titleColor: DefaultStyle.main1_500_main - nameGroupCall: true - validateButtonText: qsTr("Lancer") - onReturnRequested: listStackView.pop() - onValidateRequested: { + } + + Component { + id: groupCallItem + // RowLayout { + AddParticipantsLayout { + Control.StackView.onActivated: titleLoader.sourceComponent = groupCallTitle + id: addParticipantsLayout + onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount + nameGroupCall: true + Connections { + target: mainItem + onStartGroupCallRequested: { if (groupName.length === 0) { UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Un nom doit être donné à l'appel de groupe"), false) } if(!mainItem.isRegistered) { UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Vous n'etes pas connecté"), false) - }else { - mainItem.confInfoGui.core.subject = groupName + } else { + mainItem.confInfoGui = Qt.createQmlObject('import Linphone + ConferenceInfoGui{ + }', mainItem) + mainItem.confInfoGui.core.subject = addParticipantsLayout.groupName mainItem.confInfoGui.core.isScheduled = false - mainItem.confInfoGui.core.addParticipants(selectedParticipants) + mainItem.confInfoGui.core.addParticipants(addParticipantsLayout.selectedParticipants) mainItem.confInfoGui.core.save() } } } - // } - } + } + // } } Component{ diff --git a/Linphone/view/Page/Main/ContactPage.qml b/Linphone/view/Page/Main/ContactPage.qml index 797161a33..dbd1abb96 100644 --- a/Linphone/view/Page/Main/ContactPage.qml +++ b/Linphone/view/Page/Main/ContactPage.qml @@ -57,18 +57,20 @@ AbstractMainPage { onAccepted: contact.core.remove() } - leftPanelContent: ColumnLayout { + leftPanelContent: Item { id: leftPanel - Layout.fillWidth: true - Layout.fillHeight: true property int leftMargin: 45 * DefaultStyle.dp property int rightMargin: 39 * DefaultStyle.dp - spacing: 30 * DefaultStyle.dp + Layout.fillHeight: true + Layout.fillWidth: true RowLayout { - Layout.fillWidth: true - Layout.leftMargin: leftPanel.leftMargin - Layout.rightMargin: leftPanel.rightMargin + id: title + anchors.top: leftPanel.top + anchors.right: leftPanel.right + anchors.left: leftPanel.left + anchors.leftMargin: leftPanel.leftMargin + anchors.rightMargin: leftPanel.rightMargin Text { text: qsTr("Contacts") @@ -94,10 +96,14 @@ AbstractMainPage { } ColumnLayout { - Layout.leftMargin: leftPanel.leftMargin + anchors.top: title.bottom + anchors.right: leftPanel.right + anchors.left: leftPanel.left + anchors.bottom: leftPanel.bottom enabled: mainItem.leftPanelEnabled SearchBar { id: searchBar + Layout.leftMargin: leftPanel.leftMargin Layout.rightMargin: leftPanel.rightMargin Layout.fillWidth: true placeholderText: qsTr("Rechercher un contact") @@ -106,10 +112,10 @@ AbstractMainPage { id: contactsArea Layout.fillWidth: true Layout.fillHeight: true + Control.ScrollView { id: listLayout anchors.fill: parent - anchors.rightMargin: leftPanel.rightMargin anchors.topMargin: 25 * DefaultStyle.dp contentWidth: width contentHeight: content.height @@ -132,6 +138,8 @@ AbstractMainPage { } ColumnLayout { visible: favoriteList.contentHeight > 0 + Layout.leftMargin: leftPanel.leftMargin + Layout.rightMargin: leftPanel.rightMargin RowLayout { Text { text: qsTr("Favoris") @@ -158,6 +166,7 @@ AbstractMainPage { hoverEnabled: mainItem.leftPanelEnabled Layout.fillWidth: true Layout.preferredHeight: contentHeight + Control.ScrollBar.vertical.visible: false showOnlyFavourites: true contactMenuVisible: true model: allFriends @@ -175,6 +184,8 @@ AbstractMainPage { } ColumnLayout { visible: contactList.count > 0 + Layout.leftMargin: leftPanel.leftMargin + Layout.rightMargin: leftPanel.rightMargin RowLayout { Layout.fillWidth: true Text { @@ -202,6 +213,7 @@ AbstractMainPage { Layout.fillWidth: true Layout.preferredHeight: contentHeight interactive: false + Control.ScrollBar.vertical.visible: false hoverEnabled: mainItem.leftPanelEnabled contactMenuVisible: true searchBarText: searchBar.text @@ -219,22 +231,21 @@ AbstractMainPage { } } } - } - Control.ScrollBar { - id: contactsScrollbar - // Parent is changed from Scrollview. Do not use it. - x: contactsArea.width - width - height: listLayout.availableHeight - active: true - interactive: true - policy: Control.ScrollBar.AlwaysOn //Control.ScrollBar.AsNeeded - Rectangle{// TODO: change colors of scrollbar! - anchors.fill: parent - color: 'red' - opacity:0.2 + ScrollBar { + id: contactsScrollbar + anchors.right: listLayout.right + anchors.rightMargin: 8 * DefaultStyle.dp + anchors.top: listLayout.top + anchors.bottom: listLayout.bottom + height: listLayout.availableHeight + active: true + interactive: true + policy: Control.ScrollBar.AlwaysOn //Control.ScrollBar.AsNeeded } + } + } } } diff --git a/Linphone/view/Page/Main/MeetingPage.qml b/Linphone/view/Page/Main/MeetingPage.qml index 76abd1c58..90f75d405 100644 --- a/Linphone/view/Page/Main/MeetingPage.qml +++ b/Linphone/view/Page/Main/MeetingPage.qml @@ -16,6 +16,8 @@ AbstractMainPage { property ConferenceInfoGui selectedConference property int meetingListCount signal newConfCreated() + signal returnRequested() + signal addParticipantsValidated(list selectedParticipants) Component.onCompleted: rightPanelStackView.push(overridenRightPanel, Control.StackView.Immediate) onSelectedConferenceChanged: { @@ -39,9 +41,11 @@ AbstractMainPage { confInfoGui = Qt.createQmlObject('import Linphone ConferenceInfoGui{ }', mainItem) - leftPanelStackView.push(createConf, {"conferenceInfoGui": confInfoGui, "isCreation": isCreation}) + mainItem.selectedConference = confInfoGui + leftPanelStackView.push(createConf, {"conferenceInfoGui": mainItem.selectedConference, "isCreation": isCreation}) } else { - overridenRightPanelStackView.push(editConf, {"conferenceInfoGui": confInfoGui, "isCreation": isCreation}) + mainItem.selectedConference = confInfoGui + overridenRightPanelStackView.push(editConf, {"conferenceInfoGui": mainItem.selectedConference, "isCreation": isCreation}) } } @@ -94,70 +98,28 @@ AbstractMainPage { leftPanelContent: Item { Layout.fillHeight: true Layout.fillWidth: true - RowLayout { - id: leftPanel - anchors.fill: parent - spacing: 0 - ColumnLayout { - enabled: mainItem.leftPanelEnabled - Layout.leftMargin: 45 * DefaultStyle.dp - Layout.rightMargin: 39 * DefaultStyle.dp - spacing: 0 - RowLayout { - visible: leftPanelStackView.currentItem.objectName == "listLayout" - // Layout.rightMargin: leftPanel.sideMargin - spacing: 0 - Text { - Layout.fillWidth: true - text: qsTr("Réunions") - color: DefaultStyle.main2_700 - font.pixelSize: 29 * DefaultStyle.dp - font.weight: 800 * DefaultStyle.dp - } - Button { - background: Item { - } - icon.source: AppIcons.plusCircle - Layout.preferredWidth: 28 * DefaultStyle.dp - Layout.preferredHeight: 28 * DefaultStyle.dp - icon.width: 28 * DefaultStyle.dp - icon.height: 28 * DefaultStyle.dp - onClicked: { - mainItem.setUpConference() - } - } - } - Item { - Layout.fillWidth: true - Layout.fillHeight: true - - Control.StackView { - id: leftPanelStackView - initialItem: listLayout - anchors.fill: parent - } - } - } - } - Rectangle{// TODO: change colors of scrollbar! - anchors.right: parent.right + Control.StackView { + id: leftPanelStackView + initialItem: listLayout anchors.top: parent.top + anchors.topMargin: 18 * DefaultStyle.dp + anchors.left: parent.left + anchors.right: parent.right anchors.bottom: parent.bottom - width: 10 - color: 'red' - opacity:0.2 + anchors.leftMargin: 45 * DefaultStyle.dp } - Control.ScrollBar { + + ScrollBar { id: meetingsScrollbar anchors.right: parent.right - anchors.top: parent.top + anchors.rightMargin: 8 * DefaultStyle.dp + anchors.top: leftPanelStackView.top anchors.bottom: parent.bottom - width: 10 - //visible: leftPanelStackView.currentItem.objectName == "listLayout" + visible: leftPanelStackView.currentItem == listLayout active: true interactive: true - policy: Control.ScrollBar.AlwaysOn //Control.ScrollBar.AsNeeded + policy: Control.ScrollBar.AsNeeded } } @@ -168,8 +130,8 @@ AbstractMainPage { width: 393 * DefaultStyle.dp height: parent.height anchors.top: parent.top - // anchors.bottom: parent.bottom - // Layout.fillWidth: false + anchors.centerIn: parent + anchors.horizontalCenter: parent.horiztonalCenter } } @@ -182,12 +144,42 @@ AbstractMainPage { mainItem.selectedConference = null // mainItem.righPanelStackView.clear() } - Control.StackView.onActivated: mainItem.selectedConference = conferenceList.selectedConference + Control.StackView.onActivated: { + mainItem.selectedConference = conferenceList.selectedConference + } + RowLayout { + visible: leftPanelStackView.currentItem.objectName == "listLayout" + enabled: mainItem.leftPanelEnabled + Layout.rightMargin: 39 * DefaultStyle.dp + spacing: 0 + Text { + Layout.fillWidth: true + text: qsTr("Réunions") + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item{Layout.fillWidth: true} + Button { + background: Item { + } + icon.source: AppIcons.plusCircle + Layout.preferredWidth: 28 * DefaultStyle.dp + Layout.preferredHeight: 28 * DefaultStyle.dp + icon.width: 28 * DefaultStyle.dp + icon.height: 28 * DefaultStyle.dp + onClicked: { + mainItem.setUpConference() + } + } + } SearchBar { id: searchBar - Layout.fillWidth: true + Layout.topMargin: 18 * DefaultStyle.dp + // Layout.fillWidth: true //Layout.topMargin: 18 * DefaultStyle.dp placeholderText: qsTr("Rechercher une réunion") + Layout.preferredWidth: 331 * DefaultStyle.dp } Text { @@ -229,64 +221,222 @@ AbstractMainPage { } } } + Component { id: createConf - MeetingSetUp { - id: meetingSetup - onSaveSucceed: { - mainItem.newConfCreated() - leftPanelStackView.pop() - UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true) + ColumnLayout { + property ConferenceInfoGui conferenceInfoGui + property bool isCreation + + RowLayout { + width: 320 * DefaultStyle.dp + Layout.rightMargin: 35 * DefaultStyle.dp + Button { + background: Item{} + icon.source: AppIcons.leftArrow + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + onClicked: { + meetingSetup.conferenceInfoGui.core.undo() + leftPanelStackView.pop() + } + } + Text { + text: qsTr("Nouvelle réunion") + color: DefaultStyle.main2_700 + font { + pixelSize: 22 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + Layout.fillWidth: true + } + Button { + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + text: qsTr("Créer") + textSize: 13 * DefaultStyle.dp + onClicked: { + if (meetingSetup.conferenceInfoGui.core.subject.length === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) + } else if (meetingSetup.conferenceInfoGui.core.duration <= 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) + } else if (meetingSetup.conferenceInfoGui.core.participantCount === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) + } else { + meetingSetup.conferenceInfoGui.core.save() + } + } + } } - onReturnRequested: { - leftPanelStackView.pop() - } - onAddParticipantsRequested: { - leftPanelStackView.push(addParticipants, {"conferenceInfoGui": meetingSetup.conferenceInfoGui, "container": leftPanelStackView}) + MeetingSetUp { + id: meetingSetup + conferenceInfoGui: parent.conferenceInfoGui + isCreation: parent.isCreation + Layout.rightMargin: 35 * DefaultStyle.dp + onSaveSucceed: { + mainItem.newConfCreated() + leftPanelStackView.pop() + UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true) + } + onAddParticipantsRequested: { + leftPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": leftPanelStackView}) + } + Connections { + target: mainItem + onAddParticipantsValidated: (selectedParticipants) => { + meetingSetup.conferenceInfoGui.core.resetParticipants(selectedParticipants) + leftPanelStackView.pop() + } + } } } } + Component { id: editConf - MeetingSetUp { + ColumnLayout { property bool isCreation - isCreation: parent.isCreation - onReturnRequested: { - overridenRightPanelStackView.pop() + property ConferenceInfoGui conferenceInfoGui + Section { + content: RowLayout { + spacing: 10 * DefaultStyle.dp + Button { + background: Item{} + icon.source: AppIcons.leftArrow + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + onClicked: { + conferenceEdit.conferenceInfoGui.core.undo() + overridenRightPanelStackView.pop() + } + } + + TextInput { + Component.onCompleted: text = mainItem.selectedConference.core.subject + color: DefaultStyle.main2_600 + font { + pixelSize: 20 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + Layout.fillWidth: true + onActiveFocusChanged: if(activeFocus==true) selectAll() + onEditingFinished: mainItem.selectedConference.core.subject = text + } + Button { + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + leftPadding: 12 * DefaultStyle.dp + rightPadding: 12 * DefaultStyle.dp + text: qsTr("Save") + textSize: 13 * DefaultStyle.dp + onClicked: { + if (mainItem.selectedConference.core.subject.length === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) + } else if (mainItem.selectedConference.core.duration <= 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) + } else if (mainItem.selectedConference.core.participantCount === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) + } else { + mainItem.selectedConference.core.save() + } + } + } + } } - onSaveSucceed: { - overridenRightPanelStackView.pop() - UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Réunion modifiée avec succès"), true) - } - onAddParticipantsRequested: { - overridenRightPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": overridenRightPanelStackView}) + MeetingSetUp { + id: conferenceEdit + property bool isCreation + isCreation: parent.isCreation + conferenceInfoGui: parent.conferenceInfoGui + onSaveSucceed: { + overridenRightPanelStackView.pop() + UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Réunion modifiée avec succès"), true) + } + onAddParticipantsRequested: { + overridenRightPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": overridenRightPanelStackView}) + } + Connections { + target: mainItem + onAddParticipantsValidated: (selectedParticipants) => { + conferenceEdit.conferenceInfoGui.core.resetParticipants(selectedParticipants) + overridenRightPanelStackView.pop() + } + } } } } + Component { id: addParticipants - AddParticipantsLayout { - id: addParticipantLayout + ColumnLayout { property Control.StackView container - // Layout.fillHeight: true - title: qsTr("Ajouter des participants") - validateButtonText: qsTr("Ajouter") - titleColor: DefaultStyle.main1_500_main - onReturnRequested: { - container.pop() + property ConferenceInfoGui conferenceInfoGui + RowLayout { + Button { + background: Item{} + icon.source: AppIcons.leftArrow + contentImageColor: DefaultStyle.main1_500_main + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + onClicked: mainItem.returnRequested() + } + ColumnLayout { + spacing: 3 * DefaultStyle.dp + Text { + text: qsTr("Appel de groupe") + color: DefaultStyle.main1_500_main + maximumLineCount: 1 + font { + pixelSize: 18 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + Layout.fillWidth: true + } + Text { + text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "") + color: DefaultStyle.main2_500main + maximumLineCount: 1 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + Layout.fillWidth: true + } + } + Button { + enabled: addParticipantLayout.selectedParticipantsCount.length != 0 + Layout.rightMargin: 21 * DefaultStyle.dp + topPadding: 6 * DefaultStyle.dp + bottomPadding: 6 * DefaultStyle.dp + leftPadding: 12 * DefaultStyle.dp + rightPadding: 12 * DefaultStyle.dp + text: qsTr("Ajouter") + textSize: 13 * DefaultStyle.dp + onClicked: { + mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants) + } + } } - onValidateRequested: { - conferenceInfoGui.core.resetParticipants(addParticipantLayout.selectedParticipants) - returnRequested() + AddParticipantsLayout { + id: addParticipantLayout + conferenceInfoGui: parent.conferenceInfoGui } } } + Component { id: meetingDetail ColumnLayout { visible: mainItem.selectedConference spacing: 25 * DefaultStyle.dp Section { + visible: mainItem.selectedConference content: RowLayout { spacing: 8 * DefaultStyle.dp Image { @@ -343,10 +493,12 @@ AbstractMainPage { } } onClicked: { - cancelAndDeleteConfDialog.cancel = UtilsCpp.isMe(mainItem.selectedConference.core.organizerAddress) - cancelAndDeleteConfDialog.open() - // mainItem.contactDeletionRequested(mainItem.selectedConference) - deletePopup.close() + if (mainItem.selectedConference) { + cancelAndDeleteConfDialog.cancel = UtilsCpp.isMe(mainItem.selectedConference.core.organizerAddress) + cancelAndDeleteConfDialog.open() + // mainItem.contactDeletionRequested(mainItem.selectedConference) + deletePopup.close() + } } Connections { target: cancelAndDeleteConfDialog