diff --git a/CHANGELOG.md b/CHANGELOG.md
index 943c2e742..41004283a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 5.0.7 - undefined
+
+### Added
+- Interactive preview in call:
+ * Movable on holding mouse's left click.
+ * Resizeable on mouse's wheel.
+ * Reset on mouse's right click (first for size if changed, second for position)
+
## 5.0.6 - 2023-01-10
### Fixed
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index 7ebb4a073..efac25df6 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -224,6 +224,7 @@
ui/modules/Common/Form/TransparentTextInput.qml
ui/modules/Common/Helpers/DragBox.qml
ui/modules/Common/Helpers/InvertedMouseArea.qml
+ ui/modules/Common/Helpers/MovableMouseArea.qml
ui/modules/Common/Image/Icon.qml
ui/modules/Common/Image/RoundedImage.qml
ui/modules/Common/Indicators/MediaProgressBar.qml
diff --git a/linphone-app/ui/modules/Common/Helpers/MovableMouseArea.qml b/linphone-app/ui/modules/Common/Helpers/MovableMouseArea.qml
new file mode 100644
index 000000000..61ac41cb2
--- /dev/null
+++ b/linphone-app/ui/modules/Common/Helpers/MovableMouseArea.qml
@@ -0,0 +1,83 @@
+import QtQuick 2.7
+
+import Common 1.0
+import Utils 1.0
+
+MouseArea{
+ id: mainItem
+ property var movableArea: mainItem.Window.contentItem
+
+ signal requestResetPosition()
+
+ property bool dragging: drag.active
+ onDraggingChanged: {
+ if(dragging){
+ xClicked = mouseX
+ yClicked = mouseY
+ }
+
+ }
+// Position buffer
+ property int xClicked : 0
+ property int yClicked : 0
+// Scaling buffer
+ property int heightOrigin
+ property int widthOrigin
+ property double startTime: 0 // For acceleration computation to avoid excessive wheel scrolling
+ property double mScale: 1.0 // Using scale reduce quality. Apply our factor.
+ property bool scaled : false // Zoom state : -for storing origin state ; -for resetting scale on right click. In this case, second click lead to emit reset signal instead of first..
+
+ acceptedButtons: Qt.LeftButton | Qt.RightButton // Left is for Dragging. Right is for resetting. Wheel will scale.
+ cursorShape: dragging ? Qt.DragMoveCursor : undefined
+ preventStealing: true
+ propagateComposedEvents: true
+ hoverEnabled: true
+
+ function updateScale(){// Avoid scaling if leading outside movableArea.
+ drag.target.height = Math.max(0, Math.min(movableArea.height, heightOrigin * mScale))
+ drag.target.width = Math.max(0, Math.min(movableArea.width, widthOrigin * mScale))
+ updatePosition(0,0)
+ }
+ function updatePosition(x, y){// Avoid moving outside movableArea.
+ var parentTLBounds = drag.target.parent.mapFromItem(movableArea, 0, 0);
+ var parentBRBounds = drag.target.parent.mapFromItem(movableArea, movableArea.width, movableArea.height);
+ drag.target.x = Math.max(parentTLBounds.x, Math.min(parentBRBounds.x - drag.target.width, drag.target.x + x))
+ drag.target.y = Math.max(parentTLBounds.y, Math.min(parentBRBounds.y - drag.target.height, drag.target.y + y))
+ }
+ onMScaleChanged: updateScale()
+ onPositionChanged: {
+ if(dragging){
+ updatePosition(mouse.x - xClicked, mouse.y - yClicked)
+ }
+ mouse.accepted = false
+ }
+ onWheel: {
+ if(!scaled){
+ scaled = true
+ heightOrigin = drag.target.height
+ widthOrigin = drag.target.width
+ }
+ var acceleration = 0.01; // Try to make smoother the scaling from wheel
+ if(startTime == 0){
+ startTime = new Date().getTime();
+ }else{
+ var delay = new Date().getTime() - startTime;
+ if(delay > 0)
+ acceleration = Math.max(0.01, Math.min(1, 4/delay));
+ else
+ acceleration = 1
+ }
+ mScale = Math.max(0.5 , mScale * ( 1 + acceleration*(wheel.angleDelta.y >0 ? 1 : -1) ));
+ startTime = new Date().getTime();
+ }
+ onClicked: {
+ if(mouse.button == Qt.RightButton){
+ if(scaled) {
+ scaled = false
+ mScale = 1.0
+ }else
+ requestResetPosition()
+ }
+ mouse.accepted = false
+ }
+}
diff --git a/linphone-app/ui/modules/Common/qmldir b/linphone-app/ui/modules/Common/qmldir
index a025a39b3..f3b9d8c7e 100644
--- a/linphone-app/ui/modules/Common/qmldir
+++ b/linphone-app/ui/modules/Common/qmldir
@@ -66,6 +66,7 @@ TabContainer 1.0 Form/Tab/TabContainer.qml
DragBox 1.0 Helpers/DragBox.qml
InvertedMouseArea 1.0 Helpers/InvertedMouseArea.qml
+MovableMouseArea 1.0 Helpers/MovableMouseArea.qml
Icon 1.0 Image/Icon.qml
RoundedImage 1.0 Image/RoundedImage.qml
diff --git a/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml b/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml
index 3a0e10a68..5b740aaf0 100644
--- a/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml
+++ b/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml
@@ -106,6 +106,25 @@ Item {
}
active: parent.visible
}
+
+ MovableMouseArea{
+ id: dragger
+ anchors.fill: parent
+ visible: mainItem.participantCount <= 2
+ function resetPosition(){
+ preview.anchors.right = mainItem.right
+ preview.anchors.bottom = mainItem.bottom
+ }
+ onVisibleChanged: if(!visible){
+ resetPosition()
+ }
+ drag.target: preview
+ onDraggingChanged: if(dragging){
+ preview.anchors.right = undefined
+ preview.anchors.bottom = undefined
+ }
+ onRequestResetPosition: resetPosition()
+ }
}
Item{
anchors.right: parent.right