Warning, /plasma/plasma-desktop/applets/kickoff/package/contents/ui/Header.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org> 0003 SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu> 0004 SPDX-FileCopyrightText: 2021 Mikel Johnson <mikel5764@gmail.com> 0005 SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 import QtQuick 2.15 0011 import QtQml 2.15 0012 import QtQuick.Layouts 1.15 0013 import QtQuick.Templates 2.15 as T 0014 import Qt5Compat.GraphicalEffects 0015 import org.kde.plasma.components 3.0 as PC3 0016 import org.kde.plasma.extras 2.0 as PlasmaExtras 0017 import org.kde.kirigami 2.20 as Kirigami 0018 import org.kde.kirigamiaddons.components 1.0 as KirigamiComponents 0019 import org.kde.coreaddons 1.0 as KCoreAddons 0020 import org.kde.kcmutils as KCM 0021 import org.kde.config as KConfig 0022 import org.kde.plasma.plasmoid 2.0 0023 0024 PlasmaExtras.PlasmoidHeading { 0025 id: root 0026 0027 property alias searchText: searchField.text 0028 property Item configureButton: configureButton 0029 property Item pinButton: pinButton 0030 property Item avatar: avatar 0031 property real preferredNameAndIconWidth: 0 0032 0033 contentHeight: Math.max(searchField.implicitHeight, configureButton.implicitHeight) 0034 0035 leftPadding: 0 0036 rightPadding: 0 0037 topPadding: Math.round((background.margins.top - background.inset.top) / 2.0) 0038 bottomPadding: background.margins.bottom + Math.round((background.margins.bottom - background.inset.bottom) / 2.0) 0039 0040 leftInset: -kickoff.backgroundMetrics.leftPadding 0041 rightInset: -kickoff.backgroundMetrics.rightPadding 0042 topInset: -background.margins.top 0043 bottomInset: 0 0044 0045 KCoreAddons.KUser { 0046 id: kuser 0047 } 0048 0049 spacing: kickoff.backgroundMetrics.spacing 0050 0051 function tabSetFocus(event, invertedTarget, normalTarget) { 0052 // Set input focus depending on whether layout order matches focus chain order 0053 // normalTarget is optional 0054 const reason = event.key == Qt.Key_Tab ? Qt.TabFocusReason : Qt.BacktabFocusReason 0055 if (kickoff.paneSwap) { 0056 invertedTarget.forceActiveFocus(reason) 0057 } else if (normalTarget !== undefined) { 0058 normalTarget.forceActiveFocus(reason) 0059 } else { 0060 event.accepted = false 0061 } 0062 } 0063 0064 RowLayout { 0065 id: nameAndIcon 0066 spacing: root.spacing 0067 anchors.left: parent.left 0068 LayoutMirroring.enabled: kickoff.sideBarOnRight 0069 height: parent.height 0070 width: root.preferredNameAndIconWidth 0071 0072 KirigamiComponents.AvatarButton { 0073 id: avatar 0074 visible: KConfig.KAuthorized.authorizeControlModule("kcm_users") 0075 0076 Layout.fillHeight: true 0077 Layout.minimumWidth: height 0078 Layout.maximumWidth: height 0079 0080 text: i18n("Open user settings") 0081 name: kuser.fullName 0082 source: kuser.faceIconUrl + "?timestamp=" + Date.now() 0083 0084 Keys.onTabPressed: event => { 0085 tabSetFocus(event, kickoff.firstCentralPane); 0086 } 0087 Keys.onBacktabPressed: event => { 0088 tabSetFocus(event, nextItemInFocusChain()); 0089 } 0090 Keys.onLeftPressed: event => { 0091 if (kickoff.sideBarOnRight) { 0092 searchField.forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason) 0093 } 0094 } 0095 Keys.onRightPressed: event => { 0096 if (!kickoff.sideBarOnRight) { 0097 searchField.forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason) 0098 } 0099 } 0100 Keys.onDownPressed: event => { 0101 if (kickoff.sideBar) { 0102 kickoff.sideBar.forceActiveFocus(Qt.TabFocusReason) 0103 } else { 0104 kickoff.contentArea.forceActiveFocus(Qt.TabFocusReason) 0105 } 0106 } 0107 0108 onClicked: KCM.KCMLauncher.openSystemSettings("kcm_users") 0109 } 0110 0111 MouseArea { 0112 id: nameAndInfoMouseArea 0113 hoverEnabled: true 0114 0115 Layout.fillHeight: true 0116 Layout.fillWidth: true 0117 0118 Kirigami.Heading { 0119 id: nameLabel 0120 anchors.fill: parent 0121 opacity: parent.containsMouse ? 0 : 1 0122 color: Kirigami.Theme.textColor 0123 level: 4 0124 text: kuser.fullName 0125 textFormat: Text.PlainText 0126 elide: Text.ElideRight 0127 horizontalAlignment: kickoff.paneSwap ? Text.AlignRight : Text.AlignLeft 0128 verticalAlignment: Text.AlignVCenter 0129 0130 Behavior on opacity { 0131 NumberAnimation { 0132 duration: Kirigami.Units.longDuration 0133 easing.type: Easing.InOutQuad 0134 } 0135 } 0136 } 0137 0138 Kirigami.Heading { 0139 id: infoLabel 0140 anchors.fill: parent 0141 level: 5 0142 opacity: parent.containsMouse ? 1 : 0 0143 color: Kirigami.Theme.textColor 0144 text: kuser.os !== "" ? `${kuser.loginName}@${kuser.host} (${kuser.os})` : `${kuser.loginName}@${kuser.host}` 0145 textFormat: Text.PlainText 0146 elide: Text.ElideRight 0147 horizontalAlignment: kickoff.paneSwap ? Text.AlignRight : Text.AlignLeft 0148 verticalAlignment: Text.AlignVCenter 0149 0150 Behavior on opacity { 0151 NumberAnimation { 0152 duration: Kirigami.Units.longDuration 0153 easing.type: Easing.InOutQuad 0154 } 0155 } 0156 } 0157 0158 PC3.ToolTip.text: infoLabel.text 0159 PC3.ToolTip.delay: Kirigami.Units.toolTipDelay 0160 PC3.ToolTip.visible: infoLabel.truncated && containsMouse 0161 } 0162 } 0163 RowLayout { 0164 id: rowLayout 0165 spacing: root.spacing 0166 height: parent.height 0167 anchors { 0168 left: nameAndIcon.right 0169 right: parent.right 0170 } 0171 LayoutMirroring.enabled: kickoff.sideBarOnRight 0172 Keys.onDownPressed: event => { 0173 kickoff.contentArea.forceActiveFocus(Qt.TabFocusReason); 0174 } 0175 0176 PlasmaExtras.SearchField { 0177 id: searchField 0178 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter 0179 Layout.fillWidth: true 0180 Layout.leftMargin: kickoff.backgroundMetrics.leftPadding 0181 focus: true 0182 0183 Binding { 0184 target: kickoff 0185 property: "searchField" 0186 value: searchField 0187 // there's only one header ever, so don't waste resources 0188 restoreMode: Binding.RestoreNone 0189 } 0190 Connections { 0191 target: kickoff 0192 function onExpandedChanged() { 0193 if (kickoff.expanded) { 0194 searchField.clear() 0195 } 0196 } 0197 } 0198 onTextEdited: { 0199 searchField.forceActiveFocus(Qt.ShortcutFocusReason) 0200 } 0201 onAccepted: { 0202 kickoff.contentArea.currentItem.action.triggered() 0203 kickoff.contentArea.currentItem.forceActiveFocus(Qt.ShortcutFocusReason) 0204 } 0205 Keys.priority: Keys.AfterItem 0206 Keys.forwardTo: kickoff.contentArea !== null ? kickoff.contentArea.view : [] 0207 Keys.onTabPressed: event => { 0208 tabSetFocus(event, nextItemInFocusChain(false)); 0209 } 0210 Keys.onBacktabPressed: event => { 0211 tabSetFocus(event, nextItemInFocusChain()); 0212 } 0213 Keys.onLeftPressed: event => { 0214 if (activeFocus) { 0215 nextItemInFocusChain(kickoff.sideBarOnRight).forceActiveFocus( 0216 Qt.application.layoutDirection === Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason) 0217 } 0218 } 0219 Keys.onRightPressed: event => { 0220 if (activeFocus) { 0221 nextItemInFocusChain(!kickoff.sideBarOnRight).forceActiveFocus( 0222 Qt.application.layoutDirection === Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason) 0223 } 0224 } 0225 } 0226 0227 PC3.ToolButton { 0228 id: configureButton 0229 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter 0230 visible: Plasmoid.internalAction("configure").enabled 0231 icon.name: "configure" 0232 text: Plasmoid.internalAction("configure").text 0233 display: PC3.ToolButton.IconOnly 0234 0235 PC3.ToolTip.text: text 0236 PC3.ToolTip.delay: Kirigami.Units.toolTipDelay 0237 PC3.ToolTip.visible: hovered 0238 Keys.onTabPressed: event => { 0239 tabSetFocus(event, nextItemInFocusChain(false)); 0240 } 0241 Keys.onBacktabPressed: event => { 0242 tabSetFocus(event, nextItemInFocusChain()); 0243 } 0244 Keys.onLeftPressed: event => { 0245 nextItemInFocusChain(kickoff.sideBarOnRight).forceActiveFocus( 0246 Qt.application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason) 0247 } 0248 Keys.onRightPressed: event => { 0249 nextItemInFocusChain(!kickoff.sideBarOnRight).forceActiveFocus( 0250 Qt.application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason) 0251 } 0252 onClicked: plasmoid.internalAction("configure").trigger() 0253 } 0254 PC3.ToolButton { 0255 id: pinButton 0256 checkable: true 0257 checked: Plasmoid.configuration.pin 0258 icon.name: "window-pin" 0259 text: i18n("Keep Open") 0260 display: PC3.ToolButton.IconOnly 0261 PC3.ToolTip.text: text 0262 PC3.ToolTip.delay: Kirigami.Units.toolTipDelay 0263 PC3.ToolTip.visible: hovered 0264 Binding { 0265 target: kickoff 0266 property: "hideOnWindowDeactivate" 0267 value: !Plasmoid.configuration.pin 0268 // there should be no other bindings, so don't waste resources 0269 restoreMode: Binding.RestoreNone 0270 } 0271 Keys.onTabPressed: event => { 0272 tabSetFocus(event, nextItemInFocusChain(false), kickoff.firstCentralPane || nextItemInFocusChain()); 0273 } 0274 Keys.onBacktabPressed: event => { 0275 tabSetFocus(event, nameAndIcon.nextItemInFocusChain(false), nextItemInFocusChain(false)); 0276 } 0277 Keys.onLeftPressed: event => { 0278 if (!kickoff.sideBarOnRight) { 0279 nextItemInFocusChain(false).forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason) 0280 } 0281 } 0282 Keys.onRightPressed: event => { 0283 if (kickoff.sideBarOnRight) { 0284 nextItemInFocusChain(false).forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason) 0285 } 0286 } 0287 onToggled: Plasmoid.configuration.pin = checked 0288 } 0289 } 0290 }