Warning, /graphics/spectacle/src/Gui/VideoCaptureOverlay.qml is written in an unsupported language. File is not indexed.
0001 /* SPDX-FileCopyrightText: 2023 Noah Davis <noahadvs@gmail.com> 0002 * SPDX-License-Identifier: LGPL-2.0-or-later 0003 */ 0004 0005 import QtQuick 0006 import QtQuick.Window 0007 import QtQuick.Layouts 0008 import QtQuick.Controls as QQC 0009 import org.kde.kirigami as Kirigami 0010 import org.kde.spectacle.private 0011 0012 MouseArea { 0013 id: root 0014 readonly property rect viewportRect: G.mapFromPlatformRect(screenToFollow.geometry, 0015 screenToFollow.devicePixelRatio) 0016 focus: true 0017 acceptedButtons: Qt.LeftButton | Qt.RightButton 0018 hoverEnabled: true 0019 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft 0020 LayoutMirroring.childrenInherit: true 0021 anchors.fill: parent 0022 enabled: !VideoPlatform.isRecording 0023 0024 component Overlay: Rectangle { 0025 color: Settings.useLightMaskColor ? "white" : "black" 0026 opacity: if (VideoPlatform.isRecording) { 0027 return 0 0028 } else if (Selection.empty) { 0029 return 0.25 0030 } else { 0031 return 0.5 0032 } 0033 LayoutMirroring.enabled: false 0034 Behavior on opacity { 0035 NumberAnimation { 0036 duration: Kirigami.Units.longDuration 0037 easing.type: Easing.OutCubic 0038 } 0039 } 0040 } 0041 Overlay { // top / full overlay when nothing selected 0042 id: topOverlay 0043 anchors.top: parent.top 0044 anchors.left: parent.left 0045 anchors.right: parent.right 0046 anchors.bottom: selectionRectangle.visible ? selectionRectangle.top : parent.bottom 0047 } 0048 Overlay { // bottom 0049 id: bottomOverlay 0050 anchors.left: parent.left 0051 anchors.top: selectionRectangle.visible ? selectionRectangle.bottom : undefined 0052 anchors.right: parent.right 0053 anchors.bottom: parent.bottom 0054 visible: selectionRectangle.visible && height > 0 0055 } 0056 Overlay { // left 0057 anchors { 0058 left: topOverlay.left 0059 top: topOverlay.bottom 0060 right: selectionRectangle.visible ? selectionRectangle.left : undefined 0061 bottom: bottomOverlay.top 0062 } 0063 visible: selectionRectangle.visible && height > 0 && width > 0 0064 } 0065 Overlay { // right 0066 anchors { 0067 left: selectionRectangle.visible ? selectionRectangle.right : undefined 0068 top: topOverlay.bottom 0069 right: topOverlay.right 0070 bottom: bottomOverlay.top 0071 } 0072 visible: selectionRectangle.visible && height > 0 && width > 0 0073 } 0074 0075 Rectangle { 0076 id: selectionRectangle 0077 color: "transparent" 0078 border.color: palette.active.highlight 0079 border.width: contextWindow.dprRound(1) 0080 visible: !Selection.empty 0081 && !VideoPlatform.isRecording 0082 && G.rectIntersects(Qt.rect(x,y,width,height), Qt.rect(0,0,parent.width, parent.height)) 0083 x: Selection.x - border.width - root.viewportRect.x 0084 y: Selection.y - border.width - root.viewportRect.y 0085 width: Selection.width + border.width * 2 0086 height: Selection.height + border.width * 2 0087 0088 LayoutMirroring.enabled: false 0089 LayoutMirroring.childrenInherit: true 0090 } 0091 0092 SelectionBackground { 0093 visible: VideoPlatform.isRecording 0094 strokeWidth: selectionRectangle.border.width 0095 // We need to be a bit careful about staying out of the recorded area 0096 x: dprRound(Math.floor(Selection.x - strokeWidth - root.viewportRect.x)) 0097 y: dprRound(Math.floor(Selection.y - strokeWidth - root.viewportRect.y)) 0098 width: dprRound(Math.ceil(Selection.width + strokeWidth * 2)) 0099 height: dprRound(Math.ceil(Selection.height + strokeWidth * 2)) 0100 } 0101 0102 Item { 0103 x: -root.viewportRect.x 0104 y: -root.viewportRect.y 0105 enabled: selectionRectangle.enabled 0106 visible: !VideoPlatform.isRecording 0107 component Handle: Rectangle { 0108 visible: enabled && selectionRectangle.visible 0109 && SelectionEditor.dragLocation === SelectionEditor.None 0110 && G.rectIntersects(Qt.rect(x,y,width,height), root.viewportRect) 0111 color: selectionRectangle.color 0112 width: Kirigami.Units.gridUnit 0113 height: width 0114 radius: width / 2 0115 } 0116 0117 Handle { 0118 x: SelectionEditor.handlesRect.x 0119 y: SelectionEditor.handlesRect.y 0120 } 0121 Handle { 0122 x: SelectionEditor.handlesRect.x 0123 y: SelectionEditor.handlesRect.y + SelectionEditor.handlesRect.height/2 - height/2 0124 } 0125 Handle { 0126 x: SelectionEditor.handlesRect.x 0127 y: SelectionEditor.handlesRect.y + SelectionEditor.handlesRect.height - height 0128 } 0129 Handle { 0130 x: SelectionEditor.handlesRect.x + SelectionEditor.handlesRect.width/2 - width/2 0131 y: SelectionEditor.handlesRect.y 0132 } 0133 Handle { 0134 x: SelectionEditor.handlesRect.x + SelectionEditor.handlesRect.width/2 - width/2 0135 y: SelectionEditor.handlesRect.y + SelectionEditor.handlesRect.height - height 0136 } 0137 Handle { 0138 x: SelectionEditor.handlesRect.x + SelectionEditor.handlesRect.width - width 0139 y: SelectionEditor.handlesRect.y + SelectionEditor.handlesRect.height/2 - height/2 0140 } 0141 Handle { 0142 x: SelectionEditor.handlesRect.x + SelectionEditor.handlesRect.width - width 0143 y: SelectionEditor.handlesRect.y 0144 } 0145 Handle { 0146 x: SelectionEditor.handlesRect.x + SelectionEditor.handlesRect.width - width 0147 y: SelectionEditor.handlesRect.y + SelectionEditor.handlesRect.height - height 0148 } 0149 } 0150 0151 Item { // separate item because it needs to be above the stuff defined above 0152 visible: !VideoPlatform.isRecording 0153 width: SelectionEditor.screensRect.width 0154 height: SelectionEditor.screensRect.height 0155 x: -root.viewportRect.x 0156 y: -root.viewportRect.y 0157 0158 // Size ToolTip 0159 SizeLabel { 0160 id: ssToolTip 0161 readonly property int valignment: { 0162 if (Selection.empty) { 0163 return Qt.AlignVCenter 0164 } 0165 const margin = Kirigami.Units.mediumSpacing * 2 0166 const w = width + margin 0167 const h = height + margin 0168 if (SelectionEditor.handlesRect.top >= h) { 0169 return Qt.AlignTop 0170 } else if (SelectionEditor.screensRect.height - SelectionEditor.handlesRect.bottom >= h) { 0171 return Qt.AlignBottom 0172 } else { 0173 // At the bottom of the inside of the selection rect. 0174 return Qt.AlignBaseline 0175 } 0176 } 0177 readonly property bool normallyVisible: !Selection.empty 0178 Binding on x { 0179 value: contextWindow.dprRound(Selection.horizontalCenter - ssToolTip.width / 2) 0180 when: ssToolTip.normallyVisible 0181 restoreMode: Binding.RestoreNone 0182 } 0183 Binding on y { 0184 value: { 0185 let v = 0 0186 if (ssToolTip.valignment & Qt.AlignBaseline) { 0187 v = Math.min(Selection.bottom, SelectionEditor.handlesRect.bottom - Kirigami.Units.gridUnit) 0188 - ssToolTip.height - Kirigami.Units.mediumSpacing * 2 0189 } else if (ssToolTip.valignment & Qt.AlignTop) { 0190 v = SelectionEditor.handlesRect.top 0191 - ssToolTip.height - Kirigami.Units.mediumSpacing * 2 0192 } else if (ssToolTip.valignment & Qt.AlignBottom) { 0193 v = SelectionEditor.handlesRect.bottom + Kirigami.Units.mediumSpacing * 2 0194 } else { 0195 v = (root.height - ssToolTip.height) / 2 - parent.y 0196 } 0197 return contextWindow.dprRound(v) 0198 } 0199 when: ssToolTip.normallyVisible 0200 restoreMode: Binding.RestoreNone 0201 } 0202 visible: opacity > 0 0203 opacity: ssToolTip.normallyVisible 0204 && G.rectIntersects(Qt.rect(x,y,width,height), root.viewportRect) 0205 Behavior on opacity { 0206 NumberAnimation { 0207 duration: Kirigami.Units.longDuration 0208 easing.type: Easing.OutCubic 0209 } 0210 } 0211 size: G.rawSize(Selection.size, SelectionEditor.devicePixelRatio) // TODO: real pixel size on wayland 0212 padding: Kirigami.Units.mediumSpacing * 2 0213 topPadding: padding - QmlUtils.fontMetrics.descent 0214 bottomPadding: topPadding 0215 background: FloatingBackground { 0216 implicitWidth: Math.ceil(parent.contentWidth) + parent.leftPadding + parent.rightPadding 0217 implicitHeight: Math.ceil(parent.contentHeight) + parent.topPadding + parent.bottomPadding 0218 color: Qt.rgba(parent.palette.window.r, 0219 parent.palette.window.g, 0220 parent.palette.window.b, 0.85) 0221 border.color: Qt.rgba(parent.palette.windowText.r, 0222 parent.palette.windowText.g, 0223 parent.palette.windowText.b, 0.2) 0224 border.width: contextWindow.dprRound(1) 0225 } 0226 } 0227 } 0228 }