linphone-desktop/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml
Julien Wadel 867ec4a333 Display the subject of the conference in calls view.
Allow to add running call in conference.
Fix double participants on invitation while adding a new participant.
Fix "alone text" when the user is alone in conference.
Fix conference creation layout when switching of scheduled or not mode.
Fix led and start button behaviour while creating a new conference.
2022-06-13 19:03:12 +02:00

283 lines
9.4 KiB
QML

import QtQuick 2.12
import QtQuick.Layouts 1.3
import QtQml.Models 2.12
import QtGraphicalEffects 1.12
import QtQuick.Controls 2.12
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import LinphoneEnums 1.0
import UtilsCpp 1.0
import App.Styles 1.0
// =============================================================================
Rectangle{
id: mainItem
property CallModel callModel
property ConferenceModel conferenceModel: callModel.conferenceModel
property ParticipantModel me: conferenceModel.localParticipant
property bool isMeAdmin: me && me.adminStatus
property bool isParticipantsMenu: false
signal close()
height: 500
width: 400
color: "white"
radius: VideoConferenceMenuStyle.radius
// List of title texts in order to allow bindings between all components
property var menuTitles: [
//: 'Multimedia parameters' : Menu title to show multimedia devices configuration.
qsTr('conferenceMenuMultimedia'),
//: 'Change layout' : Menu title to change the conference layout.
qsTr('conferenceMenuLayout'),
//: 'Invite participants' : Menu title to invite participants in admin mode.
mainItem.isMeAdmin ? qsTr('conferenceMenuInvite')
//: 'Participants list' : Menu title to show participants in non-admin mode.
: qsTr('conferenceMenuParticipants')
]
function showParticipantsMenu(){
contentsStack.push(participantsMenu, {title:Qt.binding(function() { return mainItem.menuTitles[2]})})
visible = true
}
ButtonGroup{id: modeGroup}
ColumnLayout{
anchors.fill: parent
// HEADER
Borders{
Layout.fillWidth: true
Layout.preferredHeight: Math.max(VideoConferenceMenuStyle.header.height, titleMenu.implicitHeight+20)
bottomColor: VideoConferenceMenuStyle.list.border.color
bottomWidth: VideoConferenceMenuStyle.list.border.width
RowLayout{
anchors.fill: parent
ActionButton{
backgroundRadius: width/2
isCustom: true
colorSet: VideoConferenceMenuStyle.buttons.back
onClicked: contentsStack.pop()
visible: contentsStack.nViews > 1
}
Text{
id: titleMenu
text: contentsStack.currentItem.title
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
horizontalAlignment: Qt.AlignCenter
color: VideoConferenceMenuStyle.header.color
font.pointSize: VideoConferenceMenuStyle.header.pointSize
font.weight: VideoConferenceMenuStyle.header.weight
wrapMode: Text.WordWrap
elide: Text.ElideRight
}
ActionButton{
Layout.rightMargin: 10
backgroundRadius: width/2
isCustom: true
colorSet: VideoConferenceMenuStyle.buttons.close
onClicked: mainItem.close()
}
}
}
// CONTENT
StackView{
id: contentsStack
initialItem: settingsMenuComponent
Layout.fillHeight: true
Layout.fillWidth: true
}
Component{
id: settingsMenuComponent
ColumnLayout{
property string objectName: 'settingsMenu'
//: 'Settings' : Main menu title for settings.
property string title: qsTr('conferenceMenuTitle')
Layout.fillHeight: true
Layout.fillWidth: true
Repeater{
model: [
{titleIndex: 0
,icon: VideoConferenceMenuStyle.settingsIcons.mediaIcon
, nextPage:mediaMenu},
{titleIndex: 1
, icon: (mainItem.callModel.videoEnabled ?
(mainItem.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid ? VideoConferenceMenuStyle.settingsIcons.gridIcon : VideoConferenceMenuStyle.settingsIcons.activeSpeakerIcon)
: VideoConferenceMenuStyle.settingsIcons.audioOnlyIcon)
, nextPage:layoutMenu},
{ titleIndex: 2
, icon: VideoConferenceMenuStyle.settingsIcons.participantsIcon
, nextPage:participantsMenu}
]
delegate:
Borders{
bottomColor: VideoConferenceMenuStyle.list.border.color
bottomWidth: VideoConferenceMenuStyle.list.border.width
Layout.preferredHeight: Math.max(settingIcon.height, settingsDescription.implicitHeight) + 20
Layout.fillWidth: true
RowLayout{
anchors.fill: parent
Icon{
id: settingIcon
Layout.minimumWidth: iconWidth
Layout.leftMargin: 15
Layout.alignment: Qt.AlignVCenter
icon: modelData.icon
overwriteColor: VideoConferenceMenuStyle.list.color
iconWidth: VideoConferenceMenuStyle.settingsIcons.width
iconHeight: VideoConferenceMenuStyle.settingsIcons.height
}
Text{
id: settingsDescription
Layout.fillWidth: true
height: implicitHeight
wrapMode: Text.WordWrap
elide: Text.ElideRight
text: mainItem.menuTitles[modelData.titleIndex]
font.pointSize: VideoConferenceMenuStyle.list.pointSize
color: VideoConferenceMenuStyle.list.color
}
ActionButton{
Layout.minimumWidth: iconWidth
Layout.rightMargin: 10
Layout.alignment: Qt.AlignVCenter
backgroundRadius: width/2
isCustom: true
colorSet: VideoConferenceMenuStyle.buttons.next
}
}
MouseArea{
anchors.fill: parent
onClicked: {
contentsStack.push(modelData.nextPage, {title:Qt.binding(function() { return settingsDescription.text})})
}
}
}
}
Item{// Spacer
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
Component{
id: mediaMenu
ColumnLayout{
property string title
Layout.fillHeight: true
Layout.fillWidth: true
MultimediaParametersDialog{
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumHeight: fitHeight
call: conference.callModel
flat: true
showMargins: true
expandHeight: false
fixedSize: false
showTitleBar: false
onExitStatus: contentsStack.pop()
}
Item{// Spacer
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
Component{
id: layoutMenu
ColumnLayout{
property string title
Layout.fillHeight: true
Layout.fillWidth: true
Repeater{
//: 'Mosaic mode' : Grid layout for video conference.
model: [{text: qsTr('conferenceMenuGridLayout'), icon: VideoConferenceMenuStyle.modeIcons.gridIcon, value:LinphoneEnums.ConferenceLayoutGrid}
//: 'Active speaker mode' : Active speaker layout for video conference.
, {text: qsTr('conferenceMenuActiveSpeakerLayout'), icon: VideoConferenceMenuStyle.modeIcons.activeSpeakerIcon, value:LinphoneEnums.ConferenceLayoutActiveSpeaker}
//: 'Audio only mode' : Audio only layout for video conference.
, {text: qsTr('conferenceMenuAudioLayout'), icon: VideoConferenceMenuStyle.modeIcons.audioOnlyIcon, value:2}
]
delegate:
Borders{
bottomColor: VideoConferenceMenuStyle.list.border.color
bottomWidth: VideoConferenceMenuStyle.list.border.width
Layout.preferredHeight: Math.max(layoutIcon.height, radio.contentItem.implicitHeight) + 20
Layout.fillWidth: true
RowLayout{
anchors.fill: parent
RadioButton{
id: radio
Layout.fillWidth: true
Layout.leftMargin: 15
Layout.preferredHeight: contentItem.implicitHeight
Layout.alignment: Qt.AlignVCenter
ButtonGroup.group: modeGroup
checked: mainItem.callModel ? (mainItem.callModel.videoEnabled && modelData.value == mainItem.callModel.conferenceVideoLayout)
|| (!mainItem.callModel.videoEnabled && modelData.value == 2)
: false
text: modelData.text
onClicked: if(modelData.value == 2) mainItem.callModel.videoEnabled = false
else mainItem.callModel.conferenceVideoLayout = modelData.value
}
Icon{
id: layoutIcon
Layout.minimumWidth: iconWidth
Layout.rightMargin: 10
Layout.alignment: Qt.AlignVCenter
icon: modelData.icon
iconWidth: VideoConferenceMenuStyle.modeIcons.width
iconHeight: VideoConferenceMenuStyle.modeIcons.height
}
}
}
}
Item{// Spacer
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
Component{
id: participantsMenu
ColumnLayout{
property string title
Layout.fillHeight: true
Layout.fillWidth: true
ParticipantsListView{
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: 10
Layout.rightMargin: 10
conferenceModel: mainItem.conferenceModel
isAdmin: mainItem.isMeAdmin
Text{
//: 'Your are currently alone in this conference' : Message to warn the user when there is no other participant.
text: qsTr('conferenceMenuParticipantsAlone')
visible: parent.count <= 1
}
}
Item{// Spacer
Layout.fillWidth: true
Layout.fillHeight: true
}
Component.onCompleted: mainItem.isParticipantsMenu = true
Component.onDestruction: mainItem.isParticipantsMenu = false
}
}
}
}