From fe4c1982bb18cb4ad4cfd34cca4bd553ed30c65c Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Wed, 6 Jul 2022 19:58:04 +0200 Subject: [PATCH] Rework sticker view (camera/avatar). Adapt video conference view to be used for one-one. Adapt waiting room to be used for outgoing and ending calls. Fix display of the icon in ActionButton to respect custom sizes. Fix camera refreshing. Hide some item memu on One-one. Update SDK. --- linphone-app/resources.qrc | 8 + .../other/colors/ColorListModel.hpp | 1 + .../ParticipantDeviceProxyModel.cpp | 1 + .../ui/modules/Common/Form/ActionButton.qml | 4 +- .../ui/modules/Linphone/Camera/CameraItem.qml | 5 +- .../ui/modules/Linphone/Camera/CameraView.qml | 7 +- .../Linphone/Menus/VideoConferenceMenu.qml | 12 +- .../Linphone/Sticker/AvatarSticker.qml | 56 ++++ .../Linphone/Sticker/CameraSticker.qml | 92 ++++++ .../Linphone/Sticker/DecorationSticker.qml | 133 +++++++++ .../ui/modules/Linphone/Sticker/Sticker.qml | 97 +++++++ .../Styles/Sticker/AvatarStickerStyle.qml | 16 ++ .../Styles/Sticker/CameraStickerStyle.qml | 15 + .../Styles/Sticker/DecorationStickerStyle.qml | 60 ++++ .../Linphone/Styles/Sticker/StickerStyle.qml | 27 ++ .../ui/modules/Linphone/Styles/qmldir | 5 + linphone-app/ui/modules/Linphone/qmldir | 5 + linphone-app/ui/scripts/Utils/utils.js | 6 +- .../ui/views/App/Calls/CallsWindow.js | 2 +- .../ui/views/App/Calls/CallsWindow.qml | 3 +- linphone-app/ui/views/App/Calls/Incall.js | 1 - linphone-app/ui/views/App/Calls/Incall.qml | 2 +- .../ui/views/App/Calls/VideoConference.qml | 110 ++++--- .../Calls/VideoConferenceActiveSpeaker.qml | 54 +++- .../App/Calls/VideoConferenceFullscreen.qml | 52 +++- .../views/App/Calls/VideoConferenceGrid.qml | 13 +- .../ui/views/App/Calls/WaitingRoom.qml | 270 +++++++++++------- .../App/Styles/Calls/VideoConferenceStyle.qml | 32 ++- .../App/Styles/Calls/WaitingRoomStyle.qml | 39 ++- linphone-sdk | 2 +- 30 files changed, 924 insertions(+), 206 deletions(-) create mode 100644 linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml create mode 100644 linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml create mode 100644 linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml create mode 100644 linphone-app/ui/modules/Linphone/Sticker/Sticker.qml create mode 100644 linphone-app/ui/modules/Linphone/Styles/Sticker/AvatarStickerStyle.qml create mode 100644 linphone-app/ui/modules/Linphone/Styles/Sticker/CameraStickerStyle.qml create mode 100644 linphone-app/ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml create mode 100644 linphone-app/ui/modules/Linphone/Styles/Sticker/StickerStyle.qml diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc index 2a06d1bc4..37ecfb231 100644 --- a/linphone-app/resources.qrc +++ b/linphone-app/resources.qrc @@ -362,6 +362,10 @@ ui/modules/Linphone/Presence/PresenceLevel.qml ui/modules/Linphone/qmldir ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml + ui/modules/Linphone/Sticker/AvatarSticker.qml + ui/modules/Linphone/Sticker/CameraSticker.qml + ui/modules/Linphone/Sticker/DecorationSticker.qml + ui/modules/Linphone/Sticker/Sticker.qml ui/modules/Linphone/Styles/Account/AccountStatusStyle.qml ui/modules/Linphone/Styles/Blocks/CardBlockStyle.qml ui/modules/Linphone/Styles/Blocks/RequestBlockStyle.qml @@ -395,6 +399,10 @@ ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml ui/modules/Linphone/Styles/qmldir + ui/modules/Linphone/Styles/Sticker/AvatarStickerStyle.qml + ui/modules/Linphone/Styles/Sticker/CameraStickerStyle.qml + ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml + ui/modules/Linphone/Styles/Sticker/StickerStyle.qml ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml ui/modules/Linphone/Styles/View/ParticipantsListViewStyle.qml diff --git a/linphone-app/src/components/other/colors/ColorListModel.hpp b/linphone-app/src/components/other/colors/ColorListModel.hpp index 8886e751b..662726ca7 100644 --- a/linphone-app/src/components/other/colors/ColorListModel.hpp +++ b/linphone-app/src/components/other/colors/ColorListModel.hpp @@ -86,6 +86,7 @@ class ColorListModel : public ProxyListModel { ADD_COLOR("r", "#909fab", "Background button normal.") ADD_COLOR("s", "#96be64", "Security") + ADD_COLOR("unsecure", "#FF0000", "Unsecure") ADD_COLOR("t", "#C2C2C2", "Title Header") diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp index 62c7c5220..2487afaca 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp @@ -102,6 +102,7 @@ void ParticipantDeviceProxyModel::setShowMe(const bool& show){ } void ParticipantDeviceProxyModel::onCountChanged(){ + qDebug() << "Count changed : " << getCount(); } void ParticipantDeviceProxyModel::onParticipantSpeaking(ParticipantDeviceModel * speakingDevice){ diff --git a/linphone-app/ui/modules/Common/Form/ActionButton.qml b/linphone-app/ui/modules/Common/Form/ActionButton.qml index ca8914fcc..4b2b20ae9 100644 --- a/linphone-app/ui/modules/Common/Form/ActionButton.qml +++ b/linphone-app/ui/modules/Common/Form/ActionButton.qml @@ -286,7 +286,7 @@ Item { } OpacityMask{ - anchors.fill: foregroundColor + anchors.fill: icon source: foregroundColor maskSource: icon @@ -301,7 +301,7 @@ Item { OpacityMask{ id: mask - anchors.fill: foregroundHiddenPartColor + anchors.fill: icon source: foregroundHiddenPartColor maskSource: icon diff --git a/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml b/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml index adc186ecd..310b38f17 100644 --- a/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml +++ b/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml @@ -22,8 +22,7 @@ Item { property bool isFullscreen: false property bool hideCamera: false property bool isPaused: false - property bool isVideoEnabled: enabled - && (!callModel || callModel.videoEnabled) + property bool isVideoEnabled: (!callModel || callModel.videoEnabled) && (!container.currentDevice || callModel && (container.currentDevice && (container.currentDevice.videoEnabled || (container.currentDevice.isMe && callModel.cameraEnabled)))) @@ -46,7 +45,7 @@ Item { anchors.fill: parent - active: container.enabled && !resetActive && container.isVideoEnabled + active: !resetActive && container.isVideoEnabled sourceComponent: container.isVideoEnabled && !container.isPaused? camera : null Timer{ diff --git a/linphone-app/ui/modules/Linphone/Camera/CameraView.qml b/linphone-app/ui/modules/Linphone/Camera/CameraView.qml index 5ea7ceccc..42cd2e201 100644 --- a/linphone-app/ui/modules/Linphone/Camera/CameraView.qml +++ b/linphone-app/ui/modules/Linphone/Camera/CameraView.qml @@ -23,6 +23,8 @@ Item{ property bool showCloseButton: false property bool showActiveSpeakerOverlay: true property color color : camera.isReady ? CameraViewStyle.cameraBackgroundColor : CameraViewStyle.outBackgroundColor + property real avatarRatio : 2/3 + signal closeRequested() signal videoDefinitionChanged() @@ -49,7 +51,8 @@ Item{ IncallAvatar { participantDeviceModel: mainItem.currentDevice - height: Utils.computeAvatarSize(backgroundArea, CallStyle.container.avatar.maxSize) + call: participantDeviceModel ? undefined : camera.callModel + height: Utils.computeAvatarSize(backgroundArea, CallStyle.container.avatar.maxSize, avatarRatio) width: height backgroundColor: CameraViewStyle.inAvatarBackgroundColor } @@ -57,7 +60,7 @@ Item{ Loader { anchors.centerIn: parent - active: mainItem.currentDevice && !camera.isReady + active: (mainItem.callModel || mainItem.currentDevice) && !camera.isReady sourceComponent: avatar } } diff --git a/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml b/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml index db1e9f77c..1e9a2ab63 100644 --- a/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml +++ b/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml @@ -106,17 +106,20 @@ Rectangle{ model: [ {titleIndex: 0 ,icon: VideoConferenceMenuStyle.settingsIcons.mediaIcon - , nextPage:mediaMenu}, - + , nextPage:mediaMenu + , visible: true}, + {titleIndex: 1 , icon: (mainItem.callModel && mainItem.callModel.videoEnabled ? (mainItem.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid ? VideoConferenceMenuStyle.settingsIcons.gridIcon : VideoConferenceMenuStyle.settingsIcons.activeSpeakerIcon) : VideoConferenceMenuStyle.settingsIcons.audioOnlyIcon) - , nextPage:layoutMenu}, + , nextPage:layoutMenu + , visible: mainItem.callModel && mainItem.callModel.isConference}, { titleIndex: 2 , icon: VideoConferenceMenuStyle.settingsIcons.participantsIcon - , nextPage:participantsMenu} + , nextPage:participantsMenu + , visible: mainItem.callModel && mainItem.callModel.isConference} ] delegate: Borders{ @@ -124,6 +127,7 @@ Rectangle{ bottomWidth: VideoConferenceMenuStyle.list.border.width Layout.preferredHeight: Math.max(settingIcon.height, settingsDescription.implicitHeight) + 20 Layout.fillWidth: true + visible: modelData.visible RowLayout{ anchors.fill: parent Icon{ diff --git a/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml new file mode 100644 index 000000000..fcd36f504 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml @@ -0,0 +1,56 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.12 + +import App.Styles 1.0 +import Common 1.0 +import Common.Styles 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 + +import 'qrc:/ui/scripts/Utils/utils.js' as Utils + +// ============================================================================= + +DecorationSticker { + id:mainItem + + property ParticipantDeviceModel currentDevice + property CallModel callModel + property bool isPaused + property bool isPreview + property bool showCloseButton: false + property bool showActiveSpeakerOverlay: true + property real avatarRatio : 2/3 + property color color : AvatarStickerStyle.outBackgroundColor + + property alias image: avatar.image + property alias username: avatar.username + property alias avatarBackgroundColor: avatar.backgroundColor + + property alias showCustomButton: mainItem._showCustomButton + property alias customButtonToggled: mainItem._customButtonToggled + property alias customButtonColorSet: mainItem._customButtonColorSet + + _currentDevice: currentDevice + _callModel: callModel + _isPaused: isPaused + _isPreview: isPreview + _showCloseButton: showCloseButton + _showActiveSpeakerOverlay: showActiveSpeakerOverlay + + _content: Rectangle{ + anchors.fill: parent + color: mainItem.color + radius: AvatarStickerStyle.radius + IncallAvatar { + id: avatar + anchors.centerIn: parent + participantDeviceModel: mainItem.currentDevice + call: participantDeviceModel ? undefined : mainItem.callModel + height: Utils.computeAvatarSize(mainItem, mainItem.width, avatarRatio) + width: height + backgroundColor: AvatarStickerStyle.inBackgroundColor + } + } +} diff --git a/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml new file mode 100644 index 000000000..8a5417a9c --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml @@ -0,0 +1,92 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.12 + +import App.Styles 1.0 +import Common 1.0 +import Common.Styles 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 + +import 'qrc:/ui/scripts/Utils/utils.js' as Utils + +// ============================================================================= +DecorationSticker{ + id: mainItem + property alias currentDevice: camera.currentDevice + property alias callModel: camera.callModel + property bool cameraEnabled: true + property alias hideCamera: camera.hideCamera + property alias isPaused: camera.isPaused + property alias isPreview: camera.isPreview + property alias isFullscreen: camera.isFullscreen + property alias isCameraFromDevice: camera.isCameraFromDevice + property alias isReady: camera.isReady + property bool showCloseButton: false + property bool showActiveSpeakerOverlay: true + property color color : CameraStickerStyle.cameraBackgroundColor + + property alias showCustomButton: mainItem._showCustomButton + property alias customButtonToggled: mainItem._customButtonToggled + property alias customButtonColorSet: mainItem._customButtonColorSet + + signal videoDefinitionChanged() + onBackgroundClicked: camera.resetActive() + onCameraEnabledChanged: if( cameraEnabled) camera.resetActive() + + _currentDevice: currentDevice + _callModel: callModel + _isPaused: isPaused + _isPreview: isPreview + _showCloseButton: showCloseButton + _showActiveSpeakerOverlay: showActiveSpeakerOverlay + _content: Rectangle{ + anchors.fill: parent + color: mainItem.color + radius: CameraStickerStyle.radius + + Rectangle{ + id: showArea + + anchors.fill: parent + radius: CameraStickerStyle.radius + visible: false + color: 'red' + } + CameraItem{ + id: camera + currentDevice: mainItem.currentDevice + callModel: mainItem.callModel + + anchors.centerIn: parent + anchors.fill: parent + visible: false + onVideoDefinitionChanged: mainItem.videoDefinitionChanged() + } + OpacityMask{ + id: renderedCamera + anchors.fill: parent + source: camera + maskSource: showArea + invert:false + visible: true + + /* In case we need transformations. + property Matrix4x4 mirroredRotationMatrix : Matrix4x4 {// 180 rotation + mirror + matrix: Qt.matrix4x4(-Math.cos(Math.PI), -Math.sin(Math.PI), 0, 0, + Math.sin(Math.PI), Math.cos(Math.PI), 0, camera.height, + 0, 0, 1, 0, + 0, 0, 0, 1) + } + property Matrix4x4 rotationMatrix : Matrix4x4 {// 180 rotation only + matrix: Qt.matrix4x4(Math.cos(Math.PI), -Math.sin(Math.PI), 0, camera.width, + Math.sin(Math.PI), Math.cos(Math.PI), 0, camera.height, + 0, 0, 1, 0, + 0, 0, 0, 1) + } + + //transform: ( camera.isPreview ? mirroredRotationMatrix : rotationMatrix) + */ + } + } +} diff --git a/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml new file mode 100644 index 000000000..1fe369736 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml @@ -0,0 +1,133 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.12 + +import App.Styles 1.0 +import Common 1.0 +import Common.Styles 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 + +import 'qrc:/ui/scripts/Utils/utils.js' as Utils + +// Decoration is used to be inherited +// Variables in '_' allow to use alias in inheritance. These variables should not be change inside DecorationSticker + +// ============================================================================= +Item{ + id: mainItem + default property alias _content: content.data + + property ParticipantDeviceModel _currentDevice + property CallModel _callModel + property bool _isPaused + property bool _isPreview + property bool _showCloseButton: false + property bool _showActiveSpeakerOverlay: true + + property bool _showCustomButton: false + property bool _customButtonToggled: false + property alias _customButtonColorSet : customButton.colorSet + + signal closeRequested() + signal backgroundClicked() + signal customButtonClicked() + + MouseArea{ + anchors.fill: parent + onClicked: mainItem.backgroundClicked() + } + RectangularGlow { + id: effect + anchors.fill: content + glowRadius: 4 + spread: 0.9 + color: DecorationStickerStyle.border.color + cornerRadius: (content.radius? content.radius : 0) + glowRadius + visible: mainItem._showActiveSpeakerOverlay && mainItem._currentDevice && mainItem._currentDevice.isSpeaking + } + Item{ + id: content + anchors.fill: parent + } + + Rectangle{ + id: hideView + anchors.fill: parent + color: DecorationStickerStyle.pauseView.backgroundColor + radius: DecorationStickerStyle.radius + visible: mainItem._isPaused + Rectangle{ + anchors.centerIn: parent + height: DecorationStickerStyle.pauseView.button.iconSize + width: height + radius: width/2 + color: DecorationStickerStyle.pauseView.button.backgroundNormalColor + Icon{ + anchors.centerIn: parent + icon: DecorationStickerStyle.pauseView.button.icon + overwriteColor: DecorationStickerStyle.pauseView.button.foregroundNormalColor + iconSize: DecorationStickerStyle.pauseView.button.iconSize + } + } + } + Text{ + id: username + visible: mainItem._currentDevice + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 10 + elide: Text.ElideRight + maximumLineCount: 1 + text: mainItem._currentDevice && mainItem._currentDevice.displayName + (mainItem._isPaused ? ' (en pause)' : '') + font.pointSize: DecorationStickerStyle.contactDescription.pointSize + font.weight: DecorationStickerStyle.contactDescription.weight + color: DecorationStickerStyle.contactDescription.color + } + Glow { + anchors.fill: username + //spread: 1 + radius: 12 + samples: 25 + color: "#80000000" + source: username + } + ActionButton{ + visible: mainItem._showCloseButton && mainItem._isPreview && mainItem._callModel && mainItem._callModel.videoEnabled + anchors.right: parent.right + anchors.top: parent.top + anchors.rightMargin: 5 + anchors.topMargin: 5 + isCustom: true + colorSet: DecorationStickerStyle.closePreview + onClicked: mainItem.closeRequested() + } + ColumnLayout{ + anchors.top: parent.top + anchors.right: parent.right + anchors.topMargin: 10 + anchors.rightMargin: 10 + ActionButton{// Custom action + id: customButton + visible: mainItem._showCustomButton + isCustom: true + backgroundRadius: width/2 + toggled: mainItem._customButtonToggled + onClicked: mainItem.customButtonClicked() + } + Rectangle{// Mute + visible: mainItem.currentDevice && mainItem.currentDevice.isMuted + height: DecorationStickerStyle.isMuted.button.iconSize + width: height + radius: width/2 + color: DecorationStickerStyle.isMuted.button.backgroundNormalColor + Icon{ + anchors.centerIn: parent + icon: DecorationStickerStyle.isMuted.button.icon + overwriteColor: DecorationStickerStyle.isMuted.button.foregroundNormalColor + iconSize: DecorationStickerStyle.isMuted.button.iconSize + } + } + } +} diff --git a/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml b/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml new file mode 100644 index 000000000..9c5e55067 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml @@ -0,0 +1,97 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.12 + +import App.Styles 1.0 +import Common 1.0 +import Common.Styles 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 + +import 'qrc:/ui/scripts/Utils/utils.js' as Utils + + +// A sticker display the avatar or its camera view + + +// ============================================================================= +Flipable{ + id: mainItem + + property bool flipped : cameraEnabled && camera.isReady + + + property bool showCustomButton: false + property bool customButtonToggled: false + property QtObject customButtonColorSet: StickerStyle.custom + + property alias currentDevice: camera.currentDevice + property alias callModel: camera.callModel + property alias isPaused: camera.isPaused + property alias isPreview: camera.isPreview + property alias showCloseButton: camera.showCloseButton + property alias showActiveSpeakerOverlay: camera.showActiveSpeakerOverlay + property alias isCameraFromDevice: camera.isCameraFromDevice + property alias cameraEnabled: camera.cameraEnabled + + property alias image: avatar.image + property alias username: avatar.username + property alias avatarBackgroundColor: avatar.avatarBackgroundColor + property alias avatarOutBackgroundColor: avatar.color + property alias avatarRatio: avatar.avatarRatio + + signal videoDefinitionChanged() + signal customButtonClicked() + + transform: Rotation { + id: rotation + origin.x: mainItem.width/2 + origin.y: mainItem.height/2 + axis.x: 0; axis.y: 1; axis.z: 0 // set axis.y to 1 to rotate around y-axis + angle: 0 // the default angle + } + + states: State { + name: "back" + PropertyChanges { target: rotation; angle: 180 } + when: mainItem.flipped + } + property bool quickTransition : flipped + transitions: Transition { + SequentialAnimation { + NumberAnimation { target: rotation; duration: quickTransition || rotation.angle != 0 ? 0 : 300 } + NumberAnimation { target: rotation; property: "angle"; duration: quickTransition ? 200 : 800 } + } + } + + front: AvatarSticker{ + id: avatar + currentDevice: mainItem.currentDevice + callModel: mainItem.callModel + isPaused: mainItem.isPaused + isPreview: mainItem.isPreview + showCloseButton: mainItem.showCloseButton + showActiveSpeakerOverlay: mainItem.showActiveSpeakerOverlay + + showCustomButton: mainItem.showCustomButton + customButtonToggled: mainItem.customButtonToggled + customButtonColorSet: mainItem.customButtonColorSet + + height: mainItem.height + width: mainItem.width + + onCustomButtonClicked: mainItem.customButtonClicked() + } + back: CameraSticker{ + id: camera + height: mainItem.height + width: mainItem.width + + showCustomButton: mainItem.showCustomButton + customButtonToggled: mainItem.customButtonToggled + customButtonColorSet: mainItem.customButtonColorSet + + onVideoDefinitionChanged: mainItem.videoDefinitionChanged() + onCustomButtonClicked: mainItem.customButtonClicked() + } +} diff --git a/linphone-app/ui/modules/Linphone/Styles/Sticker/AvatarStickerStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Sticker/AvatarStickerStyle.qml new file mode 100644 index 000000000..6fea676b4 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Styles/Sticker/AvatarStickerStyle.qml @@ -0,0 +1,16 @@ +pragma Singleton +import QtQml 2.2 +import QtQuick 2.7 + +import Units 1.0 +import ColorsList 1.0 + + +// ============================================================================= + +QtObject { + property string sectionName: 'AvatarSticker' + property color outBackgroundColor: ColorsList.add(sectionName+'_out_bg', 'conference_out_avatar_bg').color + property color inBackgroundColor: ColorsList.add(sectionName+'_in_bg', 'conference_bg').color + property int radius : 10 +} diff --git a/linphone-app/ui/modules/Linphone/Styles/Sticker/CameraStickerStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Sticker/CameraStickerStyle.qml new file mode 100644 index 000000000..1e3edd194 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Styles/Sticker/CameraStickerStyle.qml @@ -0,0 +1,15 @@ +pragma Singleton +import QtQml 2.2 +import QtQuick 2.7 + +import Units 1.0 +import ColorsList 1.0 + + +// ============================================================================= + +QtObject { + property string sectionName: 'CameraSticker' + property color cameraBackgroundColor: ColorsList.add(sectionName+'_camera_bg', 'fullscreen_conference_bg').color + property int radius : 10 +} diff --git a/linphone-app/ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml new file mode 100644 index 000000000..f65a05d52 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml @@ -0,0 +1,60 @@ +pragma Singleton +import QtQml 2.2 +import QtQuick 2.7 + +import Units 1.0 +import ColorsList 1.0 + + +// ============================================================================= + +QtObject { + property string sectionName: 'DecorationSticker' + + property int radius : 10 + + property QtObject border: QtObject { + property color color: ColorsList.add(sectionName+'_border', 'b').color + property int width: 2 + } + + property QtObject pauseView: QtObject{ + property color backgroundColor : ColorsList.add(sectionName+'_pauseView_bg_n', 'l').color + property QtObject button: QtObject { + property int iconSize: 80 + property string icon : 'pause_custom' + property string name : 'pause' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg', icon, 's_n_b_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg', icon, 's_n_b_fg').color + } + } + + property QtObject contactDescription: QtObject { + property color color: ColorsList.add(sectionName+'_username', 'q').color + property int pointSize: Units.dp * 12 + property int weight: Font.Bold + } + + property QtObject closePreview: QtObject { + property int iconSize: 40 + property string icon : 'close_custom' + property string name : 'close_preview' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_inv_bg').color + property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_inv_bg').color + property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_inv_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_inv_fg').color + property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_inv_fg').color + property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_inv_fg').color + } + + property QtObject isMuted: QtObject{ + property color backgroundColor : ColorsList.add(sectionName+'_isMuted_bg', 'j').color + property QtObject button: QtObject { + property int iconSize: 30 + property string icon : 'micro_off_custom' + property string name : 'isMuted' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg', icon, 's_d_b_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg', icon, 's_d_b_fg').color + } + } +} diff --git a/linphone-app/ui/modules/Linphone/Styles/Sticker/StickerStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Sticker/StickerStyle.qml new file mode 100644 index 000000000..2d60a76b7 --- /dev/null +++ b/linphone-app/ui/modules/Linphone/Styles/Sticker/StickerStyle.qml @@ -0,0 +1,27 @@ +pragma Singleton +import QtQml 2.2 +import QtQuick 2.7 + +import Units 1.0 +import ColorsList 1.0 + + +// ============================================================================= + +QtObject { + property string sectionName: 'Sticker' + + property QtObject custom: QtObject { + property int iconSize: 40 + property string icon : 'menu_vdots_custom' + property string name : 'custom' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 's_n_b_bg').color + property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 's_h_b_bg').color + property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 's_p_b_bg').color + property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_c', icon, 's_p_b_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 's_n_b_fg').color + property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 's_n_b_fg').color + property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 's_p_b_fg').color + property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 's_p_b_fg').color + } +} diff --git a/linphone-app/ui/modules/Linphone/Styles/qmldir b/linphone-app/ui/modules/Linphone/Styles/qmldir index 57d355143..acfb665be 100644 --- a/linphone-app/ui/modules/Linphone/Styles/qmldir +++ b/linphone-app/ui/modules/Linphone/Styles/qmldir @@ -48,6 +48,11 @@ singleton NotificationReceivedFileMessageStyle 1.0 Notifications/NotificationRec singleton NotificationReceivedMessageStyle 1.0 Notifications/NotificationReceivedMessageStyle.qml singleton NotificationStyle 1.0 Notifications/NotificationStyle.qml +singleton AvatarStickerStyle 1.0 Sticker/AvatarStickerStyle.qml +singleton CameraStickerStyle 1.0 Sticker/CameraStickerStyle.qml +singleton DecorationStickerStyle 1.0 Sticker/DecorationStickerStyle.qml +singleton StickerStyle 1.0 Sticker/StickerStyle.qml + singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml diff --git a/linphone-app/ui/modules/Linphone/qmldir b/linphone-app/ui/modules/Linphone/qmldir index 5be907067..eb53e3442 100644 --- a/linphone-app/ui/modules/Linphone/qmldir +++ b/linphone-app/ui/modules/Linphone/qmldir @@ -50,6 +50,11 @@ PresenceLevel 1.0 Presence/PresenceLevel.qml SmartSearchBar 1.0 SmartSearchBar/SmartSearchBar.qml +AvatarSticker 1.0 Sticker/AvatarSticker.qml +CameraSticker 1.0 Sticker/CameraSticker.qml +DecorationSticker 1.0 Sticker/DecorationSticker.qml +Sticker 1.0 Sticker/Sticker.qml + TelKeypad 1.0 TelKeypad/TelKeypad.qml Timeline 1.0 Timeline/Timeline.qml diff --git a/linphone-app/ui/scripts/Utils/utils.js b/linphone-app/ui/scripts/Utils/utils.js index 2e2c2341c..f971f7e3b 100644 --- a/linphone-app/ui/scripts/Utils/utils.js +++ b/linphone-app/ui/scripts/Utils/utils.js @@ -742,9 +742,9 @@ function write (fileName, text) { request.send(text) } -function computeAvatarSize (container, maxSize) { - var height = 2*container.height/3 - var width = 2*container.width/3 +function computeAvatarSize (container, maxSize, ratio) { + var height = container.height * ratio + var width = container.width * ratio var size = height < maxSize && height > 0 ? height : maxSize return size < width ? size : width } diff --git a/linphone-app/ui/views/App/Calls/CallsWindow.js b/linphone-app/ui/views/App/Calls/CallsWindow.js index ab9572662..b003f0921 100644 --- a/linphone-app/ui/views/App/Calls/CallsWindow.js +++ b/linphone-app/ui/views/App/Calls/CallsWindow.js @@ -89,7 +89,7 @@ function getContent (call, conferenceInfoModel) { if(call.isConference) return videoConference - return incall + return videoConference //incall } // ----------------------------------------------------------------------------- diff --git a/linphone-app/ui/views/App/Calls/CallsWindow.qml b/linphone-app/ui/views/App/Calls/CallsWindow.qml index 9bb975ab8..74b7af706 100644 --- a/linphone-app/ui/views/App/Calls/CallsWindow.qml +++ b/linphone-app/ui/views/App/Calls/CallsWindow.qml @@ -184,8 +184,7 @@ Window { minimumRightLimit: CallsWindowStyle.chat.minimumWidth resizeAInPriority: true - hideSplitter: !middlePane.sourceComponent || middlePane.sourceComponent == videoConference || !rightPane.sourceComponent - + hideSplitter: !window.chatIsOpened && (!middlePane.sourceComponent || middlePane.sourceComponent == videoConference || !rightPane.sourceComponent) // ----------------------------------------------------------------------- Component { diff --git a/linphone-app/ui/views/App/Calls/Incall.js b/linphone-app/ui/views/App/Calls/Incall.js index bc9f1cebf..f33058d54 100644 --- a/linphone-app/ui/views/App/Calls/Incall.js +++ b/linphone-app/ui/views/App/Calls/Incall.js @@ -86,7 +86,6 @@ function handleVideoRequested (call) { } } call.statusChanged.connect(endedHandler) -console.log("D") // Ask video to user. window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), { descriptionText: qsTr('acceptVideoDescription'), diff --git a/linphone-app/ui/views/App/Calls/Incall.qml b/linphone-app/ui/views/App/Calls/Incall.qml index 83e9971a9..fe8e2b011 100644 --- a/linphone-app/ui/views/App/Calls/Incall.qml +++ b/linphone-app/ui/views/App/Calls/Incall.qml @@ -242,7 +242,7 @@ Rectangle { IncallAvatar { call: incall.call - height: Utils.computeAvatarSize(container, CallStyle.container.avatar.maxSize) + height: Utils.computeAvatarSize(container, CallStyle.container.avatar.maxSize, 2/3) width: height } } diff --git a/linphone-app/ui/views/App/Calls/VideoConference.qml b/linphone-app/ui/views/App/Calls/VideoConference.qml index 0a6e5aa0b..6c3eb16a6 100644 --- a/linphone-app/ui/views/App/Calls/VideoConference.qml +++ b/linphone-app/ui/views/App/Calls/VideoConference.qml @@ -120,21 +120,41 @@ Rectangle { onClicked: telKeypad.visible = !telKeypad.visible } // Title - Text{ - id: title - Timer{ - id: elapsedTimeRefresher - running: true - interval: 1000 - repeat: true - onTriggered: if(conferenceModel) parent.elaspedTime = ' - ' +Utils.formatElapsedTime(conferenceModel.getElapsedSeconds()) - } - property string elaspedTime - horizontalAlignment: Qt.AlignHCenter + ColumnLayout{ Layout.fillWidth: true - text: conferenceModel ? conferenceModel.subject+ elaspedTime : '' - color: VideoConferenceStyle.title.color - font.pointSize: VideoConferenceStyle.title.pointSize + Text{ + id: title + Timer{ + id: elapsedTimeRefresher + running: true + interval: 1000 + repeat: true + onTriggered: if(conferenceModel) parent.elaspedTime = ' - ' +Utils.formatElapsedTime(conferenceModel.getElapsedSeconds()) + else parent.elaspedTime = Utils.formatElapsedTime(conference.callModel.duration) + } + property string elaspedTime + horizontalAlignment: Qt.AlignHCenter + Layout.fillWidth: true + text: conferenceModel + ? conferenceModel.subject+ elaspedTime + : callModel + ? elaspedTime + : '' + color: VideoConferenceStyle.title.color + font.pointSize: VideoConferenceStyle.title.pointSize + } + Text{ + id: address + Layout.fillWidth: true + horizontalAlignment: Qt.AlignHCenter + visible: !conferenceModel && callModel + text: !conferenceModel && callModel + ? callModel.peerAddress + : '' + color: VideoConferenceStyle.title.color + font.pointSize: VideoConferenceStyle.title.addressPointSize + } + } // Mode buttons ActionButton{ @@ -186,21 +206,15 @@ Rectangle { // Contacts visual. // ------------------------------------------------------------------------- - MouseArea{ + Item{ id: mainGrid anchors.top: featuresRow.bottom anchors.left: parent.left anchors.right: parent.right - anchors.bottom: actionsButtons.top + anchors.bottom: zrtp.top anchors.topMargin: 15 anchors.bottomMargin: 20 - onClicked: { - if(!conference.callModel) - grid.add({color: '#'+ Math.floor(Math.random()*255).toString(16) - +Math.floor(Math.random()*255).toString(16) - +Math.floor(Math.random()*255).toString(16)}) - } Component{ id: gridComponent @@ -220,6 +234,7 @@ Rectangle { isRightReducedLayout: rightMenu.visible isLeftReducedLayout: conference.listCallsOpened cameraEnabled: !conference.isFullScreen + onCameraEnabledChanged: console.log(cameraEnabled) } } RowLayout{ @@ -228,8 +243,10 @@ Rectangle { id: conferenceLayout Layout.fillHeight: true Layout.fillWidth: true - sourceComponent: conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid || !conference.callModel.videoEnabled? gridComponent : activeSpeakerComponent - onSourceComponentChanged: console.log(conference.callModel.conferenceVideoLayout) + sourceComponent: conference.conferenceModel + ? conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid || !conference.callModel.videoEnabled? gridComponent : activeSpeakerComponent + : activeSpeakerComponent + onSourceComponentChanged: console.log("conferenceLayout: "+conference.callModel.conferenceVideoLayout) active: conference.callModel ColumnLayout { anchors.fill: parent @@ -261,25 +278,39 @@ Rectangle { } } } + + ZrtpTokenAuthentication { + id: zrtp + + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: CallStyle.container.margins + anchors.bottom: actionsButtons.top + height: visible ? implicitHeight : 0 + + call: callModel + visible: !call.isSecured && call.encryption !== CallModel.CallEncryptionNone + z: Constants.zPopup + } // ------------------------------------------------------------------------- // Action Buttons. // ------------------------------------------------------------------------- // Security ActionButton{ - visible: false // TODO + visible: callModel && !callModel.isConference anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.bottomMargin: 30 + anchors.verticalCenter: actionsButtons.verticalCenter anchors.leftMargin: 25 height: VideoConferenceStyle.buttons.secure.buttonSize width: height isCustom: true - iconIsCustom: false backgroundRadius: width/2 - colorSet: VideoConferenceStyle.buttons.secure - icon: 'secure_level_1' + colorSet: callModel.isSecured ? VideoConferenceStyle.buttons.secure : VideoConferenceStyle.buttons.unsecure + + onClicked: zrtp.visible = (callModel.encryption === CallModel.CallEncryptionZrtp) + + tooltipText: Logic.makeReadableSecuredString(callModel.securedString) } // Action buttons RowLayout{ @@ -342,8 +373,14 @@ Rectangle { colorSet: callModel && callModel.cameraEnabled ? VideoConferenceStyle.buttons.cameraOn : VideoConferenceStyle.buttons.cameraOff updating: callModel.videoEnabled && callModel.updating enabled: callModel.videoEnabled - onClicked: if(callModel) callModel.cameraEnabled = !callModel.cameraEnabled + onClicked: if(callModel){ + if( callModel.isConference)// Only deactivate camera in conference. + callModel.cameraEnabled = !callModel.cameraEnabled + else// In one-one, we deactivate all videos. + callModel.videoEnabled = !callModel.videoEnabled + } } + } RowLayout{ spacing: 10 @@ -376,9 +413,18 @@ Rectangle { isCustom: true backgroundRadius: width/2 colorSet: VideoConferenceStyle.buttons.chat - visible: false // TODO for next version + visible: (SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled) && callModel && !callModel.isConference + toggled: window.chatIsOpened + onClicked: { + if (window.chatIsOpened) { + window.closeChat() + } else { + window.openChat() + } + } } ActionButton{ + visible: callModel && callModel.isConference isCustom: true backgroundRadius: width/2 colorSet: VideoConferenceStyle.buttons.participants diff --git a/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml b/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml index e90f5a69b..e360a174f 100644 --- a/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml +++ b/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml @@ -20,15 +20,16 @@ import 'qrc:/ui/scripts/Utils/utils.js' as Utils Item { id: mainItem - property alias callModel: allDevices.callModel + property CallModel callModel property bool isRightReducedLayout: false property bool isLeftReducedLayout: false property bool cameraEnabled: true property alias showMe : allDevices.showMe - property int participantCount: allDevices.count + property int participantCount: callModel.isConference ? allDevices.count : 2 property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel { id: allDevices + callModel: mainItem.callModel showMe: true onParticipantSpeaking: { var device = getLastActiveSpeaking() @@ -38,11 +39,10 @@ Item { property bool cameraEnabled: callModel && callModel.cameraEnabled onCameraEnabledChanged: showMe = cameraEnabled // Do it on changed to ignore hard bindings (that can be override) } - - CameraView{ + Sticker{ id: cameraView callModel: mainItem.callModel - enabled: mainItem.cameraEnabled + cameraEnabled: mainItem.cameraEnabled isCameraFromDevice: false isPreview: false anchors.fill: parent @@ -51,8 +51,24 @@ Item { isPaused: (callModel && callModel.pausedByUser) || (currentDevice && currentDevice.isPaused) //callModel.pausedByUser showCloseButton: false showActiveSpeakerOverlay: false // This is an active speaker. We don't need to show the indicator. - color: 'black' + showCustomButton: false } + /* + CameraView{ + id: cameraView + callModel: mainItem.callModel + //enabled: mainItem.cameraEnabled + isCameraFromDevice: false + isPreview: false + anchors.fill: parent + anchors.leftMargin: isRightReducedLayout || isLeftReducedLayout? 30 : 140 + anchors.rightMargin: isRightReducedLayout ? 10 : 140 + isPaused: (callModel && callModel.pausedByUser) || (currentDevice && currentDevice.isPaused) //callModel.pausedByUser + showCloseButton: false + showActiveSpeakerOverlay: false // This is an active speaker. We don't need to show the indicator. + //color: callModel && callModel.isConference ? 'black' : 'transparent' + //color: 'black' + }*/ ScrollableListView{ id: miniViews anchors.right: parent.right @@ -64,23 +80,31 @@ Item { property int cellHeight: 150 width: 16 * cellHeight / 9 - model: mainItem.participantDevices + model: mainItem.callModel.isConference + ? mainItem.participantDevices + : mainItem.callModel.videoEnabled + ? [{modelData:null}] + : [] + onModelChanged: console.log(mainItem.callModel.videoEnabled + "/" +mainItem.callModel.cameraEnabled + " / " +count) spacing: 15 verticalLayoutDirection: ItemView.BottomToTop delegate:Item{ height: miniViews.cellHeight width: miniViews.width - CameraView{ + + Sticker{ id: miniView - anchors.centerIn: parent - height: miniViews.cellHeight - 6 - width: miniViews.width - 6 - enabled: index >=0 && mainItem.cameraEnabled + anchors.fill: parent + + cameraEnabled: index >=0 && mainItem.cameraEnabled currentDevice: modelData - callModel: mainItem.callModel - isCameraFromDevice: true + callModel: mainItem.callModel.isConference ? mainItem.callModel : null + isCameraFromDevice: mainItem.callModel.isConference isPaused: mainItem.callModel.pausedByUser || currentDevice && currentDevice.isPaused - onCloseRequested: mainItem.showMe = false + showCloseButton: false + showCustomButton: false + + //onCloseRequested: mainItem.showMe = false } } } diff --git a/linphone-app/ui/views/App/Calls/VideoConferenceFullscreen.qml b/linphone-app/ui/views/App/Calls/VideoConferenceFullscreen.qml index 00dfd3819..99b71b66a 100644 --- a/linphone-app/ui/views/App/Calls/VideoConferenceFullscreen.qml +++ b/linphone-app/ui/views/App/Calls/VideoConferenceFullscreen.qml @@ -224,7 +224,7 @@ Window { anchors.top: featuresRow.bottom anchors.left: parent.left anchors.right: parent.right - anchors.bottom: actionsButtons.top + anchors.bottom: zrtp.top anchors.topMargin: window.hideButtons ? 0 : 15 anchors.bottomMargin: window.hideButtons ? 0 : 20 @@ -260,7 +260,13 @@ Window { id: conferenceLayout Layout.fillHeight: true Layout.fillWidth: true - sourceComponent: conference.callModel ? (conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid || !conference.callModel.videoEnabled? gridComponent : activeSpeakerComponent) : null + + sourceComponent: conference.callModel + ? conference.conferenceModel + ? conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid || !conference.callModel.videoEnabled? gridComponent : activeSpeakerComponent + : activeSpeakerComponent + : null + onSourceComponentChanged: console.log(conference.callModel.conferenceVideoLayout) active: conference.callModel ColumnLayout { @@ -296,23 +302,36 @@ Window { // ------------------------------------------------------------------------- // Action Buttons. // ------------------------------------------------------------------------- - - // Security + ZrtpTokenAuthentication { + id: zrtp + + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: CallStyle.container.margins + anchors.bottom: actionsButtons.top + height: visible ? implicitHeight : 0 + + call: callModel + visible: !call.isSecured && call.encryption !== CallModel.CallEncryptionNone + z: Constants.zPopup + } + // Security ActionButton{ - visible: false // TODO + visible: callModel && !callModel.isConference anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.bottomMargin: 30 + anchors.verticalCenter: actionsButtons.verticalCenter anchors.leftMargin: 25 height: VideoConferenceStyle.buttons.secure.buttonSize width: height isCustom: true - iconIsCustom: false backgroundRadius: width/2 - colorSet: VideoConferenceStyle.buttons.secure - - icon: 'secure_level_1' + + colorSet: callModel.isSecured ? VideoConferenceStyle.buttons.secure : VideoConferenceStyle.buttons.unsecure + + onClicked: zrtp.visible = (callModel.encryption === CallModel.CallEncryptionZrtp) + + tooltipText: Logic.makeReadableSecuredString(callModel.securedString) } + // Action buttons RowLayout{ id: actionsButtons @@ -410,9 +429,18 @@ Window { isCustom: true backgroundRadius: width/2 colorSet: VideoConferenceStyle.buttons.chat - visible: false // TODO for next version + visible: (SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled) && callModel && !callModel.isConference + toggled: window.chatIsOpened + onClicked: { + if (window.chatIsOpened) { + window.closeChat() + } else { + window.openChat() + } + } } ActionButton{ + visible: callModel && callModel.isConference isCustom: true backgroundRadius: width/2 colorSet: VideoConferenceStyle.buttons.participants diff --git a/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml b/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml index d789f3213..c5e7c14a4 100644 --- a/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml +++ b/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml @@ -44,16 +44,19 @@ Mosaic { height: grid.cellHeight - 10 width: grid.cellWidth - 10 - CameraView{ + Sticker{ id: cameraView - enabled: index >=0 && grid.cameraEnabled anchors.fill: parent - currentDevice: avatarCell.currentDevice + + cameraEnabled: index >=0 && grid.cameraEnabled + currentDevice: gridModel.participantDevices.getAt(index) callModel: participantDevices.callModel isCameraFromDevice: true isPaused: grid.callModel.pausedByUser || avatarCell.currentDevice && avatarCell.currentDevice.isPaused - onCloseRequested: participantDevices.showMe = false - //showCloseButton: participantDevices.count > 1 + showCloseButton: false + showCustomButton: false + + //onCloseRequested: participantDevices.showMe = false } } } diff --git a/linphone-app/ui/views/App/Calls/WaitingRoom.qml b/linphone-app/ui/views/App/Calls/WaitingRoom.qml index 637ee8213..363ef0bc3 100644 --- a/linphone-app/ui/views/App/Calls/WaitingRoom.qml +++ b/linphone-app/ui/views/App/Calls/WaitingRoom.qml @@ -33,37 +33,77 @@ Rectangle { } //onCallModelChanged: callModel ? contentsStack.replace(callingComponent) : contentsStack.replace(cameraComponent) - onCallModelChanged: contentsStack.flipped = !!callModel + //onCallModelChanged: contentsStack.flipped = !!callModel Component.onDestruction: {mainItem.previewLoaderEnabled = false;_sipAddressObserver=null}// Need to set it to null because of not calling destructor if not. ColumnLayout { anchors.fill: parent ColumnLayout{ - Layout.preferredHeight: 60 Layout.alignment: Qt.AlignCenter - Layout.topMargin: 15 - spacing: 5 + Layout.bottomMargin: (mainItem.conferenceInfoModel && mainItem.callModel ? 10 : 40) - (errorArea.visible ? errorArea.height + 10: 0) + spacing: 10 BusyIndicator { Layout.alignment: Qt.AlignCenter Layout.preferredHeight: WaitingRoomStyle.header.busyIndicator.height Layout.preferredWidth: WaitingRoomStyle.header.busyIndicator.width + Layout.topMargin: 30 color: WaitingRoomStyle.header.busyIndicator.color visible: mainItem.callModel && mainItem.callModel.isOutgoing } + Text{ - Layout.preferredHeight: 60 Layout.alignment: Qt.AlignCenter + text: mainItem.callModel + ? mainItem.callModel.status == CallModel.CallStatusEnded + ? "Ending call" + : mainItem.callModel.isOutgoing + ? "Outgoing call" + : "Incoming call" + : '' + color: WaitingRoomStyle.title.color + font.pointSize: WaitingRoomStyle.title.pointSize + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + visible: mainItem.callModel + } + Text { + id: elapsedTime + Layout.alignment: Qt.AlignCenter + color: WaitingRoomStyle.elapsedTime.color + font.pointSize: WaitingRoomStyle.elapsedTime.pointSize + horizontalAlignment: Text.AlignHCenter + width: parent.width + visible: mainItem.callModel + Timer { + interval: 1000 + repeat: true + running: mainItem.callModel + triggeredOnStart: true + property var startDate + onRunningChanged: if( running) { + elapsedTime.text = Utils.formatElapsedTime(0); + startDate = new Date() + } + onTriggered: {elapsedTime.text = Utils.formatElapsedTime((new Date() - startDate)/1000)} + } + } + Text{ + Layout.alignment: Qt.AlignCenter + Layout.topMargin: mainItem.callModel ? 0 : 50 text: mainItem.conferenceInfoModel ? mainItem.conferenceInfoModel.subject : (mainItem._sipAddressObserver ? UtilsCpp.getDisplayName(mainItem._sipAddressObserver.peerAddress) : '') color: WaitingRoomStyle.title.color font.pointSize: WaitingRoomStyle.title.pointSize horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter + visible: mainItem.conferenceInfoModel } } Text { + id: errorArea Layout.fillWidth: true + Layout.bottomMargin: 10 horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter @@ -74,72 +114,39 @@ Rectangle { text: mainItem.callModel && mainItem.callModel.callError ? mainItem.callModel.callError : '' } RowLayout{ - id: loader Layout.fillWidth: true Layout.fillHeight: true - property var previewDefinition: SettingsModel.getCurrentPreviewVideoDefinition() - property real cameraRatio: previewDefinition.height > 0 ? previewDefinition.width/previewDefinition.height : 1.0 - property int minSize: Math.min( loader.height, loader.width) - property int cameraHeight: Math.min(Math.min(cameraRatio * minSize, loader.width) / cameraRatio, minSize) - property int cameraWidth: cameraRatio * cameraHeight Item{ + id: stickerView Layout.fillHeight: true Layout.fillWidth: true - - Flipable{ + Sticker{ id: contentsStack + + property var previewDefinition: SettingsModel.getCurrentPreviewVideoDefinition() + property real cameraRatio: previewDefinition.height > 0 ? previewDefinition.width/previewDefinition.height : 1.0 + property int minSize: Math.min( stickerView.height, stickerView.width) + property int cameraHeight: Math.min(Math.min(cameraRatio * minSize, stickerView.width) / cameraRatio, minSize) + property int cameraWidth: cameraRatio * cameraHeight + anchors.centerIn: parent - height: loader.cameraHeight - width : loader.cameraWidth - property bool flipped: false + height: cameraHeight + width : cameraWidth - transform: Rotation { - id: rotation - origin.x: contentsStack.width/2 - origin.y: contentsStack.height/2 - axis.x: 0; axis.y: 1; axis.z: 0 // set axis.y to 1 to rotate around y-axis - angle: 0 // the default angle - } - states: State { - name: "back" - PropertyChanges { target: rotation; angle: 180 } - when: contentsStack.flipped - } - - transitions: Transition { - NumberAnimation { target: rotation; property: "angle"; duration: 500 } - } - - front: CameraView{ - id: previewLoader - showCloseButton: false - enabled: mainItem.previewLoaderEnabled - height: loader.cameraHeight - width : loader.cameraWidth - onVideoDefinitionChanged: loader.previewDefinition = SettingsModel.getCurrentPreviewVideoDefinition() - ActionButton{ - anchors.top: parent.top - anchors.right: parent.right - anchors.topMargin: 10 - anchors.rightMargin: 10 - isCustom: true - backgroundRadius: width/2 - colorSet: WaitingRoomStyle.buttons.options - toggled: mediaMenu.visible - onClicked: mediaMenu.visible = !mediaMenu.visible - } - } - back: IncallAvatar { - id: avatar - anchors.centerIn: parent - height: Utils.computeAvatarSize(loader, CallStyle.container.avatar.maxSize) - width: height - backgroundColor: WaitingRoomStyle.avatar.backgroundColor - image: mainItem._sipAddressObserver && mainItem._sipAddressObserver.contact && mainItem._sipAddressObserver.contact.vcard.avatar - username: mainItem.conferenceInfoModel ? mainItem.conferenceInfoModel.subject + callModel: mainItem.callModel + image: mainItem._sipAddressObserver && mainItem._sipAddressObserver.contact && mainItem._sipAddressObserver.contact.vcard.avatar + username: mainItem.conferenceInfoModel ? mainItem.conferenceInfoModel.subject : (mainItem._sipAddressObserver ? UtilsCpp.getDisplayName(mainItem._sipAddressObserver.peerAddress) : '') - } + avatarRatio: 1 + avatarBackgroundColor: WaitingRoomStyle.avatar.backgroundColor + + showCustomButton: true + customButtonColorSet : WaitingRoomStyle.buttons.options + customButtonToggled: mediaMenu.visible + + onVideoDefinitionChanged: previewDefinition = SettingsModel.getCurrentPreviewVideoDefinition() + onCustomButtonClicked: mediaMenu.visible = !mediaMenu.visible } } MultimediaParametersDialog{ @@ -157,18 +164,81 @@ Rectangle { visible: false } } + ColumnLayout{ + Layout.fillWidth: true + //Layout.preferredHeight: 120 + 30 + Layout.topMargin: 20 + Layout.bottomMargin: 70 + Layout.alignment: Qt.AlignCenter + visible: !mainItem.conferenceInfoModel + spacing: 10 + Text{ + Layout.alignment: Qt.AlignCenter + text: mainItem._sipAddressObserver ? UtilsCpp.getDisplayName(mainItem._sipAddressObserver.peerAddress) : '' + color: WaitingRoomStyle.callee.color + font.pointSize: WaitingRoomStyle.callee.displayNamePointSize + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + visible: !mainItem.conferenceInfoModel + } + Text{ + Layout.fillWidth: true + text: mainItem.callModel && mainItem.callModel.peerAddress + color: WaitingRoomStyle.callee.color + font.pointSize: WaitingRoomStyle.callee.addressPointSize + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + visible: mainItem.callModel && !mainItem.conferenceInfoModel + } + } // ------------------------------------------------------------------------- // Action Buttons. // ------------------------------------------------------------------------- + RowLayout{ + Layout.preferredHeight: 40 + Layout.alignment: Qt.AlignCenter + Layout.topMargin: 20 + Layout.bottomMargin: 15 + //visible: mainItem.conferenceInfoModel + visible: false + spacing: 30 + TextButtonA { + //: 'Cancel' : Cancel button. + text: qsTr('cancelButton') + capitalization: Font.AllUppercase + + onClicked: { + mainItem.close() + if(mainItem.callModel) + callModel.terminate() + mainItem.cancel() + } + } + TextButtonB { + //: 'Start' : Button label for starting the conference. + text: qsTr('startButton') + capitalization: Font.AllUppercase + visible: !mainItem.callModel + + onClicked: {CallsListModel.launchVideoCall(conferenceInfoModel.uri, '', 0, + { video: modeChoice.selectedMode != 2 + , camera: camera.cameraEnabled + , micro: !micro.microMuted + , audio: !speaker.speakerMuted + , layout: (modeChoice.selectedMode % 2)}) } + } + } Item{ Layout.fillWidth: true - Layout.topMargin: 25 - Layout.bottomMargin: 25 - Layout.leftMargin: 25 - Layout.rightMargin: 25 + Layout.preferredHeight: actionsButtons.height + Layout.bottomMargin: 30 + Layout.topMargin: 20 // Action buttons RowLayout{ - anchors.centerIn: parent + id: actionsButtons + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + height: 40 spacing: 10 ActionSwitch { id: micro @@ -209,55 +279,43 @@ Rectangle { enabled: modeChoice.selectedMode != 2 onClicked: cameraEnabled = !cameraEnabled } - } - RowLayout{ - anchors.centerIn: parent - anchors.horizontalCenterOffset: loader.cameraWidth/2 - modeChoice.width/2 - visible: !mainItem.callModel ActionButton{ - id: modeChoice - property int selectedMode: SettingsModel.videoConferenceLayout isCustom: true backgroundRadius: width/2 - colorSet: selectedMode == LinphoneEnums.ConferenceLayoutGrid ? WaitingRoomStyle.buttons.gridLayout : - selectedMode == LinphoneEnums.ConferenceLayoutActiveSpeaker ? WaitingRoomStyle.buttons.activeSpeakerLayout : WaitingRoomStyle.buttons.audioOnly - onClicked: selectedMode = (selectedMode + 1) % 3 - } - } - Item{ - Layout.fillWidth: true - } - } - RowLayout{ - Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: 15 - TextButtonA { - //: 'Cancel' : Cancel button. - text: qsTr('cancelButton') - capitalization: Font.AllUppercase - - onClicked: { - mainItem.close() - if(mainItem.callModel) - callModel.terminate() - mainItem.cancel() - } - } - TextButtonB { - //: 'Start' : Button label for starting the conference. - text: qsTr('startButton') - capitalization: Font.AllUppercase - visible: !mainItem.callModel - - onClicked: {CallsListModel.launchVideoCall(conferenceInfoModel.uri, '', 0, + colorSet: WaitingRoomStyle.buttons.call + visible: !callModel && conferenceInfoModel + onClicked: {CallsListModel.launchVideoCall(conferenceInfoModel.uri, '', 0, { video: modeChoice.selectedMode != 2 , camera: camera.cameraEnabled , micro: !micro.microMuted , audio: !speaker.speakerMuted , layout: (modeChoice.selectedMode % 2)}) } + } + ActionButton{ + isCustom: true + backgroundRadius: width/2 + colorSet: WaitingRoomStyle.buttons.hangup + visible: callModel + onClicked: { + mainItem.close() + if(mainItem.callModel) + callModel.terminate() + mainItem.cancel() + } + } + } + ActionButton{ + id: modeChoice + property int selectedMode: SettingsModel.videoConferenceLayout + anchors.centerIn: parent + anchors.horizontalCenterOffset: contentsStack.cameraWidth/2 - modeChoice.width/2 + visible: !mainItem.callModel + isCustom: true + backgroundRadius: width/2 + colorSet: selectedMode == LinphoneEnums.ConferenceLayoutGrid ? WaitingRoomStyle.buttons.gridLayout : + selectedMode == LinphoneEnums.ConferenceLayoutActiveSpeaker ? WaitingRoomStyle.buttons.activeSpeakerLayout : WaitingRoomStyle.buttons.audioOnly + onClicked: selectedMode = (selectedMode + 1) % 3 } } - } - } diff --git a/linphone-app/ui/views/App/Styles/Calls/VideoConferenceStyle.qml b/linphone-app/ui/views/App/Styles/Calls/VideoConferenceStyle.qml index a91533596..20250675a 100644 --- a/linphone-app/ui/views/App/Styles/Calls/VideoConferenceStyle.qml +++ b/linphone-app/ui/views/App/Styles/Calls/VideoConferenceStyle.qml @@ -16,6 +16,7 @@ QtObject { property QtObject title: QtObject { property color color: ColorsList.add(sectionName+'_title', 'q').color property int pointSize: Units.dp * 12 + property int addressPointSize: Units.dp * 10 } property QtObject grid: QtObject { @@ -233,25 +234,32 @@ QtObject { property QtObject secure: QtObject { property int buttonSize: 40 property int iconSize: 20 - property string icon : '' + property string icon : 'secure_on' property string name : 'secure' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, '', '', '#66727B').color property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, '', '', '#66727B').color property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, '', '', '#66727B').color - property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, '', '', 'transparent').color - property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, '', '', 'transparent').color - property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, '', '', 'transparent').color + property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_c', icon, '', '', '#66727B').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 's').color + property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 's').color + property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 's').color + property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 's').color } property QtObject unsecure: QtObject { - property int iconSize: 16 + property int buttonSize: 40 + property int iconSize: 20 property string icon : 'call_chat_unsecure_custom' property string name : 'unsecure' - property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, '', '', 'transparent').color - property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, '', '', 'transparent').color - property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, '', '', 'transparent').color - property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, '', '', '#ff0000').color - property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, '', '', '#ff0000').color - property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, '', '', '#ff0000').color + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_inv_bg').color + property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_inv_bg').color + property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_inv_bg').color + property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_c', icon, 'me_c_b_inv_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'unsecure').color + property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'unsecure').color + property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'unsecure').color + property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 'unsecure').color + } property QtObject microOn: QtObject { property int iconSize: 40 @@ -368,9 +376,11 @@ QtObject { property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_inv_bg').color property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_inv_bg').color property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_inv_bg').color + property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_c', icon, 'me_c_b_inv_bg').color property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_inv_fg').color property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_inv_fg').color property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_inv_fg').color + property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 'me_c_b_inv_fg').color } property QtObject participants: QtObject { property int iconSize: 40 diff --git a/linphone-app/ui/views/App/Styles/Calls/WaitingRoomStyle.qml b/linphone-app/ui/views/App/Styles/Calls/WaitingRoomStyle.qml index 7779451ee..b6ecc4594 100644 --- a/linphone-app/ui/views/App/Styles/Calls/WaitingRoomStyle.qml +++ b/linphone-app/ui/views/App/Styles/Calls/WaitingRoomStyle.qml @@ -12,10 +12,17 @@ QtObject { property QtObject title: QtObject { property color color: ColorsList.add(sectionName+'_title', 'q').color - property int pointSize: Units.dp * 12 + property int pointSize: Units.dp * 10 + } + property QtObject elapsedTime: QtObject { + property color color: ColorsList.add(sectionName+'_elapsed_time', 'q').color + property int pointSize: Units.dp * 10 + } + property QtObject callee: QtObject { + property color color: ColorsList.add(sectionName+'_callee', 'q').color + property int displayNamePointSize: Units.dp * 10 + property int addressPointSize: Units.dp * 8 } - - @@ -132,8 +139,8 @@ QtObject { property QtObject header: QtObject { property QtObject busyIndicator: QtObject { property color color: ColorsList.add(sectionName+'_header_busy', 'i').color - property int height: 30 - property int width: 30 + property int height: 20 + property int width: 20 } } property QtObject avatar: QtObject { @@ -264,5 +271,27 @@ QtObject { property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 's_p_b_fg').color property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 's_p_b_fg').color } + property QtObject hangup: QtObject { + property int iconSize: 40 + property string icon : 'hangup_custom' + property string name : 'hangup' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'r_n_b_bg').color + property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'r_h_b_bg').color + property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'r_p_b_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'r_n_b_fg').color + property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'r_h_b_fg').color + property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'r_p_b_fg').color + } + property QtObject call: QtObject { + property int iconSize: 40 + property string icon : 'call_accept_custom' + property string name : 'call' + property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'a_n_b_bg').color + property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'a_h_b_bg').color + property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'a_p_b_bg').color + property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'a_n_b_fg').color + property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'a_h_b_fg').color + property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'a_p_b_fg').color + } } } diff --git a/linphone-sdk b/linphone-sdk index af5116a58..64ee6969e 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit af5116a58c2293d2e97a57a9a1b7231445c126d3 +Subproject commit 64ee6969e500d23f5843a6b2a5fd0918707f88f1