NPanel now can properly be positioned relative to their opener (button)
This commit is contained in:
parent
3c39ea192b
commit
f3ae0101d7
6 changed files with 66 additions and 31 deletions
|
|
@ -66,7 +66,7 @@ NIconButton {
|
||||||
|
|
||||||
if (ArchUpdaterService.updatePackages.length > 0) {
|
if (ArchUpdaterService.updatePackages.length > 0) {
|
||||||
// Show confirmation dialog for updates
|
// Show confirmation dialog for updates
|
||||||
PanelService.getPanel("archUpdaterPanel").toggle(screen)
|
PanelService.getPanel("archUpdaterPanel").toggle(screen, this)
|
||||||
} else {
|
} else {
|
||||||
// Just refresh if no updates available
|
// Just refresh if no updates available
|
||||||
ArchUpdaterService.doPoll()
|
ArchUpdaterService.doPoll()
|
||||||
|
|
|
||||||
|
|
@ -31,5 +31,5 @@ NIconButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tooltipText: "Bluetooth Devices"
|
tooltipText: "Bluetooth Devices"
|
||||||
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(screen)
|
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(screen, this)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tooltip.hide()
|
tooltip.hide()
|
||||||
PanelService.getPanel("calendarPanel")?.toggle(screen)
|
PanelService.getPanel("calendarPanel")?.toggle(screen, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,5 @@ NIconButton {
|
||||||
colorFg: Color.mOnSurface
|
colorFg: Color.mOnSurface
|
||||||
colorBorder: Color.transparent
|
colorBorder: Color.transparent
|
||||||
colorBorderHover: Color.transparent
|
colorBorderHover: Color.transparent
|
||||||
onClicked: PanelService.getPanel("notificationHistoryPanel")?.toggle(screen)
|
onClicked: PanelService.getPanel("notificationHistoryPanel")?.toggle(screen, this)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ NIconButton {
|
||||||
|
|
||||||
icon: {
|
icon: {
|
||||||
try {
|
try {
|
||||||
if (NetworkService.ethernet)
|
if (NetworkService.ethernet) {
|
||||||
return "lan"
|
return "lan"
|
||||||
|
}
|
||||||
let connected = false
|
let connected = false
|
||||||
let signalStrength = 0
|
let signalStrength = 0
|
||||||
for (const net in NetworkService.networks) {
|
for (const net in NetworkService.networks) {
|
||||||
|
|
@ -50,12 +51,5 @@ NIconButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tooltipText: "Network / WiFi"
|
tooltipText: "Network / WiFi"
|
||||||
onClicked: {
|
onClicked: PanelService.getPanel("wifiPanel")?.toggle(screen, this)
|
||||||
try {
|
|
||||||
Logger.log("WiFi", "Button clicked, toggling panel")
|
|
||||||
PanelService.getPanel("wifiPanel")?.toggle(screen)
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error("WiFi", "Error toggling panel:", error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ Loader {
|
||||||
active: false
|
active: false
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
readonly property real scaling: ScalingService.scale(screen)
|
|
||||||
property ShellScreen screen
|
property ShellScreen screen
|
||||||
|
readonly property real scaling: ScalingService.scale(screen)
|
||||||
|
|
||||||
property Component panelContent: null
|
property Component panelContent: null
|
||||||
property int panelWidth: 1500
|
property int panelWidth: 1500
|
||||||
|
|
@ -20,6 +20,12 @@ Loader {
|
||||||
property bool panelAnchorLeft: false
|
property bool panelAnchorLeft: false
|
||||||
property bool panelAnchorRight: false
|
property bool panelAnchorRight: false
|
||||||
|
|
||||||
|
// Properties to support positioning relative to the opener (button)
|
||||||
|
property bool useButtonPosition: false
|
||||||
|
property point buttonPosition: Qt.point(0, 0)
|
||||||
|
property int buttonWidth: 0
|
||||||
|
property int buttonHeight: 0
|
||||||
|
|
||||||
// Animation properties
|
// Animation properties
|
||||||
readonly property real originalScale: 0.7
|
readonly property real originalScale: 0.7
|
||||||
readonly property real originalOpacity: 0.0
|
readonly property real originalOpacity: 0.0
|
||||||
|
|
@ -27,6 +33,8 @@ Loader {
|
||||||
property real opacityValue: originalOpacity
|
property real opacityValue: originalOpacity
|
||||||
|
|
||||||
property alias isClosing: hideTimer.running
|
property alias isClosing: hideTimer.running
|
||||||
|
readonly property real barHeight: Style.barHeight * scaling
|
||||||
|
readonly property bool barAtBottom: Settings.data.bar.position === "bottom"
|
||||||
|
|
||||||
signal opened
|
signal opened
|
||||||
signal closed
|
signal closed
|
||||||
|
|
@ -36,20 +44,32 @@ Loader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
function toggle(aScreen) {
|
function toggle(aScreen, buttonItem) {
|
||||||
if (!active || isClosing) {
|
if (!active || isClosing) {
|
||||||
open(aScreen)
|
open(aScreen, buttonItem)
|
||||||
} else {
|
} else {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
function open(aScreen) {
|
function open(aScreen, buttonItem) {
|
||||||
if (aScreen !== null) {
|
if (aScreen !== null) {
|
||||||
screen = aScreen
|
screen = aScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get t button position if provided
|
||||||
|
if (buttonItem !== undefined && buttonItem !== null) {
|
||||||
|
useButtonPosition = true
|
||||||
|
|
||||||
|
var itemPos = buttonItem.mapToItem(null, 0, 0)
|
||||||
|
buttonPosition = Qt.point(itemPos.x, itemPos.y)
|
||||||
|
buttonWidth = buttonItem.width
|
||||||
|
buttonHeight = buttonItem.height
|
||||||
|
} else {
|
||||||
|
useButtonPosition = false
|
||||||
|
}
|
||||||
|
|
||||||
// Special case if currently closing/animating
|
// Special case if currently closing/animating
|
||||||
if (isClosing) {
|
if (isClosing) {
|
||||||
hideTimer.stop() // in case we were closing
|
hideTimer.stop() // in case we were closing
|
||||||
|
|
@ -74,6 +94,7 @@ Loader {
|
||||||
function closeCompleted() {
|
function closeCompleted() {
|
||||||
root.closed()
|
root.closed()
|
||||||
active = false
|
active = false
|
||||||
|
useButtonPosition = false // Reset button position usage
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
@ -113,8 +134,8 @@ Loader {
|
||||||
anchors.left: true
|
anchors.left: true
|
||||||
anchors.right: true
|
anchors.right: true
|
||||||
anchors.bottom: true
|
anchors.bottom: true
|
||||||
margins.top: Settings.data.bar.position === "top" ? Style.barHeight * scaling : 0
|
margins.top: !barAtBottom ? barHeight : 0
|
||||||
margins.bottom: Settings.data.bar.position === "bottom" ? Style.barHeight * scaling : 0
|
margins.bottom: barAtBottom ? barHeight : 0
|
||||||
|
|
||||||
// Close any panel with Esc without requiring focus
|
// Close any panel with Esc without requiring focus
|
||||||
Shortcut {
|
Shortcut {
|
||||||
|
|
@ -140,21 +161,41 @@ Loader {
|
||||||
width: panelWidth
|
width: panelWidth
|
||||||
height: panelHeight
|
height: panelHeight
|
||||||
|
|
||||||
anchors {
|
property int calculatedX: {
|
||||||
centerIn: panelAnchorCentered ? parent : null
|
if (root.useButtonPosition) {
|
||||||
left: !panelAnchorCentered && panelAnchorLeft ? parent.left : parent.center
|
// Position panel relative to button
|
||||||
right: !panelAnchorCentered && panelAnchorRight ? parent.right : parent.center
|
var targetX = root.buttonPosition.x + (root.buttonWidth / 2) - (panelWidth / 2)
|
||||||
top: !panelAnchorCentered && (Settings.data.bar.position === "top") ? parent.top : undefined
|
|
||||||
bottom: !panelAnchorCentered && (Settings.data.bar.position === "bottom") ? parent.bottom : undefined
|
|
||||||
|
|
||||||
// margins
|
// Keep panel within screen bounds
|
||||||
topMargin: !panelAnchorCentered
|
var maxX = panelWindow.width - panelWidth - (Style.marginS * scaling)
|
||||||
&& (Settings.data.bar.position === "top") ? Style.marginS * scaling : undefined
|
var minX = Style.marginS * scaling
|
||||||
bottomMargin: !panelAnchorCentered
|
|
||||||
&& (Settings.data.bar.position === "bottom") ? Style.marginS * scaling : undefined
|
return Math.max(minX, Math.min(targetX, maxX))
|
||||||
rightMargin: !panelAnchorCentered && panelAnchorRight ? Style.marginS * scaling : undefined
|
} else if (!panelAnchorCentered && panelAnchorLeft) {
|
||||||
|
return Style.marginS * scaling
|
||||||
|
} else if (!panelAnchorCentered && panelAnchorRight) {
|
||||||
|
return panelWindow.width - panelWidth - (Style.marginS * scaling)
|
||||||
|
} else {
|
||||||
|
return (panelWindow.width - panelWidth) / 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property int calculatedY: {
|
||||||
|
// Position panel below or above the bar
|
||||||
|
if (!panelAnchorCentered) {
|
||||||
|
if (!barAtBottom) {
|
||||||
|
return Style.marginS * scaling
|
||||||
|
} else {
|
||||||
|
return panelWindow.height - panelHeight - (Style.marginS * scaling)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (panelWindow.height - panelHeight) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x: calculatedX
|
||||||
|
y: calculatedY
|
||||||
|
|
||||||
scale: root.scaleValue
|
scale: root.scaleValue
|
||||||
opacity: root.opacityValue
|
opacity: root.opacityValue
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue