Warning, /plasma/kscreen/kcm/ui/OutputPanel.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 import QtCore 0007 import QtQuick 2.15 0008 import QtQuick.Layouts 1.15 0009 import QtQuick.Controls 2.15 as QQC2 0010 import QtQuick.Dialogs 0011 import org.kde.kirigami 2.20 as Kirigami 0012 import org.kde.kitemmodels 1.0 0013 0014 import org.kde.kcmutils as KCM 0015 import org.kde.private.kcm.kscreen 1.0 as KScreen 0016 0017 Kirigami.FormLayout { 0018 id: root 0019 0020 property KSortFilterProxyModel enabledOutputs 0021 property var element: model 0022 0023 signal reorder() 0024 0025 QQC2.CheckBox { 0026 text: i18n("Enabled") 0027 checked: element.enabled 0028 onToggled: element.enabled = checked 0029 visible: kcm.multipleScreensAvailable 0030 } 0031 0032 RowLayout { 0033 visible: kcm.primaryOutputSupported && root.enabledOutputs.count >= 2 0034 0035 QQC2.Button { 0036 visible: root.enabledOutputs.count >= 3 0037 text: i18n("Change Screen Priorities…") 0038 icon.name: "document-edit" 0039 onClicked: root.reorder(); 0040 } 0041 0042 QQC2.RadioButton { 0043 visible: root.enabledOutputs.count === 2 0044 text: i18n("Primary") 0045 checked: element.priority === 1 0046 onToggled: element.priority = 1 0047 } 0048 0049 KCM.ContextualHelpButton { 0050 toolTipText: xi18nc("@info", "This determines which screen your main desktop appears on, along with any Plasma Panels in it. Some older games also use this setting to decide which screen to appear on.<nl/><nl/>It has no effect on what screen notifications or other windows appear on.") 0051 } 0052 } 0053 0054 RowLayout { 0055 Kirigami.FormData.label: i18n("Resolution:") 0056 0057 QQC2.ComboBox { 0058 id: resolutionCombobox 0059 Layout.minimumWidth: Kirigami.Units.gridUnit * 11 0060 visible: count > 1 0061 model: element.resolutions 0062 onActivated: element.resolutionIndex = currentIndex; 0063 Component.onCompleted: currentIndex = Qt.binding(function() {return element.resolutionIndex}); 0064 } 0065 // When the combobox is has only one item, it's basically non-interactive 0066 // and is serving purely in a descriptive role, so make this explicit by 0067 // using a label instead 0068 QQC2.Label { 0069 id: singleResolutionLabel 0070 visible: resolutionCombobox.count <= 1 0071 text: element.resolutions[0] || "" 0072 } 0073 KCM.ContextualHelpButton { 0074 visible: resolutionCombobox.count <= 1 0075 toolTipText: xi18nc("@info", ""%1" is the only resolution supported by this display.", singleResolutionLabel.text) 0076 } 0077 } 0078 0079 RowLayout { 0080 Layout.fillWidth: true 0081 // Set the same limit as the device ComboBox 0082 Layout.maximumWidth: Kirigami.Units.gridUnit * 16 0083 0084 visible: kcm.perOutputScaling 0085 Kirigami.FormData.label: i18n("Scale:") 0086 0087 QQC2.Slider { 0088 id: scaleSlider 0089 0090 Layout.fillWidth: true 0091 from: 0.5 0092 to: 3 0093 stepSize: 0.25 0094 live: true 0095 value: element.scale 0096 onMoved: element.scale = value 0097 } 0098 QQC2.SpinBox { 0099 id: spinbox 0100 // Because QQC2 SpinBox doesn't natively support decimal step 0101 // sizes: https://bugreports.qt.io/browse/QTBUG-67349 0102 readonly property real factor: 20.0 0103 readonly property real realValue: value / factor 0104 0105 from : 0.5 * factor 0106 to : 3.0 * factor 0107 stepSize: 1 0108 value: element.scale * factor 0109 validator: DoubleValidator { 0110 bottom: Math.min(spinbox.from, spinbox.to) * spinbox.factor 0111 top: Math.max(spinbox.from, spinbox.to) * spinbox.factor 0112 } 0113 textFromValue: (value, locale) => 0114 i18nc("Global scale factor expressed in percentage form", "%1%", 0115 parseFloat(value * 1.0 / factor * 100.0)) 0116 valueFromText: (text, locale) => 0117 Number.fromLocaleString(locale, text.replace("%", "")) * factor / 100.0 0118 0119 onValueModified: element.scale = realValue 0120 } 0121 } 0122 0123 Orientation {} 0124 0125 RowLayout { 0126 Kirigami.FormData.label: i18n("Refresh rate:") 0127 0128 QQC2.ComboBox { 0129 id: refreshRateCombobox 0130 Layout.minimumWidth: Kirigami.Units.gridUnit * 11 0131 visible: count > 1 0132 model: element.refreshRates 0133 onActivated: element.refreshRateIndex = currentIndex; 0134 Component.onCompleted: currentIndex = Qt.binding(function() {return element.refreshRateIndex}); 0135 } 0136 // When the combobox is has only one item, it's basically non-interactive 0137 // and is serving purely in a descriptive role, so make this explicit by 0138 // using a label instead 0139 QQC2.Label { 0140 id: singleRefreshRateLabel 0141 visible: refreshRateCombobox.count <= 1 0142 text: element.refreshRates[0] || "" 0143 } 0144 KCM.ContextualHelpButton { 0145 visible: refreshRateCombobox.count <= 1 0146 toolTipText: i18n("\"%1\" is the only refresh rate supported by this display.", singleRefreshRateLabel.text) 0147 } 0148 } 0149 0150 QQC2.ComboBox { 0151 Kirigami.FormData.label: i18n("Adaptive sync:") 0152 Layout.minimumWidth: Kirigami.Units.gridUnit * 11 0153 model: [ 0154 { label: i18n("Never"), value: KScreen.Output.VrrPolicy.Never }, 0155 { label: i18n("Automatic"), value: KScreen.Output.VrrPolicy.Automatic }, 0156 { label: i18n("Always"), value: KScreen.Output.VrrPolicy.Always }, 0157 ] 0158 textRole: "label" 0159 valueRole: "value" 0160 visible: element.capabilities & KScreen.Output.Capability.Vrr 0161 0162 onActivated: element.vrrPolicy = currentValue; 0163 Component.onCompleted: currentIndex = indexOfValue(element.vrrPolicy); 0164 } 0165 0166 RowLayout { 0167 Kirigami.FormData.label: i18n("Overscan:") 0168 visible: element.capabilities & KScreen.Output.Capability.Overscan 0169 0170 QQC2.SpinBox { 0171 from: 0 0172 to: 100 0173 value: element.overscan 0174 onValueModified: element.overscan = value 0175 textFromValue: (value, locale) => 0176 i18nc("Overscan expressed in percentage form", "%1%", value) 0177 valueFromText: (text, locale) => 0178 Number.fromLocaleString(locale, text.replace("%", "")) 0179 } 0180 0181 KCM.ContextualHelpButton { 0182 toolTipText: xi18nc("@info", `Determines how much padding is put around the image sent to the display 0183 to compensate for part of the content being cut off around the edges.<nl/><nl/> 0184 This is sometimes needed when using a TV as a screen`) 0185 } 0186 } 0187 0188 RowLayout { 0189 Kirigami.FormData.label: i18n("RGB range:") 0190 visible: element.capabilities & KScreen.Output.Capability.RgbRange 0191 0192 QQC2.ComboBox { 0193 Layout.minimumWidth: Kirigami.Units.gridUnit * 11 0194 model: [ 0195 { label: i18n("Automatic"), value: KScreen.Output.RgbRange.Automatic }, 0196 { label: i18n("Full"), value: KScreen.Output.RgbRange.Full }, 0197 { label: i18n("Limited"), value: KScreen.Output.RgbRange.Limited } 0198 ] 0199 textRole: "label" 0200 valueRole: "value" 0201 0202 onActivated: element.rgbRange = currentValue; 0203 Component.onCompleted: currentIndex = indexOfValue(element.rgbRange); 0204 } 0205 0206 KCM.ContextualHelpButton { 0207 toolTipText: xi18nc("@info", `Determines whether or not the range of possible color values needs to be limited for the display. 0208 This should only be changed if the colors on the screen look washed out.`) 0209 } 0210 } 0211 0212 RowLayout { 0213 Kirigami.FormData.label: i18nc("@label:textbox", "Color Profile:") 0214 visible: element.capabilities & KScreen.Output.Capability.IccProfile 0215 spacing: Kirigami.Units.smallSpacing 0216 0217 Kirigami.ActionTextField { 0218 id: iccProfileField 0219 onTextChanged: element.iccProfilePath = text 0220 onTextEdited: element.iccProfilePath = text 0221 placeholderText: i18nc("@info:placeholder", "Enter ICC profile path…") 0222 enabled: !element.hdr 0223 0224 rightActions: Kirigami.Action { 0225 icon.name: "edit-clear-symbolic" 0226 visible: iccProfileField.text !== "" 0227 onTriggered: { 0228 iccProfileField.text = "" 0229 } 0230 } 0231 0232 Component.onCompleted: text = element.iccProfilePath; 0233 } 0234 0235 QQC2.Button { 0236 icon.name: "document-open-symbolic" 0237 text: i18nc("@action:button", "Select ICC profile…") 0238 display: QQC2.AbstractButton.IconOnly 0239 onClicked: fileDialogComponent.incubateObject(root); 0240 enabled: !element.hdr 0241 0242 QQC2.ToolTip.visible: hovered 0243 QQC2.ToolTip.text: text 0244 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay 0245 0246 Accessible.role: Accessible.Button 0247 Accessible.name: text 0248 Accessible.description: i18n("Opens a file picker for the ICC profile") 0249 Accessible.onPressAction: onClicked(); 0250 } 0251 0252 Component { 0253 id: fileDialogComponent 0254 0255 FileDialog { 0256 id: fileDialog 0257 title: i18nc("@title:window", "Select ICC Profile") 0258 currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] 0259 nameFilters: ["ICC profiles (*.icc *.icm)"] 0260 0261 onAccepted: { 0262 iccProfileField.text = urlToProfilePath(selectedFile); 0263 destroy(); 0264 } 0265 onRejected: destroy(); 0266 Component.onCompleted: open(); 0267 0268 function urlToProfilePath(qmlUrl) { 0269 const url = new URL(qmlUrl); 0270 let path = decodeURIComponent(url.pathname); 0271 // Remove the leading slash from the url 0272 if (url.protocol === "file:" && path.charAt(1) === ':') { 0273 path = path.substring(1); 0274 } 0275 return path; 0276 } 0277 } 0278 } 0279 0280 KCM.ContextualHelpButton { 0281 visible: element.hdr 0282 toolTipText: i18nc("@info:tooltip", "ICC profiles aren't compatible with HDR yet") 0283 } 0284 } 0285 0286 RowLayout { 0287 Kirigami.FormData.label: i18nc("@label", "High Dynamic Range:") 0288 visible: (element.capabilities & KScreen.Output.Capability.HighDynamicRange) && (element.capabilities & KScreen.Output.Capability.WideColorGamut) 0289 spacing: Kirigami.Units.smallSpacing 0290 0291 QQC2.CheckBox { 0292 text: i18nc("@option:check", "Enable HDR") 0293 checked: element.hdr 0294 onToggled: element.hdr = checked 0295 } 0296 0297 KCM.ContextualHelpButton { 0298 toolTipText: i18nc("@info:tooltip", "HDR allows compatible applications to show brighter and more vivid colors. Note that this feature is still experimental") 0299 } 0300 } 0301 0302 RowLayout { 0303 Layout.fillWidth: true 0304 // Set the same limit as the device ComboBox 0305 Layout.maximumWidth: Kirigami.Units.gridUnit * 16 0306 spacing: Kirigami.Units.smallSpacing 0307 0308 visible: element.hdr 0309 Kirigami.FormData.label: i18nc("@label", "SDR Brightness:") 0310 0311 QQC2.Slider { 0312 Layout.fillWidth: true 0313 from: 50 0314 to: element.peakBrightness == 0 ? 500 : element.peakBrightness 0315 stepSize: 50 0316 live: true 0317 value: element.sdrBrightness 0318 onMoved: element.sdrBrightness = value 0319 } 0320 QQC2.SpinBox { 0321 from : 50 0322 to : element.peakBrightness == 0 ? 500 : element.peakBrightness 0323 stepSize: 10 0324 value: element.sdrBrightness 0325 onValueModified: element.sdrBrightness = value 0326 } 0327 KCM.ContextualHelpButton { 0328 toolTipText: i18nc("@info:tooltip", "Sets the brightness of non-HDR content on the screen, in nits") 0329 } 0330 } 0331 0332 RowLayout { 0333 Layout.fillWidth: true 0334 // Set the same limit as the device ComboBox 0335 Layout.maximumWidth: Kirigami.Units.gridUnit * 16 0336 spacing: Kirigami.Units.smallSpacing 0337 0338 visible: element.hdr 0339 Kirigami.FormData.label: i18nc("@label", "SDR Color Intensity:") 0340 0341 QQC2.Slider { 0342 Layout.fillWidth: true 0343 from: 0 0344 to: 100 0345 stepSize: 10 0346 live: true 0347 value: element.sdrGamutWideness * 100 0348 onMoved: element.sdrGamutWideness = value / 100.0 0349 } 0350 QQC2.SpinBox { 0351 // Because QQC2 SpinBox doesn't natively support decimal step 0352 // sizes: https://bugreports.qt.io/browse/QTBUG-67349 0353 readonly property real factor: 20.0 0354 readonly property real realValue: value / factor 0355 0356 from : 0 0357 to : 1.0 * factor 0358 stepSize: 1 0359 value: element.sdrGamutWideness * factor 0360 validator: DoubleValidator { 0361 bottom: Math.min(spinbox.from, spinbox.to) * spinbox.factor 0362 top: Math.max(spinbox.from, spinbox.to) * spinbox.factor 0363 } 0364 textFromValue: (value, locale) => 0365 i18nc("Color intensity factor expressed in percentage form", "%1%", 0366 parseFloat(value * 1.0 / factor * 100.0)) 0367 valueFromText: (text, locale) => 0368 Number.fromLocaleString(locale, text.replace("%", "")) * factor / 100.0 0369 0370 onValueModified: element.sdrGamutWideness = realValue 0371 } 0372 KCM.ContextualHelpButton { 0373 toolTipText: i18nc("@info:tooltip", "Increases the intensity of non-HDR content on the screen") 0374 } 0375 } 0376 0377 QQC2.ComboBox { 0378 Kirigami.FormData.label: i18n("Replica of:") 0379 Layout.minimumWidth: Kirigami.Units.gridUnit * 11 0380 model: element.replicationSourceModel 0381 visible: kcm.outputReplicationSupported && kcm.multipleScreensAvailable 0382 0383 onModelChanged: enabled = (count > 1); 0384 onCountChanged: enabled = (count > 1); 0385 0386 Component.onCompleted: currentIndex = element.replicationSourceIndex; 0387 onActivated: element.replicationSourceIndex = currentIndex; 0388 } 0389 }