2021-12-22 23:29:00 +00:00
|
|
|
/*
|
|
|
|
|
* SPDX-FileCopyrightText: 2014 Marco Martin <notmart@gmail.com>
|
|
|
|
|
* SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import QtQuick 2.15
|
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
|
import QtQuick.Layouts 1.1
|
|
|
|
|
import QtQuick.Window 2.2
|
|
|
|
|
|
|
|
|
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
2022-05-12 13:20:39 +00:00
|
|
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
2022-03-13 21:47:42 +00:00
|
|
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
2022-11-11 16:21:12 +00:00
|
|
|
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
|
2021-12-22 23:29:00 +00:00
|
|
|
|
|
|
|
|
import "../../components" as Components
|
|
|
|
|
import "../../components/util.js" as Util
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Quick settings elements layout, change the height to clip.
|
|
|
|
|
*/
|
|
|
|
|
Item {
|
|
|
|
|
id: root
|
|
|
|
|
clip: true
|
|
|
|
|
|
|
|
|
|
required property var actionDrawer
|
|
|
|
|
|
|
|
|
|
readonly property real columns: Math.round(Util.applyMinMaxRange(3, 6, width / intendedColumnWidth))
|
|
|
|
|
readonly property real columnWidth: Math.floor(width / columns)
|
2022-05-07 17:10:02 +00:00
|
|
|
readonly property int minimizedColumns: Math.round(Util.applyMinMaxRange(5, 8, width / intendedMinimizedColumnWidth))
|
2021-12-22 23:29:00 +00:00
|
|
|
readonly property real minimizedColumnWidth: Math.floor(width / minimizedColumns)
|
|
|
|
|
|
|
|
|
|
readonly property real rowHeight: columnWidth * 0.7
|
|
|
|
|
readonly property real fullHeight: fullView.implicitHeight
|
|
|
|
|
|
|
|
|
|
readonly property real intendedColumnWidth: 120
|
|
|
|
|
readonly property real intendedMinimizedColumnWidth: PlasmaCore.Units.gridUnit * 3 + PlasmaCore.Units.largeSpacing
|
|
|
|
|
readonly property real minimizedRowHeight: PlasmaCore.Units.gridUnit * 3 + PlasmaCore.Units.largeSpacing
|
|
|
|
|
|
|
|
|
|
property real minimizedViewProgress: 0
|
|
|
|
|
property real fullViewProgress: 1
|
2022-05-07 17:10:02 +00:00
|
|
|
|
|
|
|
|
readonly property MobileShell.QuickSettingsModel quickSettingsModel: MobileShell.QuickSettingsModel {}
|
|
|
|
|
|
2022-05-07 21:19:56 +00:00
|
|
|
readonly property int columnCount: Math.floor(width/columnWidth)
|
2022-06-28 03:47:51 +00:00
|
|
|
readonly property int rowCount: {
|
2022-07-11 03:18:34 +00:00
|
|
|
let totalRows = Math.ceil(quickSettingsCount / columnCount);
|
2022-11-11 16:21:12 +00:00
|
|
|
let isPortrait = MobileShellState.Shell.orientation === MobileShellState.Shell.Portrait;
|
2022-12-07 00:01:42 +00:00
|
|
|
|
|
|
|
|
if (isPortrait) {
|
|
|
|
|
// portrait orientation
|
|
|
|
|
let maxRows = 5; // more than 5 is just disorienting
|
|
|
|
|
let targetRows = Math.floor(Window.height * 0.65 / rowHeight);
|
|
|
|
|
return Math.min(maxRows, Math.min(totalRows, targetRows));
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// horizontal orientation
|
|
|
|
|
let targetRows = Math.floor(Window.height * 0.8 / rowHeight);
|
|
|
|
|
return Math.min(totalRows, targetRows);
|
|
|
|
|
}
|
2022-06-28 03:47:51 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 21:19:56 +00:00
|
|
|
readonly property int pageSize: rowCount * columnCount
|
|
|
|
|
readonly property int quickSettingsCount: quickSettingsModel.count
|
2022-05-09 22:12:25 +00:00
|
|
|
|
2022-05-07 17:10:02 +00:00
|
|
|
function resetSwipeView() {
|
2022-11-11 16:21:12 +00:00
|
|
|
if (MobileShellState.Shell.orientation === MobileShellState.Shell.Portrait) {
|
2022-05-09 22:12:25 +00:00
|
|
|
pageLoader.item.view.currentIndex = 0;
|
|
|
|
|
}
|
2022-05-07 17:10:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// return to the first page when the action drawer is closed
|
|
|
|
|
Connections {
|
|
|
|
|
target: actionDrawer
|
|
|
|
|
|
2022-06-28 16:31:18 +00:00
|
|
|
function onOpenedChanged() {
|
|
|
|
|
if (!actionDrawer.opened) {
|
2022-05-07 17:10:02 +00:00
|
|
|
resetSwipeView();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-22 23:29:00 +00:00
|
|
|
|
|
|
|
|
// view when fully open
|
|
|
|
|
ColumnLayout {
|
|
|
|
|
id: fullView
|
|
|
|
|
opacity: root.fullViewProgress
|
|
|
|
|
visible: opacity !== 0
|
|
|
|
|
transform: Translate { y: (1 - fullView.opacity) * root.rowHeight }
|
|
|
|
|
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
|
2022-05-09 22:12:25 +00:00
|
|
|
// Dynamically loads the appropriate view
|
2022-05-07 21:19:56 +00:00
|
|
|
Loader {
|
2022-05-09 22:12:25 +00:00
|
|
|
id: pageLoader
|
2022-05-07 21:19:56 +00:00
|
|
|
|
2022-05-09 22:12:25 +00:00
|
|
|
Layout.fillWidth: true
|
2022-05-12 13:20:39 +00:00
|
|
|
Layout.minimumHeight: rowCount * rowHeight
|
|
|
|
|
|
2022-05-09 22:12:25 +00:00
|
|
|
asynchronous: true
|
2022-11-11 16:21:12 +00:00
|
|
|
sourceComponent: MobileShellState.Shell.orientation === MobileShellState.Shell.Portrait ? swipeViewComponent : scrollViewComponent
|
2022-05-07 17:10:02 +00:00
|
|
|
}
|
2022-05-09 22:12:25 +00:00
|
|
|
|
2021-12-22 23:29:00 +00:00
|
|
|
BrightnessItem {
|
|
|
|
|
id: brightnessItem
|
|
|
|
|
Layout.bottomMargin: PlasmaCore.Units.smallSpacing * 2
|
|
|
|
|
Layout.leftMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// view when in minimized mode
|
|
|
|
|
RowLayout {
|
|
|
|
|
id: minimizedView
|
|
|
|
|
spacing: 0
|
|
|
|
|
opacity: root.minimizedViewProgress
|
|
|
|
|
visible: opacity !== 0
|
|
|
|
|
transform: Translate { y: (1 - minimizedView.opacity) * -root.rowHeight }
|
|
|
|
|
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
|
|
|
|
|
Repeater {
|
2022-05-07 17:10:02 +00:00
|
|
|
model: MobileShell.PaginateModel {
|
|
|
|
|
sourceModel: quickSettingsModel
|
|
|
|
|
pageSize: minimizedColumns
|
|
|
|
|
}
|
2021-12-22 23:29:00 +00:00
|
|
|
delegate: Components.BaseItem {
|
|
|
|
|
required property var modelData
|
|
|
|
|
|
|
|
|
|
implicitHeight: root.minimizedRowHeight
|
|
|
|
|
implicitWidth: root.minimizedColumnWidth
|
|
|
|
|
horizontalPadding: (width - PlasmaCore.Units.gridUnit * 3) / 2
|
|
|
|
|
verticalPadding: (height - PlasmaCore.Units.gridUnit * 3) / 2
|
|
|
|
|
|
|
|
|
|
contentItem: QuickSettingsMinimizedDelegate {
|
2022-04-07 18:11:08 +00:00
|
|
|
restrictedPermissions: actionDrawer.restrictedPermissions
|
|
|
|
|
|
2021-12-22 23:29:00 +00:00
|
|
|
text: modelData.text
|
|
|
|
|
status: modelData.status
|
|
|
|
|
icon: modelData.icon
|
|
|
|
|
enabled: modelData.enabled
|
|
|
|
|
settingsCommand: modelData.settingsCommand
|
|
|
|
|
toggleFunction: modelData.toggle
|
2021-12-29 05:08:32 +00:00
|
|
|
|
|
|
|
|
onCloseRequested: {
|
|
|
|
|
actionDrawer.close();
|
|
|
|
|
}
|
2021-12-22 23:29:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-09 22:12:25 +00:00
|
|
|
|
2022-05-12 13:20:39 +00:00
|
|
|
// Loads portrait quick settings view
|
2022-05-09 22:12:25 +00:00
|
|
|
Component {
|
|
|
|
|
id: swipeViewComponent
|
|
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
|
readonly property var view: swipeView
|
|
|
|
|
|
|
|
|
|
SwipeView {
|
|
|
|
|
id: swipeView
|
|
|
|
|
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.preferredHeight: rowCount * rowHeight
|
|
|
|
|
|
|
|
|
|
Repeater {
|
|
|
|
|
model: Math.ceil(quickSettingsCount / pageSize)
|
|
|
|
|
delegate: Flow {
|
|
|
|
|
id: flow
|
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
|
|
required property int index
|
|
|
|
|
|
|
|
|
|
Repeater {
|
|
|
|
|
model: MobileShell.PaginateModel {
|
|
|
|
|
sourceModel: quickSettingsModel
|
|
|
|
|
pageSize: root.pageSize
|
|
|
|
|
firstItem: pageSize * flow.index
|
|
|
|
|
}
|
|
|
|
|
delegate: Loader {
|
|
|
|
|
required property var modelData
|
|
|
|
|
|
|
|
|
|
asynchronous: true
|
|
|
|
|
|
|
|
|
|
sourceComponent: quickSettingComponent
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Loader {
|
|
|
|
|
id: indicatorLoader
|
|
|
|
|
|
|
|
|
|
Layout.alignment: Qt.AlignCenter
|
|
|
|
|
Layout.topMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
|
Layout.leftMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
|
|
|
|
|
|
// Avoid wasting space when not loaded
|
|
|
|
|
Layout.maximumHeight: active ? item.implicitHeight : 0
|
|
|
|
|
|
|
|
|
|
active: swipeView.count > 1 ? true: false
|
|
|
|
|
asynchronous: true
|
|
|
|
|
|
|
|
|
|
sourceComponent: PageIndicator {
|
|
|
|
|
count: swipeView.count
|
|
|
|
|
currentIndex: swipeView.currentIndex
|
|
|
|
|
|
|
|
|
|
delegate: Rectangle {
|
|
|
|
|
implicitWidth: 8
|
|
|
|
|
implicitHeight: count > 1 ? 8 : 0
|
|
|
|
|
|
|
|
|
|
radius: parent.width / 2
|
|
|
|
|
color: PlasmaCore.Theme.disabledTextColor
|
|
|
|
|
|
|
|
|
|
opacity: index === currentIndex ? 0.95 : 0.45
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 13:20:39 +00:00
|
|
|
// Loads landscape quick settings view
|
2022-05-09 22:12:25 +00:00
|
|
|
Component {
|
|
|
|
|
id: scrollViewComponent
|
|
|
|
|
|
2022-05-12 13:20:39 +00:00
|
|
|
Item {
|
|
|
|
|
width: parent.width
|
|
|
|
|
height: rowCount * rowHeight
|
2022-05-09 22:12:25 +00:00
|
|
|
|
2022-05-12 13:20:39 +00:00
|
|
|
Flickable {
|
|
|
|
|
id: flickable
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
contentWidth: width
|
|
|
|
|
contentHeight: flow.height
|
2022-05-09 22:12:25 +00:00
|
|
|
|
2022-05-12 13:20:39 +00:00
|
|
|
clip: true
|
2022-05-09 22:12:25 +00:00
|
|
|
|
2022-05-12 13:20:39 +00:00
|
|
|
ScrollIndicator.vertical: ScrollIndicator {
|
2022-09-24 21:34:57 +00:00
|
|
|
id: scrollIndicator
|
2022-05-12 13:20:39 +00:00
|
|
|
visible: quickSettingsCount > pageSize ? true : false
|
|
|
|
|
position: 0.1
|
|
|
|
|
|
2022-09-24 21:34:57 +00:00
|
|
|
contentItem: Item {
|
2022-07-11 03:18:34 +00:00
|
|
|
implicitWidth: PlasmaCore.Units.smallSpacing / 4
|
2022-09-24 21:34:57 +00:00
|
|
|
Rectangle {
|
|
|
|
|
// shift over the indicator a bit to the right
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
anchors.leftMargin: 2
|
|
|
|
|
anchors.rightMargin: -2
|
|
|
|
|
|
|
|
|
|
color: PlasmaCore.Theme.textColor
|
|
|
|
|
opacity: scrollIndicator.active ? 0.5 : 0
|
|
|
|
|
|
|
|
|
|
Behavior on opacity { NumberAnimation {} }
|
|
|
|
|
}
|
2022-05-12 13:20:39 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Flow {
|
|
|
|
|
id: flow
|
|
|
|
|
width: parent.width
|
|
|
|
|
height: Math.ceil(quickSettingsCount / columnCount) * rowHeight
|
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
|
|
Repeater {
|
|
|
|
|
model: quickSettingsModel
|
|
|
|
|
delegate: Loader {
|
|
|
|
|
required property var modelData
|
|
|
|
|
|
|
|
|
|
asynchronous: true
|
|
|
|
|
|
|
|
|
|
sourceComponent: quickSettingComponent
|
|
|
|
|
}
|
2022-05-09 22:12:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Quick setting component
|
|
|
|
|
Component {
|
|
|
|
|
id: quickSettingComponent
|
|
|
|
|
|
|
|
|
|
Components.BaseItem {
|
|
|
|
|
height: root.rowHeight
|
|
|
|
|
width: root.columnWidth
|
|
|
|
|
padding: PlasmaCore.Units.smallSpacing
|
|
|
|
|
|
|
|
|
|
contentItem: QuickSettingsFullDelegate {
|
|
|
|
|
restrictedPermissions: actionDrawer.restrictedPermissions
|
|
|
|
|
|
|
|
|
|
text: modelData.text
|
|
|
|
|
status: modelData.status
|
|
|
|
|
icon: modelData.icon
|
|
|
|
|
enabled: modelData.enabled
|
|
|
|
|
settingsCommand: modelData.settingsCommand
|
|
|
|
|
toggleFunction: modelData.toggle
|
|
|
|
|
|
|
|
|
|
onCloseRequested: {
|
|
|
|
|
actionDrawer.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-22 23:29:00 +00:00
|
|
|
}
|