Skip to content
Snippets Groups Projects
PhotoboothView.qml 8.25 KiB
Newer Older
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
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 alias saveToConfig: avatarImg.saveToConfig
    property string fileName: ""

    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() {
        AccountAdapter.startPreviewing(false)
        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.FromBase64)
            avatarImg.enableAnimation = true
        else
            avatarImg.enableAnimation = false

        if (mode === AvatarImage.Mode.Default) {
            avatarImg.updateImage(imageId)
            return
        }

        if (imageId)
            avatarImg.updateImage(imageId)
    function manualSaveToConfig() {
        avatarImg.saveAvatarToConfig()
    }

    onVisibleChanged: {
        if(!visible){
            stopBooth()
        }
    }

    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
                SettingsAdapter.clearCurrentAvatar()
                setAvatarImage()

            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
Sébastien Blin's avatar
Sébastien Blin committed
            radius: height / 2
                id: avatarImg

                anchors.fill: parent
                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
                    if (mode === AvatarImage.Mode.FromBase64)
                        photoState = PhotoboothView.PhotoState.Taken
                    if (photoState === PhotoboothView.PhotoState.Taken) {
                        avatarImg.state = ""
                        avatarImg.state = "flashIn"
                    }
                }

                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
        lrcInstance: LRCInstance

        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
            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 {
                    setAvatarImage(AvatarImage.Mode.FromBase64,
                                   previewWidget.takePhoto(boothWidth))
            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()
            }
        }
    }
}