mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 19:38:09 +00:00
329 lines
11 KiB
QML
329 lines
11 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts as Layout
|
|
import QtQuick.Effects
|
|
import QtQml.Models
|
|
import QtQuick.Controls as Control
|
|
import Linphone
|
|
import EnumsToStringCpp 1.0
|
|
import UtilsCpp 1.0
|
|
import SettingsCpp 1.0
|
|
// =============================================================================
|
|
|
|
Item {
|
|
id: mainItem
|
|
anchors.fill: parent
|
|
|
|
property CallGui call
|
|
property bool callTerminatedByUser: false
|
|
readonly property var callState: call && call.core.state || undefined
|
|
property int conferenceLayout: call && call.core.conferenceVideoLayout || 0
|
|
onConferenceLayoutChanged:console.log("CallLayout change : " +conferenceLayout)
|
|
onCallStateChanged: if (callState === LinphoneEnums.CallState.End) {
|
|
callTerminatedText.visible = true
|
|
}else if( callState === LinphoneEnums.CallState.Error) {
|
|
centerLayout.currentIndex = 1
|
|
}
|
|
|
|
Text {
|
|
id: callTerminatedText
|
|
visible: false
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.top: parent.top
|
|
anchors.topMargin: 25 * DefaultStyle.dp
|
|
text: mainItem.callTerminatedByUser ? qsTr("Vous avez terminé l'appel") : qsTr("Votre correspondant a terminé l'appel")
|
|
color: DefaultStyle.grey_0
|
|
z: 1
|
|
font {
|
|
pixelSize: 22 * DefaultStyle.dp
|
|
weight: 300 * DefaultStyle.dp
|
|
}
|
|
}
|
|
Layout.StackLayout {
|
|
id: centerLayout
|
|
currentIndex: 0
|
|
anchors.fill: parent
|
|
Loader{
|
|
id: callLayout
|
|
Layout.Layout.fillWidth: true
|
|
Layout.Layout.fillHeight: true
|
|
sourceComponent: mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker
|
|
? activeSpeakerComponent
|
|
: gridComponent
|
|
}
|
|
Layout.ColumnLayout {
|
|
id: userNotFoundLayout
|
|
Layout.Layout.preferredWidth: parent.width
|
|
Layout.Layout.preferredHeight: parent.height
|
|
Layout.Layout.alignment: Qt.AlignCenter
|
|
Text {
|
|
text: qsTr(mainItem.call.core.lastErrorMessage)
|
|
Layout.Layout.alignment: Qt.AlignCenter
|
|
color: DefaultStyle.grey_0
|
|
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 {
|
|
// id: waitingForParticipant
|
|
// Text {
|
|
// text: qsTr("Waiting for other participants...")
|
|
// color: DefaultStyle.frey_0
|
|
// font {
|
|
// pixelSize: 30 * DefaultStyle.dp
|
|
// weight: 300 * DefaultStyle.dp
|
|
// }
|
|
// }
|
|
// Button {
|
|
// inversedColors: true
|
|
// text: qsTr("Share invitation")
|
|
// icon.source: AppIcons.shareNetwork
|
|
// color: DefaultStyle.main2_400
|
|
// Layout.preferredWidth: 206 * DefaultStyle.dp
|
|
// Layout.preferredHeight: 47 * DefaultStyle.dp
|
|
// }
|
|
// }
|
|
/*
|
|
Sticker {
|
|
id: preview
|
|
visible: mainItem.callState != LinphoneEnums.CallState.End
|
|
&& mainItem.callState != LinphoneEnums.CallState.Released
|
|
height: 180 * DefaultStyle.dp
|
|
width: 300 * DefaultStyle.dp
|
|
anchors.right: mainItem.right
|
|
anchors.bottom: mainItem.bottom
|
|
anchors.rightMargin: 10 * DefaultStyle.dp
|
|
anchors.bottomMargin: 10 * DefaultStyle.dp
|
|
AccountProxy{
|
|
id: accounts
|
|
}
|
|
account: accounts.defaultAccount
|
|
previewEnabled: mainItem.call.core.cameraEnabled
|
|
|
|
MovableMouseArea {
|
|
id: previewMouseArea
|
|
anchors.fill: parent
|
|
// visible: mainItem.participantCount <= 2
|
|
movableArea: mainItem
|
|
margin: 10 * DefaultStyle.dp
|
|
function resetPosition(){
|
|
preview.anchors.right = mainItem.right
|
|
preview.anchors.bottom = mainItem.bottom
|
|
preview.anchors.rightMargin = previewMouseArea.margin
|
|
preview.anchors.bottomMargin = previewMouseArea.margin
|
|
}
|
|
onVisibleChanged: if(!visible){
|
|
resetPosition()
|
|
}
|
|
drag.target: preview
|
|
onDraggingChanged: if(dragging) {
|
|
preview.anchors.right = undefined
|
|
preview.anchors.bottom = undefined
|
|
}
|
|
onRequestResetPosition: resetPosition()
|
|
}
|
|
}
|
|
|
|
property int previousWidth
|
|
Component.onCompleted: {
|
|
previousWidth = width
|
|
}
|
|
onWidthChanged: {
|
|
if (width < previousWidth) {
|
|
previewMouseArea.updatePosition(0, 0)
|
|
} else {
|
|
previewMouseArea.updatePosition(width - previousWidth, 0)
|
|
}
|
|
previousWidth = width
|
|
}*/
|
|
|
|
/*
|
|
|
|
Item {
|
|
id: mainItem
|
|
property CallModel callModel
|
|
property bool isRightReducedLayout: false
|
|
property bool isLeftReducedLayout: false
|
|
property bool cameraEnabled: true
|
|
property bool isConference: callModel && callModel.isConference
|
|
property bool isConferenceReady: isConference && callModel.conferenceModel && callModel.conferenceModel.isReady
|
|
|
|
property int participantCount: isConference ? allDevices.count + 1 : 2 // +me. allDevices==0 if !conference
|
|
|
|
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel {
|
|
id: allDevices
|
|
callModel: mainItem.callModel
|
|
showMe: false
|
|
|
|
onConferenceCreated: cameraView.resetCamera()
|
|
}
|
|
|
|
Sticker{
|
|
id: cameraView
|
|
anchors.fill: parent
|
|
anchors.leftMargin: isRightReducedLayout || isLeftReducedLayout? 30 : 140
|
|
anchors.rightMargin: isRightReducedLayout ? 10 : 140
|
|
cameraQmlName: 'AS'
|
|
callModel: mainItem.callModel
|
|
currentDevice: isPreview
|
|
? allDevices.me
|
|
: mainItem.isConference
|
|
? allDevices.activeSpeaker
|
|
: null
|
|
deactivateCamera: !mainItem.cameraEnabled || (isPreview && callModel.pausedByUser)
|
|
? true
|
|
: mainItem.isConference
|
|
? (callModel && (callModel.pausedByUser || callModel.status === CallModel.CallStatusPaused) )
|
|
|| (!(callModel && callModel.cameraEnabled) && mainItem.participantCount == 1)
|
|
|| (currentDevice && !currentDevice.videoEnabled)// && mainItem.participantCount == 2)
|
|
|| !mainItem.isConferenceReady
|
|
: (callModel && (callModel.pausedByUser || callModel.status === CallModel.CallStatusPaused || !callModel.videoEnabled) )
|
|
|| currentDevice && !currentDevice.videoEnabled
|
|
isPreview: !preview.visible && mainItem.participantCount == 1
|
|
onIsPreviewChanged: {cameraView.resetCamera() }
|
|
isCameraFromDevice: isPreview
|
|
isPaused: isPreview && callModel.pausedByUser
|
|
? false
|
|
: mainItem.isConference
|
|
? //callModel && callModel.pausedByUser && mainItem.participantCount != 2 ||
|
|
(currentDevice && currentDevice.isPaused)
|
|
: callModel && !callModel.pausedByUser && (callModel.status === CallModel.CallStatusPaused)
|
|
|
|
quickTransition: true
|
|
showCloseButton: false
|
|
showActiveSpeakerOverlay: false // This is an active speaker. We don't need to show the indicator.
|
|
showCustomButton: false
|
|
avatarStickerBackgroundColor: isPreview ? IncallStyle.container.avatar.stickerPreviewBackgroundColor.color : IncallStyle.container.avatar.stickerBackgroundColor.color
|
|
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
|
}
|
|
Item{// Need an item to not override Sticker internal states. States are needed for changing anchors.
|
|
id: preview
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
anchors.rightMargin: 30
|
|
anchors.bottomMargin: 15
|
|
|
|
height: visible ? miniViews.cellHeight : 0
|
|
width: 16 * height / 9
|
|
|
|
visible: mainItem.isConferenceReady && allDevices.count >= 1
|
|
|| (!mainItem.isConference && mainItem.callModel && mainItem.callModel.cameraEnabled)// use videoEnabled if we want to show the preview sticker
|
|
|
|
Loader{
|
|
anchors.fill: parent
|
|
anchors.margins: 3
|
|
sourceComponent:
|
|
Sticker{
|
|
id: previewSticker
|
|
cameraQmlName: 'AS_Preview'
|
|
deactivateCamera: !mainItem.cameraEnabled || !mainItem.callModel || callModel.pausedByUser || !mainItem.callModel.cameraEnabled
|
|
currentDevice: allDevices.me
|
|
isPreview: true
|
|
callModel: mainItem.callModel
|
|
isCameraFromDevice: true
|
|
showCloseButton: false
|
|
showCustomButton: false
|
|
showAvatarBorder: true
|
|
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerPreviewBackgroundColor.color
|
|
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
|
}
|
|
active: parent.visible
|
|
}
|
|
|
|
MovableMouseArea{
|
|
id: dragger
|
|
anchors.fill: parent
|
|
visible: mainItem.participantCount <= 2
|
|
function resetPosition(){
|
|
preview.anchors.right = mainItem.right
|
|
preview.anchors.bottom = mainItem.bottom
|
|
}
|
|
onVisibleChanged: if(!visible){
|
|
resetPosition()
|
|
}
|
|
drag.target: preview
|
|
onDraggingChanged: if(dragging){
|
|
preview.anchors.right = undefined
|
|
preview.anchors.bottom = undefined
|
|
}
|
|
onRequestResetPosition: resetPosition()
|
|
}
|
|
}
|
|
|
|
Item{
|
|
id: miniViewArea
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
anchors.bottom: preview.top
|
|
anchors.rightMargin: 30
|
|
anchors.topMargin: 15
|
|
anchors.bottomMargin: 0
|
|
//---------------
|
|
width: 16 * miniViews.cellHeight / 9
|
|
visible: mainItem.isConferenceReady || !mainItem.isConference
|
|
property int heightLeft: parent.height - preview.height
|
|
onHeightLeftChanged: {Qt.callLater(miniViewArea.forceRefresh)}
|
|
function forceRefresh(){// Force a content refresh via margins. Qt is buggy when managing sizes in ListView.
|
|
++miniViewArea.anchors.topMargin
|
|
--miniViewArea.anchors.topMargin
|
|
}
|
|
|
|
ScrollableListView{
|
|
id: miniViews
|
|
property int cellHeight: 150
|
|
anchors.fill: parent
|
|
model : mainItem.isConference && mainItem.participantDevices.count > 1 ? mainItem.participantDevices : []
|
|
spacing: 0
|
|
verticalLayoutDirection: ListView.BottomToTop
|
|
fitCacheToContent: false
|
|
property int oldCount : 0// Count changed can be called without a change... (bug?). Use oldCount to avoid it.
|
|
onCountChanged: {if(oldCount != count){ oldCount = count ; Qt.callLater(miniViewArea.forceRefresh)}}
|
|
Component.onCompleted: {Qt.callLater(miniViewArea.forceRefresh)}
|
|
delegate:Item{
|
|
height: visible ? miniViews.cellHeight + 15 : 0
|
|
width: visible ? miniViews.width : 0
|
|
visible: cameraView.currentDevice != modelData
|
|
clip:false
|
|
Sticker{
|
|
id: miniView
|
|
anchors.fill: parent
|
|
anchors.topMargin: 3
|
|
anchors.leftMargin: 3
|
|
anchors.rightMargin: 3
|
|
anchors.bottomMargin: 18
|
|
cameraQmlName: 'S_'+index
|
|
deactivateCamera: (!mainItem.isConferenceReady || !mainItem.isConference)
|
|
&& (index <0 || !mainItem.cameraEnabled || (!modelData.videoEnabled) || (callModel && callModel.pausedByUser) )
|
|
currentDevice: modelData.isPreview ? null : modelData
|
|
callModel: modelData.isPreview ? null : mainItem.callModel
|
|
isCameraFromDevice: mainItem.isConference
|
|
isPaused: currentDevice && currentDevice.isPaused
|
|
showCloseButton: false
|
|
showCustomButton: false
|
|
showAvatarBorder: true
|
|
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor.color
|
|
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|