From 58ee8ae7aaacf2874cf61f3bf609912bd64cbe5e Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Tue, 18 Apr 2017 11:51:56 +0200 Subject: [PATCH] feat(ui/views/App/Calls/Incall): supports `TelKeypad`. --- linphone-desktop/resources.qrc | 12 +- .../src/components/call/CallModel.cpp | 6 + .../src/components/call/CallModel.hpp | 2 + .../ui/modules/Common/Helpers/DragBox.qml | 116 +++++++++++++++ linphone-desktop/ui/modules/Common/qmldir | 1 + .../{ => SmartSearchBar}/SmartSearchBar.qml | 0 .../Linphone/Styles/{ => Chat}/ChatStyle.qml | 0 .../SmartSearchBarStyle.qml | 0 .../Styles/TelKeypad/TelKeypadStyle.qml | 26 ++++ .../Styles/{ => Timeline}/TimelineStyle.qml | 0 .../ui/modules/Linphone/Styles/qmldir | 8 +- .../modules/Linphone/TelKeypad/TelKeypad.qml | 135 +++++++++++++----- .../Linphone/TelKeypad/TelKeypadButton.qml | 41 +++++- .../Linphone/{ => Timeline}/Timeline.qml | 0 linphone-desktop/ui/modules/Linphone/qmldir | 6 +- linphone-desktop/ui/views/App/Calls/Incall.js | 2 + .../ui/views/App/Calls/Incall.qml | 10 ++ .../App/Calls/IncallFullscreenWindow.qml | 57 ++------ 18 files changed, 331 insertions(+), 91 deletions(-) create mode 100644 linphone-desktop/ui/modules/Common/Helpers/DragBox.qml rename linphone-desktop/ui/modules/Linphone/{ => SmartSearchBar}/SmartSearchBar.qml (100%) rename linphone-desktop/ui/modules/Linphone/Styles/{ => Chat}/ChatStyle.qml (100%) rename linphone-desktop/ui/modules/Linphone/Styles/{ => SmartSearchBar}/SmartSearchBarStyle.qml (100%) create mode 100644 linphone-desktop/ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml rename linphone-desktop/ui/modules/Linphone/Styles/{ => Timeline}/TimelineStyle.qml (100%) rename linphone-desktop/ui/modules/Linphone/{ => Timeline}/Timeline.qml (100%) diff --git a/linphone-desktop/resources.qrc b/linphone-desktop/resources.qrc index 4d4d9577b..592a47153 100644 --- a/linphone-desktop/resources.qrc +++ b/linphone-desktop/resources.qrc @@ -208,6 +208,7 @@ ui/modules/Common/Form/Tab/TabButton.qml ui/modules/Common/Form/Tab/TabContainer.qml ui/modules/Common/Form/TransparentTextInput.qml + ui/modules/Common/Helpers/DragBox.qml ui/modules/Common/Helpers/InvertedMouseArea.qml ui/modules/Common/Image/Icon.qml ui/modules/Common/Image/RoundedImage.qml @@ -298,13 +299,13 @@ ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml ui/modules/Linphone/Presence/PresenceLevel.qml ui/modules/Linphone/qmldir - ui/modules/Linphone/SmartSearchBar.qml + ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml ui/modules/Linphone/Styles/Account/AccountStatusStyle.qml ui/modules/Linphone/Styles/Blocks/CardBlockStyle.qml ui/modules/Linphone/Styles/Blocks/RequestBlockStyle.qml ui/modules/Linphone/Styles/Calls/CallControlsStyle.qml ui/modules/Linphone/Styles/Calls/CallsStyle.qml - ui/modules/Linphone/Styles/ChatStyle.qml + ui/modules/Linphone/Styles/Chat/ChatStyle.qml ui/modules/Linphone/Styles/Codecs/CodecsViewerStyle.qml ui/modules/Linphone/Styles/Contact/AvatarStyle.qml ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml @@ -316,11 +317,12 @@ ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml ui/modules/Linphone/Styles/qmldir - ui/modules/Linphone/Styles/SmartSearchBarStyle.qml - ui/modules/Linphone/Styles/TimelineStyle.qml + ui/modules/Linphone/Styles/SmartSearchBar/SmartSearchBarStyle.qml + ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml + ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml ui/modules/Linphone/TelKeypad/TelKeypadButton.qml ui/modules/Linphone/TelKeypad/TelKeypad.qml - ui/modules/Linphone/Timeline.qml + ui/modules/Linphone/Timeline/Timeline.qml ui/scripts/LinphoneUtils/linphone-utils.js ui/scripts/LinphoneUtils/qmldir ui/scripts/Utils/port-tools.js diff --git a/linphone-desktop/src/components/call/CallModel.cpp b/linphone-desktop/src/components/call/CallModel.cpp index daaad7735..6ac5f0898 100644 --- a/linphone-desktop/src/components/call/CallModel.cpp +++ b/linphone-desktop/src/components/call/CallModel.cpp @@ -381,3 +381,9 @@ bool CallModel::getUpdating () const { bool CallModel::getRecording () const { return mRecording; } + +// ----------------------------------------------------------------------------- + +void CallModel::sendDtmf (const QString &dtmf) { + mLinphoneCall->sendDtmf(dtmf.constData()[0].toLatin1()); +} diff --git a/linphone-desktop/src/components/call/CallModel.hpp b/linphone-desktop/src/components/call/CallModel.hpp index 6df3b4200..344442db7 100644 --- a/linphone-desktop/src/components/call/CallModel.hpp +++ b/linphone-desktop/src/components/call/CallModel.hpp @@ -83,6 +83,8 @@ public: Q_INVOKABLE void startRecording (); Q_INVOKABLE void stopRecording (); + Q_INVOKABLE void sendDtmf (const QString &dtmf); + signals: void statusChanged (CallStatus status); void microMutedChanged (bool status); diff --git a/linphone-desktop/ui/modules/Common/Helpers/DragBox.qml b/linphone-desktop/ui/modules/Common/Helpers/DragBox.qml new file mode 100644 index 000000000..0b3ade33a --- /dev/null +++ b/linphone-desktop/ui/modules/Common/Helpers/DragBox.qml @@ -0,0 +1,116 @@ +import QtQuick 2.7 + +// ============================================================================= + +Item { + id: dragBox + + // --------------------------------------------------------------------------- + + property var container + property var draggable + + property var xPosition + property var yPosition + + // --------------------------------------------------------------------------- + + property var _mouseArea: null + + // --------------------------------------------------------------------------- + + signal pressed (var mouse) + signal released (var mouse) + signal wheel (var wheel) + + // --------------------------------------------------------------------------- + + function _create () { + draggable.x = Qt.binding(xPosition) + draggable.y = Qt.binding(yPosition) + + var drag = draggable.Drag + + drag.hotSpot.x = Qt.binding(function () { + return draggable.width / 2 + }) + drag.hotSpot.y = Qt.binding(function () { + return draggable.height / 2 + }) + + if (_mouseArea == null) { + _mouseArea = builder.createObject(draggable) + + drag.active = Qt.binding(function () { + return _mouseArea && _mouseArea.held + }) + + drag.source = Qt.binding(function () { + return _mouseArea + }) + } + } + + function _delete () { + if (_mouseArea != null) { + _mouseArea.destroy() + _mouseArea = null + } + } + + // --------------------------------------------------------------------------- + + Component.onCompleted: enabled && _create() + Component.onDestruction: _delete() + + onEnabledChanged: { + _delete() + + if (enabled) { + _create() + } + } + + // --------------------------------------------------------------------------- + + Component { + id: builder + + MouseArea { + property bool held: false + + anchors.fill: parent + + drag { + axis: Drag.XandYAxis + target: parent + } + + onPressed: { + dragBox.pressed(mouse) + held = true + } + + onReleased: { + dragBox.released(mouse) + held = false + + var container = dragBox.container + + if (parent.x < 0) { + parent.x = 0 + } else if (parent.x + parent.width >= container.width) { + parent.x = container.width - parent.width + } + + if (parent.y < 0) { + parent.y = 0 + } else if (parent.y + parent.height >= container.height) { + parent.y = container.height - parent.height + } + } + + onWheel: dragBox.wheel(wheel) + } + } +} diff --git a/linphone-desktop/ui/modules/Common/qmldir b/linphone-desktop/ui/modules/Common/qmldir index df6cee6a2..66411e108 100644 --- a/linphone-desktop/ui/modules/Common/qmldir +++ b/linphone-desktop/ui/modules/Common/qmldir @@ -51,6 +51,7 @@ TabBar 1.0 Form/Tab/TabBar.qml TabButton 1.0 Form/Tab/TabButton.qml TabContainer 1.0 Form/Tab/TabContainer.qml +DragBox 1.0 Helpers/DragBox.qml InvertedMouseArea 1.0 Helpers/InvertedMouseArea.qml Icon 1.0 Image/Icon.qml diff --git a/linphone-desktop/ui/modules/Linphone/SmartSearchBar.qml b/linphone-desktop/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml similarity index 100% rename from linphone-desktop/ui/modules/Linphone/SmartSearchBar.qml rename to linphone-desktop/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml diff --git a/linphone-desktop/ui/modules/Linphone/Styles/ChatStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/Chat/ChatStyle.qml similarity index 100% rename from linphone-desktop/ui/modules/Linphone/Styles/ChatStyle.qml rename to linphone-desktop/ui/modules/Linphone/Styles/Chat/ChatStyle.qml diff --git a/linphone-desktop/ui/modules/Linphone/Styles/SmartSearchBarStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/SmartSearchBar/SmartSearchBarStyle.qml similarity index 100% rename from linphone-desktop/ui/modules/Linphone/Styles/SmartSearchBarStyle.qml rename to linphone-desktop/ui/modules/Linphone/Styles/SmartSearchBar/SmartSearchBarStyle.qml diff --git a/linphone-desktop/ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml new file mode 100644 index 000000000..5cfd20026 --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml @@ -0,0 +1,26 @@ +pragma Singleton +import QtQuick 2.7 + +import Common 1.0 + +// ============================================================================= + +QtObject { + property int columnSpacing: 0 + property int height: 180 + property int rowSpacing: 0 + property int width: 150 + property color color: Colors.k + + property QtObject button: QtObject { + property QtObject color: QtObject { + property color normal: Colors.k + property color pressed: Colors.i + } + + property QtObject text: QtObject { + property color color: Colors.d + property int fontSize: 10 + } + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Styles/TimelineStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml similarity index 100% rename from linphone-desktop/ui/modules/Linphone/Styles/TimelineStyle.qml rename to linphone-desktop/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml diff --git a/linphone-desktop/ui/modules/Linphone/Styles/qmldir b/linphone-desktop/ui/modules/Linphone/Styles/qmldir index 9682d909c..f4db82bdf 100644 --- a/linphone-desktop/ui/modules/Linphone/Styles/qmldir +++ b/linphone-desktop/ui/modules/Linphone/Styles/qmldir @@ -9,7 +9,7 @@ singleton AccountStatusStyle 1.0 Account/AccountStatusStyle.qm singleton CardBlockStyle 1.0 Blocks/CardBlockStyle.qml singleton RequestBlockStyle 1.0 Blocks/RequestBlockStyle.qml -singleton ChatStyle 1.0 ChatStyle.qml +singleton ChatStyle 1.0 Chat/ChatStyle.qml singleton CallsStyle 1.0 Calls/CallsStyle.qml singleton CallControlsStyle 1.0 Calls/CallControlsStyle.qml @@ -28,6 +28,8 @@ singleton NotificationReceivedCallStyle 1.0 Notifications/NotificationRec singleton NotificationReceivedMessageStyle 1.0 Notifications/NotificationReceivedMessageStyle.qml singleton NotificationReceivedFileMessageStyle 1.0 Notifications/NotificationReceivedFileMessageStyle.qml -singleton SmartSearchBarStyle 1.0 SmartSearchBarStyle.qml +singleton SmartSearchBarStyle 1.0 SmartSearchBar/SmartSearchBarStyle.qml -singleton TimelineStyle 1.0 TimelineStyle.qml +singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml + +singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml diff --git a/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypad.qml b/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypad.qml index beb7b2152..fd69aba13 100644 --- a/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypad.qml +++ b/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypad.qml @@ -1,48 +1,115 @@ import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +import Common 1.0 +import Linphone.Styles 1.0 // ============================================================================= -Grid { +Rectangle { + id: telKeypad + + property var container: parent property var call + color: TelKeypadStyle.color + + layer { + effect: PopupShadow {} + enabled: true + } + + height: TelKeypadStyle.height + width: TelKeypadStyle.width + // --------------------------------------------------------------------------- - columns: 3 + GridLayout { + id: grid - Repeater { - model: [{ - text: '1', - icon: 'answering_machine' - }, { - text: '2' - },{ - text: '3' - }, { - text: '4' - }, { - text: '5' - }, { - text: '6' - }, { - text: '7' - }, { - text: '8' - }, { - text: '9' - }, { - text: '*' - }, { - text: '0', - icon: 'plus' - }, { - text: '#' - }] + anchors.fill: parent - TelKeypadButton { - icon: modelData.icon - text: modelData.text + columns: 3 // Not a style. + rows: 4 // Same idea. - onClicked: console.log('TODO') + columnSpacing: TelKeypadStyle.columnSpacing + rowSpacing: TelKeypadStyle.rowSpacing + + Repeater { + model: [{ + text: '1', + icon: 'answering_machine' + }, { + text: '2' + },{ + text: '3' + }, { + text: '4' + }, { + text: '5' + }, { + text: '6' + }, { + text: '7' + }, { + text: '8' + }, { + text: '9' + }, { + text: '*' + }, { + text: '0', + icon: 'plus' + }, { + text: '#' + }] + + TelKeypadButton { + Layout.fillHeight: true + Layout.fillWidth: true + + icon: modelData.icon || '' + text: modelData.text + + onClicked: { + var text = modelData.text + console.info('Send dtmf: ' + text) + telKeypad.call.sendDtmf(text) + } + } + } + } + + // --------------------------------------------------------------------------- + + DragBox { + id: dragBox + + readonly property int delta: 5 + + property var _mouseX + property var _mouseY + + container: telKeypad.container + draggable: parent + + xPosition: (function () { + return 0 + }) + yPosition: (function () { + return 0 + }) + + onPressed: { + _mouseX = mouse.x + _mouseY = mouse.y + } + + onReleased: { + if (Math.abs(_mouseX - mouse.x) <= delta && Math.abs(_mouseY - mouse.y) <= delta) { + var id = parseInt(_mouseX / (parent.width / grid.columns)) + parseInt(_mouseY / (parent.height / grid.rows)) * grid.columns + grid.children[id].clicked() + } } } } diff --git a/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypadButton.qml b/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypadButton.qml index 230a57d7d..3f172ab7c 100644 --- a/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypadButton.qml +++ b/linphone-desktop/ui/modules/Linphone/TelKeypad/TelKeypadButton.qml @@ -1,5 +1,44 @@ import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import Linphone.Styles 1.0 // ============================================================================= -Item {} +Item { + id: button + + property string icon: '' + property string text: '' + + signal clicked + + // --------------------------------------------------------------------------- + + Button { + anchors.fill: parent + + background: Rectangle { + color: TelKeypadStyle.button.color.normal + } + + contentItem: Text { + color: TelKeypadStyle.button.text.color + + font { + bold: true + pointSize: TelKeypadStyle.button.text.fontSize + } + + elide: Text.ElideRight + text: button.text + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + hoverEnabled: true + + onClicked: button.clicked() + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Timeline.qml b/linphone-desktop/ui/modules/Linphone/Timeline/Timeline.qml similarity index 100% rename from linphone-desktop/ui/modules/Linphone/Timeline.qml rename to linphone-desktop/ui/modules/Linphone/Timeline/Timeline.qml diff --git a/linphone-desktop/ui/modules/Linphone/qmldir b/linphone-desktop/ui/modules/Linphone/qmldir index 56e4b6cbf..69bb88f52 100644 --- a/linphone-desktop/ui/modules/Linphone/qmldir +++ b/linphone-desktop/ui/modules/Linphone/qmldir @@ -25,8 +25,8 @@ SipAddressesMenu 1.0 Menus/SipAddressesMenu.qml PresenceLevel 1.0 Presence/PresenceLevel.qml -SmartSearchBar 1.0 SmartSearchBar.qml +SmartSearchBar 1.0 SmartSearchBar/SmartSearchBar.qml -TelKeypad 1.0 TelKeypad.qml +TelKeypad 1.0 TelKeypad/TelKeypad.qml -Timeline 1.0 Timeline.qml +Timeline 1.0 Timeline/Timeline.qml diff --git a/linphone-desktop/ui/views/App/Calls/Incall.js b/linphone-desktop/ui/views/App/Calls/Incall.js index d932bd10c..872228553 100644 --- a/linphone-desktop/ui/views/App/Calls/Incall.js +++ b/linphone-desktop/ui/views/App/Calls/Incall.js @@ -22,6 +22,8 @@ function handleStatusChanged (status) { if (fullscreen) { fullscreen.close() } + + telKeypad.visible = false } } diff --git a/linphone-desktop/ui/views/App/Calls/Incall.qml b/linphone-desktop/ui/views/App/Calls/Incall.qml index 586ff5b88..a3c839e33 100644 --- a/linphone-desktop/ui/views/App/Calls/Incall.qml +++ b/linphone-desktop/ui/views/App/Calls/Incall.qml @@ -367,4 +367,14 @@ Rectangle { } } } + + // --------------------------------------------------------------------------- + // TelKeypad. + // --------------------------------------------------------------------------- + + TelKeypad { + id: telKeypad + + call: incall.call + } } diff --git a/linphone-desktop/ui/views/App/Calls/IncallFullscreenWindow.qml b/linphone-desktop/ui/views/App/Calls/IncallFullscreenWindow.qml index 8be1397ff..c4b91f7b6 100644 --- a/linphone-desktop/ui/views/App/Calls/IncallFullscreenWindow.qml +++ b/linphone-desktop/ui/views/App/Calls/IncallFullscreenWindow.qml @@ -331,10 +331,13 @@ Window { Camera { property bool scale: false - Drag.active: cameraDrag.held - Drag.source: cameraDrag - Drag.hotSpot.x: width / 2 - Drag.hotSpot.y: height / 2 + function xPosition () { + return incall.width / 2 - width / 2 + } + + function yPosition () { + return incall.height - height + } call: incall.call isPreview: true @@ -342,48 +345,12 @@ Window { height: CallStyle.actionArea.userVideo.height * (scale ? 2 : 1) width: CallStyle.actionArea.userVideo.width * (scale ? 2 : 1) - Component.onCompleted: { - x = incall.width / 2 - width / 2 - y = incall.height - height - } + DragBox { + container: incall + draggable: parent - // Workaround. - // x and y are not binded to functions because if the scale is updated, - // the position of the preview is reset. - Connections { - target: incall - onHeightChanged: y = incall.height - parent.height - onWidthChanged: x = incall.width / 2 - parent.width / 2 - } - - MouseArea { - id: cameraDrag - - property bool held: false - - anchors.fill: parent - - drag { - axis: Drag.XandYAxis - target: parent - } - - onPressed: held = true - onReleased: { - held = false - - if (parent.x < 0) { - parent.x = 0 - } else if (parent.x + parent.width >= incall.width) { - parent.x = incall.width - parent.width - } - - if (parent.y < 0) { - parent.y = 0 - } else if (parent.y + parent.height >= incall.height) { - parent.y = incall.height - parent.height - } - } + xPosition: parent.xPosition + yPosition: parent.yPosition onWheel: parent.scale = wheel.angleDelta.y > 0 }