diff --git a/src/app/mainview/components/ScreensharingElementPreview.qml b/src/app/mainview/components/ScreensharingElementPreview.qml new file mode 100644 index 0000000000000000000000000000000000000000..024fc4b01604ec2f65e5e1b7852e90b6160ac76d --- /dev/null +++ b/src/app/mainview/components/ScreensharingElementPreview.qml @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 Savoir-faire Linux Inc. + * Author: Nicolas Vengeon <Nicolas.vengeon@savoirfairelinux.com> + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import net.jami.Adapters 1.1 +import net.jami.Models 1.1 +import net.jami.Constants 1.1 + +import "../../commoncomponents" + +Rectangle { + id: root + + color: JamiTheme.secondaryBackgroundColor + border.color: selectedScreenNumber === elementIndex ? JamiTheme.screenSelectionBorderColor : JamiTheme.tabbarBorderColor + + width: elementWidth + height: 3 * width / 4 + + property var elementIndex + property string rectTitle + property var rId + property bool isSelectAllScreens + + Text { + id: textTitle + + anchors.top: root.top + anchors.topMargin: marginSize + anchors.horizontalCenter: root.horizontalCenter + width: root.width - 2 * marginSize + + font.pointSize: JamiTheme.textFontSize + text: rectTitle + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + color: JamiTheme.textColor + } + + VideoView { + anchors.top: textTitle.bottom + anchors.topMargin: 10 + anchors.horizontalCenter: root.horizontalCenter + height: root.height - 50 + width: root.width - 50 + + Component.onDestruction: { + VideoDevices.stopDevice(rendererId) + } + Component.onCompleted: { + if (root.rId !== "") { + rendererId = VideoDevices.startDevice(root.rId) + } + } + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton + + onClicked: { + if (selectedScreenNumber !== root.elementIndex) { + selectedScreenNumber = root.elementIndex + } + } + } +} diff --git a/src/app/mainview/components/SelectScreen.qml b/src/app/mainview/components/SelectScreen.qml index dcd35feaa61d3c8c65798aed222783b8251d2d83..13cadcf904202d76d4dd6e96198aecaaab0193ad 100644 --- a/src/app/mainview/components/SelectScreen.qml +++ b/src/app/mainview/components/SelectScreen.qml @@ -1,8 +1,9 @@ /* - * Copyright (C) 2020-2022 Savoir-faire Linux Inc. + * Copyright (C) 2020-2023 Savoir-faire Linux Inc. * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> - * + * Author: Nicolas Vengeon <Nicolas.vengeon@savoirfairelinux.com> + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or @@ -35,371 +36,203 @@ import "../../commoncomponents" Window { id: root - property bool window: false + minimumHeight: minimumWidth * 3 / 4 + minimumWidth: componentMinWidth + 2 * marginSize + modality: Qt.ApplicationModal + title: window ? JamiStrings.selectWindow : JamiStrings.selectScreen - property int selectedScreenNumber: -1 - property bool selectAllScreens: false + property bool window: false + property int selectedScreenNumber: -2 + property bool selectAllScreens: selectedScreenNumber == -1 property string currentPreview: "" - property var screens: [] - property real componentMinWidth: 200 - property real componentWidthDoubleColumn: screenSelectionScrollView.width / 2 - - screenSelectionScrollViewFlow.spacing / 2 - JamiTheme.preferredMarginSize - property real componentWidthSingleColumn: screenSelectionScrollView.width - - 2 * JamiTheme.preferredMarginSize + property var listModel: [] + property real componentMinWidth: 350 + property real marginSize: JamiTheme.preferredMarginSize + property real elementWidth: { + var layoutWidth = selectScreenWindowLayout.width + var minSize = componentMinWidth + 2 * marginSize + var numberElementPerRow = Math.floor(layoutWidth / minSize) + if (numberElementPerRow == 1 && layoutWidth > componentMinWidth * 1.5) { + numberElementPerRow = 2 + } + if (window) + numberElementPerRow = Math.min(listModel.length, numberElementPerRow) + else + numberElementPerRow = Math.min(listModel.length + 1, numberElementPerRow) + var spacingLength = marginSize * (numberElementPerRow + 2) - modality: Qt.ApplicationModal - title: window ? JamiStrings.selectWindow : JamiStrings.selectScreen + return (layoutWidth - spacingLength) / numberElementPerRow + } - // How many rows the ScrollView should have. function calculateRepeaterModel() { - screens = [] + listModel = [] var idx - for (idx in Qt.application.screens) { - screens.push(JamiStrings.screen.arg(idx)) - } - AvAdapter.getListWindows() - for (idx in AvAdapter.windowsNames) { - screens.push(AvAdapter.windowsNames[idx]) + if (!root.window) { + for (idx in Qt.application.screens) { + listModel.push(JamiStrings.screen.arg(idx)) + } + } else { + AvAdapter.getListWindows() + for (idx in AvAdapter.windowsNames) { + listModel.push(AvAdapter.windowsNames[idx]) + } } - - return screens.length } onVisibleChanged: { if (!visible) return if (!active) { - selectedScreenNumber = -1 - selectAllScreens = false + selectedScreenNumber = -2 } screenInfo.model = {} - screenInfo2.model = {} calculateRepeaterModel() - screenInfo.model = screens.length - screenInfo2.model = screens.length - windowsText.visible = root.window + screenInfo.model = root.listModel } Rectangle { id: selectScreenWindowRect anchors.fill: parent - color: JamiTheme.backgroundColor - ScrollView { - id: screenSelectionScrollView + ColumnLayout { + id: selectScreenWindowLayout - anchors.topMargin: JamiTheme.preferredMarginSize - anchors.horizontalCenter: selectScreenWindowRect.horizontalCenter + anchors.fill: parent - width: selectScreenWindowRect.width - height: selectScreenWindowRect.height - - (selectButton.height + JamiTheme.preferredMarginSize * 4) + Text { + font.pointSize: JamiTheme.menuFontSize + font.bold: true + text: root.window ? JamiStrings.windows : JamiStrings.screens + verticalAlignment: Text.AlignBottom + color: JamiTheme.textColor + Layout.margins: marginSize + } - clip: true - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - ScrollBar.vertical.policy: ScrollBar.AlwaysOn + ScrollView { + id: screenSelectionScrollView - Flow { - id: screenSelectionScrollViewFlow + Layout.alignment: Qt.AlignCenter + Layout.preferredWidth: selectScreenWindowLayout.width + Layout.fillHeight: true - anchors.fill: parent - topPadding: JamiTheme.preferredMarginSize - rightPadding: JamiTheme.preferredMarginSize - leftPadding: JamiTheme.preferredMarginSize + clip: true + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + ScrollBar.vertical.policy: ScrollBar.AsNeeded - spacing: JamiTheme.preferredMarginSize + Flow { + id: screenSelectionScrollViewFlow - Text { + // https://bugreports.qt.io/browse/QTBUG-110323 width: screenSelectionScrollView.width - height: JamiTheme.preferredFieldHeight - - font.pointSize: JamiTheme.menuFontSize - font.bold: true - text: JamiStrings.screens - verticalAlignment: Text.AlignBottom - color: JamiTheme.textColor - visible: !root.window - } - - Repeater { - id: screenInfo + height: screenSelectionScrollView.height - model: screens ? screens.length : 0 + topPadding: marginSize + rightPadding: marginSize + leftPadding: marginSize + spacing: marginSize - delegate: Rectangle { - id: screenItem + ScreensharingElementPreview { + id: screenSelectionRectAll - color: JamiTheme.secondaryBackgroundColor + visible: !root.window && Qt.application.screens.length > 1 && Qt.platform.os.toString() !== "windows" + elementIndex: -1 + rectTitle: JamiStrings.allScreens + rId: AvAdapter.getSharingResource(-1, "") + isSelectAllScreens: true + } - width: componentWidthDoubleColumn > componentMinWidth ? componentWidthDoubleColumn : componentWidthSingleColumn - height: 3 * width / 4 - border.color: selectedScreenNumber === index ? JamiTheme.screenSelectionBorderColor : JamiTheme.tabbarBorderColor - visible: !root.window && JamiStrings.selectScreen !== screens[index] && index < Qt.application.screens.length + Repeater { + id: screenInfo - Text { - id: screenName - - anchors.top: screenItem.top - anchors.topMargin: 10 - anchors.horizontalCenter: screenItem.horizontalCenter - width: parent.width - font.pointSize: JamiTheme.textFontSize - text: screens[index] ? screens[index] : "" - elide: Text.ElideMiddle - horizontalAlignment: Text.AlignHCenter - color: JamiTheme.textColor - } + model: listModel.length - VideoView { - id: screenPreview + delegate: ScreensharingElementPreview { + id: screenItem - anchors.top: screenName.bottom - anchors.topMargin: 10 - anchors.horizontalCenter: screenItem.horizontalCenter - height: screenItem.height - 50 - width: screenItem.width - 50 - - Component.onDestruction: { - VideoDevices.stopDevice(rendererId) - } - Component.onCompleted: { - if (visible) { - const rId = AvAdapter.getSharingResource(index) - if (rId !== "") { - rendererId = VideoDevices.startDevice(rId) - } - } + visible: JamiStrings.selectScreen !== listModel[index] + elementIndex: index + rectTitle: listModel[index] ? listModel[index] : "" + rId: { + if (root.window) + return rId = AvAdapter.getSharingResource(-2, AvAdapter.windowsIds[index]) + return rId = AvAdapter.getSharingResource(index, "") } - } + isSelectAllScreens: false - MouseArea { - anchors.fill: screenItem - acceptedButtons: Qt.LeftButton + Connections { + target: AvAdapter - onClicked: { - selectAllScreens = false - if (selectedScreenNumber == -1 - || selectedScreenNumber !== index) { - selectedScreenNumber = index + function onScreenCaptured(screenNumber, source) { + if (screenNumber === -1 && !root.window) + screenShotAll.source = JamiQmlUtils.base64StringTitle + source } } } - - Connections { - target: AvAdapter - - function onScreenCaptured(screenNumber, source) { - if (screenNumber === -1) - screenShotAll.source = JamiQmlUtils.base64StringTitle + source - } - } } } + } - Rectangle { - id: screenSelectionRectAll - - color: JamiTheme.secondaryBackgroundColor - - width: componentWidthDoubleColumn > componentMinWidth ? componentWidthDoubleColumn : componentWidthSingleColumn - height: 3 * width / 4 - - border.color: selectAllScreens ? JamiTheme.screenSelectionBorderColor : JamiTheme.tabbarBorderColor - - visible: !root.window && Qt.application.screens.length > 1 && Qt.platform.os.toString() !== "windows" - - Text { - id: screenNameAll - - anchors.top: screenSelectionRectAll.top - anchors.topMargin: 10 - anchors.horizontalCenter: screenSelectionRectAll.horizontalCenter - - font.pointSize: JamiTheme.textFontSize - text: JamiStrings.allScreens - color: JamiTheme.textColor - } - - VideoView { - id: screenShotAll - - anchors.top: screenNameAll.bottom - anchors.topMargin: 10 - anchors.horizontalCenter: screenSelectionRectAll.horizontalCenter - height: screenSelectionRectAll.height - 50 - width: screenSelectionRectAll.width - 50 - - Component.onDestruction: { - VideoDevices.stopDevice(rendererId) - } - Component.onCompleted: { - if (visible) { - const rId = AvAdapter.getSharingResource(-1) - if (rId !== "") { - rendererId = VideoDevices.startDevice(rId) - } + RowLayout { + Layout.margins: marginSize + Layout.preferredWidth: selectScreenWindowLayout.width + Layout.preferredHeight: childrenRect.height + spacing: marginSize + + MaterialButton { + id: selectButton + + Layout.maximumWidth: 200 + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + Layout.leftMargin: marginSize + + enabled: selectedScreenNumber != -2 + opacity: enabled ? 1.0 : 0.5 + + color: JamiTheme.buttonTintedBlack + hoveredColor: JamiTheme.buttonTintedBlackHovered + pressedColor: JamiTheme.buttonTintedBlackPressed + secondary: true + autoAccelerator: true + + text: window ? JamiStrings.shareWindow : JamiStrings.shareScreen + + onClicked: { + if (selectAllScreens) + AvAdapter.shareAllScreens() + else { + if (!root.window) + AvAdapter.shareEntireScreen(selectedScreenNumber) + else { + AvAdapter.shareWindow(AvAdapter.windowsIds[selectedScreenNumber]) } } + root.close() } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - - onClicked: { - selectedScreenNumber = -1 - selectAllScreens = true - } - } - } - - Text { - id: windowsText - width: screenSelectionScrollView.width - height: JamiTheme.preferredFieldHeight - - font.pointSize: JamiTheme.menuFontSize - font.bold: true - text: JamiStrings.windows - verticalAlignment: Text.AlignBottom - color: JamiTheme.textColor - visible: root.window } - Repeater { - id: screenInfo2 + MaterialButton { + id: cancelButton - model: screens ? screens.length : 0 + Layout.maximumWidth: 200 + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + Layout.rightMargin: marginSize - delegate: Rectangle { - id: screenItem2 + color: JamiTheme.buttonTintedBlack + hoveredColor: JamiTheme.buttonTintedBlackHovered + pressedColor: JamiTheme.buttonTintedBlackPressed + secondary: true + autoAccelerator: true - color: JamiTheme.secondaryBackgroundColor + text: JamiStrings.optionCancel - width: componentWidthDoubleColumn > componentMinWidth ? componentWidthDoubleColumn : componentWidthSingleColumn - height: 3 * width / 4 - - border.color: selectedScreenNumber === index ? JamiTheme.screenSelectionBorderColor : JamiTheme.tabbarBorderColor - visible: root.window && JamiStrings.selectScreen !== screens[index] && index >= Qt.application.screens.length - - Text { - id: screenName2 - - anchors.top: screenItem2.top - anchors.topMargin: 10 - anchors.horizontalCenter: screenItem2.horizontalCenter - width: parent.width - font.pointSize: JamiTheme.textFontSize - text: screens[index] ? screens[index] : "" - elide: Text.ElideMiddle - horizontalAlignment: Text.AlignHCenter - color: JamiTheme.textColor - } - - VideoView { - id: screenPreview2 - - anchors.top: screenName2.bottom - anchors.topMargin: 10 - anchors.horizontalCenter: screenItem2.horizontalCenter - anchors.leftMargin: 25 - anchors.rightMargin: 25 - height: screenItem2.height - 60 - width: screenItem2.width - 50 - - Component.onDestruction: { - VideoDevices.stopDevice(rendererId) - } - Component.onCompleted: { - if (visible) { - const rId = AvAdapter.getSharingResource(-2, AvAdapter.windowsIds[index - Qt.application.screens.length], AvAdapter.windowsNames[index - Qt.application.screens.length]) - if (rId !== "") { - rendererId = VideoDevices.startDevice(rId) - } - } - } - } - - MouseArea { - anchors.fill: screenItem2 - acceptedButtons: Qt.LeftButton - - onClicked: { - selectAllScreens = false - if (selectedScreenNumber == -1 - || selectedScreenNumber !== index) { - selectedScreenNumber = index - } - } - } - } + onClicked: root.close() } } } } - - RowLayout { - anchors.bottom: selectScreenWindowRect.bottom - anchors.bottomMargin: JamiTheme.preferredMarginSize - anchors.horizontalCenter: selectScreenWindowRect.horizontalCenter - - width: parent.width - height: childrenRect.height - spacing: JamiTheme.preferredMarginSize - - MaterialButton { - id: selectButton - - Layout.maximumWidth: 200 - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - Layout.leftMargin: JamiTheme.preferredMarginSize - - enabled: selectedScreenNumber != -1 || selectAllScreens - opacity: enabled ? 1.0 : 0.5 - - color: JamiTheme.buttonTintedBlack - hoveredColor: JamiTheme.buttonTintedBlackHovered - pressedColor: JamiTheme.buttonTintedBlackPressed - secondary: true - autoAccelerator: true - - text: window ? JamiStrings.shareWindow : JamiStrings.shareScreen - - onClicked: { - if (selectAllScreens) - AvAdapter.shareAllScreens() - else { - if (selectedScreenNumber < Qt.application.screens.length) - AvAdapter.shareEntireScreen(selectedScreenNumber) - else { - AvAdapter.shareWindow(AvAdapter.windowsIds[selectedScreenNumber - Qt.application.screens.length], AvAdapter.windowsNames[selectedScreenNumber - Qt.application.screens.length]) - } - } - root.close() - } - } - - MaterialButton { - id: cancelButton - - Layout.maximumWidth: 200 - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - Layout.rightMargin: JamiTheme.preferredMarginSize - - color: JamiTheme.buttonTintedBlack - hoveredColor: JamiTheme.buttonTintedBlackHovered - pressedColor: JamiTheme.buttonTintedBlackPressed - secondary: true - autoAccelerator: true - - text: JamiStrings.optionCancel - - onClicked: root.close() - } - } }