refactor: SplitPaneLayout now component
This commit is contained in:
parent
50e29f8be3
commit
ad4213d45c
6 changed files with 1317 additions and 1436 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
|
import "../components"
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
import qs.components.effects
|
import qs.components.effects
|
||||||
|
|
@ -11,52 +12,17 @@ import Quickshell.Widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Session session
|
required property Session session
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
spacing: 0
|
SplitPaneLayout {
|
||||||
|
|
||||||
Item {
|
|
||||||
id: leftAudioItem
|
|
||||||
Layout.preferredWidth: Math.floor(parent.width * 0.4)
|
|
||||||
Layout.minimumWidth: 420
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: leftAudioClippingRect
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: leftAudioBorder.innerRadius
|
leftContent: Component {
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: leftAudioLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
|
||||||
anchors.leftMargin: Appearance.padding.large
|
|
||||||
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: audioLeftContentComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: leftAudioBorder
|
|
||||||
leftThickness: 0
|
|
||||||
rightThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: audioLeftContentComponent
|
|
||||||
|
|
||||||
StyledFlickable {
|
StyledFlickable {
|
||||||
id: leftAudioFlickable
|
id: leftAudioFlickable
|
||||||
|
|
@ -248,47 +214,18 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
rightContent: Component {
|
||||||
Item {
|
Item {
|
||||||
id: rightAudioItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: rightAudioClippingRect
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: rightAudioBorder.innerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: rightAudioLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin: Appearance.padding.large * 2
|
anchors.topMargin: Appearance.padding.large * 2
|
||||||
anchors.bottomMargin: Appearance.padding.large * 2
|
anchors.bottomMargin: Appearance.padding.large * 2
|
||||||
anchors.leftMargin: 0
|
anchors.leftMargin: 0
|
||||||
anchors.rightMargin: 0
|
anchors.rightMargin: 0
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: audioRightContentComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: rightAudioBorder
|
|
||||||
leftThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: audioRightContentComponent
|
|
||||||
|
|
||||||
StyledFlickable {
|
StyledFlickable {
|
||||||
id: rightAudioFlickable
|
id: rightAudioFlickable
|
||||||
|
anchors.fill: parent
|
||||||
flickableDirection: Flickable.VerticalFlick
|
flickableDirection: Flickable.VerticalFlick
|
||||||
contentHeight: contentLayout.height
|
contentHeight: contentLayout.height
|
||||||
|
|
||||||
|
|
@ -591,4 +528,5 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
|
import "../components"
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
import qs.components.effects
|
import qs.components.effects
|
||||||
import qs.components.containers
|
import qs.components.containers
|
||||||
|
|
@ -10,95 +11,50 @@ import Quickshell.Bluetooth
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Session session
|
required property Session session
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
spacing: 0
|
SplitPaneLayout {
|
||||||
|
|
||||||
Item {
|
|
||||||
id: leftBtItem
|
|
||||||
Layout.preferredWidth: Math.floor(parent.width * 0.4)
|
|
||||||
Layout.minimumWidth: 420
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: leftBtClippingRect
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: leftBtBorder.innerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: leftBtLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
|
||||||
anchors.leftMargin: Appearance.padding.large
|
|
||||||
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: btDeviceListComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: leftBtBorder
|
|
||||||
leftThickness: 0
|
|
||||||
rightThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: btDeviceListComponent
|
|
||||||
|
|
||||||
|
leftContent: Component {
|
||||||
DeviceList {
|
DeviceList {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
session: root.session
|
session: root.session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
rightContent: Component {
|
||||||
Item {
|
Item {
|
||||||
id: rightBtItem
|
id: rightBtPane
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: btClippingRect
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: rightBorder.innerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
|
|
||||||
property BluetoothDevice pane: root.session.bt.active
|
property BluetoothDevice pane: root.session.bt.active
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: rightLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.large * 2
|
anchors.margins: Appearance.padding.large * 2
|
||||||
|
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
sourceComponent: pane ? details : settings
|
sourceComponent: rightBtPane.pane ? details : settings
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on pane {
|
Behavior on pane {
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
|
target: rightLoader
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 0
|
to: 0
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
|
target: rightLoader
|
||||||
property: "scale"
|
property: "scale"
|
||||||
to: 0.8
|
to: 0.8
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||||
|
|
@ -107,11 +63,13 @@ RowLayout {
|
||||||
PropertyAction {}
|
PropertyAction {}
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
|
target: rightLoader
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 1
|
to: 1
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
|
target: rightLoader
|
||||||
property: "scale"
|
property: "scale"
|
||||||
to: 1
|
to: 1
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||||
|
|
@ -119,13 +77,15 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.session.bt
|
||||||
|
function onActiveChanged() {
|
||||||
|
rightBtPane.pane = root.session.bt.active;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: rightBorder
|
|
||||||
|
|
||||||
leftThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -158,10 +118,8 @@ RowLayout {
|
||||||
session: root.session
|
session: root.session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
component Anim: NumberAnimation {
|
component Anim: NumberAnimation {
|
||||||
target: loader
|
|
||||||
duration: Appearance.anim.durations.normal / 2
|
duration: Appearance.anim.durations.normal / 2
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
}
|
}
|
||||||
|
|
|
||||||
120
modules/controlcenter/components/SplitPaneLayout.qml
Normal file
120
modules/controlcenter/components/SplitPaneLayout.qml
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import qs.components
|
||||||
|
import qs.components.effects
|
||||||
|
import qs.config
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
property Component leftContent: null
|
||||||
|
property Component rightContent: null
|
||||||
|
|
||||||
|
// Left pane configuration
|
||||||
|
property real leftWidthRatio: 0.4
|
||||||
|
property int leftMinimumWidth: 420
|
||||||
|
property var leftLoaderProperties: ({})
|
||||||
|
|
||||||
|
// Right pane configuration
|
||||||
|
property var rightLoaderProperties: ({})
|
||||||
|
|
||||||
|
// Expose loaders for customization (access via splitLayout.leftLoader or splitLayout.rightLoader)
|
||||||
|
property alias leftLoader: leftLoader
|
||||||
|
property alias rightLoader: rightLoader
|
||||||
|
|
||||||
|
// Left pane
|
||||||
|
Item {
|
||||||
|
id: leftPane
|
||||||
|
|
||||||
|
Layout.preferredWidth: Math.floor(parent.width * root.leftWidthRatio)
|
||||||
|
Layout.minimumWidth: root.leftMinimumWidth
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
ClippingRectangle {
|
||||||
|
id: leftClippingRect
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.normal
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
anchors.rightMargin: Appearance.padding.normal / 2
|
||||||
|
|
||||||
|
radius: leftBorder.innerRadius
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: leftLoader
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
||||||
|
anchors.leftMargin: Appearance.padding.large
|
||||||
|
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2
|
||||||
|
|
||||||
|
asynchronous: true
|
||||||
|
sourceComponent: root.leftContent
|
||||||
|
|
||||||
|
// Apply any additional properties from leftLoaderProperties
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (const key in root.leftLoaderProperties) {
|
||||||
|
leftLoader[key] = root.leftLoaderProperties[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InnerBorder {
|
||||||
|
id: leftBorder
|
||||||
|
|
||||||
|
leftThickness: 0
|
||||||
|
rightThickness: Appearance.padding.normal / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right pane
|
||||||
|
Item {
|
||||||
|
id: rightPane
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
ClippingRectangle {
|
||||||
|
id: rightClippingRect
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.normal
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
anchors.rightMargin: Appearance.padding.normal / 2
|
||||||
|
|
||||||
|
radius: rightBorder.innerRadius
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: rightLoader
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.large * 2
|
||||||
|
|
||||||
|
asynchronous: true
|
||||||
|
sourceComponent: root.rightContent
|
||||||
|
|
||||||
|
// Apply any additional properties from rightLoaderProperties
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (const key in root.rightLoaderProperties) {
|
||||||
|
rightLoader[key] = root.rightLoaderProperties[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InnerBorder {
|
||||||
|
id: rightBorder
|
||||||
|
|
||||||
|
leftThickness: Appearance.padding.normal / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
|
import "../components"
|
||||||
import "../../launcher/services"
|
import "../../launcher/services"
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
|
|
@ -16,7 +17,7 @@ import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import "../../../utils/scripts/fuzzysort.js" as Fuzzy
|
import "../../../utils/scripts/fuzzysort.js" as Fuzzy
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Session session
|
required property Session session
|
||||||
|
|
@ -26,8 +27,6 @@ RowLayout {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
onSelectedAppChanged: {
|
onSelectedAppChanged: {
|
||||||
root.session.launcher.active = root.selectedApp;
|
root.session.launcher.active = root.selectedApp;
|
||||||
updateToggleState();
|
updateToggleState();
|
||||||
|
|
@ -156,43 +155,10 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
SplitPaneLayout {
|
||||||
id: leftLauncherItem
|
|
||||||
Layout.preferredWidth: Math.floor(parent.width * 0.4)
|
|
||||||
Layout.minimumWidth: 420
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: leftLauncherClippingRect
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: leftLauncherBorder.innerRadius
|
leftContent: Component {
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: leftLauncherLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
|
||||||
anchors.leftMargin: Appearance.padding.large
|
|
||||||
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: leftContentComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: leftLauncherBorder
|
|
||||||
leftThickness: 0
|
|
||||||
rightThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: leftContentComponent
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: leftLauncherLayout
|
id: leftLauncherLayout
|
||||||
|
|
@ -336,7 +302,8 @@ RowLayout {
|
||||||
// Lazy load: activate when left pane is loaded
|
// Lazy load: activate when left pane is loaded
|
||||||
// The ListView will load asynchronously, and search will work because filteredApps
|
// The ListView will load asynchronously, and search will work because filteredApps
|
||||||
// is updated regardless of whether the ListView is loaded
|
// is updated regardless of whether the ListView is loaded
|
||||||
return leftLauncherLoader.item !== null;
|
// Access loader through parent - this will be set when component loads
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceComponent: StyledListView {
|
sourceComponent: StyledListView {
|
||||||
|
|
@ -412,25 +379,10 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
rightContent: Component {
|
||||||
Item {
|
Item {
|
||||||
id: rightLauncherItem
|
id: rightLauncherPane
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: rightLauncherClippingRect
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: rightLauncherBorder.innerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: rightLauncherLoader
|
|
||||||
|
|
||||||
property var pane: root.session.launcher.active
|
property var pane: root.session.launcher.active
|
||||||
property string paneId: pane ? (pane.id || pane.entry?.id || "") : ""
|
property string paneId: pane ? (pane.id || pane.entry?.id || "") : ""
|
||||||
|
|
@ -442,8 +394,16 @@ RowLayout {
|
||||||
return pane ? appDetails : settings;
|
return pane ? appDetails : settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
displayedApp = pane;
|
||||||
|
targetComponent = getComponentForPane();
|
||||||
|
nextComponent = targetComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: rightLauncherLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.large * 2
|
|
||||||
|
|
||||||
opacity: 1
|
opacity: 1
|
||||||
scale: 1
|
scale: 1
|
||||||
|
|
@ -451,19 +411,17 @@ RowLayout {
|
||||||
clip: false
|
clip: false
|
||||||
|
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
sourceComponent: rightLauncherLoader.targetComponent
|
sourceComponent: rightLauncherPane.targetComponent
|
||||||
active: true
|
active: true
|
||||||
|
|
||||||
Component.onCompleted: {
|
// Expose displayedApp to loaded components
|
||||||
displayedApp = pane;
|
property var displayedApp: rightLauncherPane.displayedApp
|
||||||
targetComponent = getComponentForPane();
|
|
||||||
nextComponent = targetComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
onItemChanged: {
|
onItemChanged: {
|
||||||
// Ensure displayedApp is set when item is created (for async loading)
|
// Ensure displayedApp is set when item is created (for async loading)
|
||||||
if (item && pane && displayedApp !== pane) {
|
if (item && rightLauncherPane.pane && rightLauncherPane.displayedApp !== rightLauncherPane.pane) {
|
||||||
displayedApp = pane;
|
rightLauncherPane.displayedApp = rightLauncherPane.pane;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,9 +442,9 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: rightLauncherLoader
|
target: rightLauncherPane
|
||||||
property: "displayedApp"
|
property: "displayedApp"
|
||||||
value: rightLauncherLoader.pane
|
value: rightLauncherPane.pane
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: rightLauncherLoader
|
target: rightLauncherLoader
|
||||||
|
|
@ -494,9 +452,9 @@ RowLayout {
|
||||||
value: false
|
value: false
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: rightLauncherLoader
|
target: rightLauncherPane
|
||||||
property: "targetComponent"
|
property: "targetComponent"
|
||||||
value: rightLauncherLoader.nextComponent
|
value: rightLauncherPane.nextComponent
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: rightLauncherLoader
|
target: rightLauncherLoader
|
||||||
|
|
@ -539,11 +497,6 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: rightLauncherBorder
|
|
||||||
|
|
||||||
leftThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -573,8 +526,12 @@ RowLayout {
|
||||||
id: appDetails
|
id: appDetails
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
id: appDetailsLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
// Get displayedApp from parent Loader (the Loader has displayedApp property we set)
|
||||||
|
readonly property var displayedApp: parent && parent.displayedApp !== undefined ? parent.displayedApp : null
|
||||||
|
|
||||||
spacing: Appearance.spacing.normal
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -587,7 +544,7 @@ RowLayout {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: iconLoader
|
id: iconLoader
|
||||||
sourceComponent: rightLauncherLoader.displayedApp ? appIconComponent : defaultIconComponent
|
sourceComponent: parent.parent.displayedApp ? appIconComponent : defaultIconComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -595,8 +552,9 @@ RowLayout {
|
||||||
IconImage {
|
IconImage {
|
||||||
implicitSize: Appearance.font.size.extraLarge * 3 * 2
|
implicitSize: Appearance.font.size.extraLarge * 3 * 2
|
||||||
source: {
|
source: {
|
||||||
if (!rightLauncherLoader.displayedApp) return "image-missing";
|
const app = iconLoader.parent.parent.displayedApp;
|
||||||
const entry = rightLauncherLoader.displayedApp.entry;
|
if (!app) return "image-missing";
|
||||||
|
const entry = app.entry;
|
||||||
if (entry && entry.icon) {
|
if (entry && entry.icon) {
|
||||||
return Quickshell.iconPath(entry.icon, "image-missing");
|
return Quickshell.iconPath(entry.icon, "image-missing");
|
||||||
}
|
}
|
||||||
|
|
@ -619,7 +577,7 @@ RowLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.leftMargin: Appearance.padding.large * 2
|
Layout.leftMargin: Appearance.padding.large * 2
|
||||||
Layout.rightMargin: Appearance.padding.large * 2
|
Layout.rightMargin: Appearance.padding.large * 2
|
||||||
text: rightLauncherLoader.displayedApp ? (rightLauncherLoader.displayedApp.name || rightLauncherLoader.displayedApp.entry?.name || qsTr("Application Details")) : qsTr("Launcher Applications")
|
text: displayedApp ? (displayedApp.name || displayedApp.entry?.name || qsTr("Application Details")) : qsTr("Launcher Applications")
|
||||||
font.pointSize: Appearance.font.size.large
|
font.pointSize: Appearance.font.size.large
|
||||||
font.bold: true
|
font.bold: true
|
||||||
}
|
}
|
||||||
|
|
@ -650,14 +608,15 @@ RowLayout {
|
||||||
|
|
||||||
SwitchRow {
|
SwitchRow {
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
visible: rightLauncherLoader.displayedApp !== null
|
visible: appDetailsLayout.displayedApp !== null
|
||||||
label: qsTr("Hide from launcher")
|
label: qsTr("Hide from launcher")
|
||||||
checked: root.hideFromLauncherChecked
|
checked: root.hideFromLauncherChecked
|
||||||
enabled: rightLauncherLoader.displayedApp !== null
|
enabled: appDetailsLayout.displayedApp !== null
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
root.hideFromLauncherChecked = checked;
|
root.hideFromLauncherChecked = checked;
|
||||||
if (rightLauncherLoader.displayedApp) {
|
const app = appDetailsLayout.displayedApp;
|
||||||
const appId = rightLauncherLoader.displayedApp.id || rightLauncherLoader.displayedApp.entry?.id;
|
if (app) {
|
||||||
|
const appId = app.id || app.entry?.id;
|
||||||
const hiddenApps = Config.launcher.hiddenApps ? [...Config.launcher.hiddenApps] : [];
|
const hiddenApps = Config.launcher.hiddenApps ? [...Config.launcher.hiddenApps] : [];
|
||||||
if (checked) {
|
if (checked) {
|
||||||
if (!hiddenApps.includes(appId)) {
|
if (!hiddenApps.includes(appId)) {
|
||||||
|
|
@ -680,7 +639,6 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
component Anim: NumberAnimation {
|
component Anim: NumberAnimation {
|
||||||
target: rightLauncherLoader
|
target: rightLauncherLoader
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
|
import "../components"
|
||||||
import "."
|
import "."
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
|
|
@ -21,49 +22,12 @@ Item {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
RowLayout {
|
SplitPaneLayout {
|
||||||
id: contentLayout
|
id: splitLayout
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
leftContent: Component {
|
||||||
id: leftNetworkItem
|
|
||||||
Layout.preferredWidth: Math.floor(parent.width * 0.4)
|
|
||||||
Layout.minimumWidth: 420
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: leftNetworkClippingRect
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: leftNetworkBorder.innerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: leftNetworkLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
|
||||||
anchors.leftMargin: Appearance.padding.large
|
|
||||||
anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
sourceComponent: networkListComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: leftNetworkBorder
|
|
||||||
leftThickness: 0
|
|
||||||
rightThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: networkListComponent
|
|
||||||
|
|
||||||
StyledFlickable {
|
StyledFlickable {
|
||||||
id: leftFlickable
|
id: leftFlickable
|
||||||
|
|
@ -474,27 +438,12 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
rightContent: Component {
|
||||||
Item {
|
Item {
|
||||||
id: rightNetworkItem
|
id: rightPaneItem
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ClippingRectangle {
|
|
||||||
id: networkClippingRect
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: Appearance.padding.normal / 2
|
|
||||||
|
|
||||||
radius: rightBorder.innerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
// Right pane - networking details/settings
|
// Right pane - networking details/settings
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
|
|
||||||
property var ethernetPane: root.session.ethernet.active
|
property var ethernetPane: root.session.ethernet.active
|
||||||
property var wirelessPane: root.session.network.active
|
property var wirelessPane: root.session.network.active
|
||||||
property var pane: ethernetPane || wirelessPane
|
property var pane: ethernetPane || wirelessPane
|
||||||
|
|
@ -506,6 +455,30 @@ Item {
|
||||||
return pane ? (ethernetPane ? ethernetDetails : wirelessDetails) : settings;
|
return pane ? (ethernetPane ? ethernetDetails : wirelessDetails) : settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
targetComponent = getComponentForPane();
|
||||||
|
nextComponent = targetComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.session.ethernet
|
||||||
|
function onActiveChanged() {
|
||||||
|
nextComponent = getComponentForPane();
|
||||||
|
paneId = ethernetPane ? (ethernetPane.interface || "") : (wirelessPane ? (wirelessPane.ssid || wirelessPane.bssid || "") : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.session.network
|
||||||
|
function onActiveChanged() {
|
||||||
|
nextComponent = getComponentForPane();
|
||||||
|
paneId = ethernetPane ? (ethernetPane.interface || "") : (wirelessPane ? (wirelessPane.ssid || wirelessPane.bssid || "") : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: rightLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.large * 2
|
anchors.margins: Appearance.padding.large * 2
|
||||||
|
|
||||||
|
|
@ -515,43 +488,46 @@ Item {
|
||||||
clip: false
|
clip: false
|
||||||
|
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
sourceComponent: loader.targetComponent
|
sourceComponent: rightPaneItem.targetComponent
|
||||||
|
|
||||||
Component.onCompleted: {
|
Connections {
|
||||||
targetComponent = getComponentForPane();
|
target: rightPaneItem
|
||||||
nextComponent = targetComponent;
|
function onPaneIdChanged() {
|
||||||
|
rightPaneItem.targetComponent = rightPaneItem.nextComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on paneId {
|
Behavior on paneId {
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
target: loader
|
target: rightLoader
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 0
|
to: 0
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
target: loader
|
target: rightLoader
|
||||||
property: "scale"
|
property: "scale"
|
||||||
to: 0.8
|
to: 0.8
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: loader
|
target: rightPaneItem
|
||||||
property: "targetComponent"
|
property: "targetComponent"
|
||||||
value: loader.nextComponent
|
value: rightPaneItem.nextComponent
|
||||||
}
|
}
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
target: loader
|
target: rightLoader
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 1
|
to: 1
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
target: loader
|
target: rightLoader
|
||||||
property: "scale"
|
property: "scale"
|
||||||
to: 1
|
to: 1
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||||
|
|
@ -560,17 +536,14 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPaneChanged: {
|
Connections {
|
||||||
nextComponent = getComponentForPane();
|
target: rightPaneItem
|
||||||
paneId = ethernetPane ? (ethernetPane.interface || "") : (wirelessPane ? (wirelessPane.ssid || wirelessPane.bssid || "") : "");
|
function onPaneIdChanged() {
|
||||||
|
rightPaneItem.targetComponent = rightPaneItem.nextComponent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerBorder {
|
|
||||||
id: rightBorder
|
|
||||||
|
|
||||||
leftThickness: Appearance.padding.normal / 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -641,8 +614,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WirelessPasswordDialog {
|
WirelessPasswordDialog {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -651,7 +622,6 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
component Anim: NumberAnimation {
|
component Anim: NumberAnimation {
|
||||||
target: loader
|
|
||||||
duration: Appearance.anim.durations.normal / 2
|
duration: Appearance.anim.durations.normal / 2
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue