From 007cb3269021b977b87d38c07abe70a82da6d479 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 19 Apr 2026 22:21:49 +0200 Subject: [PATCH 1/9] test blob bounciness --- Drawers/Windows.qml | 16 +++++++++++++--- Modules/ClipWrapper.qml | 6 +++++- Modules/Updates/UpdatesPopout.qml | 2 +- Modules/Wrapper.qml | 3 +-- Plugins/ZShell/Blobs/blobrect.cpp | 4 ++-- Plugins/ZShell/Blobs/blobshape.cpp | 17 ++--------------- Plugins/ZShell/Blobs/blobshape.hpp | 10 +++------- shell.qml | 2 +- 8 files changed, 28 insertions(+), 32 deletions(-) diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 460484f..790b9c6 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -219,10 +219,20 @@ Variants { PanelBg { id: popoutBg - deformAmount: 0.15 * Config.appearance.deform.scale - implicitWidth: panels.popouts.width + // Extra height to prevent vertical movement deformation partially detaching panel from bar + property real extraHeight: panels.popouts.isDetached ? 0 : 0.2 + + deformAmount: panels.popouts.isDetached ? 0.05 * Config.appearance.deform.scale : panels.popouts.hasCurrent ? 0.15 * Config.appearance.deform.scale : 0.1 * Config.appearance.deform.scale + implicitHeight: panels.popouts.height * (1 + extraHeight) + implicitWidth: panels.popoutsWrapper.width panel: panels.popoutsWrapper radius: (panels.popouts.currentName.startsWith("audio") || panels.popouts.currentName.startsWith("updates")) ? Appearance.rounding.normal : Appearance.rounding.smallest + y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight + + Behavior on extraHeight { + Anim { + } + } } PanelBg { @@ -342,7 +352,7 @@ Variants { required property Item panel deformScale: deformAmount / 10000 - group: panel.width > 0 && panel.height > 0 ? blobGroup : null + group: blobGroup implicitHeight: panel.height implicitWidth: panel.width radius: Appearance.rounding.smallest diff --git a/Modules/ClipWrapper.qml b/Modules/ClipWrapper.qml index d9265d0..6b735f5 100644 --- a/Modules/ClipWrapper.qml +++ b/Modules/ClipWrapper.qml @@ -17,12 +17,16 @@ Item { implicitWidth: content.implicitWidth visible: width > 0 && height > 0 x: { - const off = content.currentCenter - content.nonAnimWidth / 2; + if (content.isDetached) + return (parent.width - content.nonAnimWidth) / 2; + + const off = content.currentCenter - Config.barConfig.border - content.nonAnimWidth / 2; const diff = parent.width - Math.floor(off + content.nonAnimWidth); if (diff < 0) return off + diff; return Math.floor(Math.max(off, 0)); } + y: content.isDetached ? (parent.height - content.nonAnimHeight) / 2 : 0 Behavior on offsetScale { Anim { diff --git a/Modules/Updates/UpdatesPopout.qml b/Modules/Updates/UpdatesPopout.qml index c8b7dd3..4284c3e 100644 --- a/Modules/Updates/UpdatesPopout.qml +++ b/Modules/Updates/UpdatesPopout.qml @@ -25,7 +25,7 @@ CustomClippingRect { anchors.centerIn: parent height: 200 visible: script.values.length === 0 - width: 300 + width: 600 MaterialIcon { id: noUpdatesIcon diff --git a/Modules/Wrapper.qml b/Modules/Wrapper.qml index 8b7f4e9..8bf0ab7 100644 --- a/Modules/Wrapper.qml +++ b/Modules/Wrapper.qml @@ -15,6 +15,7 @@ Item { property real currentCenter property alias currentName: popoutState.currentName property string detachedMode + readonly property bool isDetached: detachedMode.length > 0 property alias hasCurrent: popoutState.hasCurrent readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth @@ -50,8 +51,6 @@ Item { implicitWidth: nonAnimWidth Behavior on implicitHeight { - enabled: root.offsetScale < 1 - Anim { duration: root.animLength easing.bezierCurve: root.animCurve diff --git a/Plugins/ZShell/Blobs/blobrect.cpp b/Plugins/ZShell/Blobs/blobrect.cpp index dc03432..aeedae1 100644 --- a/Plugins/ZShell/Blobs/blobrect.cpp +++ b/Plugins/ZShell/Blobs/blobrect.cpp @@ -14,8 +14,6 @@ BlobRect::~BlobRect() { } void BlobRect::updatePolish() { - BlobShape::updatePolish(); - if (m_physicsActive) { // Check if deformation is visually imperceptible float totalDelta = std::abs(m_dm00 - 1.0f) + std::abs(m_dm01) + std::abs(m_dm11 - 1.0f); @@ -41,6 +39,8 @@ void BlobRect::updatePolish() { Qt::QueuedConnection); } } + + BlobShape::updatePolish(); } void BlobRect::updatePhysics() { diff --git a/Plugins/ZShell/Blobs/blobshape.cpp b/Plugins/ZShell/Blobs/blobshape.cpp index d284a5e..40a7eab 100644 --- a/Plugins/ZShell/Blobs/blobshape.cpp +++ b/Plugins/ZShell/Blobs/blobshape.cpp @@ -68,21 +68,8 @@ void BlobShape::componentComplete() { void BlobShape::geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry) { QQuickItem::geometryChange(newGeometry, oldGeometry); updateCenteredDeformMatrix(); - if (m_group) { - // Accumulate sub-pixel drift so slow movements don't desync the shader - m_pendingDx += static_cast(newGeometry.x() - oldGeometry.x()); - m_pendingDy += static_cast(newGeometry.y() - oldGeometry.y()); - m_pendingDw += static_cast(newGeometry.width() - oldGeometry.width()); - m_pendingDh += static_cast(newGeometry.height() - oldGeometry.height()); - - if (std::abs(m_pendingDx) > 0.5f || std::abs(m_pendingDy) > 0.5f || - std::abs(m_pendingDw) > 0.5f || std::abs(m_pendingDh) > 0.5f) { - m_pendingDx = 0; - m_pendingDy = 0; - m_pendingDw = 0; - m_pendingDh = 0; - m_group->markShapeDirty(this); - } + if (m_group && newGeometry != oldGeometry) { + m_group->markShapeDirty(this); } } diff --git a/Plugins/ZShell/Blobs/blobshape.hpp b/Plugins/ZShell/Blobs/blobshape.hpp index f130c23..4acfe1d 100644 --- a/Plugins/ZShell/Blobs/blobshape.hpp +++ b/Plugins/ZShell/Blobs/blobshape.hpp @@ -82,13 +82,9 @@ float m_cachedPaddedW = 0; float m_cachedPaddedH = 0; QRectF m_localPaddedRect; QVector m_cachedRects; -int m_cachedMyIndex = -2; -float m_pendingDx = 0; -float m_pendingDy = 0; -float m_pendingDw = 0; -float m_pendingDh = 0; -bool m_cachedHasInverted = false; -float m_cachedInvertedRadius = 0; + int m_cachedMyIndex = -2; + bool m_cachedHasInverted = false; + float m_cachedInvertedRadius = 0; float m_cachedInvertedOuter[4] = {}; float m_cachedInvertedInner[4] = {}; }; diff --git a/shell.qml b/shell.qml index 92e91f9..9bf3bc9 100644 --- a/shell.qml +++ b/shell.qml @@ -1,6 +1,6 @@ //@ pragma UseQApplication //@ pragma Env QSG_RENDER_LOOP=threaded -//@ pragma Env QSG_RHI_BACKEND=vulkan +// @ pragma Env QSG_RHI_BACKEND=vulkan //@ pragma Env QSG_USE_SIMPLE_ANIMATION_DRIVER=0 //@ pragma Env QS_NO_RELOAD_POPUP=1 //@ pragma Env QT_SCALE_FACTOR_ROUNDING_POLICY=Round From 2fd01a7274dd2c1bc1ea9336b196dae42d21df5d Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 19 Apr 2026 22:31:46 +0200 Subject: [PATCH 2/9] test blob bounciness, slight revert --- Plugins/ZShell/Blobs/blobrect.cpp | 4 ++-- Plugins/ZShell/Blobs/blobshape.cpp | 17 +++++++++++++++-- Plugins/ZShell/Blobs/blobshape.hpp | 10 +++++++--- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Plugins/ZShell/Blobs/blobrect.cpp b/Plugins/ZShell/Blobs/blobrect.cpp index aeedae1..dc03432 100644 --- a/Plugins/ZShell/Blobs/blobrect.cpp +++ b/Plugins/ZShell/Blobs/blobrect.cpp @@ -14,6 +14,8 @@ BlobRect::~BlobRect() { } void BlobRect::updatePolish() { + BlobShape::updatePolish(); + if (m_physicsActive) { // Check if deformation is visually imperceptible float totalDelta = std::abs(m_dm00 - 1.0f) + std::abs(m_dm01) + std::abs(m_dm11 - 1.0f); @@ -39,8 +41,6 @@ void BlobRect::updatePolish() { Qt::QueuedConnection); } } - - BlobShape::updatePolish(); } void BlobRect::updatePhysics() { diff --git a/Plugins/ZShell/Blobs/blobshape.cpp b/Plugins/ZShell/Blobs/blobshape.cpp index 40a7eab..d284a5e 100644 --- a/Plugins/ZShell/Blobs/blobshape.cpp +++ b/Plugins/ZShell/Blobs/blobshape.cpp @@ -68,8 +68,21 @@ void BlobShape::componentComplete() { void BlobShape::geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry) { QQuickItem::geometryChange(newGeometry, oldGeometry); updateCenteredDeformMatrix(); - if (m_group && newGeometry != oldGeometry) { - m_group->markShapeDirty(this); + if (m_group) { + // Accumulate sub-pixel drift so slow movements don't desync the shader + m_pendingDx += static_cast(newGeometry.x() - oldGeometry.x()); + m_pendingDy += static_cast(newGeometry.y() - oldGeometry.y()); + m_pendingDw += static_cast(newGeometry.width() - oldGeometry.width()); + m_pendingDh += static_cast(newGeometry.height() - oldGeometry.height()); + + if (std::abs(m_pendingDx) > 0.5f || std::abs(m_pendingDy) > 0.5f || + std::abs(m_pendingDw) > 0.5f || std::abs(m_pendingDh) > 0.5f) { + m_pendingDx = 0; + m_pendingDy = 0; + m_pendingDw = 0; + m_pendingDh = 0; + m_group->markShapeDirty(this); + } } } diff --git a/Plugins/ZShell/Blobs/blobshape.hpp b/Plugins/ZShell/Blobs/blobshape.hpp index 4acfe1d..f130c23 100644 --- a/Plugins/ZShell/Blobs/blobshape.hpp +++ b/Plugins/ZShell/Blobs/blobshape.hpp @@ -82,9 +82,13 @@ float m_cachedPaddedW = 0; float m_cachedPaddedH = 0; QRectF m_localPaddedRect; QVector m_cachedRects; - int m_cachedMyIndex = -2; - bool m_cachedHasInverted = false; - float m_cachedInvertedRadius = 0; +int m_cachedMyIndex = -2; +float m_pendingDx = 0; +float m_pendingDy = 0; +float m_pendingDw = 0; +float m_pendingDh = 0; +bool m_cachedHasInverted = false; +float m_cachedInvertedRadius = 0; float m_cachedInvertedOuter[4] = {}; float m_cachedInvertedInner[4] = {}; }; From c1035e8a065ee3b06b43a0db779d9556414825ef Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 19 Apr 2026 22:55:51 +0200 Subject: [PATCH 3/9] **bounciness** --- Drawers/Interactions.qml | 32 +++---- Drawers/Panels.qml | 34 +++++--- Drawers/Windows.qml | 6 +- Modules/Dashboard/Wrapper.qml | 81 ++++------------- Modules/Dock/Wrapper.qml | 87 +++---------------- Modules/Launcher/Wrapper.qml | 59 +++---------- .../Notifications/Sidebar/Utils/Wrapper.qml | 64 +++----------- Modules/Notifications/Sidebar/Wrapper.qml | 45 +++------- Modules/Notifications/Wrapper.qml | 4 +- Modules/Osd/Wrapper.qml | 72 ++++++--------- Modules/Resources/Wrapper.qml | 81 ++++------------- 11 files changed, 159 insertions(+), 406 deletions(-) diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index e09228f..c3abfe8 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -96,25 +96,25 @@ CustomMouseArea { if (dragY < -10) visibilities.dock = true; - if (panels.sidebar.width === 0) { - const showOsd = inRightPanel(panels.osd, x, y); + if (panels.sidebar.width === 0) { + const showOsd = inRightPanel(panels.osdWrapper, x, y); - if (showOsd) { - osdShortcutActive = false; - root.panels.osd.hovered = true; - } - } else { - const outOfSidebar = x < width - panels.sidebar.width; - const showOsd = outOfSidebar && inRightPanel(panels.osd, x, y); + if (showOsd) { + osdShortcutActive = false; + root.panels.osd.hovered = true; + } + } else { + const outOfSidebar = x < width - panels.sidebar.width; + const showOsd = outOfSidebar && inRightPanel(panels.osdWrapper, x, y); - if (!osdShortcutActive) { - visibilities.osd = showOsd; - root.panels.osd.hovered = showOsd; - } else if (showOsd) { - osdShortcutActive = false; - root.panels.osd.hovered = true; + if (!osdShortcutActive) { + visibilities.osd = showOsd; + root.panels.osd.hovered = showOsd; + } else if (showOsd) { + osdShortcutActive = false; + root.panels.osd.hovered = true; + } } - } if (Config.dock.enable && !Config.dock.hoverToReveal && !visibilities.dock && !visibilities.launcher && inBottomPanel(panels.dock, x, y)) visibilities.dock = true; diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index a328fa7..b9d230c 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -26,6 +26,7 @@ Item { readonly property alias launcher: launcher readonly property alias notifications: notifications readonly property alias osd: osd + readonly property alias osdWrapper: osdWrapper readonly property alias popouts: popouts.content readonly property alias popoutsWrapper: popouts readonly property alias resources: resources @@ -48,6 +49,28 @@ Item { visibilities: root.visibilities } + Item { + id: osdWrapper + + anchors.right: parent.right + anchors.rightMargin: sidebar.width * (1 - sidebar.offsetScale) + anchors.verticalCenter: parent.verticalCenter + clip: sidebar.visible + + implicitHeight: osd.implicitHeight + implicitWidth: osd.implicitWidth * (1 - osd.offsetScale) + + Osd.Wrapper { + id: osd + + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + screen: root.screen + sidebarOrSessionVisible: sidebar.visible + visibilities: root.visibilities + } + } + Drawing.Wrapper { id: drawing @@ -58,17 +81,6 @@ Item { visibilities: root.visibilities } - Osd.Wrapper { - id: osd - - anchors.right: parent.right - anchors.rightMargin: sidebar.width - anchors.verticalCenter: parent.verticalCenter - clip: sidebar.width > 0 - screen: root.screen - visibilities: root.visibilities - } - Modules.ClipWrapper { id: popouts diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 790b9c6..b1364b5 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -188,7 +188,7 @@ Variants { bottomLeftRadius: 0 deformAmount: 0.1 * Config.appearance.deform.scale - exclude: panels.sidebar.offsetscale > 0.08 ? [] : [utilsBg] + exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg] implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2 panel: panels.sidebar } @@ -197,8 +197,10 @@ Variants { id: osdBg deformAmount: 0.1 * Config.appearance.deform.scale - panel: panels.osd + implicitWidth: panels.osd.width + panel: panels.osdWrapper radius: 20 + x: panels.osdWrapper.x + panels.osd.x + Config.barConfig.border } PanelBg { diff --git a/Modules/Dashboard/Wrapper.qml b/Modules/Dashboard/Wrapper.qml index 11858d6..757eab9 100644 --- a/Modules/Dashboard/Wrapper.qml +++ b/Modules/Dashboard/Wrapper.qml @@ -17,76 +17,33 @@ Item { readonly property real nonAnimHeight: state === "visible" ? (content.item?.nonAnimHeight ?? 0) : 0 required property PersistentProperties visibilities - implicitHeight: 0 - implicitWidth: content.implicitWidth - visible: height > 0 + readonly property bool shouldBeActive: root.visibilities.dashboard && Config.dashboard.enabled + property real offsetScale: shouldBeActive ? 0 : 1 - states: State { - name: "visible" - when: root.visibilities.dashboard && Config.dashboard.enabled + visible: offsetScale < 1 + anchors.topMargin: (-implicitHeight - 5) * offsetScale + implicitHeight: content.implicitHeight + implicitWidth: content.implicitWidth || 854 // Hard coded fallback for first open + opacity: 1 - offsetScale - PropertyChanges { - root.implicitHeight: content.implicitHeight - } - } - transitions: [ - Transition { - from: "" - to: "visible" - - Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - }, - Transition { - from: "visible" - to: "" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - } - ] - - onStateChanged: { - if (state === "visible" && timer.running) { - timer.triggered(); - timer.stop(); + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } - Timer { - id: timer + Loader { + id: content - interval: Appearance.anim.durations.extraLarge - running: true + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter - onTriggered: { - content.active = Qt.binding(() => (root.visibilities.dashboard && Config.dashboard.enabled) || root.visible); - content.visible = true; - } - } + active: root.shouldBeActive || root.visible - CustomClippingRect { - anchors.fill: parent - - Loader { - id: content - - active: true - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - visible: false - - sourceComponent: Content { - state: root.dashState - visibilities: root.visibilities - } + sourceComponent: Content { + state: root.dashState + visibilities: root.visibilities } } } diff --git a/Modules/Dock/Wrapper.qml b/Modules/Dock/Wrapper.qml index 667ab62..26dbb15 100644 --- a/Modules/Dock/Wrapper.qml +++ b/Modules/Dock/Wrapper.qml @@ -11,97 +11,36 @@ Item { property int contentHeight required property var panels required property ShellScreen screen - readonly property bool shouldBeActive: visibilities.dock required property PersistentProperties visibilities - implicitHeight: 0 - implicitWidth: content.implicitWidth - visible: height > 0 + readonly property bool shouldBeActive: visibilities.dock + property real offsetScale: shouldBeActive ? 0 : 1 - Behavior on implicitWidth { + visible: offsetScale < 1 + anchors.bottomMargin: (-implicitHeight - 5) * offsetScale + implicitHeight: content.implicitHeight + implicitWidth: content.implicitWidth || 400 + opacity: 1 - offsetScale + + Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.small - } - } - - onShouldBeActiveChanged: { - if (shouldBeActive) { - timer.stop(); - hideAnim.stop(); - showAnim.start(); - } else { - showAnim.stop(); - hideAnim.start(); - } - } - - SequentialAnimation { - id: showAnim - - Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects - property: "implicitHeight" - target: root - to: root.contentHeight - } - - ScriptAction { - script: root.implicitHeight = Qt.binding(() => content.implicitHeight) - } - } - - SequentialAnimation { - id: hideAnim - - ScriptAction { - script: root.implicitHeight = root.implicitHeight - } - - Anim { - easing.bezierCurve: Appearance.anim.curves.expressiveEffects - property: "implicitHeight" - target: root - to: 0 - } - } - - Timer { - id: timer - - interval: Appearance.anim.durations.small - - onRunningChanged: { - if (running && !root.shouldBeActive) { - content.visible = false; - content.active = true; - } else { - content.active = Qt.binding(() => root.shouldBeActive || root.visible); - content.visible = true; - if (showAnim.running) { - showAnim.stop(); - showAnim.start(); - } - } + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } Loader { id: content - active: false anchors.left: parent.left anchors.top: parent.top - visible: false + + active: root.shouldBeActive || root.visible sourceComponent: Content { panels: root.panels screen: root.screen visibilities: root.visibilities - - Component.onCompleted: root.contentHeight = implicitHeight } - - Component.onCompleted: timer.start() } } diff --git a/Modules/Launcher/Wrapper.qml b/Modules/Launcher/Wrapper.qml index 677abb1..a2c6ea6 100644 --- a/Modules/Launcher/Wrapper.qml +++ b/Modules/Launcher/Wrapper.qml @@ -21,53 +21,27 @@ Item { } required property var panels required property ShellScreen screen - readonly property bool shouldBeActive: visibilities.launcher required property PersistentProperties visibilities + readonly property bool shouldBeActive: visibilities.launcher + property real offsetScale: shouldBeActive ? 0 : 1 - implicitHeight: 0 - implicitWidth: content.implicitWidth - visible: height > 0 + visible: offsetScale < 1 + anchors.bottomMargin: (-implicitHeight - 5) * offsetScale + implicitHeight: contentHeight + implicitWidth: content.implicitWidth || 400 + opacity: 1 - offsetScale + + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } onMaxHeightChanged: timer.start() onShouldBeActiveChanged: { if (shouldBeActive) { timer.stop(); - hideAnim.stop(); - showAnim.start(); - } else { - showAnim.stop(); - hideAnim.start(); - } - } - - SequentialAnimation { - id: showAnim - - Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects - property: "implicitHeight" - target: root - to: root.contentHeight - } - - ScriptAction { - script: root.implicitHeight = Qt.binding(() => content.implicitHeight) - } - } - - SequentialAnimation { - id: hideAnim - - ScriptAction { - script: root.implicitHeight = root.implicitHeight - } - - Anim { - easing.bezierCurve: Appearance.anim.curves.expressiveEffects - property: "implicitHeight" - target: root - to: 0 } } @@ -105,10 +79,6 @@ Item { root.contentHeight = Math.min(root.maxHeight, content.implicitHeight); content.active = Qt.binding(() => root.shouldBeActive || root.visible); content.visible = true; - if (showAnim.running) { - showAnim.stop(); - showAnim.start(); - } } } } @@ -119,7 +89,6 @@ Item { active: false anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - visible: false sourceComponent: Content { maxHeight: root.maxHeight diff --git a/Modules/Notifications/Sidebar/Utils/Wrapper.qml b/Modules/Notifications/Sidebar/Utils/Wrapper.qml index b37fd1c..81d7d00 100644 --- a/Modules/Notifications/Sidebar/Utils/Wrapper.qml +++ b/Modules/Notifications/Sidebar/Utils/Wrapper.qml @@ -20,69 +20,29 @@ Item { required property Item sidebar required property var visibilities - implicitHeight: 0 - implicitWidth: sidebar.visible ? sidebar.width : Config.utilities.sizes.width - visible: height > 0 + property real offsetScale: shouldBeActive ? 0 : 1 - states: State { - name: "visible" - when: root.shouldBeActive + visible: offsetScale < 1 + anchors.bottomMargin: (-implicitHeight - 5) * offsetScale + implicitHeight: content.implicitHeight + 8 * 2 + implicitWidth: sidebar.width * (1 - sidebar.offsetScale) + opacity: 1 - offsetScale - PropertyChanges { - root.implicitHeight: content.implicitHeight + 8 * 2 - } - } - transitions: [ - Transition { - from: "" - to: "visible" - - Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - }, - Transition { - from: "visible" - to: "" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - } - ] - - onStateChanged: { - if (state === "visible" && timer.running) { - timer.triggered(); - timer.stop(); - } - } - - Timer { - id: timer - - interval: 1000 - running: true - - onTriggered: { - content.active = Qt.binding(() => root.shouldBeActive || root.visible); - content.visible = true; + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } Loader { id: content - active: true anchors.left: parent.left anchors.margins: 8 anchors.top: parent.top - visible: false + + active: root.shouldBeActive || root.visible sourceComponent: Content { implicitWidth: root.implicitWidth - 8 * 2 diff --git a/Modules/Notifications/Sidebar/Wrapper.qml b/Modules/Notifications/Sidebar/Wrapper.qml index 4e10cd4..e48f9fc 100644 --- a/Modules/Notifications/Sidebar/Wrapper.qml +++ b/Modules/Notifications/Sidebar/Wrapper.qml @@ -12,57 +12,36 @@ Item { } required property var visibilities - implicitWidth: 0 - visible: width > 0 + readonly property bool shouldBeActive: root.visibilities.sidebar && Config.sidebar.enabled + property real offsetScale: shouldBeActive ? 0 : 1 - states: State { - name: "visible" - when: root.visibilities.sidebar + visible: offsetScale < 1 + anchors.rightMargin: (-implicitWidth - 5) * offsetScale + implicitWidth: Config.sidebar.sizes.width + opacity: 1 - offsetScale - PropertyChanges { - root.implicitWidth: Config.sidebar.sizes.width + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } - transitions: [ - Transition { - from: "" - to: "visible" - - Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitWidth" - target: root - } - }, - Transition { - from: "visible" - to: "" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitWidth" - target: root - } - } - ] Loader { id: content - active: true anchors.bottom: parent.bottom anchors.bottomMargin: 0 anchors.left: parent.left anchors.margins: 8 anchors.top: parent.top + active: root.shouldBeActive || root.visible + sourceComponent: Content { implicitWidth: Config.sidebar.sizes.width - 8 * 2 props: root.props visibilities: root.visibilities } - - Component.onCompleted: active = Qt.binding(() => (root.visibilities.sidebar && Config.sidebar.enabled) || root.visible) } } diff --git a/Modules/Notifications/Wrapper.qml b/Modules/Notifications/Wrapper.qml index 1e7038f..08918ef 100644 --- a/Modules/Notifications/Wrapper.qml +++ b/Modules/Notifications/Wrapper.qml @@ -22,8 +22,8 @@ Item { } transitions: Transition { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial property: "implicitHeight" target: root } diff --git a/Modules/Osd/Wrapper.qml b/Modules/Osd/Wrapper.qml index b0815e8..3d9c3c1 100644 --- a/Modules/Osd/Wrapper.qml +++ b/Modules/Osd/Wrapper.qml @@ -26,40 +26,22 @@ Item { timer.restart(); } + property real offsetScale: shouldBeActive ? 0 : 1 + required property bool sidebarOrSessionVisible + property real sidebarOffset: sidebarOrSessionVisible ? 12 : 0 + + visible: offsetScale < 1 + anchors.rightMargin: (-implicitWidth - 5 - sidebarOffset) * offsetScale + implicitWidth: content.implicitWidth implicitHeight: content.implicitHeight - implicitWidth: 0 - visible: width > 0 + opacity: 1 - offsetScale - states: State { - name: "visible" - when: root.shouldBeActive - - PropertyChanges { - root.implicitWidth: content.implicitWidth + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } - transitions: [ - Transition { - from: "" - to: "visible" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitWidth" - target: root - } - }, - Transition { - from: "visible" - to: "" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitWidth" - target: root - } - } - ] Component.onCompleted: { volume = Audio.volume; @@ -113,26 +95,22 @@ Item { } } - CustomClippingRect { - anchors.fill: parent + Loader { + id: content - Loader { - id: content + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter + active: root.shouldBeActive || root.visible - sourceComponent: Content { - brightness: root.brightness - monitor: root.monitor - muted: root.muted - sourceMuted: root.sourceMuted - sourceVolume: root.sourceVolume - visibilities: root.visibilities - volume: root.volume - } - - Component.onCompleted: active = Qt.binding(() => root.shouldBeActive || root.visible) + sourceComponent: Content { + brightness: root.brightness + monitor: root.monitor + muted: root.muted + sourceMuted: root.sourceMuted + sourceVolume: root.sourceVolume + visibilities: root.visibilities + volume: root.volume } } } diff --git a/Modules/Resources/Wrapper.qml b/Modules/Resources/Wrapper.qml index a1f750e..16f7086 100644 --- a/Modules/Resources/Wrapper.qml +++ b/Modules/Resources/Wrapper.qml @@ -11,76 +11,33 @@ Item { readonly property real nonAnimHeight: state === "visible" ? (content.item?.nonAnimHeight ?? 0) : 0 required property PersistentProperties visibilities - implicitHeight: 0 - implicitWidth: content.implicitWidth - visible: height > 0 + readonly property bool shouldBeActive: root.visibilities.resources + property real offsetScale: shouldBeActive ? 0 : 1 - states: State { - name: "visible" - when: root.visibilities.resources + visible: offsetScale < 1 + anchors.topMargin: (-implicitHeight - 5) * offsetScale + implicitHeight: content.implicitHeight + implicitWidth: content.implicitWidth || 854 // Hard coded fallback for first open + opacity: 1 - offsetScale - PropertyChanges { - root.implicitHeight: content.implicitHeight - } - } - transitions: [ - Transition { - from: "" - to: "visible" - - Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - }, - Transition { - from: "visible" - to: "" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - } - ] - - onStateChanged: { - if (state === "visible" && timer.running) { - timer.triggered(); - timer.stop(); + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } - Timer { - id: timer + Loader { + id: content - interval: Appearance.anim.durations.extraLarge - running: true + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter - onTriggered: { - content.active = Qt.binding(() => (root.visibilities.resources) || root.visible); - content.visible = true; - } - } + active: root.shouldBeActive || root.visible - CustomClippingRect { - anchors.fill: parent - - Loader { - id: content - - active: true - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - visible: false - - sourceComponent: Content { - padding: Appearance.padding.normal - visibilities: root.visibilities - } + sourceComponent: Content { + padding: Appearance.padding.normal + visibilities: root.visibilities } } } From 95a682459836a97275ee47dd71ea807785e5caf4 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 19 Apr 2026 23:10:32 +0200 Subject: [PATCH 4/9] dirty fix for notif width --- Drawers/Panels.qml | 2 +- Drawers/Windows.qml | 1 - Modules/Notifications/Wrapper.qml | 3 ++- Modules/Resources/Wrapper.qml | 11 +++++------ 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index b9d230c..23c9f44 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -56,7 +56,6 @@ Item { anchors.rightMargin: sidebar.width * (1 - sidebar.offsetScale) anchors.verticalCenter: parent.verticalCenter clip: sidebar.visible - implicitHeight: osd.implicitHeight implicitWidth: osd.implicitWidth * (1 - osd.offsetScale) @@ -102,6 +101,7 @@ Item { anchors.right: parent.right anchors.top: parent.top panels: root + sidebarPanel: sidebar visibilities: root.visibilities } diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index b1364b5..6556bdd 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -221,7 +221,6 @@ Variants { PanelBg { id: popoutBg - // Extra height to prevent vertical movement deformation partially detaching panel from bar property real extraHeight: panels.popouts.isDetached ? 0 : 0.2 deformAmount: panels.popouts.isDetached ? 0.05 * Config.appearance.deform.scale : panels.popouts.hasCurrent ? 0.15 * Config.appearance.deform.scale : 0.1 * Config.appearance.deform.scale diff --git a/Modules/Notifications/Wrapper.qml b/Modules/Notifications/Wrapper.qml index 08918ef..e430a0c 100644 --- a/Modules/Notifications/Wrapper.qml +++ b/Modules/Notifications/Wrapper.qml @@ -6,10 +6,11 @@ Item { id: root required property Item panels + required property Item sidebarPanel required property var visibilities implicitHeight: content.implicitHeight - implicitWidth: Math.max(panels.sidebar.width, content.implicitWidth) + implicitWidth: content.implicitWidth visible: height > 0 states: State { diff --git a/Modules/Resources/Wrapper.qml b/Modules/Resources/Wrapper.qml index 16f7086..a60f898 100644 --- a/Modules/Resources/Wrapper.qml +++ b/Modules/Resources/Wrapper.qml @@ -9,16 +9,16 @@ Item { id: root readonly property real nonAnimHeight: state === "visible" ? (content.item?.nonAnimHeight ?? 0) : 0 + property real offsetScale: shouldBeActive ? 0 : 1 + readonly property bool shouldBeActive: root.visibilities.resources required property PersistentProperties visibilities - readonly property bool shouldBeActive: root.visibilities.resources - property real offsetScale: shouldBeActive ? 0 : 1 - - visible: offsetScale < 1 anchors.topMargin: (-implicitHeight - 5) * offsetScale + clip: true implicitHeight: content.implicitHeight implicitWidth: content.implicitWidth || 854 // Hard coded fallback for first open opacity: 1 - offsetScale + visible: offsetScale < 1 Behavior on offsetScale { Anim { @@ -30,11 +30,10 @@ Item { Loader { id: content + active: root.shouldBeActive || root.visible anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - active: root.shouldBeActive || root.visible - sourceComponent: Content { padding: Appearance.padding.normal visibilities: root.visibilities From 93d6bf536a9d0b7a76164b2f6f20e533823ad7cc Mon Sep 17 00:00:00 2001 From: zach Date: Mon, 20 Apr 2026 15:37:14 +0200 Subject: [PATCH 5/9] launcher height fixes --- Modules/Launcher/Wrapper.qml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Modules/Launcher/Wrapper.qml b/Modules/Launcher/Wrapper.qml index a2c6ea6..a7ababd 100644 --- a/Modules/Launcher/Wrapper.qml +++ b/Modules/Launcher/Wrapper.qml @@ -25,9 +25,18 @@ Item { readonly property bool shouldBeActive: visibilities.launcher property real offsetScale: shouldBeActive ? 0 : 1 + onShouldBeActiveChanged: { + if (shouldBeActive) { + implicitHeight = Qt.binding(() => content.implicitHeight); + timer.stop(); + } else { + implicitHeight = implicitHeight; + } + } + visible: offsetScale < 1 anchors.bottomMargin: (-implicitHeight - 5) * offsetScale - implicitHeight: contentHeight + implicitHeight: content.implicitHeight implicitWidth: content.implicitWidth || 400 opacity: 1 - offsetScale @@ -39,11 +48,6 @@ Item { } onMaxHeightChanged: timer.start() - onShouldBeActiveChanged: { - if (shouldBeActive) { - timer.stop(); - } - } Connections { function onEnabledChanged(): void { From ac1d19acbbc37a303fce5fa24af2ae2ad0453ccb Mon Sep 17 00:00:00 2001 From: zach Date: Mon, 20 Apr 2026 15:40:19 +0200 Subject: [PATCH 6/9] settings window attached to bar again --- Drawers/Panels.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index 23c9f44..f496440 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -146,7 +146,9 @@ Item { Settings.Wrapper { id: settings - anchors.centerIn: parent + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + // anchors.centerIn: parent panels: root screen: root.screen visibilities: root.visibilities From c3f877c19ee34b0051f99588cf74512e4cd3711f Mon Sep 17 00:00:00 2001 From: zach Date: Tue, 21 Apr 2026 19:29:41 +0200 Subject: [PATCH 7/9] more fixes, clip wrappers for most popouts --- Drawers/Panels.qml | 45 ++++++++++++++++++++++++++++++----- Drawers/Windows.qml | 29 +++++++++++++++------- Modules/Dashboard/Wrapper.qml | 17 ++++--------- 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index f496440..51044eb 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -20,6 +20,7 @@ Item { required property Item bar readonly property alias dashboard: dashboard + readonly property alias dashboardWrapper: dashboardWrapper readonly property alias dock: dock readonly property alias drawing: drawing required property Canvas drawingItem @@ -30,6 +31,7 @@ Item { readonly property alias popouts: popouts.content readonly property alias popoutsWrapper: popouts readonly property alias resources: resources + readonly property alias resourcesWrapper: resourcesWrapper required property ShellScreen screen readonly property alias settings: settings readonly property alias sidebar: sidebar @@ -41,12 +43,22 @@ Item { anchors.margins: Config.barConfig.border anchors.topMargin: bar.implicitHeight - Resources.Wrapper { - id: resources + Item { + id: resourcesWrapper anchors.left: parent.left anchors.top: parent.top - visibilities: root.visibilities + clip: true + implicitHeight: resources.implicitHeight + implicitWidth: resources.implicitWidth + + Resources.Wrapper { + id: resources + + anchors.left: parent.left + anchors.top: parent.top + visibilities: root.visibilities + } } Item { @@ -125,12 +137,33 @@ Item { visibilities: root.visibilities } - Dashboard.Wrapper { - id: dashboard + Item { + id: dashboardWrapper + + property real offsetScale: dashboard.shouldBeActive ? 0 : 1 anchors.right: parent.right anchors.top: parent.top - visibilities: root.visibilities + clip: true + implicitHeight: dashboard.implicitHeight * (1 - offsetScale) + implicitWidth: dashboard.implicitWidth + + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + + Dashboard.Wrapper { + id: dashboard + + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: (-implicitHeight - 5) * offsetScale + offsetScale: dashboardWrapper.offsetScale + visibilities: root.visibilities + } } Sidebar.Wrapper { diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 6556bdd..df7f49b 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -170,15 +170,19 @@ Variants { PanelBg { id: dashBg - deformAmount: 0.15 * Config.appearance.deform.scale + deformAmount: 0.08 * Config.appearance.deform.scale + implicitHeight: panels.dashboard.height + implicitWidth: panels.dashboard.width panel: panels.dashboard radius: Appearance.rounding.normal + x: panels.dashboardWrapper.x + panels.dashboard.x + Config.barConfig.border + y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight } PanelBg { id: launcherBg - deformAmount: 0.15 * Config.appearance.deform.scale + deformAmount: 0.08 * Config.appearance.deform.scale panel: panels.launcher radius: Appearance.rounding.smallest + 5 } @@ -187,7 +191,7 @@ Variants { id: sidebarBg bottomLeftRadius: 0 - deformAmount: 0.1 * Config.appearance.deform.scale + deformAmount: 0.08 * Config.appearance.deform.scale exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg] implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2 panel: panels.sidebar @@ -197,10 +201,12 @@ Variants { id: osdBg deformAmount: 0.1 * Config.appearance.deform.scale + implicitHeight: panels.osd.height implicitWidth: panels.osd.width - panel: panels.osdWrapper + panel: panels.osd radius: 20 x: panels.osdWrapper.x + panels.osd.x + Config.barConfig.border + y: panels.osdWrapper.y + panels.osd.y + bar.implicitHeight } PanelBg { @@ -225,9 +231,10 @@ Variants { deformAmount: panels.popouts.isDetached ? 0.05 * Config.appearance.deform.scale : panels.popouts.hasCurrent ? 0.15 * Config.appearance.deform.scale : 0.1 * Config.appearance.deform.scale implicitHeight: panels.popouts.height * (1 + extraHeight) - implicitWidth: panels.popoutsWrapper.width - panel: panels.popoutsWrapper + implicitWidth: panels.popouts.width + panel: panels.popouts radius: (panels.popouts.currentName.startsWith("audio") || panels.popouts.currentName.startsWith("updates")) ? Appearance.rounding.normal : Appearance.rounding.smallest + x: panels.popoutsWrapper.x + panels.popouts.x + Config.barConfig.border y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight Behavior on extraHeight { @@ -239,15 +246,19 @@ Variants { PanelBg { id: resourcesBg - deformAmount: 0.15 * Config.appearance.deform.scale + deformAmount: 0.08 * Config.appearance.deform.scale + implicitHeight: panels.resources.height + implicitWidth: panels.resources.width panel: panels.resources radius: Appearance.rounding.normal + x: panels.resourcesWrapper.x + panels.resources.x + Config.barConfig.border + y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight } PanelBg { id: settingsBg - deformAmount: 0.1 * Config.appearance.deform.scale + deformAmount: 0.08 * Config.appearance.deform.scale panel: panels.settings radius: Appearance.rounding.large topLeftRadius: Appearance.rounding.large + Appearance.padding.smaller @@ -257,7 +268,7 @@ Variants { PanelBg { id: dockBg - deformAmount: 0.15 * Config.appearance.deform.scale + deformAmount: 0.08 * Config.appearance.deform.scale panel: panels.dock radius: Appearance.rounding.normal } diff --git a/Modules/Dashboard/Wrapper.qml b/Modules/Dashboard/Wrapper.qml index 757eab9..ef4e998 100644 --- a/Modules/Dashboard/Wrapper.qml +++ b/Modules/Dashboard/Wrapper.qml @@ -15,32 +15,23 @@ Item { reloadableId: "dashboardState" } readonly property real nonAnimHeight: state === "visible" ? (content.item?.nonAnimHeight ?? 0) : 0 + required property real offsetScale + readonly property bool shouldBeActive: root.visibilities.dashboard && Config.dashboard.enabled required property PersistentProperties visibilities - readonly property bool shouldBeActive: root.visibilities.dashboard && Config.dashboard.enabled - property real offsetScale: shouldBeActive ? 0 : 1 - - visible: offsetScale < 1 - anchors.topMargin: (-implicitHeight - 5) * offsetScale implicitHeight: content.implicitHeight implicitWidth: content.implicitWidth || 854 // Hard coded fallback for first open opacity: 1 - offsetScale - Behavior on offsetScale { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } - } + // visible: offsetScale < 1 Loader { id: content + active: root.shouldBeActive || root.visible anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - active: root.shouldBeActive || root.visible - sourceComponent: Content { state: root.dashState visibilities: root.visibilities From bcb0da3ab9fbedf15716069d80446da065860c4f Mon Sep 17 00:00:00 2001 From: zach Date: Tue, 21 Apr 2026 19:31:53 +0200 Subject: [PATCH 8/9] quick fix for resources popouts leaving leftover ghost region --- Drawers/Panels.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index 51044eb..8902ccf 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -49,7 +49,7 @@ Item { anchors.left: parent.left anchors.top: parent.top clip: true - implicitHeight: resources.implicitHeight + implicitHeight: resources.implicitHeight * (1 - resources.offsetScale) implicitWidth: resources.implicitWidth Resources.Wrapper { From 263ef6681623336c65d7da8e19086cef7877dcf0 Mon Sep 17 00:00:00 2001 From: zach Date: Tue, 21 Apr 2026 21:32:53 +0200 Subject: [PATCH 9/9] audio popout remove tabs --- Modules/SysTray/Popouts/AudioPopup.qml | 179 +------------------------ 1 file changed, 5 insertions(+), 174 deletions(-) diff --git a/Modules/SysTray/Popouts/AudioPopup.qml b/Modules/SysTray/Popouts/AudioPopup.qml index 5b14d11..c9c4727 100644 --- a/Modules/SysTray/Popouts/AudioPopup.qml +++ b/Modules/SysTray/Popouts/AudioPopup.qml @@ -18,8 +18,8 @@ Item { readonly property int topMargin: 0 required property var wrapper - implicitHeight: layout.implicitHeight + Appearance.padding.small * 2 - implicitWidth: layout.implicitWidth + Appearance.padding.small * 2 + implicitHeight: vol.implicitHeight + Appearance.padding.small * 2 + implicitWidth: 400 + Appearance.padding.small * 2 CustomRect { anchors.left: parent.left @@ -38,184 +38,15 @@ Item { } } - ColumnLayout { - id: layout + VolumesTab { + id: vol - // anchors.centerIn: parent anchors.left: parent.left anchors.margins: Appearance.padding.small anchors.right: parent.right - anchors.top: parent.top - implicitWidth: stack.currentItem ? stack.currentItem.childrenRect.height : 0 - spacing: 12 - - RowLayout { - id: tabBar - - property int tabHeight: 36 - - Layout.fillWidth: true - spacing: 6 - - CustomClippingRect { - Layout.fillWidth: true - Layout.preferredHeight: tabBar.tabHeight - color: stack.currentIndex === 0 ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer - radius: root.rounding - - StateLayer { - function onClicked(): void { - stack.currentIndex = 0; - } - - CustomText { - anchors.centerIn: parent - color: stack.currentIndex === 0 ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3primary - text: qsTr("Volumes") - } - } - } - - CustomClippingRect { - Layout.fillWidth: true - Layout.preferredHeight: tabBar.tabHeight - color: stack.currentIndex === 1 ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer - radius: root.rounding - - StateLayer { - function onClicked(): void { - stack.currentIndex = 1; - } - - CustomText { - anchors.centerIn: parent - color: stack.currentIndex === 1 ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3primary - text: qsTr("Devices") - } - } - } - } - - StackLayout { - id: stack - - Layout.fillWidth: true - Layout.preferredHeight: currentIndex === 0 ? vol.childrenRect.height : dev.childrenRect.height - currentIndex: 0 - - // Behavior on Layout.preferredHeight { - // Anim { - // duration: MaterialEasing.expressiveEffectsTime - // easing.bezierCurve: MaterialEasing.expressiveEffects - // } - // } - Behavior on currentIndex { - SequentialAnimation { - ParallelAnimation { - Anim { - duration: MaterialEasing.expressiveEffectsTime - property: "opacity" - target: stack - to: 0 - } - - Anim { - duration: MaterialEasing.expressiveEffectsTime - property: "scale" - target: stack - to: 0.9 - } - } - - PropertyAction { - } - - ParallelAnimation { - Anim { - duration: MaterialEasing.expressiveEffectsTime - property: "opacity" - target: stack - to: 1 - } - - Anim { - duration: MaterialEasing.expressiveEffectsTime - property: "scale" - target: stack - to: 1 - } - } - } - } - - VolumesTab { - id: vol - } - - DevicesTab { - id: dev - } - } + anchors.verticalCenter: parent.verticalCenter } - component DevicesTab: Item { - implicitHeight: deviceColumn.height + Appearance.padding.normal - implicitWidth: deviceColumn.width + Appearance.padding.normal - - ColumnLayout { - id: deviceColumn - - anchors.centerIn: parent - spacing: 12 - - ButtonGroup { - id: sinks - } - - ButtonGroup { - id: sources - } - - CustomText { - font.weight: 500 - text: qsTr("Output device") - } - - Repeater { - model: Audio.sinks - - CustomRadioButton { - required property PwNode modelData - - ButtonGroup.group: sinks - checked: Audio.sink?.id === modelData.id - text: modelData.description - - onClicked: Audio.setAudioSink(modelData) - } - } - - CustomText { - Layout.topMargin: 10 - font.weight: 500 - text: qsTr("Input device") - } - - Repeater { - model: Audio.sources - - CustomRadioButton { - required property PwNode modelData - - ButtonGroup.group: sources - checked: Audio.source?.id === modelData.id - text: modelData.description - - onClicked: Audio.setAudioSource(modelData) - } - } - } - } component VolumesTab: ColumnLayout { spacing: 12