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