Skip to content
Snippets Groups Projects
Commit 8dd04cab authored by Capucine Berthet's avatar Capucine Berthet Committed by Sébastien Blin
Browse files

RecordBox: new design

GitLab: #1417
Change-Id: I892d140a4989e8cd6e96ca6f81abaa0cdaab2e54
parent be9725ec
No related branches found
No related tags found
No related merge requests found
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path id="check_circle_FILL0_wght400_GRAD0_opsz24" d="M88.6-865.4l7.05-7.05-1.4-1.4L88.6-868.2l-2.85-2.85-1.4,1.4ZM90-860a9.738,9.738,0,0,1-3.9-.787,10.1,10.1,0,0,1-3.175-2.138,10.1,10.1,0,0,1-2.138-3.175A9.738,9.738,0,0,1,80-870a9.738,9.738,0,0,1,.787-3.9,10.1,10.1,0,0,1,2.138-3.175,10.1,10.1,0,0,1,3.175-2.138A9.738,9.738,0,0,1,90-880a9.738,9.738,0,0,1,3.9.787,10.1,10.1,0,0,1,3.175,2.138,10.1,10.1,0,0,1,2.138,3.175A9.738,9.738,0,0,1,100-870a9.738,9.738,0,0,1-.787,3.9,10.1,10.1,0,0,1-2.138,3.175,10.1,10.1,0,0,1-3.175,2.138A9.738,9.738,0,0,1,90-860Zm0-2a7.721,7.721,0,0,0,5.675-2.325A7.721,7.721,0,0,0,98-870a7.721,7.721,0,0,0-2.325-5.675A7.721,7.721,0,0,0,90-878a7.721,7.721,0,0,0-5.675,2.325A7.721,7.721,0,0,0,82-870a7.721,7.721,0,0,0,2.325,5.675A7.721,7.721,0,0,0,90-862ZM90-870Z" transform="translate(-80 880)" fill="#fff"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M24 24H0V0h24v24z"/><circle fill="#ff0000" cx="12" cy="12" r="8"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<path d="M20.2,6.5c-1.4-2.2-3.6-3.7-6-4.2C9,1.1,3.9,4.2,2.7,9.3c0,0,0,0,0,0l0,0.1c-0.6,2.4-0.1,4.9,1.2,6.9c1.2,1.9,3,3.3,5.1,4
l-0.4,0.3c-0.1,0-0.1,0.1-0.2,0.1C8,20.9,8,21.4,8.2,21.7C8.3,21.9,8.5,22,8.7,22c0,0,0.1,0,0.1,0c0.2,0,0.3-0.1,0.4-0.1l2-1.2
c0.2-0.1,0.3-0.3,0.3-0.5s0-0.4-0.1-0.6l-1.3-2c-0.2-0.3-0.6-0.4-1-0.2c-0.4,0.2-0.5,0.7-0.3,1l0.2,0.4c-1.7-0.6-3.1-1.7-4.1-3.3
c-1.1-1.7-1.4-3.8-1-5.9c0,0,0,0,0,0l0-0.1c1-4.2,5.3-6.8,9.7-5.9c2.1,0.5,3.9,1.8,5.1,3.6c1.1,1.7,1.4,3.8,1,5.9
c-0.6,2.7-2.8,4.9-5.6,5.8c-0.4,0.1-0.6,0.5-0.5,0.9c0.1,0.4,0.5,0.6,0.9,0.5c3.3-1,5.9-3.7,6.7-6.9l0-0.1
C21.9,11,21.5,8.5,20.2,6.5z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g id="Picture_FILLO" transform="translate(-378.5 -900)">
<circle id="Oval" cx="7.222" cy="7.222" r="7.222" transform="translate(381.278 902.778)" fill="#fff"/>
<g id="Oval-2" data-name="Oval" transform="translate(378.5 900)" fill="none" stroke="#fff" stroke-width="1">
<circle cx="10" cy="10" r="10" stroke="none"/>
<circle cx="10" cy="10" r="9.5" fill="none"/>
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path id="refresh_FILL0_wght400_GRAD0_opsz24" d="M170-780a9.651,9.651,0,0,0,7.094-2.906A9.651,9.651,0,0,0,180-790a9.651,9.651,0,0,0-2.906-7.094A9.651,9.651,0,0,0,170-800a9.9,9.9,0,0,0-4.125.891,9.528,9.528,0,0,0-3.375,2.547V-800H160v8.75h8.75v-2.5H163.5a7.3,7.3,0,0,1,2.734-2.75,7.409,7.409,0,0,1,3.766-1,7.233,7.233,0,0,1,5.313,2.188A7.233,7.233,0,0,1,177.5-790a7.233,7.233,0,0,1-2.187,5.313A7.233,7.233,0,0,1,170-782.5a7.328,7.328,0,0,1-4.344-1.375,7.261,7.261,0,0,1-2.719-3.625h-2.625a9.87,9.87,0,0,0,3.563,5.406A9.7,9.7,0,0,0,170-780Z" transform="translate(-160 800)" fill="#fff"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M6 6h12v12H6z" fill="#ff0000"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="16" viewBox="0 0 15 16">
<g id="Stop_FILLO" fill="none" stroke="#fff" stroke-width="1.5">
<rect width="15" height="16" rx="5" stroke="none"/>
<rect x="0.75" y="0.75" width="13.5" height="14.5" rx="4.25" fill="none"/>
</g>
</svg>
......@@ -64,7 +64,8 @@ BaseModalDialog {
RecordBox {
id: recordBox
anchors.centerIn: parent
x: 100
y: 100
isPhoto: true
visible: false
......@@ -120,14 +121,6 @@ BaseModalDialog {
onClicked: {
recordBox.parent = buttonsRowLayout
recordBox.x = Qt.binding(function() {
var buttonCenterX = buttonsRowLayout.width / 2
return buttonCenterX - recordBox.width / 2
})
recordBox.y = Qt.binding(function() {
return - recordBox.height / 2
})
startBooth()
}
}
......
......@@ -169,6 +169,12 @@ Item {
property color spinboxBackgroundColor: darkTheme ? editBackgroundColor : selectedColor
property color spinboxBorderColor: darkTheme ? "#1D5F70" : "#A3C2DA"
//RecordBox
property color screenshotButtonColor: "#CC0022"
property color recordBoxcloseButtonColor: "#8d8a87"
property color recordBoxHoverColor: "#4D4D4D"
property color recordBoxButtonColor: "#272727"
// Toast
property color toastColor: darkTheme ? "#f0f0f0" : "#000000"
property color toastRectColor: !darkTheme ? "#f0f0f0" : "#000000"
......
......@@ -193,12 +193,14 @@ Rectangle {
}
onVideoRecordMessageButtonClicked: {
recordBox.y = -recordBox.height;
recordBox.y = -recordBox.height - 200;
recordBox.x = recordBox.width + 200
recordBox.openRecorder(true);
}
onAudioRecordMessageButtonClicked: {
recordBox.y = -recordBox.height;
recordBox.y = -recordBox.height - 150;
recordBox.x = recordBox.width + 200;
recordBox.openRecorder(false);
}
......
......@@ -38,9 +38,10 @@ Popup {
property int state: RecordBox.States.INIT
property bool isVideo: false
property bool isPhoto: false
property bool isAudio: false
property bool showVideo: (root.isVideo && VideoDevices.listSize !== 0)
property int preferredWidth: 320
property int preferredHeight: 240
property int preferredHeight: 500
property int btnSize: 40
property int offset: 3
......@@ -56,6 +57,7 @@ Popup {
function openRecorder(vid) {
isVideo = vid;
isAudio = !vid && !isPhoto;
updateState(RecordBox.States.INIT);
if (isVideo) {
localVideo.startWithId(VideoDevices.getDefaultDevice());
......@@ -136,260 +138,315 @@ Popup {
}
}
background: Item {
} // Computed by id: box, to do the layer on LocalVideo
width: preferredWidth
height: isVideo ? previewWidget.height + 80 : preferredHeight
Rectangle {
id: box
id: boxBackground
radius: 5
anchors.fill: parent
color: JamiTheme.backgroundColor
PushButton {
id: cancelBtn
objectName: "cancelBtn"
z: 1
normalColor: "transparent"
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
preferredSize: 12
source: JamiResources.round_close_24dp_svg
toolTipText: JamiStrings.back
anchors.right: box.right
anchors.top: box.top
anchors.margins: 8
focusPolicy: Qt.TabFocus
onClicked: {
closeRecorder();
updateState(RecordBox.States.INIT);
}
}
Item {
// Else it will be resized by the layer effect
id: photoMask
visible: false
anchors.fill: parent
Rectangle {
anchors.centerIn: parent
height: parent.height
width: parent.height
radius: height / 2
}
}
width: 300
height: 300
Rectangle {
id: rectBox
visible: false
anchors.fill: parent
radius: 5
}
ColumnLayout {
id: recordItem
anchors.fill: parent
spacing: 0
Layout.alignment: Qt.AlignTop
radius: 5
id: previewWidget
anchors.centerIn: parent
height: root.isAudio ? 100 : 300
width: 300
color: root.isAudio ? JamiTheme.secondaryBackgroundColor : "transparent"
// Video
Image {
id: screenshotImg
visible: root.showVideo && root.isPhoto && btnSend.visible
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
sourceSize.width: parent.width
sourceSize.height: width * localVideo.invAspectRatio
anchors.fill: parent
fillMode: Image.PreserveAspectCrop // Ajuste l'image tout en préservant l'aspect
source: root.photo === "" ? "" : "data:image/png;base64," + root.photo
}
// video Preview
Rectangle {
id: previewWidget
LocalVideo {
id: localVideo
anchors.fill: parent
visible: root.showVideo && !screenshotImg.visible
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
height: localVideo.width * localVideo.invAspectRatio
width: parent.width
color: JamiTheme.primaryForegroundColor
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
LocalVideo {
id: localVideo
Rectangle {
id: rectBox
visible: false
anchors.fill: parent
radius: 5
}
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
Rectangle {
anchors.fill: parent
color: "black"
opacity: 0.6
visible: root.isPhoto
radius: 5
layer.enabled: true
layer.effect: OpacityMask {
anchors.centerIn: parent
maskSource: photoMask
invert: true
}
Item {
// Else it will be resized by the layer effect
id: photoMask
visible: false
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "black"
opacity: 0.6
visible: root.isPhoto
layer.enabled: true
layer.effect: OpacityMask {
anchors.centerIn: parent
maskSource: photoMask
invert: true
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 20
height: 200
width: 200
radius: height / 2
}
}
}
RowLayout {
id: controls
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
spacing: 24
Layout.bottomMargin: isVideo ? 8 : 0
ColumnLayout{
id: mainLayout
PushButton {
id: recordButton
objectName: "recordButton"
Layout.alignment: Qt.AlignCenter
anchors.fill: parent
Component.onCompleted: print("mainLayout width: " + width + " height: " + height)
preferredSize: btnSize
JamiPushButton {
id: cancelBtn
objectName: "cancelBtn"
z: 1
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 20
Layout.preferredWidth: 20
Layout.topMargin: 5
Layout.rightMargin: 5
source: JamiResources.fiber_manual_record_24dp_svg
imageColor: JamiTheme.recordIconColor
imageColor: hovered ? JamiTheme.whiteColor : JamiTheme.recordBoxcloseButtonColor
normalColor: "transparent"
hoveredColor: JamiTheme.recordBoxHoverColor
source: JamiResources.round_close_24dp_svg
toolTipText: JamiStrings.back
focusPolicy: Qt.TabFocus
onClicked: {
updateState(RecordBox.States.RECORDING);
if (!root.isPhoto)
startRecording();
closeRecorder();
updateState(RecordBox.States.INIT);
}
}
PushButton {
id: screenshotBtn
objectName: "screenshotBtn"
Layout.alignment: Qt.AlignCenter
RowLayout {
id: controls
preferredSize: btnSize
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.fillWidth: true
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
border.width: 1
border.color: imageColor
spacing: 2
Layout.bottomMargin: 20//isVideo ? 8 : 0
Component.onCompleted: print("controls width: " + width + " height: " + height)
source: JamiResources.fiber_manual_record_24dp_svg
imageColor: UtilsAdapter.luma(JamiTheme.backgroundColor) ? "white" : JamiTheme.redColor
JamiPushButton {
id: recordButton
focusPolicy: Qt.TabFocus
onClicked: {
root.photo = videoProvider.captureVideoFrame(VideoDevices.getDefaultDevice());
updateState(RecordBox.States.REC_SUCCESS);
objectName: "recordButton"
Layout.alignment: Qt.AlignCenter
preferredSize: btnSize
source: JamiResources.record_black_24dp_svg
imageColor: JamiTheme.whiteColor
imageContainerHeight: 20
imageContainerWidth: 20
focusPolicy: Qt.TabFocus
background: RoundedBorderRectangle {
opacity: recordButton.hovered ? 1 : 0.7
fillColor: recordButton.hovered ? JamiTheme.recordBoxHoverColor : JamiTheme.recordBoxButtonColor
radius: {
"tl": 5,
"tr": root.isAudio ? 0 : 5,
"br": root.isAudio ? 0 : 5,
"bl": 5
}
}
onClicked: {
updateState(RecordBox.States.RECORDING);
if (!root.isPhoto)
startRecording();
}
}
}
JamiPushButton {
id: screenshotBtn
objectName: "screenshotBtn"
PushButton {
id: btnStop
objectName: "btnStop"
Layout.alignment: Qt.AlignCenter
Layout.alignment: Qt.AlignCenter
preferredSize: btnSize
preferredSize: btnSize
normalColor: JamiTheme.screenshotButtonColor
hoveredColor: JamiTheme.screenshotButtonColor
background.opacity: hovered ? 1 : 0.5
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
source: JamiResources.record_round_black_24dp_svg
source: JamiResources.stop_24dp_red_svg
imageColor: UtilsAdapter.luma(JamiTheme.backgroundColor) ? "white" : JamiTheme.buttonTintedBlue
border.width: 1
border.color: imageColor
imageColor: JamiTheme.whiteColor
imageContainerHeight: 25
imageContainerWidth: 25
focusPolicy: Qt.TabFocus
focusPolicy: Qt.TabFocus
onClicked: {
if (!root.isPhoto)
stopRecording();
updateState(RecordBox.States.REC_SUCCESS);
onClicked: {
root.photo = videoProvider.captureVideoFrame(VideoDevices.getDefaultDevice());
updateState(RecordBox.States.REC_SUCCESS);
}
}
}
PushButton {
id: btnRestart
objectName: "btnRestart"
Layout.alignment: Qt.AlignCenter
PushButton {
id: btnStop
objectName: "btnStop"
preferredSize: btnSize
Layout.alignment: Qt.AlignCenter
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.stop_rectangle_24dp_svg
source: JamiResources.re_record_24dp_svg
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
imageColor: UtilsAdapter.luma(JamiTheme.backgroundColor) ? "white" : JamiTheme.buttonTintedBlue
border.width: 1
border.color: imageColor
imageColor: JamiTheme.whiteColor
imageContainerHeight: 20
imageContainerWidth: 20
focusPolicy: Qt.TabFocus
onClicked: {
if (!root.isPhoto)
stopRecording();
updateState(RecordBox.States.INIT);
focusPolicy: Qt.TabFocus
background: RoundedBorderRectangle {
opacity: btnStop.hovered ? 1 : 0.7
fillColor: btnStop.hovered ? JamiTheme.recordBoxHoverColor : JamiTheme.recordBoxButtonColor
radius: {
"tl": 5,
"tr": 0,
"br": 0,
"bl": 5
}
}
onClicked: {
if (!root.isPhoto)
stopRecording();
updateState(RecordBox.States.REC_SUCCESS);
}
}
}
PushButton {
id: btnSend
objectName: "btnSend"
Layout.alignment: Qt.AlignCenter
JamiPushButton {
id: btnRestart
preferredSize: btnSize
objectName: "btnRestart"
Layout.alignment: Qt.AlignCenter
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.restart_black_24dp_svg
source: JamiResources.check_black_24dp_svg
imageColor: UtilsAdapter.luma(JamiTheme.backgroundColor) ? "white" : JamiTheme.buttonTintedBlue
border.width: 1
border.color: imageColor
imageColor: JamiTheme.whiteColor
imageContainerHeight: 25
imageContainerWidth: 25
focusPolicy: Qt.TabFocus
onClicked: {
if (!root.isPhoto) {
stopRecording();
sendRecord();
} else if (root.photo !== "") {
root.validatePhoto(root.photo);
focusPolicy: Qt.TabFocus
background: RoundedBorderRectangle {
opacity: btnRestart.hovered ? 1 : 0.7
fillColor: btnRestart.hovered ? JamiTheme.recordBoxHoverColor : JamiTheme.recordBoxButtonColor
radius: {
"tl": 5,
"tr": 0,
"br": 0,
"bl": 5
}
}
onClicked: {
if (!root.isPhoto)
stopRecording();
updateState(RecordBox.States.INIT);
}
closeRecorder();
updateState(RecordBox.States.INIT);
}
}
Timer {
id: timer
JamiPushButton {
id: btnSend
interval: 1000
running: false
repeat: true
objectName: "btnSend"
Layout.alignment: Qt.AlignCenter
preferredSize: btnSize
onTriggered: updateTimer()
}
imageColor: JamiTheme.whiteColor
imageContainerHeight: 25
imageContainerWidth: 25
source: JamiResources.check_circle_24dp_svg
focusPolicy: Qt.TabFocus
Text {
id: time
background: RoundedBorderRectangle {
opacity: btnSend.hovered ? 1 : 0.7
fillColor: btnSend.hovered ? JamiTheme.recordBoxHoverColor : JamiTheme.recordBoxButtonColor
radius: {
"tl": 0,
"tr": root.isPhoto ? 5 : 0,
"br": root.isPhoto ? 5 : 0,
"bl": 0
}
}
Layout.alignment: Qt.AlignCenter
onClicked: {
if (!root.isPhoto) {
stopRecording();
sendRecord();
} else if (root.photo !== "") {
root.validatePhoto(root.photo);
}
closeRecorder();
updateState(RecordBox.States.INIT);
}
}
Timer {
id: timer
interval: 1000
running: false
repeat: true
onTriggered: updateTimer()
}
visible: !root.isPhoto
text: "00:00"
color: JamiTheme.textColor
font.pointSize: (isVideo ? 12 : 20)
RoundedBorderRectangle {
opacity: 0.7
fillColor: JamiTheme.recordBoxButtonColor
visible: (!recordButton.visible && !root.isPhoto) || root.isAudio
Layout.preferredHeight: btnSend.height
Layout.preferredWidth: time.width + 20
radius: {
"tl": 0,
"tr": 5,
"br": 5,
"bl": 0
}
Text {
id: time
anchors.centerIn: parent
opacity: 1
text: "00:00"
color: JamiTheme.whiteColor
font.pointSize: (isVideo ? 12 : 20)
}
}
}
}
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment