This commit is contained in:
Julien Wadel 2024-04-04 15:45:59 +02:00
parent 589c67999f
commit b834b7c669
12 changed files with 202 additions and 91 deletions

View file

@ -92,6 +92,7 @@ CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullpt
} }
mMicrophoneVolume = call->getRecordVolume(); mMicrophoneVolume = call->getRecordVolume();
mRecordable = mState == LinphoneEnums::CallState::StreamsRunning; mRecordable = mState == LinphoneEnums::CallState::StreamsRunning;
mConferenceVideoLayout = mCallModel->getConferenceVideoLayout();
} }
CallCore::~CallCore() { CallCore::~CallCore() {
@ -220,7 +221,7 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
mCallModelConnection->makeConnectToModel(&CallModel::microphoneVolumeGainChanged, [this](float gain) { mCallModelConnection->makeConnectToModel(&CallModel::microphoneVolumeGainChanged, [this](float gain) {
mCallModelConnection->invokeToCore([this, gain]() { setMicrophoneVolumeGain(gain); }); mCallModelConnection->invokeToCore([this, gain]() { setMicrophoneVolumeGain(gain); });
}); });
mCallModelConnection->makeConnectToCore(&CallCore::lSetInputAudioDevice, [this](const QString &id) { mCallModelConnection->makeConnectToCore(&CallCore::lSetInputAudioDevice, [this](QString id) {
mCallModelConnection->invokeToModel([this, id]() { mCallModelConnection->invokeToModel([this, id]() {
if (auto device = ToolModel::findAudioDevice(id)) { if (auto device = ToolModel::findAudioDevice(id)) {
mCallModel->setInputAudioDevice(device); mCallModel->setInputAudioDevice(device);
@ -230,7 +231,7 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
mCallModelConnection->makeConnectToModel(&CallModel::inputAudioDeviceChanged, [this](const std::string &id) { mCallModelConnection->makeConnectToModel(&CallModel::inputAudioDeviceChanged, [this](const std::string &id) {
mCallModelConnection->invokeToCore([this, id]() {}); mCallModelConnection->invokeToCore([this, id]() {});
}); });
mCallModelConnection->makeConnectToCore(&CallCore::lSetOutputAudioDevice, [this](const QString &id) { mCallModelConnection->makeConnectToCore(&CallCore::lSetOutputAudioDevice, [this](QString id) {
mCallModelConnection->invokeToModel([this, id]() { mCallModelConnection->invokeToModel([this, id]() {
if (auto device = ToolModel::findAudioDevice(id)) { if (auto device = ToolModel::findAudioDevice(id)) {
mCallModel->setOutputAudioDevice(device); mCallModel->setOutputAudioDevice(device);
@ -253,6 +254,14 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
mCallModelConnection->makeConnectToCore(&CallCore::lTerminateAllCalls, [this]() { mCallModelConnection->makeConnectToCore(&CallCore::lTerminateAllCalls, [this]() {
mCallModelConnection->invokeToModel([this]() { mCallModel->terminateAllCalls(); }); mCallModelConnection->invokeToModel([this]() { mCallModel->terminateAllCalls(); });
}); });
mCallModelConnection->makeConnectToModel(
&CallModel::conferenceVideoLayoutChanged, [this](LinphoneEnums::ConferenceLayout layout) {
mCallModelConnection->invokeToCore([this, layout]() { setConferenceVideoLayout(layout); });
});
mCallModelConnection->makeConnectToCore(
&CallCore::lSetConferenceVideoLayout, [this](LinphoneEnums::ConferenceLayout layout) {
mCallModelConnection->invokeToModel([this, layout]() { mCallModel->changeConferenceVideoLayout(layout); });
});
} }
QString CallCore::getPeerAddress() const { QString CallCore::getPeerAddress() const {
@ -509,6 +518,18 @@ void CallCore::setTransferState(LinphoneEnums::CallState state, const QString &m
} }
} }
LinphoneEnums::ConferenceLayout CallCore::getConferenceVideoLayout() const {
return mConferenceVideoLayout;
}
void CallCore::setConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout) {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (mConferenceVideoLayout != layout) {
mConferenceVideoLayout = layout;
emit conferenceVideoLayoutChanged();
}
}
std::shared_ptr<CallModel> CallCore::getModel() const { std::shared_ptr<CallModel> CallCore::getModel() const {
return mCallModel; return mCallModel;
} }

View file

@ -61,6 +61,8 @@ class CallCore : public QObject, public AbstractObject {
Q_PROPERTY(float microVolume READ getMicrophoneVolume WRITE setMicrophoneVolume NOTIFY microphoneVolumeChanged) Q_PROPERTY(float microVolume READ getMicrophoneVolume WRITE setMicrophoneVolume NOTIFY microphoneVolumeChanged)
Q_PROPERTY(LinphoneEnums::CallState transferState READ getTransferState NOTIFY transferStateChanged) Q_PROPERTY(LinphoneEnums::CallState transferState READ getTransferState NOTIFY transferStateChanged)
Q_PROPERTY(ConferenceGui *conference READ getConferenceGui NOTIFY conferenceChanged) Q_PROPERTY(ConferenceGui *conference READ getConferenceGui NOTIFY conferenceChanged)
Q_PROPERTY(LinphoneEnums::ConferenceLayout conferenceVideoLayout READ getConferenceVideoLayout WRITE
lSetConferenceVideoLayout NOTIFY conferenceVideoLayoutChanged)
public: public:
// Should be call from model Thread. Will be automatically in App thread after initialization // Should be call from model Thread. Will be automatically in App thread after initialization
@ -141,6 +143,9 @@ public:
LinphoneEnums::CallState getTransferState() const; LinphoneEnums::CallState getTransferState() const;
void setTransferState(LinphoneEnums::CallState state, const QString &message); void setTransferState(LinphoneEnums::CallState state, const QString &message);
LinphoneEnums::ConferenceLayout getConferenceVideoLayout() const;
void setConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout);
std::shared_ptr<CallModel> getModel() const; std::shared_ptr<CallModel> getModel() const;
signals: signals:
@ -165,6 +170,7 @@ signals:
void microphoneVolumeChanged(); void microphoneVolumeChanged();
void microphoneVolumeGainChanged(); void microphoneVolumeGainChanged();
void conferenceChanged(); void conferenceChanged();
void conferenceVideoLayoutChanged();
// Linphone commands // Linphone commands
void lAccept(bool withVideo); // Accept an incoming call void lAccept(bool withVideo); // Accept an incoming call
@ -175,14 +181,15 @@ signals:
void lSetMicrophoneMuted(bool isMuted); void lSetMicrophoneMuted(bool isMuted);
void lSetCameraEnabled(bool enabled); void lSetCameraEnabled(bool enabled);
void lSetPaused(bool paused); void lSetPaused(bool paused);
void lTransferCall(const QString &dest); void lTransferCall(QString &est);
void lStartRecording(); void lStartRecording();
void lStopRecording(); void lStopRecording();
void lVerifyAuthenticationToken(bool verified); void lVerifyAuthenticationToken(bool verified);
void lSetSpeakerVolumeGain(float gain); void lSetSpeakerVolumeGain(float gain);
void lSetMicrophoneVolumeGain(float gain); void lSetMicrophoneVolumeGain(float gain);
void lSetInputAudioDevice(const QString &id); void lSetInputAudioDevice(QString id);
void lSetOutputAudioDevice(const QString &id); void lSetOutputAudioDevice(QString id);
void lSetConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout);
/* TODO /* TODO
Q_INVOKABLE void acceptWithVideo(); Q_INVOKABLE void acceptWithVideo();
@ -209,7 +216,9 @@ private:
LinphoneEnums::CallState mState; LinphoneEnums::CallState mState;
LinphoneEnums::CallState mTransferState; LinphoneEnums::CallState mTransferState;
LinphoneEnums::CallDir mDir; LinphoneEnums::CallDir mDir;
LinphoneEnums::ConferenceLayout mConferenceVideoLayout;
LinphoneEnums::MediaEncryption mEncryption; LinphoneEnums::MediaEncryption mEncryption;
QString mLastErrorMessage; QString mLastErrorMessage;
QString mPeerAddress; QString mPeerAddress;
bool mIsSecured; bool mIsSecured;

View file

@ -153,6 +153,7 @@ void CallModel::setRecordFile(const std::string &path) {
} }
void CallModel::setSpeakerVolumeGain(float gain) { void CallModel::setSpeakerVolumeGain(float gain) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
mMonitor->setSpeakerVolumeGain(gain); mMonitor->setSpeakerVolumeGain(gain);
emit speakerVolumeGainChanged(gain); emit speakerVolumeGainChanged(gain);
} }
@ -165,21 +166,25 @@ float CallModel::getSpeakerVolumeGain() const {
} }
void CallModel::setMicrophoneVolumeGain(float gain) { void CallModel::setMicrophoneVolumeGain(float gain) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
mMonitor->setMicrophoneVolumeGain(gain); mMonitor->setMicrophoneVolumeGain(gain);
emit microphoneVolumeGainChanged(gain); emit microphoneVolumeGainChanged(gain);
} }
float CallModel::getMicrophoneVolumeGain() const { float CallModel::getMicrophoneVolumeGain() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto gain = mMonitor->getMicrophoneVolumeGain(); auto gain = mMonitor->getMicrophoneVolumeGain();
return gain; return gain;
} }
float CallModel::getMicrophoneVolume() const { float CallModel::getMicrophoneVolume() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto volume = mMonitor->getRecordVolume(); auto volume = mMonitor->getRecordVolume();
return volume; return volume;
} }
void CallModel::setInputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &device) { void CallModel::setInputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &device) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
mMonitor->setInputAudioDevice(device); mMonitor->setInputAudioDevice(device);
std::string deviceName; std::string deviceName;
if (device) deviceName = device->getDeviceName(); if (device) deviceName = device->getDeviceName();
@ -187,10 +192,12 @@ void CallModel::setInputAudioDevice(const std::shared_ptr<linphone::AudioDevice>
} }
std::shared_ptr<const linphone::AudioDevice> CallModel::getInputAudioDevice() const { std::shared_ptr<const linphone::AudioDevice> CallModel::getInputAudioDevice() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return mMonitor->getInputAudioDevice(); return mMonitor->getInputAudioDevice();
} }
void CallModel::setOutputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &device) { void CallModel::setOutputAudioDevice(const std::shared_ptr<linphone::AudioDevice> &device) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
mMonitor->setOutputAudioDevice(device); mMonitor->setOutputAudioDevice(device);
std::string deviceName; std::string deviceName;
if (device) deviceName = device->getDeviceName(); if (device) deviceName = device->getDeviceName();
@ -198,6 +205,7 @@ void CallModel::setOutputAudioDevice(const std::shared_ptr<linphone::AudioDevice
} }
std::shared_ptr<const linphone::AudioDevice> CallModel::getOutputAudioDevice() const { std::shared_ptr<const linphone::AudioDevice> CallModel::getOutputAudioDevice() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return mMonitor->getOutputAudioDevice(); return mMonitor->getOutputAudioDevice();
} }
@ -229,12 +237,53 @@ std::string CallModel::getAuthenticationToken() const {
} }
void CallModel::setConference(const std::shared_ptr<linphone::Conference> &conference) { void CallModel::setConference(const std::shared_ptr<linphone::Conference> &conference) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
if (mConference != conference) { if (mConference != conference) {
mConference = conference; mConference = conference;
emit conferenceChanged(); emit conferenceChanged();
} }
} }
LinphoneEnums::ConferenceLayout CallModel::getConferenceVideoLayout() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return LinphoneEnums::fromLinphone(mMonitor->getParams()->getConferenceVideoLayout());
}
void CallModel::changeConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto coreManager = CoreModel::getInstance();
// if (layout == LinphoneEnums::ConferenceLayout::Grid)
// coreManager->getSettingsModel()->setCameraMode(coreManager->getSettingsModel()->getGridCameraMode());
// else
// coreManager->getSettingsModel()->setCameraMode(coreManager->getSettingsModel()->getActiveSpeakerCameraMode());
auto params = coreManager->getCore()->createCallParams(mMonitor);
params->setConferenceVideoLayout(LinphoneEnums::toLinphone(layout));
params->enableVideo(layout != LinphoneEnums::ConferenceLayout::AudioOnly);
if (!params->videoEnabled() && params->screenSharingEnabled()) {
params->enableScreenSharing(false); // Deactivate screensharing if going to audio only.
}
mMonitor->update(params);
}
void CallModel::updateConferenceVideoLayout() {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto callParams = mMonitor->getParams();
// auto settings = CoreManager::getInstance()->getSettingsModel();
auto newLayout = LinphoneEnums::fromLinphone(callParams->getConferenceVideoLayout());
if (!callParams->videoEnabled()) newLayout = LinphoneEnums::ConferenceLayout::AudioOnly;
if (mConferenceVideoLayout != newLayout) { // && !getPausedByUser()) { // Only update if not in pause.
// if (mMonitor->getConference()) {
// if (callParams->getConferenceVideoLayout() == linphone::Conference::Layout::Grid)
// settings->setCameraMode(settings->getGridCameraMode());
// else settings->setCameraMode(settings->getActiveSpeakerCameraMode());
// } else settings->setCameraMode(settings->getCallCameraMode());
qDebug() << "Changing layout from " << mConferenceVideoLayout << " into " << newLayout;
mConferenceVideoLayout = newLayout;
emit conferenceVideoLayoutChanged(mConferenceVideoLayout);
}
}
void CallModel::onDtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf) { void CallModel::onDtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf) {
emit dtmfReceived(call, dtmf); emit dtmfReceived(call, dtmf);
} }
@ -272,6 +321,7 @@ void CallModel::onStateChanged(const std::shared_ptr<linphone::Call> &call,
emit remoteVideoEnabledChanged(params && params->videoEnabled()); emit remoteVideoEnabledChanged(params && params->videoEnabled());
emit cameraEnabledChanged(call->cameraEnabled()); emit cameraEnabledChanged(call->cameraEnabled());
setConference(call->getConference()); setConference(call->getConference());
updateConferenceVideoLayout();
} }
emit stateChanged(state, message); emit stateChanged(state, message);
} }

View file

@ -23,6 +23,7 @@
#include "model/listener/Listener.hpp" #include "model/listener/Listener.hpp"
#include "tool/AbstractObject.hpp" #include "tool/AbstractObject.hpp"
#include "tool/LinphoneEnums.hpp"
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
@ -67,6 +68,10 @@ public:
void setAuthenticationTokenVerified(bool verified); void setAuthenticationTokenVerified(bool verified);
std::string getAuthenticationToken() const; std::string getAuthenticationToken() const;
LinphoneEnums::ConferenceLayout getConferenceVideoLayout() const;
void changeConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout); // Make a call request
void updateConferenceVideoLayout(); // Called from call state changed ater the new layout has been set.
signals: signals:
void microphoneMutedChanged(bool isMuted); void microphoneMutedChanged(bool isMuted);
void speakerMutedChanged(bool isMuted); void speakerMutedChanged(bool isMuted);
@ -82,11 +87,13 @@ signals:
void inputAudioDeviceChanged(const std::string &id); void inputAudioDeviceChanged(const std::string &id);
void outputAudioDeviceChanged(const std::string &id); void outputAudioDeviceChanged(const std::string &id);
void conferenceChanged(); void conferenceChanged();
void conferenceVideoLayoutChanged(LinphoneEnums::ConferenceLayout layout);
private: private:
QTimer mDurationTimer; QTimer mDurationTimer;
QTimer mMicroVolumeTimer; QTimer mMicroVolumeTimer;
std::shared_ptr<linphone::Conference> mConference; std::shared_ptr<linphone::Conference> mConference;
LinphoneEnums::ConferenceLayout mConferenceVideoLayout;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT

View file

@ -20,6 +20,8 @@ Window {
property ConferenceGui conference: call && call.core.conference || null property ConferenceGui conference: call && call.core.conference || null
onConferenceChanged: console.log ("CONFERENCE CHANGED", conference) onConferenceChanged: console.log ("CONFERENCE CHANGED", conference)
property var conferenceLayout: call && call.core.conferenceVideoLayout || undefined
property bool callTerminatedByUser: false property bool callTerminatedByUser: false
onCallChanged: { onCallChanged: {
@ -47,13 +49,15 @@ Window {
function changeLayout(layoutIndex) { function changeLayout(layoutIndex) {
if (layoutIndex == 0) { if (layoutIndex == 0) {
console.log("TODO : set mosaic layout") console.log("Set Grid layout")
call.core.lSetConferenceVideoLayout(LinphoneEnums.ConferenceLayout.Grid)
} else if (layoutIndex == 1) { } else if (layoutIndex == 1) {
console.log("TODO : set pip layout") console.log("Set AS layout")
call.core.lSetConferenceVideoLayout(LinphoneEnums.ConferenceLayout.ActiveSpeaker)
} else { } else {
console.log("TODO : set audio layout") console.log("Set audio-only layout")
call.core.lSetConferenceVideoLayout(LinphoneEnums.ConferenceLayout.AudioOnly)
} }
console.log("+ change settings default layout")
} }
Connections { Connections {
@ -469,14 +473,19 @@ Window {
] ]
RadioButton { RadioButton {
id: radiobutton id: radiobutton
checkOnClick: false
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
indicatorSize: 20 * DefaultStyle.dp indicatorSize: 20 * DefaultStyle.dp
leftPadding: indicator.width + spacing leftPadding: indicator.width + spacing
spacing: 8 * DefaultStyle.dp spacing: 8 * DefaultStyle.dp
Component.onCompleted: { checkable: false // Qt Documentation is wrong: It is true by default. We don't want to change the checked state if the layout change is not effective.
console.log("TODO : set checked true if is current layout") checked: index == 0
if (index == 0) checked = true ? mainWindow.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid
} : index == 1
? mainWindow.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker
: mainWindow.conferenceLayout === LinphoneEnums.ConferenceLayout.AudioOnly
onClicked: mainWindow.changeLayout(index)
contentItem: RowLayout { contentItem: RowLayout {
spacing: 5 * DefaultStyle.dp spacing: 5 * DefaultStyle.dp
EffectImage { EffectImage {
@ -494,7 +503,6 @@ Window {
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
onCheckedChanged: if (checked) mainWindow.changeLayout(index)
} }
} }
} }

View file

@ -7,7 +7,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Layout/Call/ActiveSpeakerLayout.qml view/Layout/Call/ActiveSpeakerLayout.qml
view/Layout/Call/CallLayout.qml view/Layout/Call/CallLayout.qml
#view/Layout/Call/GridLayout.qml view/Layout/Call/GridLayout.qml
view/Layout/Conference/IncallGrid.qml view/Layout/Conference/IncallGrid.qml
view/Layout/Contact/ContactLayout.qml view/Layout/Contact/ContactLayout.qml

View file

@ -1,6 +1,6 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 as Control import QtQuick.Controls 2.2 as Control
import QtQuick.Layouts import QtQuick.Layouts as Layout
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
@ -59,16 +59,16 @@ Control.Popup {
onClicked: mainItem.close() onClicked: mainItem.close()
} }
} }
contentItem: GridLayout { contentItem: Layout.GridLayout {
columns: 3 columns: 3
columnSpacing: 3 columnSpacing: 3
Layout.fillWidth: true Layout.Layout.fillWidth: true
Layout.fillHeight: true Layout.Layout.fillHeight: true
Repeater { Repeater {
model: 9 model: 9
Button { Button {
id: numPadButton id: numPadButton
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
required property int index required property int index
implicitWidth: 60 * DefaultStyle.dp implicitWidth: 60 * DefaultStyle.dp
implicitHeight: 60 * DefaultStyle.dp implicitHeight: 60 * DefaultStyle.dp
@ -101,7 +101,7 @@ Control.Popup {
] ]
Button { Button {
id: digitButton id: digitButton
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
shadowEnabled: true shadowEnabled: true
implicitWidth: 60 * DefaultStyle.dp implicitWidth: 60 * DefaultStyle.dp
implicitHeight: 60 * DefaultStyle.dp implicitHeight: 60 * DefaultStyle.dp
@ -146,7 +146,7 @@ Control.Popup {
id: launchCallButton id: launchCallButton
implicitWidth: 75 * DefaultStyle.dp implicitWidth: 75 * DefaultStyle.dp
implicitHeight: 55 * DefaultStyle.dp implicitHeight: 55 * DefaultStyle.dp
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.success_500main color: DefaultStyle.success_500main
@ -163,7 +163,7 @@ Control.Popup {
rightPadding: 5 * DefaultStyle.dp rightPadding: 5 * DefaultStyle.dp
topPadding: 5 * DefaultStyle.dp topPadding: 5 * DefaultStyle.dp
bottomPadding: 5 * DefaultStyle.dp bottomPadding: 5 * DefaultStyle.dp
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
background: Item { background: Item {
visible: false visible: false
} }

View file

@ -8,15 +8,16 @@ Control.RadioButton {
property string title property string title
property string contentText property string contentText
property string imgUrl property string imgUrl
property bool checkOnClick: true
property color color property color color
hoverEnabled: true
property int indicatorSize: 16 * DefaultStyle.dp property int indicatorSize: 16 * DefaultStyle.dp
//onClicked: if (checkOnClick && !mainItem.checked) mainItem.toggle()
MouseArea{ MouseArea{
anchors.fill:parent anchors.fill:parent
hoverEnabled: false hoverEnabled: true
cursorShape: mainItem.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor acceptedButtons: Qt.NoButton
onClicked: if (!mainItem.checked) mainItem.toggle() cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
} }
indicator: Rectangle { indicator: Rectangle {

View file

@ -1,5 +1,5 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts as Layout
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
@ -27,10 +27,10 @@ Dialog {
onStatusChanged: if (status === CallModel.CallStatusEnded) close() onStatusChanged: if (status === CallModel.CallStatusEnded) close()
} }
buttons: ColumnLayout { buttons: Layout.ColumnLayout {
spacing: 15 * DefaultStyle.dp spacing: 15 * DefaultStyle.dp
Button { Button {
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
background: Item{} background: Item{}
contentItem: Text { contentItem: Text {
text: qsTr("Skip") text: qsTr("Skip")
@ -49,7 +49,7 @@ Dialog {
text: qsTr("Letters doesn't match") text: qsTr("Letters doesn't match")
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500main
inversedColors: true inversedColors: true
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
width: 330 * DefaultStyle.dp width: 330 * DefaultStyle.dp
onClicked: { onClicked: {
if(mainItem.call) mainItem.call.core.lVerifyAuthenticationToken(false) if(mainItem.call) mainItem.call.core.lVerifyAuthenticationToken(false)
@ -58,14 +58,14 @@ Dialog {
} }
} }
content: ColumnLayout { content: Layout.ColumnLayout {
spacing: 32 * DefaultStyle.dp spacing: 32 * DefaultStyle.dp
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
ColumnLayout { Layout.ColumnLayout {
spacing: 10 * DefaultStyle.dp spacing: 10 * DefaultStyle.dp
Text { Text {
Layout.preferredWidth: 330 * DefaultStyle.dp Layout.Layout.preferredWidth: 330 * DefaultStyle.dp
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
text: qsTr("Vérifier l'appareil") text: qsTr("Vérifier l'appareil")
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
@ -76,8 +76,8 @@ Dialog {
} }
Text { Text {
Layout.preferredWidth: 330 * DefaultStyle.dp Layout.Layout.preferredWidth: 330 * DefaultStyle.dp
Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
//: 'To raise the security level, you can check the following codes with your correspondent.' : Explanation to do a security check. //: 'To raise the security level, you can check the following codes with your correspondent.' : Explanation to do a security check.
@ -88,10 +88,10 @@ Dialog {
} }
} }
GridLayout { Layout.GridLayout {
id: securityGridView id: securityGridView
// Layout.fillWidth: true // Layout.Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom Layout.Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
rows: 2 rows: 2
columns: 2 columns: 2
rowSpacing: 32 * DefaultStyle.dp rowSpacing: 32 * DefaultStyle.dp

View file

@ -1,5 +1,5 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts as Layout
import QtQuick.Effects import QtQuick.Effects
import QtQml.Models import QtQml.Models
import QtQuick.Controls as Control import QtQuick.Controls as Control
@ -16,6 +16,8 @@ Item {
property CallGui call property CallGui call
property bool callTerminatedByUser: false property bool callTerminatedByUser: false
readonly property var callState: call && call.core.state || undefined readonly property var callState: call && call.core.state || undefined
property var conferenceLayout: call && call.core.conferenceVideoLayout || undefined
onConferenceLayoutChanged:console.log("CallLayout change : " +conferenceLayout)
onCallStateChanged: if (callState === LinphoneEnums.CallState.End) { onCallStateChanged: if (callState === LinphoneEnums.CallState.End) {
callTerminatedText.visible = true callTerminatedText.visible = true
}else if( callState === LinphoneEnums.CallState.Error) { }else if( callState === LinphoneEnums.CallState.Error) {
@ -36,33 +38,47 @@ Item {
weight: 300 * DefaultStyle.dp weight: 300 * DefaultStyle.dp
} }
} }
StackLayout { Layout.StackLayout {
id: centerLayout id: centerLayout
currentIndex: 0 currentIndex: 0
anchors.fill: parent anchors.fill: parent
Loader{ Loader{
id: callLayout id: callLayout
Layout.fillWidth: true Layout.Layout.fillWidth: true
Layout.fillHeight: true Layout.Layout.fillHeight: true
sourceComponent:ActiveSpeakerLayout{ sourceComponent: mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker
Layout.fillWidth: true ? activeSpeakerComponent
Layout.fillHeight: true : gridComponent
call: mainItem.call
} }
} Layout.ColumnLayout {
ColumnLayout {
id: userNotFoundLayout id: userNotFoundLayout
Layout.preferredWidth: parent.width Layout.Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height Layout.Layout.preferredHeight: parent.height
Layout.alignment: Qt.AlignCenter Layout.Layout.alignment: Qt.AlignCenter
Text { Text {
text: qsTr(mainItem.call.core.lastErrorMessage) text: qsTr(mainItem.call.core.lastErrorMessage)
Layout.alignment: Qt.AlignCenter Layout.Layout.alignment: Qt.AlignCenter
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font.pixelSize: 40 * DefaultStyle.dp font.pixelSize: 40 * DefaultStyle.dp
} }
} }
} }
Component{
id: activeSpeakerComponent
ActiveSpeakerLayout{
Layout.Layout.fillWidth: true
Layout.Layout.fillHeight: true
call: mainItem.call
}
}
Component{
id: gridComponent
GridLayout{
Layout.Layout.fillWidth: true
Layout.Layout.fillHeight: true
call: mainItem.call
}
}
} }
// ColumnLayout { // ColumnLayout {

View file

@ -1,27 +1,14 @@
import QtQuick 2.7 import QtQuick
import QtQuick.Layouts 1.3 import QtQuick.Layouts
import QtQml.Models 2.12 import QtQml.Models
import QtGraphicalEffects 1.12
import Common 1.0 import Linphone
import Common.Styles 1.0
import Linphone 1.0
import LinphoneEnums 1.0
import UtilsCpp 1.0
import App.Styles 1.0
import ConstantsCpp 1.0
// Temp
import 'Incall.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// ============================================================================= // =============================================================================
Mosaic { Mosaic {
id: grid id: grid
property alias callModel: participantDevices.callModel property alias call: allDevices.currentCall
property bool cameraEnabled: true property bool cameraEnabled: true
property int participantCount: gridModel.count property int participantCount: gridModel.count
@ -29,27 +16,41 @@ Mosaic {
//onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality() //onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality()
delegateModel: DelegateModel{ delegateModel: DelegateModel{
id: gridModel id: gridModel
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel { property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy {
id: participantDevices id: allDevices
showMe: true qmlName: "G"
Component.onCompleted: console.log("Loaded : " +allDevices)
} }
model: participantDevices model: participantDevices
delegate: Item{ delegate: Item{
id: avatarCell id: avatarCell
property ParticipantDeviceModel currentDevice: gridModel.participantDevices.getAt(index) property ParticipantDeviceGui currentDevice: gridModel.participantDevices.getAt(index)
onCurrentDeviceChanged: { onCurrentDeviceChanged: {
if(index < 0) cameraView.enabled = false // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer) if(index < 0) cameraView.enabled = false // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer)
} }
height: grid.cellHeight - 10 height: grid.cellHeight - 10
width: grid.cellWidth - 10 width: grid.cellWidth - 10
Sticker {
id: cameraView
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
&& modelData.core.address != activeSpeakerSticker.address
anchors.fill: parent
//height: visible ? 180 * DefaultStyle.dp : 0
//width: 300 * DefaultStyle.dp
qmlName: 'G_'+index
participantDevice: avatarCell.currentDevice
previewEnabled: index == 0
Component.onCompleted: console.log(qmlName + " is " +modelData.core.address)
}
/*
Sticker{ Sticker{
id: cameraView id: cameraView
anchors.fill: parent anchors.fill: parent
cameraQmlName: 'G_'+index cameraQmlName: 'G_'+index
callModel: index >= 0 ? participantDevices.callModel : null // do this before to prioritize changing call on remove callModel: index >= 0 ? allDevices.callModel : null // do this before to prioritize changing call on remove
deactivateCamera: index <0 || !grid.cameraEnabled || grid.callModel.pausedByUser deactivateCamera: index <0 || !grid.cameraEnabled || grid.callModel.pausedByUser
currentDevice: gridModel.participantDevices.getAt(index) currentDevice: gridModel.participantDevices.getAt(index)
@ -61,7 +62,7 @@ Mosaic {
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
//onCloseRequested: participantDevices.showMe = false //onCloseRequested: participantDevices.showMe = false
} }*/
} }
} }
} }

View file

@ -1,10 +1,8 @@
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.2 import QtQuick.Controls
import QtQuick.Layouts 1.0 import QtQuick.Layouts
import QtQml.Models 2.12 import QtQml.Models
import Common 1.0
import Common.Styles 1.0
// ============================================================================= // =============================================================================
ColumnLayout{ ColumnLayout{