mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-10 15:32:52 -05:00
Animation improvements, fix SysTray
This commit is contained in:
@@ -470,7 +470,6 @@ PanelWindow {
|
|||||||
source: parent.entryType === "image" && parent.entryId ? "file://" + parent.tempImagePath : ""
|
source: parent.entryType === "image" && parent.entryId ? "file://" + parent.tempImagePath : ""
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
console.log("Image preview initializing for entry:", parent.entryId, "path:", parent.tempImagePath)
|
|
||||||
if (parent.entryType === "image" && parent.entryId) {
|
if (parent.entryType === "image" && parent.entryId) {
|
||||||
// Simple approach: use shell redirection to write to file
|
// Simple approach: use shell redirection to write to file
|
||||||
imageDecodeProcess.entryId = parent.entryId
|
imageDecodeProcess.entryId = parent.entryId
|
||||||
@@ -482,11 +481,8 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
console.log("Image preview status changed:", status, "for path:", source)
|
|
||||||
if (status === Image.Error) {
|
if (status === Image.Error) {
|
||||||
console.warn("Failed to load image from:", source)
|
console.warn("Failed to load clipboard image from:", source)
|
||||||
} else if (status === Image.Ready) {
|
|
||||||
console.log("Successfully loaded image:", source)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,16 +786,12 @@ PanelWindow {
|
|||||||
property var imagePreview: null
|
property var imagePreview: null
|
||||||
|
|
||||||
onExited: (exitCode) => {
|
onExited: (exitCode) => {
|
||||||
console.log("Image decode process exited with code:", exitCode, "for entry:", entryId)
|
|
||||||
if (exitCode === 0 && imagePreview && tempPath) {
|
if (exitCode === 0 && imagePreview && tempPath) {
|
||||||
console.log("Image decoded successfully to:", tempPath)
|
|
||||||
// Force the Image component to reload
|
// Force the Image component to reload
|
||||||
Qt.callLater(function() {
|
Qt.callLater(function() {
|
||||||
imagePreview.source = ""
|
imagePreview.source = ""
|
||||||
imagePreview.source = "file://" + tempPath
|
imagePreview.source = "file://" + tempPath
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
console.warn("Failed to decode clipboard image for entry:", entryId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,14 +34,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: Math.min(600, parent.width - Theme.spacingL * 2)
|
width: Math.min(600, parent.width - Theme.spacingL * 2)
|
||||||
height: {
|
height: controlCenterPopup.powerOptionsExpanded ? 570 : 500
|
||||||
let baseHeight = Math.min(500, parent.height - Theme.barHeight - Theme.spacingS * 2)
|
|
||||||
// Expand container when power menu is open
|
|
||||||
if (controlCenterPopup.powerOptionsExpanded) {
|
|
||||||
baseHeight += 70 // Extra space for power options
|
|
||||||
}
|
|
||||||
return baseHeight
|
|
||||||
}
|
|
||||||
x: Math.max(Theme.spacingL, parent.width - width - Theme.spacingL)
|
x: Math.max(Theme.spacingL, parent.width - width - Theme.spacingL)
|
||||||
y: Theme.barHeight + Theme.spacingXS
|
y: Theme.barHeight + Theme.spacingXS
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
@@ -49,8 +42,61 @@ PanelWindow {
|
|||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
|
// TopBar dropdown animation - optimized for performance
|
||||||
|
transform: [
|
||||||
|
Scale {
|
||||||
|
id: scaleTransform
|
||||||
|
origin.x: parent.width // Scale from top-right corner
|
||||||
|
origin.y: 0
|
||||||
|
xScale: root.controlCenterVisible ? 1.0 : 0.95
|
||||||
|
yScale: root.controlCenterVisible ? 1.0 : 0.8
|
||||||
|
},
|
||||||
|
Translate {
|
||||||
|
id: translateTransform
|
||||||
|
x: root.controlCenterVisible ? 0 : 15 // Slide slightly left when hidden
|
||||||
|
y: root.controlCenterVisible ? 0 : -30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Single coordinated animation for better performance
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "visible"
|
||||||
|
when: root.controlCenterVisible
|
||||||
|
PropertyChanges { target: scaleTransform; xScale: 1.0; yScale: 1.0 }
|
||||||
|
PropertyChanges { target: translateTransform; x: 0; y: 0 }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hidden"
|
||||||
|
when: !root.controlCenterVisible
|
||||||
|
PropertyChanges { target: scaleTransform; xScale: 0.95; yScale: 0.8 }
|
||||||
|
PropertyChanges { target: translateTransform; x: 15; y: -30 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Power menu height animation
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration // Faster for height changes
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
from: "*"; to: "*"
|
||||||
|
ParallelAnimation {
|
||||||
|
NumberAnimation {
|
||||||
|
targets: [scaleTransform, translateTransform]
|
||||||
|
properties: "xScale,yScale,x,y"
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
opacity: root.controlCenterVisible ? 1.0 : 0.0
|
opacity: root.controlCenterVisible ? 1.0 : 0.0
|
||||||
scale: root.controlCenterVisible ? 1.0 : 0.85
|
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -59,19 +105,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
// Height animation handled by states below for better performance
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -115,11 +149,12 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Circular clipping container for profile image
|
// Circular clipping container for profile image
|
||||||
ClippingRectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 1
|
anchors.margins: 1
|
||||||
radius: 31
|
radius: 31
|
||||||
antialiasing: true
|
color: "transparent"
|
||||||
|
clip: true
|
||||||
visible: parent.hasImage
|
visible: parent.hasImage
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -135,14 +170,14 @@ PanelWindow {
|
|||||||
return Prefs.profileImage
|
return Prefs.profileImage
|
||||||
}
|
}
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
smooth: true
|
smooth: false // Disable smooth scaling during animations for performance
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
mipmap: true
|
mipmap: false // Disable mipmap for better performance
|
||||||
cache: false
|
cache: true // Enable caching to prevent reloads
|
||||||
|
|
||||||
onStatusChanged: {
|
// Optimize source size to prevent unnecessary scaling
|
||||||
console.log("Control Center profile image status:", status, "source:", source)
|
sourceSize.width: 64
|
||||||
}
|
sourceSize.height: 64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +357,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animated Collapsible Power Options (moved here for better integration)
|
// Animated Collapsible Power Options (optimized)
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: controlCenterPopup.powerOptionsExpanded ? 60 : 0
|
height: controlCenterPopup.powerOptionsExpanded ? 60 : 0
|
||||||
@@ -333,38 +368,25 @@ PanelWindow {
|
|||||||
opacity: controlCenterPopup.powerOptionsExpanded ? 1.0 : 0.0
|
opacity: controlCenterPopup.powerOptionsExpanded ? 1.0 : 0.0
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
// Single coordinated animation for power options
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on border.width {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
opacity: controlCenterPopup.powerOptionsExpanded ? 1.0 : 0.0
|
visible: controlCenterPopup.powerOptionsExpanded
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logout
|
// Logout
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -611,29 +633,14 @@ PanelWindow {
|
|||||||
// Tab content area
|
// Tab content area
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: {
|
height: controlCenterPopup.powerOptionsExpanded ? 240 : 300
|
||||||
// More generous height calculation - use most of the available space
|
|
||||||
let baseHeight = parent.height
|
|
||||||
|
|
||||||
// Subtract only the essential fixed elements
|
|
||||||
baseHeight -= 90 + Theme.spacingL // User header + spacing
|
|
||||||
baseHeight -= 40 + Theme.spacingM // Tab buttons + spacing
|
|
||||||
baseHeight -= Theme.spacingM // Bottom spacing
|
|
||||||
|
|
||||||
// Subtract power options height when expanded
|
|
||||||
if (controlCenterPopup.powerOptionsExpanded) {
|
|
||||||
baseHeight -= 60 + Theme.spacingL
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.max(300, baseHeight) // Higher minimum height for better content display
|
|
||||||
}
|
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,17 +50,55 @@ PanelWindow {
|
|||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
opacity: root.notificationHistoryVisible ? 1.0 : 0.0
|
// TopBar dropdown animation - slide down from bar (consistent with other TopBar widgets)
|
||||||
scale: root.notificationHistoryVisible ? 1.0 : 0.85
|
transform: [
|
||||||
|
Scale {
|
||||||
|
id: scaleTransform
|
||||||
|
origin.x: parent.width // Scale from top-right corner
|
||||||
|
origin.y: 0
|
||||||
|
xScale: root.notificationHistoryVisible ? 1.0 : 0.95
|
||||||
|
yScale: root.notificationHistoryVisible ? 1.0 : 0.8
|
||||||
|
},
|
||||||
|
Translate {
|
||||||
|
id: translateTransform
|
||||||
|
x: root.notificationHistoryVisible ? 0 : 15 // Slide slightly left when hidden
|
||||||
|
y: root.notificationHistoryVisible ? 0 : -30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
Behavior on opacity {
|
opacity: root.notificationHistoryVisible ? 1.0 : 0.0
|
||||||
|
|
||||||
|
// Single coordinated animation for better performance
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "visible"
|
||||||
|
when: root.notificationHistoryVisible
|
||||||
|
PropertyChanges { target: scaleTransform; xScale: 1.0; yScale: 1.0 }
|
||||||
|
PropertyChanges { target: translateTransform; x: 0; y: 0 }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hidden"
|
||||||
|
when: !root.notificationHistoryVisible
|
||||||
|
PropertyChanges { target: scaleTransform; xScale: 0.95; yScale: 0.8 }
|
||||||
|
PropertyChanges { target: translateTransform; x: 15; y: -30 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
from: "*"; to: "*"
|
||||||
|
ParallelAnimation {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
|
targets: [scaleTransform, translateTransform]
|
||||||
|
properties: "xScale,yScale,x,y"
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
|
|||||||
@@ -41,16 +41,50 @@ PanelWindow {
|
|||||||
radius: Theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
border.width: 0 // Remove border completely
|
border.width: 0 // Remove border completely
|
||||||
|
|
||||||
opacity: root.showNotificationPopup ? 1.0 : 0.0
|
// TopBar dropdown animation - slide down from bar
|
||||||
|
transform: [
|
||||||
// Transform for swipe animations
|
Translate {
|
||||||
transform: Translate {
|
|
||||||
id: swipeTransform
|
id: swipeTransform
|
||||||
x: 0
|
x: 0
|
||||||
|
y: root.showNotificationPopup ? 0 : -30
|
||||||
|
|
||||||
|
Behavior on y {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Scale {
|
||||||
|
id: scaleTransform
|
||||||
|
origin.x: parent.width
|
||||||
|
origin.y: 0
|
||||||
|
xScale: root.showNotificationPopup ? 1.0 : 0.95
|
||||||
|
yScale: root.showNotificationPopup ? 1.0 : 0.8
|
||||||
|
|
||||||
|
Behavior on xScale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on yScale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
opacity: root.showNotificationPopup ? 1.0 : 0.0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation { duration: 200; easing.type: Easing.OutQuad }
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drag area for swipe gestures
|
// Drag area for swipe gestures
|
||||||
|
|||||||
@@ -52,8 +52,51 @@ PanelWindow {
|
|||||||
border.width: 1
|
border.width: 1
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
// TopBar dropdown animation - slide down from bar
|
||||||
|
transform: [
|
||||||
|
Scale {
|
||||||
|
id: scaleTransform
|
||||||
|
origin.x: parent.width * 0.85 // Scale from top-right
|
||||||
|
origin.y: 0
|
||||||
|
xScale: processDropdown.isVisible ? 1.0 : 0.95
|
||||||
|
yScale: processDropdown.isVisible ? 1.0 : 0.8
|
||||||
|
|
||||||
|
Behavior on xScale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on yScale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Translate {
|
||||||
|
id: translateTransform
|
||||||
|
x: processDropdown.isVisible ? 0 : 20
|
||||||
|
y: processDropdown.isVisible ? 0 : -30
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on y {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
opacity: processDropdown.isVisible ? 1.0 : 0.0
|
opacity: processDropdown.isVisible ? 1.0 : 0.0
|
||||||
scale: processDropdown.isVisible ? 1.0 : 0.85
|
|
||||||
|
|
||||||
// Add shadow effect
|
// Add shadow effect
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
@@ -66,7 +109,6 @@ PanelWindow {
|
|||||||
shadowOpacity: processDropdown.isVisible ? 0.15 : 0
|
shadowOpacity: processDropdown.isVisible ? 0.15 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smooth animations
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
@@ -74,13 +116,6 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Click inside dropdown - consume the event
|
// Click inside dropdown - consume the event
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -320,12 +320,23 @@ PanelWindow {
|
|||||||
shadowColor: Qt.rgba(0, 0, 0, 0.3)
|
shadowColor: Qt.rgba(0, 0, 0, 0.3)
|
||||||
shadowOpacity: 0.3
|
shadowOpacity: 0.3
|
||||||
}
|
}
|
||||||
transform: Scale { origin.x: width/2; origin.y: height/2; xScale: spotlightOpen?1:0.9; yScale: spotlightOpen?1:0.9;
|
// Center-screen fade with subtle scale
|
||||||
Behavior on xScale { NumberAnimation { duration: Theme.mediumDuration; easing.type: Easing.OutBack; easing.overshoot:1.1 } }
|
opacity: spotlightOpen ? 1.0 : 0.0
|
||||||
Behavior on yScale { NumberAnimation { duration: Theme.mediumDuration; easing.type: Easing.OutBack; easing.overshoot:1.1 } }
|
scale: spotlightOpen ? 1.0 : 0.96
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
opacity: spotlightOpen?1:0
|
|
||||||
Behavior on opacity { NumberAnimation { duration: Theme.mediumDuration; easing.type: Theme.emphasizedEasing } }
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent; anchors.margins: Theme.spacingXL; spacing: Theme.spacingL
|
anchors.fill: parent; anchors.margins: Theme.spacingXL; spacing: Theme.spacingL
|
||||||
|
|||||||
@@ -64,10 +64,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
if (trayItem.hasMenu) {
|
if (trayItem.hasMenu) {
|
||||||
console.log("Right-click detected, showing menu for:", trayItem.title || "Unknown")
|
|
||||||
customTrayMenu.showMenu(mouse.x, mouse.y)
|
customTrayMenu.showMenu(mouse.x, mouse.y)
|
||||||
} else {
|
|
||||||
console.log("No menu available for:", trayItem.title || "Unknown")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ PanelWindow {
|
|||||||
property real trayMenuY: 0
|
property real trayMenuY: 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Proxy objects for external connections
|
// Proxy objects for external connections
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
@@ -231,13 +232,14 @@ PanelWindow {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: Prefs.showSystemTray
|
visible: Prefs.showSystemTray
|
||||||
onMenuRequested: (menu, item, x, y) => {
|
onMenuRequested: (menu, item, x, y) => {
|
||||||
topBar.currentTrayMenu = menu
|
if (topBar.shellRoot) {
|
||||||
topBar.currentTrayItem = item
|
topBar.shellRoot.currentTrayMenu = menu
|
||||||
topBar.trayMenuX = rightSection.x + rightSection.width - 400 - Theme.spacingL
|
topBar.shellRoot.currentTrayItem = item
|
||||||
topBar.trayMenuY = Theme.barHeight + Theme.spacingS
|
topBar.shellRoot.trayMenuX = rightSection.x + rightSection.width - 400 - Theme.spacingL
|
||||||
console.log("Showing menu at:", topBar.trayMenuX, topBar.trayMenuY)
|
topBar.shellRoot.trayMenuY = Theme.barHeight - Theme.spacingXS
|
||||||
|
topBar.shellRoot.showTrayMenu = true
|
||||||
|
}
|
||||||
menu.menuVisible = true
|
menu.menuVisible = true
|
||||||
topBar.showTrayMenu = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ PanelWindow {
|
|||||||
id: menuContainer
|
id: menuContainer
|
||||||
x: root.trayMenuX
|
x: root.trayMenuX
|
||||||
y: root.trayMenuY
|
y: root.trayMenuY
|
||||||
width: 180
|
width: Math.max(180, Math.min(300, menuList.maxTextWidth + Theme.spacingL * 2))
|
||||||
height: Math.max(60, menuList.contentHeight + Theme.spacingS * 2)
|
height: Math.max(60, menuList.contentHeight + Theme.spacingS * 2)
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
radius: Theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
@@ -78,6 +78,27 @@ PanelWindow {
|
|||||||
id: menuList
|
id: menuList
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 1
|
spacing: 1
|
||||||
|
|
||||||
|
// Calculate maximum text width for dynamic menu sizing
|
||||||
|
property real maxTextWidth: {
|
||||||
|
let maxWidth = 0
|
||||||
|
if (model && model.values) {
|
||||||
|
for (let i = 0; i < model.values.length; i++) {
|
||||||
|
const item = model.values[i]
|
||||||
|
if (item && item.text) {
|
||||||
|
const textWidth = textMetrics.advanceWidth * item.text.length * 0.6
|
||||||
|
maxWidth = Math.max(maxWidth, textWidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.min(maxWidth, 280) // Cap at reasonable width
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: textMetrics
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
text: "M"
|
||||||
|
}
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
values: menuOpener.children ? [...menuOpener.children.values].filter(item => {
|
values: menuOpener.children ? [...menuOpener.children.values].filter(item => {
|
||||||
// Filter out empty items and separators
|
// Filter out empty items and separators
|
||||||
@@ -114,6 +135,8 @@ PanelWindow {
|
|||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Normal
|
font.weight: Font.Normal
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user