forked from Shinonome/dots-hyprland
waffles: ctrl alt del menu
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
||||
import QtQuick
|
||||
import qs.services
|
||||
|
||||
QtObject {
|
||||
property string name
|
||||
property list<string> categories
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
GridLayout {
|
||||
id: root
|
||||
|
||||
columns: 4
|
||||
|
||||
Component {
|
||||
id: aggAppCatComp
|
||||
AggregatedAppCategoryModel {}
|
||||
}
|
||||
property list<AggregatedAppCategoryModel> aggregatedCategories: [
|
||||
aggAppCatComp.createObject(null, {
|
||||
name: Translation.tr("Productivity"),
|
||||
categories: ["Development", "Education", "Network", "Office"]
|
||||
}), aggAppCatComp.createObject(null, {
|
||||
name: Translation.tr("Utilities & Tools"),
|
||||
categories: ["Utility", "Science"]
|
||||
}), aggAppCatComp.createObject(null, {
|
||||
name: Translation.tr("Creativity"),
|
||||
categories: ["AudioVideo", "Graphics"]
|
||||
}), aggAppCatComp.createObject(null, {
|
||||
name: Translation.tr("Other"),
|
||||
categories: ["Game"]
|
||||
}), aggAppCatComp.createObject(null, {
|
||||
name: Translation.tr("System"),
|
||||
categories: ["Settings", "System"]
|
||||
})
|
||||
]
|
||||
|
||||
Repeater {
|
||||
model: root.aggregatedCategories
|
||||
delegate: AppCategory {
|
||||
required property var modelData
|
||||
aggregatedCategory: modelData
|
||||
}
|
||||
}
|
||||
|
||||
columnSpacing: 27
|
||||
rowSpacing: 12
|
||||
component AppCategory: Item {
|
||||
id: categoryItem
|
||||
property AggregatedAppCategoryModel aggregatedCategory
|
||||
implicitWidth: categoryLayout.implicitWidth
|
||||
implicitHeight: categoryLayout.implicitHeight
|
||||
ColumnLayout {
|
||||
id: categoryLayout
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
|
||||
AppCategoryGrid {
|
||||
id: categoryGrid
|
||||
Layout.fillWidth: true
|
||||
aggregatedCategory: categoryItem.aggregatedCategory
|
||||
}
|
||||
|
||||
WButton {
|
||||
id: categoryButton
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 32
|
||||
|
||||
contentItem: WText {
|
||||
id: categoryButtonText
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
text: categoryItem.aggregatedCategory.name
|
||||
}
|
||||
onClicked: {
|
||||
categoryGrid.openCategoryFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
property AggregatedAppCategoryModel aggregatedCategory
|
||||
property list<DesktopEntry> desktopEntries: DesktopEntries.applications.values.filter(app => {
|
||||
const appCategories = app.categories;
|
||||
const gridCategories = root.aggregatedCategory.categories;
|
||||
return appCategories.some(cat => gridCategories.indexOf(cat) !== -1);
|
||||
})
|
||||
|
||||
property Item windowRootItem: {
|
||||
var item = root;
|
||||
// print("FINDING ROOT")
|
||||
while (item.parent != null) {
|
||||
if (item.parent.toString().includes("ProxyWindow"))
|
||||
break;
|
||||
item = item.parent;
|
||||
}
|
||||
// print(item.width, item.height)
|
||||
return item;
|
||||
}
|
||||
function openCategoryFolder() {
|
||||
categoryFolderPopup.open();
|
||||
}
|
||||
|
||||
radius: Looks.radius.large
|
||||
color: Looks.colors.bg1
|
||||
border.width: 1
|
||||
border.color: ColorUtils.transparentize(Looks.colors.ambientShadow, 0.7)
|
||||
implicitWidth: 156
|
||||
implicitHeight: 156
|
||||
|
||||
GridLayout {
|
||||
id: categoryAppsGrid
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
columns: 2
|
||||
rows: 2
|
||||
columnSpacing: 0
|
||||
rowSpacing: 0
|
||||
uniformCellHeights: true
|
||||
uniformCellWidths: true
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: root.desktopEntries.slice(0, 3)
|
||||
}
|
||||
delegate: SmallGridAppButton {
|
||||
required property DesktopEntry modelData
|
||||
desktopEntry: modelData
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: categoryOpenButtonLoader
|
||||
// It's like this on the real thing - you get an invisible button if there's not enough items
|
||||
opacity: root.desktopEntries.length > 3 ? 1 : 0
|
||||
active: true
|
||||
sourceComponent: CategoryOpenButton {
|
||||
aggregatedCategory: root.aggregatedCategory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: categoryFolderPopup
|
||||
// I don't even know what the fuck is going on at this point
|
||||
// I hate point mapping
|
||||
property point originPoint: categoryOpenButtonLoader.mapToItem(root, categoryOpenButtonLoader.width / 2, categoryOpenButtonLoader.height / 2)
|
||||
property point windowCenterPoint: {
|
||||
const rootContentItem = root.windowRootItem;
|
||||
const canvasPosInRoot = root.mapFromItem(rootContentItem, rootContentItem.width / 2, rootContentItem.height / 2);
|
||||
const sectionItem = root.parent.parent.parent;
|
||||
const positionInSection = sectionItem.mapFromItem(categoryOpenButtonLoader, categoryOpenButtonLoader.x, categoryOpenButtonLoader.y);
|
||||
const targetY = Math.max(-positionInSection.y + 212, canvasPosInRoot.y);
|
||||
return Qt.point(canvasPosInRoot.x, targetY);
|
||||
}
|
||||
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
target: categoryFolderPopup
|
||||
property: "x"
|
||||
from: categoryFolderPopup.originPoint.x - categoryOpenButtonLoader.width * 5 / 2
|
||||
to: categoryFolderPopup.windowCenterPoint.x - categoryFolderPopup.width / 2
|
||||
duration: 300
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
NumberAnimation {
|
||||
target: categoryFolderPopup
|
||||
property: "y"
|
||||
from: categoryFolderPopup.originPoint.y - categoryOpenButtonLoader.height * 3 / 2
|
||||
to: categoryFolderPopup.windowCenterPoint.y - categoryFolderPopup.height / 2
|
||||
duration: 300
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
NumberAnimation {
|
||||
target: categoryFolderPopup
|
||||
property: "scale"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 300
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
}
|
||||
|
||||
exit: Transition {
|
||||
NumberAnimation {
|
||||
target: categoryFolderPopup
|
||||
property: "x"
|
||||
to: categoryFolderPopup.originPoint.x - categoryOpenButtonLoader.width * 5 / 2
|
||||
duration: 200
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
|
||||
}
|
||||
NumberAnimation {
|
||||
target: categoryFolderPopup
|
||||
property: "y"
|
||||
to: categoryFolderPopup.originPoint.y - categoryOpenButtonLoader.height * 3 / 2
|
||||
duration: 200
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
|
||||
}
|
||||
NumberAnimation {
|
||||
target: categoryFolderPopup
|
||||
property: "scale"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: 200
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
|
||||
}
|
||||
}
|
||||
|
||||
background: null
|
||||
|
||||
Loader {
|
||||
id: folderContentLoader
|
||||
active: categoryFolderPopup.visible
|
||||
sourceComponent: WRectangularShadowThis {
|
||||
CategoryFolderContent {
|
||||
title: root.aggregatedCategory.name
|
||||
desktopEntries: root.desktopEntries
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component CategoryFolderContent: WToolTipContent {
|
||||
id: categoryFolderContent
|
||||
property string title
|
||||
property list<DesktopEntry> desktopEntries: root.desktopEntries
|
||||
horizontalPadding: 0
|
||||
verticalPadding: 0
|
||||
radius: Looks.radius.large
|
||||
realContentItem: Item {
|
||||
implicitWidth: 448
|
||||
implicitHeight: 376
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 32
|
||||
rightMargin: 32
|
||||
topMargin: 40
|
||||
bottomMargin: 32
|
||||
}
|
||||
spacing: 28
|
||||
WText {
|
||||
Layout.fillWidth: true
|
||||
text: categoryFolderContent.title
|
||||
font.pixelSize: Looks.font.pixelSize.xlarger
|
||||
font.weight: Looks.font.weight.stronger
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
SwipeView {
|
||||
id: categoryFolderSwipeView
|
||||
anchors.fill: parent
|
||||
orientation: Qt.Vertical
|
||||
clip: true
|
||||
|
||||
Repeater {
|
||||
model: Math.ceil(root.desktopEntries.length / 12)
|
||||
delegate: Item {
|
||||
id: folderPage
|
||||
required property int index
|
||||
width: SwipeView.view.width
|
||||
height: SwipeView.view.height
|
||||
BigAppGrid {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
}
|
||||
columns: 4
|
||||
rows: 3
|
||||
desktopEntries: root.desktopEntries.slice(folderPage.index * 12, (folderPage.index + 1) * 12)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
VerticalPageIndicator {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: categoryFolderSwipeView.right
|
||||
anchors.rightMargin: -19
|
||||
|
||||
showArrows: false
|
||||
currentIndex: categoryFolderSwipeView.currentIndex
|
||||
count: Math.ceil(root.desktopEntries.length / 12)
|
||||
onClicked: index => categoryFolderSwipeView.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
FocusedScrollMouseArea {
|
||||
z: 999
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoverEnabled: false
|
||||
onScrollUp: categoryFolderSwipeView.decrementCurrentIndex()
|
||||
onScrollDown: categoryFolderSwipeView.incrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component CategoryOpenButton: SmallGridButton {
|
||||
id: categoryOpenButton
|
||||
property AggregatedAppCategoryModel aggregatedCategory
|
||||
|
||||
onClicked: root.openCategoryFolder()
|
||||
contentItem: Item {
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
id: scaleAnim
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
}
|
||||
GridLayout {
|
||||
anchors.centerIn: parent
|
||||
rows: 2
|
||||
columns: 2
|
||||
rowSpacing: 2
|
||||
columnSpacing: 2
|
||||
|
||||
Repeater {
|
||||
model: root.desktopEntries.slice(3, 7)
|
||||
delegate: WAppIcon {
|
||||
required property DesktopEntry modelData
|
||||
tryCustomIcon: false
|
||||
iconName: modelData.icon
|
||||
implicitSize: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component SmallGridAppButton: SmallGridButton {
|
||||
id: smallGridAppButton
|
||||
property DesktopEntry desktopEntry
|
||||
|
||||
onClicked: {
|
||||
GlobalStates.searchOpen = false;
|
||||
desktopEntry.execute();
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
id: scaleAnim
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
}
|
||||
WAppIcon {
|
||||
anchors.centerIn: parent
|
||||
tryCustomIcon: false
|
||||
iconName: smallGridAppButton.desktopEntry.icon
|
||||
implicitSize: 34
|
||||
}
|
||||
}
|
||||
|
||||
WToolTip {
|
||||
text: smallGridAppButton.desktopEntry.name
|
||||
}
|
||||
}
|
||||
|
||||
component SmallGridButton: WButton {
|
||||
id: root
|
||||
implicitWidth: 68
|
||||
implicitHeight: 68
|
||||
|
||||
property real pressedScale: 5 / 6
|
||||
|
||||
onDownChanged: {
|
||||
contentItem.scale = root.down ? root.pressedScale : 1; // If/When we do dragging, the scale is 1.25
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
GridLayout {
|
||||
id: root
|
||||
|
||||
property list<var> desktopEntries: []
|
||||
|
||||
columnSpacing: 0
|
||||
rowSpacing: 0
|
||||
|
||||
uniformCellHeights: true
|
||||
uniformCellWidths: true
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: root.desktopEntries
|
||||
}
|
||||
delegate: StartAppButton {
|
||||
id: pinnedAppButton
|
||||
required property var modelData
|
||||
desktopEntry: modelData
|
||||
onClicked: {
|
||||
GlobalStates.searchOpen = false;
|
||||
desktopEntry.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
WButton {
|
||||
id: root
|
||||
required property DesktopEntry desktopEntry
|
||||
implicitWidth: 96
|
||||
implicitHeight: 84
|
||||
horizontalPadding: 0
|
||||
verticalPadding: 0
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 3
|
||||
WAppIcon {
|
||||
Layout.topMargin: 12
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
iconName: root.desktopEntry.icon
|
||||
implicitSize: 34
|
||||
tryCustomIcon: false
|
||||
}
|
||||
WText {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 8
|
||||
Layout.rightMargin: 8
|
||||
text: root.desktopEntry.name
|
||||
wrapMode: Text.Wrap
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignTop
|
||||
}
|
||||
}
|
||||
WToolTip {
|
||||
text: root.desktopEntry.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
BodyRectangle {
|
||||
id: root
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 32
|
||||
rightMargin: 32
|
||||
topMargin: 25
|
||||
bottomMargin: 30
|
||||
}
|
||||
spacing: 26
|
||||
|
||||
PinnedApps {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
AllApps {
|
||||
implicitHeight: 300 // for now
|
||||
}
|
||||
}
|
||||
|
||||
component PinnedApps: PageSection {
|
||||
title: Translation.tr("Pinned")
|
||||
|
||||
BigAppGrid {
|
||||
Layout.fillWidth: true
|
||||
columns: 8
|
||||
desktopEntries: Config.options.launcher.pinnedApps.map(appId => DesktopEntries.byId(appId))
|
||||
}
|
||||
}
|
||||
|
||||
component AllApps: PageSection {
|
||||
title: Translation.tr("All")
|
||||
// TODO: Do we wanna also implement list view and grid view?
|
||||
// (instead of only category view)
|
||||
AllAppsGrid {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 32
|
||||
Layout.rightMargin: 32
|
||||
}
|
||||
}
|
||||
|
||||
component PageSection: ColumnLayout {
|
||||
id: pageSection
|
||||
required property string title
|
||||
default property alias data: pageSectionContentArea.data
|
||||
|
||||
spacing: 16
|
||||
|
||||
WText {
|
||||
Layout.leftMargin: 32
|
||||
text: pageSection.title
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
font.weight: Looks.font.weight.stronger
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: pageSectionContentArea
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
WPanelPageColumn {
|
||||
id: root
|
||||
|
||||
WPanelSeparator {}
|
||||
|
||||
StartPageApps {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
WPanelSeparator {}
|
||||
|
||||
StartFooter {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
component StartFooter: FooterRectangle {
|
||||
implicitHeight: 63
|
||||
|
||||
StartUserButton {
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: 52
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 12
|
||||
}
|
||||
}
|
||||
|
||||
PowerButton {
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 52
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component PowerButton: WBorderlessButton {
|
||||
id: powerButton
|
||||
implicitWidth: 40
|
||||
implicitHeight: 40
|
||||
|
||||
contentItem: Item {
|
||||
FluentIcon {
|
||||
anchors.centerIn: parent
|
||||
icon: "power"
|
||||
implicitSize: 20
|
||||
}
|
||||
}
|
||||
|
||||
WToolTip {
|
||||
extraVisibleCondition: !powerMenu.visible
|
||||
text: qsTr("Power")
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
powerMenu.open()
|
||||
}
|
||||
|
||||
WMenu {
|
||||
id: powerMenu
|
||||
x: -powerMenu.implicitWidth / 2 + powerButton.implicitWidth / 2
|
||||
y: -powerMenu.implicitHeight - 4
|
||||
Action {
|
||||
icon.name: "lock-closed"
|
||||
text: Translation.tr("Lock")
|
||||
onTriggered: Session.lock()
|
||||
}
|
||||
Action {
|
||||
icon.name: "weather-moon"
|
||||
text: Translation.tr("Sleep")
|
||||
onTriggered: Session.suspend()
|
||||
}
|
||||
Action {
|
||||
icon.name: "power"
|
||||
text: Translation.tr("Shut down")
|
||||
onTriggered: Session.poweroff()
|
||||
}
|
||||
Action {
|
||||
icon.name: "arrow-counterclockwise"
|
||||
text: Translation.tr("Restart")
|
||||
onTriggered: Session.reboot()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
WBorderlessButton {
|
||||
id: userButton
|
||||
implicitWidth: userButtonRow.implicitWidth + 12 * 2
|
||||
implicitHeight: 40
|
||||
|
||||
contentItem: Item {
|
||||
RowLayout {
|
||||
id: userButtonRow
|
||||
anchors.centerIn: parent
|
||||
spacing: 12
|
||||
|
||||
WUserAvatar {
|
||||
sourceSize: Qt.size(32, 32)
|
||||
}
|
||||
WText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: SystemInfo.username
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
userMenu.open();
|
||||
}
|
||||
|
||||
WToolTip {
|
||||
text: SystemInfo.username
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: userMenu
|
||||
x: -51
|
||||
y: -userMenu.implicitHeight + userButton.implicitHeight / 2 - 10
|
||||
|
||||
background: null
|
||||
|
||||
WToolTipContent {
|
||||
id: popupContent
|
||||
horizontalPadding: 10
|
||||
verticalPadding: 7
|
||||
radius: Looks.radius.large
|
||||
realContentItem: Item {
|
||||
implicitWidth: userMenuContentLayout.implicitWidth
|
||||
implicitHeight: userMenuContentLayout.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: userMenuContentLayout
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: popupContent.horizontalPadding
|
||||
rightMargin: popupContent.horizontalPadding
|
||||
topMargin: popupContent.verticalPadding
|
||||
bottomMargin: popupContent.verticalPadding
|
||||
}
|
||||
spacing: 5
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 6
|
||||
FluentIcon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
implicitSize: 22
|
||||
icon: "corporation"
|
||||
monochrome: false
|
||||
}
|
||||
WText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "Megahard"
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
font.weight: Looks.font.weight.strong
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
WBorderlessButton {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
implicitHeight: 36
|
||||
implicitWidth: textItem.implicitWidth + 10 * 2
|
||||
contentItem: WText {
|
||||
id: textItem
|
||||
text: Translation.tr("Sign out")
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
}
|
||||
onClicked: Session.logout()
|
||||
}
|
||||
}
|
||||
Item { // Force min width 360 (using min on the item somehow doesn't work)
|
||||
implicitWidth: 334
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: 7
|
||||
Layout.leftMargin: 6
|
||||
spacing: 12
|
||||
WUserAvatar {
|
||||
sourceSize: Qt.size(58, 58)
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 2
|
||||
WText {
|
||||
text: SystemInfo.username
|
||||
font.pixelSize: Looks.font.pixelSize.larger
|
||||
font.weight: Looks.font.weight.strong
|
||||
}
|
||||
WText {
|
||||
color: Looks.colors.fg1
|
||||
text: Translation.tr("Local account")
|
||||
}
|
||||
WText {
|
||||
color: Looks.colors.accent
|
||||
text: Translation.tr("Manage my account")
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Quickshell.execDetached(["bash", "-c", Config.options.apps.manageUser])
|
||||
GlobalStates.searchOpen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user