From ab2c01ade7220a1f0862c3bc0f882c056d369d50 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Wed, 24 Aug 2022 17:29:14 +0200 Subject: [PATCH] Allow participant device list model to get 'me' device. Display the ActiveSpeaker even if alone. Display preview rules : - Hide if alone or if paused. - Display at bottom-right if 2 participants. - Display at top-right and make it persistent if more participants. Put other participants at the bottom of the preview. --- .../ParticipantDeviceListModel.cpp | 16 +++- .../ParticipantDeviceListModel.hpp | 1 + .../ParticipantDeviceProxyModel.cpp | 7 ++ .../ParticipantDeviceProxyModel.hpp | 3 + linphone-app/ui/views/App/Calls/Incall.qml | 2 +- .../views/App/Calls/IncallActiveSpeaker.qml | 74 +++++++++++++------ 6 files changed, 76 insertions(+), 27 deletions(-) diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp index cc0ea4367..8406579ca 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp @@ -73,16 +73,22 @@ void ParticipantDeviceListModel::initConferenceModel(){ void ParticipantDeviceListModel::updateDevices(std::shared_ptr participant){ std::list> devices = participant->getDevices() ; + bool meAdded = false; beginResetModel(); qDebug() << "Update devices from participant"; mList.clear(); for(auto device : devices){ - auto deviceModel = ParticipantDeviceModel::create(mCallModel, device, isMe(device)); + bool addMe = isMe(device); + auto deviceModel = ParticipantDeviceModel::create(mCallModel, device, addMe); connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged); connect(deviceModel.get(), &ParticipantDeviceModel::isSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceSpeaking); mList << deviceModel; + if( addMe) + meAdded = true; } endResetModel(); + if( meAdded) + emit meChanged(); } void ParticipantDeviceListModel::updateDevices(const std::list>& devices, const bool& isMe){ @@ -101,12 +107,16 @@ bool ParticipantDeviceListModel::add(std::shared_ptr(deviceModel); qDebug() << "Device added. Count=" << mList.count(); + if( addMe){ + qDebug() << "Added a me device"; + emit meChanged(); + } return true; } diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp index ac61f7089..318e46730 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp @@ -69,6 +69,7 @@ signals: void securityLevelChanged(std::shared_ptr device); void participantSpeaking(ParticipantDeviceModel *speakingDevice); void conferenceCreated(); + void meChanged(); private: CallModel * mCallModel = nullptr; diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp index d39fea18c..c38a7eaa3 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp @@ -68,6 +68,11 @@ CallModel * ParticipantDeviceProxyModel::getCallModel() const{ return mCallModel; } +ParticipantDeviceModel * ParticipantDeviceProxyModel::getMe() const{ + auto listModel = qobject_cast(sourceModel()); + return listModel ? listModel->getMe().get() : nullptr; +} + bool ParticipantDeviceProxyModel::isShowMe() const{ return mShowMe; } @@ -79,6 +84,7 @@ void ParticipantDeviceProxyModel::setCallModel(CallModel * callModel){ connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::onCountChanged); connect(sourceModel, &ParticipantDeviceListModel::participantSpeaking, this, &ParticipantDeviceProxyModel::onParticipantSpeaking); connect(sourceModel, &ParticipantDeviceListModel::conferenceCreated, this, &ParticipantDeviceProxyModel::conferenceCreated); + connect(sourceModel, &ParticipantDeviceListModel::meChanged, this, &ParticipantDeviceProxyModel::meChanged); setSourceModel(sourceModel); emit countChanged(); } @@ -89,6 +95,7 @@ void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant) connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::countChanged); connect(sourceModel, &ParticipantDeviceListModel::participantSpeaking, this, &ParticipantDeviceProxyModel::onParticipantSpeaking); connect(sourceModel, &ParticipantDeviceListModel::conferenceCreated, this, &ParticipantDeviceProxyModel::conferenceCreated); + connect(sourceModel, &ParticipantDeviceListModel::meChanged, this, &ParticipantDeviceProxyModel::meChanged); setSourceModel(sourceModel); emit countChanged(); } diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp index b8c468c4a..ecdedfd02 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp @@ -41,11 +41,13 @@ class ParticipantDeviceProxyModel : public SortFilterProxyModel { public: Q_PROPERTY(CallModel * callModel READ getCallModel WRITE setCallModel NOTIFY callModelChanged) Q_PROPERTY(bool showMe READ isShowMe WRITE setShowMe NOTIFY showMeChanged) + Q_PROPERTY(ParticipantDeviceModel * me READ getMe NOTIFY meChanged) ParticipantDeviceProxyModel (QObject *parent = nullptr); Q_INVOKABLE ParticipantDeviceModel* getAt(int row); Q_INVOKABLE ParticipantDeviceModel* getLastActiveSpeaking(); + ParticipantDeviceModel * getMe() const; CallModel * getCallModel() const; bool isShowMe() const; @@ -61,6 +63,7 @@ public slots: signals: void callModelChanged(); void showMeChanged(); + void meChanged(); void participantSpeaking(ParticipantDeviceModel * speakingDevice); void conferenceCreated(); diff --git a/linphone-app/ui/views/App/Calls/Incall.qml b/linphone-app/ui/views/App/Calls/Incall.qml index e5dace53f..4495a8c61 100644 --- a/linphone-app/ui/views/App/Calls/Incall.qml +++ b/linphone-app/ui/views/App/Calls/Incall.qml @@ -296,7 +296,7 @@ Rectangle { && (!conference.conferenceModel || (conference.conferenceModel && !conference.conferenceModel.isReady)) ) - || !conferenceLayout.item || conferenceLayout.item.participantCount == 0 + || !conferenceLayout.item || (conferenceLayout.sourceComponent == gridComponent && !conference.callModel.videoEnabled && conferenceLayout.item.participantCount <= 1) ColumnLayout { anchors.fill: parent diff --git a/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml b/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml index 61dc128a3..c0f10d2f8 100644 --- a/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml +++ b/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml @@ -25,25 +25,18 @@ Item { property bool isRightReducedLayout: false property bool isLeftReducedLayout: false property bool cameraEnabled: true - property alias showMe : allDevices.showMe + property bool showMe : !(callModel && callModel.pausedByUser) property int participantCount: callModel.isConference ? allDevices.count : 2 onParticipantCountChanged: {console.log("Conf count: " +participantCount);allDevices.updateCurrentDevice()} - + property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel { id: allDevices callModel: mainItem.callModel - showMe: true - function updateShowMe(){ - showMe = cameraEnabled && !isPausedByUser - } + showMe: false + onParticipantSpeaking: updateCurrentDevice() - // Do it on changed to ignore hard bindings (that can be override) - property bool cameraEnabled: callModel && callModel.cameraEnabled - onCameraEnabledChanged:updateShowMe() - property bool isPausedByUser: callModel && callModel.pausedByUser - onIsPausedByUserChanged: updateShowMe() - //----- + onConferenceCreated: cameraView.resetCamera() function updateCurrentDevice(){ @@ -77,27 +70,63 @@ Item { avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor } + Item{// Need an item to not override Sticker internal states. States are needed for changing anchors. + id: preview + anchors.right: parent.right + anchors.rightMargin: 30 + anchors.topMargin: 30 + anchors.bottomMargin: 30 + height: miniViews.cellHeight + width: 16 * height / 9 + Sticker{ + anchors.fill: parent + visible: mainItem.showMe && allDevices.count >= 1 + anchors.margins: 3 + deactivateCamera: !mainItem.callModel || !mainItem.showMe || !mainItem.callModel.localVideoEnabled + currentDevice: allDevices.me + isPreview: true + callModel: mainItem.callModel + isCameraFromDevice: true + showCloseButton: false + showCustomButton: false + showAvatarBorder: true + avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor + avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor + } + state: allDevices.count < 2 ? 'bottom' : 'top' + states: [State { + name: "bottom" + + AnchorChanges { + target: preview + anchors.top: undefined + anchors.bottom: mainItem.bottom + } + }, + State { + name: "top" + + AnchorChanges { + target: preview + anchors.top: mainItem.top + anchors.bottom: undefined + } + }] + } ScrollableListView{ id: miniViews anchors.right: parent.right - anchors.top: parent.top + anchors.top: preview.bottom anchors.bottom: parent.bottom anchors.rightMargin: 30 - anchors.topMargin: 30 + anchors.topMargin: 15 anchors.bottomMargin: 30 property int cellHeight: 150 width: 16 * cellHeight / 9 - model: mainItem.callModel.isConference - ? mainItem.participantDevices.showMe && mainItem.participantDevices.count <= 1 - ? [] - : mainItem.participantDevices - : mainItem.callModel.localVideoEnabled && !callModel.pausedByUser - ? [{videoEnabled:true, isPreview:true}] - : [] + model: mainItem.callModel.isConference && mainItem.participantDevices.count > 1 ? mainItem.participantDevices : [] onModelChanged: console.log( mainItem.callModel.isConference+"/"+mainItem.callModel.localVideoEnabled + "/" +mainItem.callModel.cameraEnabled + " / " +count) spacing: 15 - verticalLayoutDirection: ItemView.BottomToTop delegate:Item{ height: miniViews.cellHeight width: miniViews.width @@ -116,7 +145,6 @@ Item { showAvatarBorder: true avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor - //onCloseRequested: mainItem.showMe = false } } }