1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-08-04 14:55:43 +02:00
jami-client-qt/src/commoncomponents/PhotoboothView.qml

296 lines
8.8 KiB
QML
Raw Normal View History

import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls.Styles 1.4
import Qt.labs.platform 1.1
import QtGraphicalEffects 1.14
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import net.jami.Constants 1.0
ColumnLayout {
property int photoState: PhotoboothView.PhotoState.Default
property bool avatarSet: false
// saveToConfig is to specify whether the image should be saved to account config
property bool saveToConfig: false
property string fileName: ""
property var boothImg: ""
property int boothWidth: 224
enum PhotoState {
Default = 0,
CameraRendering,
Taken
}
readonly property int size: boothWidth +
buttonsRowLayout.height +
JamiTheme.preferredMarginSize / 2
function initUI(useDefaultAvatar = true) {
photoState = PhotoboothView.PhotoState.Default
avatarSet = false
if (useDefaultAvatar)
setAvatarImage(AvatarImage.Mode.Default, "")
}
function startBooth(force = false) {
AccountAdapter.startPreviewing(force)
photoState = PhotoboothView.PhotoState.CameraRendering
}
function stopBooth(){
try{
if(!AccountAdapter.hasVideoCall()) {
AccountAdapter.stopPreviewing()
}
} catch(erro){console.log("Exception: " + erro.message)}
}
function setAvatarImage(mode = AvatarImage.Mode.FromAccount,
imageId = AccountAdapter.currentAccountId){
if (mode !== AvatarImage.Mode.FromUrl)
avatarImg.enableAnimation = true
else
avatarImg.enableAnimation = false
avatarImg.mode = mode
if (mode === AvatarImage.Mode.Default) {
boothImg = ""
avatarImg.updateImage(imageId)
return
}
if (imageId)
avatarImg.updateImage(imageId)
}
onVisibleChanged: {
if(!visible){
stopBooth()
}
}
spacing: 0
JamiFileDialog{
id: importFromFileToAvatar_Dialog
mode: JamiFileDialog.OpenFile
title: JamiStrings.chooseAvatarImage
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
nameFilters: [ qsTr("Image Files") + " (*.png *.jpg *.jpeg)",qsTr(
"All files") + " (*)"]
onAccepted: {
avatarSet = true
photoState = PhotoboothView.PhotoState.Default
fileName = file
if (fileName.length === 0) {
SettingsAdapter.clearCurrentAvatar()
setAvatarImage()
return
}
setAvatarImage(AvatarImage.Mode.FromFile,
UtilsAdapter.getAbsPath(fileName))
}
}
Label {
id: avatarLabel
visible: photoState !== PhotoboothView.PhotoState.CameraRendering
Layout.fillWidth: true
Layout.maximumWidth: boothWidth
Layout.preferredHeight: boothWidth
Layout.alignment: Qt.AlignHCenter
background: Rectangle {
id: avatarLabelBackground
anchors.fill: parent
color: "white"
radius: height / 2
AvatarImage {
id: avatarImg
anchors.fill: parent
showPresenceIndicator: false
fillMode: Image.PreserveAspectCrop
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: avatarImg.width
height: avatarImg.height
radius: {
var size = ((avatarImg.width <= avatarImg.height) ?
avatarImg.width:avatarImg.height)
return size / 2
}
}
}
onImageIsReady: {
if (mode === AvatarImage.Mode.FromUrl)
photoState = PhotoboothView.PhotoState.Taken
if (photoState === PhotoboothView.PhotoState.Taken) {
avatarImg.state = ""
avatarImg.state = "flashIn"
} else {
// Once image is loaded (updated), save to boothImg (choose from file)
avatarImg.grabToImage(function(result) {
if (mode !== AvatarImage.Mode.Default)
boothImg = result.image
if (saveToConfig)
SettingsAdapter.setCurrAccAvatar(result.image)
})
}
}
onOpacityChanged: {
if (avatarImg.state === "flashIn" && opacity === 0)
avatarImg.state = "flashOut"
}
states: [
State {
name: "flashIn"
PropertyChanges { target: avatarImg; opacity: 0}
}, State {
name: "flashOut"
PropertyChanges { target: avatarImg; opacity: 1}
}]
transitions: Transition {
NumberAnimation {
properties: "opacity"
easing.type: Easing.Linear
duration: 100
}
}
}
}
}
PhotoboothPreviewRender {
id:previewWidget
onHideBooth: stopBooth()
visible: photoState === PhotoboothView.PhotoState.CameraRendering
focus: visible
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: boothWidth
Layout.preferredHeight: boothWidth
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: previewWidget.width
height: previewWidget.height
radius: {
var size = ((previewWidget.width <= previewWidget.height) ?
previewWidget.width:previewWidget.height)
return size / 2
}
}
}
}
RowLayout {
id: buttonsRowLayout
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.topMargin: JamiTheme.preferredMarginSize / 2
PushButton {
id: takePhotoButton
property string cameraAltIconUrl: "qrc:/images/icons/baseline-camera_alt-24px.svg"
property string addPhotoIconUrl: "qrc:/images/icons/round-add_a_photo-24px.svg"
property string refreshIconUrl: "qrc:/images/icons/baseline-refresh-24px.svg"
Layout.alignment: Qt.AlignHCenter
text: ""
font.pointSize: 10
font.kerning: true
imageColor: JamiTheme.textColor
toolTipText: JamiStrings.takePhoto
radius: height / 6
source: {
if(photoState === PhotoboothView.PhotoState.Default) {
toolTipText = qsTr("Take photo")
return cameraAltIconUrl
}
if(photoState === PhotoboothView.PhotoState.Taken){
toolTipText = qsTr("Retake photo")
return refreshIconUrl
} else {
toolTipText = qsTr("Take photo")
return addPhotoIconUrl
}
}
onClicked: {
if(photoState !== PhotoboothView.PhotoState.CameraRendering){
startBooth()
return
} else {
previewWidget.grabToImage(function(result) {
boothImg = result.image
if (saveToConfig)
SettingsAdapter.setCurrAccAvatar(result.image)
setAvatarImage(AvatarImage.Mode.FromUrl, result.url)
avatarSet = true
stopBooth()
})
}
}
}
PushButton {
id: importButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignHCenter
text: ""
font.pointSize: 10
font.kerning: true
radius: height / 6
source: "qrc:/images/icons/round-folder-24px.svg"
toolTipText: JamiStrings.importFromFile
imageColor: JamiTheme.textColor
onClicked: {
importFromFileToAvatar_Dialog.open()
}
}
}
}