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

281 lines
7.3 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.0
import net.jami.Models 1.0
ColumnLayout{
property bool takePhotoState: false
property bool hasAvatar: false
property bool isDefaultIcon: false
property string imgBase64: ""
property string fileName: ""
property int boothWidht: 224
signal imageAcquired
signal imageCleared
function startBooth(force = false){
hasAvatar = false
ClientWrapper.accountAdaptor.startPreviewing(force)
takePhotoState = true
}
function stopBooth(){
try{
if(!ClientWrapper.accountAdaptor.hasVideoCall()) {
ClientWrapper.accountAdaptor.stopPreviewing()
}
} catch(erro){console.log("Exception: " + erro.message)}
takePhotoState = false
}
function setAvatarPixmap(avatarPixmapBase64, defaultValue = false){
imgBase64 = avatarPixmapBase64
stopBooth()
if(defaultValue){
isDefaultIcon = defaultValue
}
}
onVisibleChanged: {
if(!visible){
stopBooth()
}
}
JamiFileDialog{
id: importFromFileToAvatar_Dialog
mode: JamiFileDialog.OpenFile
title: qsTr("Choose an image to be the avatar")
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
nameFilters: [ qsTr("Image Files") + " (*.png *.jpg *.jpeg)",qsTr(
"All files") + " (*)"]
onAccepted: {
fileName = file
if(fileName.length === 0) {
imageCleared()
return
}
imgBase64 = ClientWrapper.utilsAdaptor.getCroppedImageBase64FromFile(
ClientWrapper.utilsAdaptor.getAbsPath(fileName),boothWidht)
imageAcquired()
stopBooth()
}
}
spacing: 0
Layout.maximumWidth: boothWidht
Layout.preferredWidth: boothWidht
Layout.minimumWidth: boothWidht
Layout.maximumHeight: 0
Layout.alignment: Qt.AlignHCenter
Label{
id: avatarLabel
visible: !takePhotoState
Layout.maximumWidth: boothWidht
Layout.preferredWidth: boothWidht
Layout.minimumWidth: boothWidht
Layout.maximumHeight: boothWidht
Layout.preferredHeight: boothWidht
Layout.minimumHeight: boothWidht
Layout.alignment: Qt.AlignHCenter
background: Rectangle {
id: avatarLabelBackground
anchors.fill: parent
color: "transparent"
Image{
id: avatarImg
anchors.fill: parent
source: {
if(imgBase64.length === 0){
return ""
} else {
return "data:image/png;base64," + imgBase64
}
}
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
}
}
}
}
}
}
PhotoboothPreviewRender{
id:previewWidget
onHideBooth:{
stopBooth()
}
visible: takePhotoState
focus: visible
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: boothWidht
Layout.preferredWidth: boothWidht
Layout.minimumWidth: boothWidht
Layout.maximumHeight: boothWidht
Layout.preferredHeight: boothWidht
Layout.minimumHeight: boothWidht
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
}
}
}
Label{
id: flashOverlay
anchors.fill: previewWidget
visible: false
color: "#fff"
OpacityAnimator on opacity{
id: flashAnimation
from: 1
to: 0
duration: 600
}
}
}
RowLayout{
Layout.fillWidth: true
Layout.minimumHeight: 30
Layout.maximumHeight: 30
Item{
Layout.fillWidth: true
Layout.fillHeight: true
}
HoverableButton {
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.maximumWidth: 30
Layout.preferredWidth: 30
Layout.minimumWidth: 30
Layout.minimumHeight: 30
Layout.preferredHeight: 30
Layout.maximumHeight: 30
text: ""
font.pointSize: 10
font.kerning: true
radius: height / 6
source: {
if(isDefaultIcon){
return addPhotoIconUrl
}
if(takePhotoState) {
return cameraAltIconUrl
}
if(hasAvatar){
return refreshIconUrl
} else {
return addPhotoIconUrl
}
}
onClicked: {
if(!takePhotoState){
imageCleared()
startBooth()
return
} else {
// show flash overlay
flashOverlay.visible = true
flashAnimation.restart()
// run concurrent function call to take photo
imgBase64 = previewWidget.takeCroppedPhotoToBase64(boothWidht)
hasAvatar = true
imageAcquired()
stopBooth()
}
}
}
Item{
Layout.fillHeight: true
Layout.minimumWidth: 6
Layout.preferredWidth: 6
Layout.maximumWidth: 6
}
HoverableButton {
id: importButton
Layout.maximumWidth: 30
Layout.preferredWidth: 30
Layout.minimumWidth: 30
Layout.minimumHeight: 30
Layout.preferredHeight: 30
Layout.maximumHeight: 30
text: ""
font.pointSize: 10
font.kerning: true
radius: height / 6
source: "qrc:/images/icons/round-folder-24px.svg"
onClicked: {
importFromFileToAvatar_Dialog.open()
}
}
Item{
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}