mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
This changeset makes the shell respect the quickSettingsColumns mobile shell setting. It renders the number of columns correctly and makes the drawer wider, as needed. As a side-effect, the width is now more dpi-independant since it switches from raw pixel values to gridUnit. Another side effect is that we make the individual quicksettings buttons ever so slightly wider (5.333 gridUnits before, gridUnits now). Signed-off-by: Sebastian Kügler <sebas@kde.org>
256 lines
8.6 KiB
QML
256 lines
8.6 KiB
QML
/*
|
|
* 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.private.mobileshell as MobileShell
|
|
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
|
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
|
|
import org.kde.kirigami 2.20 as Kirigami
|
|
|
|
/**
|
|
* Quick settings elements layout, change the height to clip.
|
|
*/
|
|
Item {
|
|
id: root
|
|
// to prevent clipping off the shadows form the BrightnessItem when the rest of the action panel view
|
|
// is transparent, we stop clipping the base view when fullViewProgress is not less then 1
|
|
clip: fullViewProgress < 1
|
|
|
|
required property var actionDrawer
|
|
|
|
required property QS.QuickSettingsModel quickSettingsModel
|
|
|
|
readonly property real columns: Math.round(Math.min(6, Math.max(ShellSettings.Settings.quickSettingsColumns, width / intendedColumnWidth)))
|
|
readonly property real columnWidth: Math.floor(width / columns)
|
|
readonly property int minimizedColumns: Math.round(Math.min(8, Math.max(5, width / intendedMinimizedColumnWidth)))
|
|
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: Kirigami.Units.gridUnit * 7
|
|
readonly property real intendedMinimizedColumnWidth: Kirigami.Units.gridUnit * 4 + Kirigami.Units.smallSpacing
|
|
readonly property real minimizedRowHeight: Kirigami.Units.gridUnit * 4 + Kirigami.Units.smallSpacing
|
|
|
|
property real fullViewProgress: 1
|
|
|
|
readonly property int columnCount: Math.floor(width/columnWidth)
|
|
readonly property int rowCount: {
|
|
let totalRows = Math.ceil(quickSettingsCount / columnCount);
|
|
|
|
if (root.mode === QuickSettings.Pages) {
|
|
// 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 if (root.mode === QuickSettings.ScrollView) {
|
|
// horizontal orientation
|
|
let targetRows = Math.floor(Window.height * 0.8 / rowHeight);
|
|
return Math.min(totalRows, targetRows);
|
|
}
|
|
}
|
|
|
|
readonly property int pageSize: rowCount * columnCount
|
|
readonly property int quickSettingsCount: quickSettingsModel.count
|
|
|
|
readonly property alias brightnessPressedValue: brightnessItem.brightnessPressedValue
|
|
|
|
function resetSwipeView() {
|
|
if (root.mode === QuickSettings.Pages) {
|
|
swipeView.currentIndex = 0;
|
|
}
|
|
}
|
|
|
|
// return to the first page when the action drawer is closed
|
|
Connections {
|
|
target: actionDrawer
|
|
|
|
function onOpenedChanged() {
|
|
if (!actionDrawer.opened) {
|
|
resetSwipeView();
|
|
}
|
|
}
|
|
}
|
|
|
|
// view when in minimized mode
|
|
RowLayout {
|
|
id: minimizedView
|
|
spacing: 0
|
|
opacity: 1 - root.fullViewProgress
|
|
|
|
anchors.topMargin: root.fullViewProgress * -height
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
|
|
Repeater {
|
|
id: repeater
|
|
model: QS.PaginateModel {
|
|
sourceModel: root.quickSettingsModel
|
|
pageSize: Math.min(root.pageSize, root.minimizedColumns) // HACK: just root.minimizedColumns appears to end up with an empty model?
|
|
}
|
|
delegate: Loader {
|
|
required property var modelData
|
|
|
|
asynchronous: true
|
|
|
|
sourceComponent: quickSettingComponentMinimized
|
|
}
|
|
}
|
|
}
|
|
|
|
// view when fully open
|
|
ColumnLayout {
|
|
id: fullView
|
|
opacity: root.fullViewProgress
|
|
|
|
anchors.top: minimizedView.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
|
|
// Quick settings view
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
Layout.minimumHeight: rowCount * rowHeight
|
|
|
|
opacity: brightnessPressedValue
|
|
|
|
SwipeView {
|
|
id: swipeView
|
|
// we need to clip this view here to prevent the other quick settings pages from being visible
|
|
// when fullViewProgress is not less then 1 and the base view is no longer being clipped
|
|
clip: true
|
|
|
|
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: QS.PaginateModel {
|
|
sourceModel: quickSettingsModel
|
|
pageSize: root.pageSize
|
|
firstItem: pageSize * flow.index
|
|
}
|
|
delegate: Loader {
|
|
required property var modelData
|
|
|
|
asynchronous: true
|
|
|
|
sourceComponent: quickSettingComponentFull
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
id: indicatorLoader
|
|
|
|
Layout.alignment: Qt.AlignCenter
|
|
Layout.topMargin: Kirigami.Units.smallSpacing
|
|
Layout.leftMargin: Kirigami.Units.smallSpacing
|
|
Layout.rightMargin: Kirigami.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: Kirigami.Theme.disabledTextColor
|
|
|
|
opacity: index === currentIndex ? 0.95 : 0.45
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Brightness slider
|
|
BrightnessItem {
|
|
id: brightnessItem
|
|
Layout.bottomMargin: Kirigami.Units.smallSpacing * 2
|
|
Layout.leftMargin: Kirigami.Units.smallSpacing
|
|
Layout.rightMargin: Kirigami.Units.smallSpacing
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
|
|
// Quick setting component minimized
|
|
Component {
|
|
id: quickSettingComponentMinimized
|
|
|
|
MobileShell.BaseItem {
|
|
implicitHeight: root.minimizedRowHeight
|
|
implicitWidth: root.minimizedColumnWidth
|
|
horizontalPadding: (width - Kirigami.Units.gridUnit * 3) / 2
|
|
verticalPadding: (height - Kirigami.Units.gridUnit * 3) / 2
|
|
|
|
contentItem: QuickSettingsMinimizedDelegate {
|
|
restrictedPermissions: actionDrawer.restrictedPermissions
|
|
|
|
text: modelData.text
|
|
status: modelData.status
|
|
icon: modelData.icon
|
|
enabled: modelData.enabled
|
|
settingsCommand: modelData.settingsCommand
|
|
toggleFunction: modelData.toggle
|
|
|
|
onCloseRequested: {
|
|
actionDrawer.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Quick setting component full
|
|
Component {
|
|
id: quickSettingComponentFull
|
|
|
|
MobileShell.BaseItem {
|
|
height: root.rowHeight
|
|
width: root.columnWidth
|
|
padding: Kirigami.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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|