Bar widgets: modular loading refactoring via BarWidgetRegistry+NWidgetLoader
- Hot reload is working again. - Should also be more memory efficient on multi monitors.
This commit is contained in:
parent
a110a0d636
commit
a10d55e7f5
36 changed files with 514 additions and 446 deletions
|
|
@ -31,6 +31,12 @@ Loader {
|
|||
signal opened
|
||||
signal closed
|
||||
|
||||
Component.onCompleted: {
|
||||
// console.log("Oh Yeah")
|
||||
// console.log(objectName)
|
||||
PanelService.registerPanel(root)
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
function toggle(aScreen) {
|
||||
if (!active || isClosing) {
|
||||
|
|
@ -53,7 +59,7 @@ Loader {
|
|||
opacityValue = 1.0
|
||||
}
|
||||
|
||||
PanelService.registerOpen(root)
|
||||
PanelService.willOpenPanel(root)
|
||||
|
||||
active = true
|
||||
root.opened()
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@ Item {
|
|||
property color collapsedIconColor: Color.mOnSurface
|
||||
property real sizeMultiplier: 0.8
|
||||
property bool autoHide: false
|
||||
// When true, keep the pill expanded regardless of hover state
|
||||
property bool forceShown: false
|
||||
property bool forceOpen: false
|
||||
property bool disableOpen: false
|
||||
|
||||
// Effective shown state (true if hovered/animated open or forced)
|
||||
readonly property bool effectiveShown: forceShown || showPill
|
||||
readonly property bool effectiveShown: forceOpen || showPill
|
||||
|
||||
signal shown
|
||||
signal hidden
|
||||
|
|
@ -85,7 +86,7 @@ Item {
|
|||
height: iconSize
|
||||
radius: width * 0.5
|
||||
// When forced shown, match pill background; otherwise use accent when hovered
|
||||
color: forceShown ? pillColor : (showPill ? iconCircleColor : Color.mSurfaceVariant)
|
||||
color: forceOpen ? pillColor : (showPill ? iconCircleColor : Color.mSurfaceVariant)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ Item {
|
|||
text: root.icon
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
// When forced shown, use pill text color; otherwise accent color when hovered
|
||||
color: forceShown ? textColor : (showPill ? iconTextColor : Color.mOnSurface)
|
||||
color: forceOpen ? textColor : (showPill ? iconTextColor : Color.mOnSurface)
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
|
@ -194,18 +195,21 @@ Item {
|
|||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
if (!forceShown) {
|
||||
root.entered()
|
||||
tooltip.show()
|
||||
if (disableOpen) {
|
||||
return
|
||||
}
|
||||
if (!forceOpen) {
|
||||
showDelayed()
|
||||
}
|
||||
tooltip.show()
|
||||
root.entered()
|
||||
}
|
||||
onExited: {
|
||||
if (!forceShown) {
|
||||
root.exited()
|
||||
if (!forceOpen) {
|
||||
hide()
|
||||
}
|
||||
tooltip.hide()
|
||||
root.exited()
|
||||
}
|
||||
onClicked: {
|
||||
root.clicked()
|
||||
|
|
@ -226,7 +230,7 @@ Item {
|
|||
}
|
||||
|
||||
function hide() {
|
||||
if (forceShown) {
|
||||
if (forceOpen) {
|
||||
return
|
||||
}
|
||||
if (showPill) {
|
||||
|
|
@ -245,8 +249,8 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
onForceShownChanged: {
|
||||
if (forceShown) {
|
||||
onForceOpenChanged: {
|
||||
if (forceOpen) {
|
||||
// Immediately lock open without animations
|
||||
showAnim.stop()
|
||||
hideAnim.stop()
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ NBox {
|
|||
colorFgHover: Color.mOnSecondary
|
||||
enabled: comboBox.selectedKey !== ""
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: Style.marginS * scaling
|
||||
onClicked: {
|
||||
if (comboBox.currentKey !== "") {
|
||||
addWidget(comboBox.currentKey, sectionName.toLowerCase())
|
||||
|
|
@ -174,27 +175,27 @@ NBox {
|
|||
anchors.fill: parent
|
||||
drag.target: parent
|
||||
|
||||
onPressed: {
|
||||
// Check if the click is on the close button area
|
||||
const closeButtonX = widgetContent.x + widgetContent.width - 20 * scaling
|
||||
const closeButtonY = widgetContent.y
|
||||
const closeButtonWidth = 20 * scaling
|
||||
const closeButtonHeight = 20 * scaling
|
||||
onPressed: mouse => {
|
||||
// Check if the click is on the close button area
|
||||
const closeButtonX = widgetContent.x + widgetContent.width - 20 * scaling
|
||||
const closeButtonY = widgetContent.y
|
||||
const closeButtonWidth = 20 * scaling
|
||||
const closeButtonHeight = 20 * scaling
|
||||
|
||||
if (mouseX >= closeButtonX && mouseX <= closeButtonX + closeButtonWidth && mouseY >= closeButtonY
|
||||
&& mouseY <= closeButtonY + closeButtonHeight) {
|
||||
// Click is on the close button, don't start drag
|
||||
mouse.accepted = false
|
||||
return
|
||||
}
|
||||
if (mouseX >= closeButtonX && mouseX <= closeButtonX + closeButtonWidth
|
||||
&& mouseY >= closeButtonY && mouseY <= closeButtonY + closeButtonHeight) {
|
||||
// Click is on the close button, don't start drag
|
||||
mouse.accepted = false
|
||||
return
|
||||
}
|
||||
|
||||
Logger.log("NWidgetCard", `Started dragging widget: ${modelData} at index ${index}`)
|
||||
// Bring to front when starting drag
|
||||
widgetItem.z = 1000
|
||||
}
|
||||
Logger.log("NSectionEditor", `Started dragging widget: ${modelData} at index ${index}`)
|
||||
// Bring to front when starting drag
|
||||
widgetItem.z = 1000
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
Logger.log("NWidgetCard", `Released widget: ${modelData} at index ${index}`)
|
||||
Logger.log("NSectionEditor", `Released widget: ${modelData} at index ${index}`)
|
||||
// Reset z-index when drag ends
|
||||
widgetItem.z = 0
|
||||
|
||||
|
|
@ -232,12 +233,12 @@ NBox {
|
|||
const fromIndex = index
|
||||
const toIndex = targetIndex
|
||||
Logger.log(
|
||||
"NWidgetCard",
|
||||
"NSectionEditor",
|
||||
`Dropped widget from index ${fromIndex} to position ${toIndex} (distance: ${minDistance.toFixed(
|
||||
2)})`)
|
||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||
} else {
|
||||
Logger.log("NWidgetCard", `No valid drop target found for widget at index ${index}`)
|
||||
Logger.log("NSectionEditor", `No valid drop target found for widget at index ${index}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -264,16 +265,16 @@ NBox {
|
|||
}
|
||||
|
||||
onEntered: function (drag) {
|
||||
Logger.log("NWidgetCard", "Entered start drop zone")
|
||||
Logger.log("NSectionEditor", "Entered start drop zone")
|
||||
}
|
||||
|
||||
onDropped: function (drop) {
|
||||
Logger.log("NWidgetCard", "Dropped on start zone")
|
||||
Logger.log("NSectionEditor", "Dropped on start zone")
|
||||
if (drop.source && drop.source.widgetIndex !== undefined) {
|
||||
const fromIndex = drop.source.widgetIndex
|
||||
const toIndex = 0 // Insert at the beginning
|
||||
if (fromIndex !== toIndex) {
|
||||
Logger.log("NWidgetCard", `Dropped widget from index ${fromIndex} to beginning`)
|
||||
Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to beginning`)
|
||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||
}
|
||||
}
|
||||
|
|
@ -299,16 +300,16 @@ NBox {
|
|||
}
|
||||
|
||||
onEntered: function (drag) {
|
||||
Logger.log("NWidgetCard", "Entered end drop zone")
|
||||
Logger.log("NSectionEditor", "Entered end drop zone")
|
||||
}
|
||||
|
||||
onDropped: function (drop) {
|
||||
Logger.log("NWidgetCard", "Dropped on end zone")
|
||||
Logger.log("NSectionEditor", "Dropped on end zone")
|
||||
if (drop.source && drop.source.widgetIndex !== undefined) {
|
||||
const fromIndex = drop.source.widgetIndex
|
||||
const toIndex = widgetModel.length // Insert at the end
|
||||
if (fromIndex !== toIndex) {
|
||||
Logger.log("NWidgetCard", `Dropped widget from index ${fromIndex} to end`)
|
||||
Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to end`)
|
||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||
}
|
||||
}
|
||||
46
Widgets/NWidgetLoader.qml
Normal file
46
Widgets/NWidgetLoader.qml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Services
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string widgetName: ""
|
||||
property var widgetProps: ({})
|
||||
property bool enabled: true
|
||||
|
||||
// Don't reserve space unless the loaded widget is really visible
|
||||
implicitWidth: loader.item ? loader.item.visible ? loader.item.implicitWidth : 0 : 0
|
||||
implicitHeight: loader.item ? loader.item.visible ? loader.item.implicitHeight : 0 : 0
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
|
||||
anchors.fill: parent
|
||||
active: enabled && widgetName !== ""
|
||||
sourceComponent: {
|
||||
if (!active) {
|
||||
return null
|
||||
}
|
||||
return BarWidgetRegistry.getWidget(widgetName)
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
if (item && widgetProps) {
|
||||
// Apply properties to loaded widget
|
||||
for (var prop in widgetProps) {
|
||||
if (item.hasOwnProperty(prop)) {
|
||||
item[prop] = widgetProps[prop]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error handling
|
||||
onWidgetNameChanged: {
|
||||
if (widgetName && !BarWidgetRegistry.hasWidget(widgetName)) {
|
||||
Logger.warn("WidgetLoader", "Widget not found in registry:", widgetName)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue