diff --git a/resources/icons/ui/screen-share.png b/resources/icons/ui/screen-share.png
new file mode 100644
index 00000000..d6cee427
--- /dev/null
+++ b/resources/icons/ui/screen-share.png
Binary files differdiff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index 48616c1a..c526aa2c 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -44,7 +44,6 @@ Rectangle {
} else if (CallManager.isOnCall) {
CallManager.hangUp();
} else {
- CallManager.refreshDevices();
var dialog = placeCallDialog.createObject(timelineRoot);
dialog.open();
}
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 7db9d041..4eac48f2 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -267,7 +267,7 @@ Page {
}
Loader {
- source: CallManager.isOnCall && CallManager.isVideo ? "voip/VideoCall.qml" : ""
+ source: CallManager.isOnCall && CallManager.callType != CallType.VOICE ? "voip/VideoCall.qml" : ""
onLoaded: TimelineManager.setVideoCallItem()
}
diff --git a/resources/qml/voip/ActiveCallBar.qml b/resources/qml/voip/ActiveCallBar.qml
index 949ba277..d7f3c6fd 100644
--- a/resources/qml/voip/ActiveCallBar.qml
+++ b/resources/qml/voip/ActiveCallBar.qml
@@ -12,7 +12,7 @@ Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
- if (CallManager.isVideo)
+ if (CallManager.callType != CallType.VOICE)
stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1;
}
@@ -42,10 +42,46 @@ Rectangle {
}
Image {
+ id: callTypeIcon
+
Layout.leftMargin: 4
Layout.preferredWidth: 24
Layout.preferredHeight: 24
- source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png"
+ }
+
+ Item {
+ states: [
+ State {
+ name: "VOICE"
+ when: CallManager.callType == CallType.VOICE
+
+ PropertyChanges {
+ target: callTypeIcon
+ source: "qrc:/icons/icons/ui/place-call.png"
+ }
+
+ },
+ State {
+ name: "VIDEO"
+ when: CallManager.callType == CallType.VIDEO
+
+ PropertyChanges {
+ target: callTypeIcon
+ source: "qrc:/icons/icons/ui/video-call.png"
+ }
+
+ },
+ State {
+ name: "SCREEN"
+ when: CallManager.callType == CallType.SCREEN
+
+ PropertyChanges {
+ target: callTypeIcon
+ source: "qrc:/icons/icons/ui/screen-share.png"
+ }
+
+ }
+ ]
}
Label {
@@ -103,7 +139,7 @@ Rectangle {
PropertyChanges {
target: stackLayout
- currentIndex: CallManager.isVideo ? 1 : 0
+ currentIndex: CallManager.callType != CallType.VOICE ? 1 : 0
}
},
@@ -147,20 +183,28 @@ Rectangle {
}
}
+ Label {
+ Layout.leftMargin: 16
+ visible: CallManager.callType == CallType.SCREEN && CallManager.callState == WebRTCState.CONNECTED
+ text: qsTr("You are screen sharing")
+ font.pointSize: fontMetrics.font.pointSize * 1.1
+ color: "#000000"
+ }
+
Item {
Layout.fillWidth: true
}
ImageButton {
- visible: CallManager.haveLocalVideo
+ visible: CallManager.haveLocalPiP
width: 24
height: 24
buttonTextColor: "#000000"
image: ":/icons/icons/ui/toggle-camera-view.png"
hoverEnabled: true
ToolTip.visible: hovered
- ToolTip.text: qsTr("Toggle camera view")
- onClicked: CallManager.toggleCameraView()
+ ToolTip.text: qsTr("Hide/Show Picture-in-Picture")
+ onClicked: CallManager.toggleLocalPiP()
}
ImageButton {
diff --git a/resources/qml/voip/CallDevices.qml b/resources/qml/voip/CallDevices.qml
index e19a2064..3c1108fb 100644
--- a/resources/qml/voip/CallDevices.qml
+++ b/resources/qml/voip/CallDevices.qml
@@ -40,7 +40,7 @@ Popup {
}
RowLayout {
- visible: CallManager.isVideo && CallManager.cameras.length > 0
+ visible: CallManager.callType == CallType.VIDEO && CallManager.cameras.length > 0
Image {
Layout.preferredWidth: 22
diff --git a/resources/qml/voip/CallInvite.qml b/resources/qml/voip/CallInvite.qml
index 00dcc77f..df3343ed 100644
--- a/resources/qml/voip/CallInvite.qml
+++ b/resources/qml/voip/CallInvite.qml
@@ -53,7 +53,7 @@ Popup {
Layout.bottomMargin: msgView.height / 25
Image {
- property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
+ property string image: CallManager.callType == CallType.VIDEO ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: msgView.height / 10
@@ -63,7 +63,7 @@ Popup {
Label {
Layout.alignment: Qt.AlignCenter
- text: CallManager.isVideo ? qsTr("Video Call") : qsTr("Voice Call")
+ text: CallManager.callType == CallType.VIDEO ? qsTr("Video Call") : qsTr("Voice Call")
font.pointSize: fontMetrics.font.pointSize * 2
color: colors.windowText
}
@@ -97,7 +97,7 @@ Popup {
}
RowLayout {
- visible: CallManager.isVideo && CallManager.cameras.length > 0
+ visible: CallManager.callType == CallType.VIDEO && CallManager.cameras.length > 0
Layout.alignment: Qt.AlignCenter
Image {
@@ -159,7 +159,7 @@ Popup {
RoundButton {
id: acceptButton
- property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
+ property string image: CallManager.callType == CallType.VIDEO ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
implicitWidth: buttonLayout.buttonSize
implicitHeight: buttonLayout.buttonSize
diff --git a/resources/qml/voip/CallInviteBar.qml b/resources/qml/voip/CallInviteBar.qml
index 65749c35..7fc8cd05 100644
--- a/resources/qml/voip/CallInviteBar.qml
+++ b/resources/qml/voip/CallInviteBar.qml
@@ -52,12 +52,12 @@ Rectangle {
Layout.leftMargin: 4
Layout.preferredWidth: 24
Layout.preferredHeight: 24
- source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png"
+ source: CallManager.callType == CallType.VIDEO ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png"
}
Label {
font.pointSize: fontMetrics.font.pointSize * 1.1
- text: CallManager.isVideo ? qsTr("Video Call") : qsTr("Voice Call")
+ text: CallManager.callType == CallType.VIDEO ? qsTr("Video Call") : qsTr("Voice Call")
color: "#000000"
}
@@ -75,7 +75,6 @@ Rectangle {
ToolTip.visible: hovered
ToolTip.text: qsTr("Devices")
onClicked: {
- CallManager.refreshDevices();
var dialog = devicesDialog.createObject(timelineRoot);
dialog.open();
}
@@ -83,7 +82,7 @@ Rectangle {
Button {
Layout.rightMargin: 4
- icon.source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png"
+ icon.source: CallManager.callType == CallType.VIDEO ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png"
text: qsTr("Accept")
palette: colors
onClicked: {
@@ -102,7 +101,7 @@ Rectangle {
dialog.open();
return ;
}
- if (CallManager.isVideo && CallManager.cameras.length > 0 && !CallManager.cameras.includes(Settings.camera)) {
+ if (CallManager.callType == CallType.VIDEO && CallManager.cameras.length > 0 && !CallManager.cameras.includes(Settings.camera)) {
var dialog = deviceError.createObject(timelineRoot, {
"errorString": qsTr("Unknown camera: %1").arg(Settings.camera),
"image": ":/icons/icons/ui/video-call.png"
diff --git a/resources/qml/voip/PlaceCall.qml b/resources/qml/voip/PlaceCall.qml
index 41cbd54c..5dbeb6e1 100644
--- a/resources/qml/voip/PlaceCall.qml
+++ b/resources/qml/voip/PlaceCall.qml
@@ -23,6 +23,14 @@ Popup {
}
+ Component {
+ id: screenShareDialog
+
+ ScreenShare {
+ }
+
+ }
+
ColumnLayout {
id: columnLayout
@@ -76,7 +84,7 @@ Popup {
onClicked: {
if (buttonLayout.validateMic()) {
Settings.microphone = micCombo.currentText;
- CallManager.sendInvite(TimelineManager.timeline.roomId(), false);
+ CallManager.sendInvite(TimelineManager.timeline.roomId(), CallType.VOICE);
close();
}
}
@@ -90,13 +98,24 @@ Popup {
if (buttonLayout.validateMic()) {
Settings.microphone = micCombo.currentText;
Settings.camera = cameraCombo.currentText;
- CallManager.sendInvite(TimelineManager.timeline.roomId(), true);
+ CallManager.sendInvite(TimelineManager.timeline.roomId(), CallType.VIDEO);
close();
}
}
}
Button {
+ visible: CallManager.screenShareSupported
+ text: qsTr("Screen")
+ icon.source: "qrc:/icons/icons/ui/screen-share.png"
+ onClicked: {
+ var dialog = screenShareDialog.createObject(timelineRoot);
+ dialog.open();
+ close();
+ }
+ }
+
+ Button {
text: qsTr("Cancel")
onClicked: {
close();
diff --git a/resources/qml/voip/ScreenShare.qml b/resources/qml/voip/ScreenShare.qml
new file mode 100644
index 00000000..a22b5b68
--- /dev/null
+++ b/resources/qml/voip/ScreenShare.qml
@@ -0,0 +1,153 @@
+import "../"
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+Popup {
+ modal: true
+ // only set the anchors on Qt 5.12 or higher
+ // see https://doc.qt.io/qt-5/qml-qtquick-controls2-popup.html#anchors.centerIn-prop
+ Component.onCompleted: {
+ if (anchors)
+ anchors.centerIn = parent;
+
+ frameRateCombo.currentIndex = frameRateCombo.find(Settings.screenShareFrameRate);
+ }
+ palette: colors
+
+ ColumnLayout {
+ Label {
+ Layout.topMargin: 16
+ Layout.bottomMargin: 16
+ Layout.leftMargin: 8
+ Layout.rightMargin: 8
+ Layout.alignment: Qt.AlignLeft
+ text: qsTr("Share desktop with %1?").arg(TimelineManager.timeline.roomName)
+ color: colors.windowText
+ }
+
+ RowLayout {
+ Layout.leftMargin: 8
+ Layout.rightMargin: 8
+ Layout.bottomMargin: 8
+
+ Label {
+ Layout.alignment: Qt.AlignLeft
+ text: qsTr("Window:")
+ color: colors.windowText
+ }
+
+ ComboBox {
+ id: windowCombo
+
+ Layout.fillWidth: true
+ model: CallManager.windowList()
+ }
+
+ }
+
+ RowLayout {
+ Layout.leftMargin: 8
+ Layout.rightMargin: 8
+ Layout.bottomMargin: 8
+
+ Label {
+ Layout.alignment: Qt.AlignLeft
+ text: qsTr("Frame rate:")
+ color: colors.windowText
+ }
+
+ ComboBox {
+ id: frameRateCombo
+
+ Layout.fillWidth: true
+ model: ["25", "20", "15", "10", "5", "2", "1"]
+ }
+
+ }
+
+ CheckBox {
+ id: pipCheckBox
+
+ enabled: CallManager.cameras.length > 0
+ checked: Settings.screenSharePiP
+ Layout.alignment: Qt.AlignLeft
+ Layout.leftMargin: 8
+ Layout.rightMargin: 8
+ text: qsTr("Include your camera picture-in-picture")
+ }
+
+ CheckBox {
+ id: remoteVideoCheckBox
+
+ Layout.alignment: Qt.AlignLeft
+ Layout.leftMargin: 8
+ Layout.rightMargin: 8
+ text: qsTr("Request remote camera")
+ checked: Settings.screenShareRemoteVideo
+ ToolTip.text: qsTr("View your callee's camera like a regular video call")
+ ToolTip.visible: hovered
+ }
+
+ CheckBox {
+ id: hideCursorCheckBox
+
+ Layout.alignment: Qt.AlignLeft
+ Layout.leftMargin: 8
+ Layout.rightMargin: 8
+ Layout.bottomMargin: 8
+ text: qsTr("Hide mouse cursor")
+ checked: Settings.screenShareHideCursor
+ }
+
+ RowLayout {
+ Layout.margins: 8
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Button {
+ text: qsTr("Share")
+ icon.source: "qrc:/icons/icons/ui/screen-share.png"
+ onClicked: {
+ if (buttonLayout.validateMic()) {
+ Settings.microphone = micCombo.currentText;
+ if (pipCheckBox.checked)
+ Settings.camera = cameraCombo.currentText;
+
+ Settings.screenShareFrameRate = frameRateCombo.currentText;
+ Settings.screenSharePiP = pipCheckBox.checked;
+ Settings.screenShareRemoteVideo = remoteVideoCheckBox.checked;
+ Settings.screenShareHideCursor = hideCursorCheckBox.checked;
+ CallManager.sendInvite(TimelineManager.timeline.roomId(), CallType.SCREEN, windowCombo.currentIndex);
+ close();
+ }
+ }
+ }
+
+ Button {
+ text: qsTr("Preview")
+ onClicked: {
+ CallManager.previewWindow(windowCombo.currentIndex);
+ }
+ }
+
+ Button {
+ text: qsTr("Cancel")
+ onClicked: {
+ close();
+ }
+ }
+
+ }
+
+ }
+
+ background: Rectangle {
+ color: colors.window
+ border.color: colors.windowText
+ }
+
+}
diff --git a/resources/res.qrc b/resources/res.qrc
index 12d098c0..e629a871 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -74,6 +74,7 @@
<file>icons/ui/end-call.png</file>
<file>icons/ui/microphone-mute.png</file>
<file>icons/ui/microphone-unmute.png</file>
+ <file>icons/ui/screen-share.png</file>
<file>icons/ui/toggle-camera-view.png</file>
<file>icons/ui/video-call.png</file>
@@ -167,6 +168,7 @@
<file>qml/voip/CallInviteBar.qml</file>
<file>qml/voip/DeviceError.qml</file>
<file>qml/voip/PlaceCall.qml</file>
+ <file>qml/voip/ScreenShare.qml</file>
<file>qml/voip/VideoCall.qml</file>
</qresource>
<qresource prefix="/media">
|