[plasma/plasma-mobile] containments/homescreens/folio: folio/appdrawer: App Gird Adjustments and Separate the Base Grid Logic to a New File for Reusability
Devin Lin <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 8cbbe5338a2c4b3bac5e8b0d892201e24c87aea0 by Devin Lin, on behalf of Micah Stanley.
Committed on 23/07/2026 at 00:43.
Pushed by devinlin into branch 'master'.
folio/appdrawer: App Gird Adjustments and Separate the Base Grid Logic to a New File for Reusability
- App drawer gird adjustments.
- Separate the base app drawer grid logic to a new file for reusability.
M +2 -1 containments/homescreens/folio/CMakeLists.txt
M +10 -3 containments/homescreens/folio/qml/AppDrawer.qml
A +62 -0 containments/homescreens/folio/qml/AppDrawerAppGrid.qml [License: GPL(v2.0+)]
M +1 -1 containments/homescreens/folio/qml/FolioHomeScreen.qml
R +26 -67 containments/homescreens/folio/qml/private/AppDrawerGrid.qml [from: containments/homescreens/folio/qml/AppDrawerGrid.qml - 055% similarity]
https://invent.kde.org/plasma/plasma-mobile/-/commit/8cbbe5338a2c4b3bac5e8b0d892201e24c87aea0
diff --git a/containments/homescreens/folio/CMakeLists.txt b/containments/homescreens/folio/CMakeLists.txt
index 960203dee..c3c76d778 100644
--- a/containments/homescreens/folio/CMakeLists.txt
+++ b/containments/homescreens/folio/CMakeLists.txt
@@ -6,7 +6,7 @@ add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.mobile.homes
plasma_add_applet(org.kde.plasma.mobile.homescreen.folio
QML_SOURCES
qml/AppDrawer.qml
- qml/AppDrawerGrid.qml
+ qml/AppDrawerAppGrid.qml
qml/AppDrawerHeader.qml
qml/DelegateDragItem.qml
qml/DelegateDropArea.qml
@@ -62,6 +62,7 @@ ecm_target_qml_sources(org.kde.plasma.mobile.homescreen.folio SOURCES
qml/private/WidgetHandlePosition.qml
qml/private/WidgetResizeHandle.qml
qml/private/WidgetResizeHandleFrame.qml
+ qml/private/AppDrawerGrid.qml
PATH private
)
diff --git a/containments/homescreens/folio/qml/AppDrawer.qml b/containments/homescreens/folio/qml/AppDrawer.qml
index a389b2054..d0d1d5264 100644
--- a/containments/homescreens/folio/qml/AppDrawer.qml
+++ b/containments/homescreens/folio/qml/AppDrawer.qml
@@ -42,6 +42,11 @@ Item {
}
}
+ function reset() {
+ root.flickable.contentY = 0 - root.flickable.topMargin;
+ root.flickable.returnToBounds();
+ }
+
// App drawer container
Item {
anchors.fill: parent
@@ -79,16 +84,18 @@ Item {
}
// App list
- AppDrawerGrid {
+ AppDrawerAppGrid {
id: appDrawerGrid
folio: root.folio
homeScreen: root.homeScreen
height: parent.height - drawerHeader.height
+ anchors.top: parent.top
+ anchors.topMargin: root.headerHeight
anchors.left: parent.left
anchors.right: parent.right
- anchors.bottom: parent.bottom
opacity: 0 // we display with the opacity gradient below
- headerHeight: root.headerHeight
+
+ model: folio.ApplicationListSearchModel
// Keyboard navigation
topEdgeCallback: () => {
diff --git a/containments/homescreens/folio/qml/AppDrawerAppGrid.qml b/containments/homescreens/folio/qml/AppDrawerAppGrid.qml
new file mode 100644
index 000000000..4b69f266a
--- /dev/null
+++ b/containments/homescreens/folio/qml/AppDrawerAppGrid.qml
@@ -0,0 +1,62 @@
+/*
+ SPDX-FileCopyrightText: 2023 Devin Lin <[email protected]>
+ SPDX-FileCopyrightText: 2026 Micah Stanley <[email protected]>
+
+ SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+import QtQuick
+import org.kde.kirigami as Kirigami
+import org.kde.plasma.private.mobileshell as MobileShell
+import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
+import "./delegate"
+import "./private"
+
+AppDrawerGrid {
+ id: root
+
+ readonly property int columns: baseColumns
+
+ cellWidth: Math.floor(effectiveContentWidth / columns)
+ cellHeight: Math.max(folio.FolioSettings.delegateIconSize + folio.HomeScreenState.pageDelegateLabelHeight + Kirigami.Units.gridUnit * 2, cellWidth * 0.75)
+
+ // separate margins for portrait mode as aesthetically it does not look great to have excessive padding when the screen height is larger then the width
+ readonly property real __portraitHorizontalMargin: Math.max(Kirigami.Units.largeSpacing, horizontalMargin * 0.25)
+
+ leftMargin: Screen.height > Screen.width ? __portraitHorizontalMargin : horizontalMargin
+ rightMargin: leftMargin
+
+ MobileShell.HapticsEffect {
+ id: haptics
+ }
+
+ delegate: AppDelegate {
+ folio: root.folio
+ shadow: false
+ application: model.delegate.application
+ width: root.cellWidth
+ height: root.cellHeight
+
+ onPressAndHold: {
+ // prevent editing if lock layout is enabled
+ if (folio.FolioSettings.lockLayout) return;
+
+ const mappedCoords = root.homeScreen.prepareStartDelegateDrag(model.delegate, delegateItem, true, true);
+ folio.HomeScreenState.closeAppDrawer();
+
+ haptics.buttonVibrate();
+
+ // we need to adjust because app drawer delegates have a different size than regular homescreen delegates
+ const centerX = mappedCoords.x + root.cellWidth / 2;
+ const centerY = mappedCoords.y + root.cellHeight / 2;
+
+ folio.HomeScreenState.startDelegateAppDrawerDrag(
+ centerX - folio.HomeScreenState.pageCellWidth / 2,
+ centerY - folio.HomeScreenState.pageCellHeight / 2,
+ pressPosition.x * (folio.HomeScreenState.pageCellWidth / root.cellWidth),
+ pressPosition.y * (folio.HomeScreenState.pageCellHeight / root.cellHeight),
+ model.delegate.application.storageId
+ );
+ }
+ }
+}
diff --git a/containments/homescreens/folio/qml/FolioHomeScreen.qml b/containments/homescreens/folio/qml/FolioHomeScreen.qml
index cff22dbf2..da4067f25 100644
--- a/containments/homescreens/folio/qml/FolioHomeScreen.qml
+++ b/containments/homescreens/folio/qml/FolioHomeScreen.qml
@@ -599,7 +599,7 @@ Item {
function onAppDrawerClosed() {
// reset app drawer position when closed
- appDrawer.flickable.contentY = 0;
+ appDrawer.reset();
}
}
}
diff --git a/containments/homescreens/folio/qml/AppDrawerGrid.qml b/containments/homescreens/folio/qml/private/AppDrawerGrid.qml
similarity index 55%
rename from containments/homescreens/folio/qml/AppDrawerGrid.qml
rename to containments/homescreens/folio/qml/private/AppDrawerGrid.qml
index 2b698d60e..615820bed 100644
--- a/containments/homescreens/folio/qml/AppDrawerGrid.qml
+++ b/containments/homescreens/folio/qml/private/AppDrawerGrid.qml
@@ -13,42 +13,47 @@ import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
-import "./delegate"
-
MobileShell.GridView {
id: root
+
property Folio.HomeScreen folio
+ property var homeScreen
cacheBuffer: cellHeight * 20
reuseItems: true
layer.enabled: true
-
keyNavigationEnabled: true
highlightMoveDuration: 0
highlight: null // We supply our own highlight from the delegate
+ boundsBehavior: Flickable.DragAndOvershootBounds
- property var homeScreen
- property real headerHeight
-
- readonly property int reservedSpaceForLabel: folio.HomeScreenState.pageDelegateLabelHeight
- readonly property real effectiveContentWidth: width - leftMargin - rightMargin
- readonly property real horizontalMargin: Math.round(width * 0.05)
-
- leftMargin: horizontalMargin
- rightMargin: horizontalMargin
+ // HACK: the first swipe from the top of the app drawer is done from HomeScreenState, not the flickable
+ // due to issues with Flickable getting its swipe stolen by SwipeArea
+ interactive: (dragging || !atYBeginning) && folio.HomeScreenState.swipeState !== Folio.HomeScreenState.SwipingAppDrawerGrid
- cellWidth: effectiveContentWidth / Math.min(Math.floor(effectiveContentWidth / (folio.FolioSettings.delegateIconSize + Kirigami.Units.largeSpacing * 3.5)), 8)
- cellHeight: cellWidth + reservedSpaceForLabel
+ readonly property real __iconCellPadding: Kirigami.Units.largeSpacing * 5 // extra space reserved around the icons to fit comfortably within the grid
+ readonly property real __horizontalMarginLowerLimit: Kirigami.Units.largeSpacing
+ readonly property real __horizontalMarginUpperLimit: Kirigami.Units.gridUnit * 26
- boundsBehavior: Flickable.DragAndOvershootBounds
+ // this value represent how many app icons can comfortably fit on the screen with a lower limit of the homescreen column value and a upper limit of 8
+ // we add a portion of the `horizontalMargin` value to the icon size to make sure the column value does not grow as much for the wider screen sizes
+ readonly property int baseColumns: Math.min(Math.max(Math.round(width / (folio.FolioSettings.delegateIconSize + __iconCellPadding + horizontalMargin * 0.5)), folio.FolioSettings.homeScreenColumns), 8)
+ readonly property real effectiveContentWidth: width - leftMargin - rightMargin
+ // make sure we set a lower limit for the `baseHorizontalMargin` and `horizontalMargin` so it never goes under `__horizontalMarginLowerLimit`
+ readonly property real baseHorizontalMargin: Math.max(Math.round(width * 0.125) - Kirigami.Units.gridUnit * 2.25, __horizontalMarginLowerLimit)
+ // we set an upper limit for the horizontal margins, as aesthetically for a grid full of apps, it looks better to not let the padding get too exessive
+ readonly property real horizontalMargin: Math.min(Math.max((root.width - __horizontalMarginUpperLimit) * 0.5, __horizontalMarginLowerLimit), baseHorizontalMargin)
- readonly property int columns: Math.floor(effectiveContentWidth / cellWidth)
- readonly property int rows: Math.ceil(root.count / columns)
+ // Keyboard focus on app delegate when it is the selected item
+ onCurrentItemChanged: {
+ if (currentItem) {
+ currentItem.keyboardFocus();
+ }
+ }
- // HACK: the first swipe from the top of the app drawer is done from HomeScreenState, not the flickable
- // due to issues with Flickable getting its swipe stolen by SwipeArea
- interactive: (dragging || !atYBeginning) // allow us to drag to the top
- && folio.HomeScreenState.swipeState !== Folio.HomeScreenState.SwipingAppDrawerGrid
+ Component.onCompleted: Qt.callLater(() => {
+ root.contentY = 0 - root.topMargin
+ })
Connections {
target: folio.HomeScreenState
@@ -82,51 +87,6 @@ MobileShell.GridView {
id: velocityCalculator
}
- MobileShell.HapticsEffect {
- id: haptics
- }
-
- model: folio.ApplicationListSearchModel
-
- // Keyboard focus on app delegate when it is the selected item
- onCurrentItemChanged: {
- if (currentItem) {
- currentItem.keyboardFocus();
- }
- }
-
- delegate: AppDelegate {
- id: appDelegate
-
- folio: root.folio
- shadow: false
- application: model.delegate.application
-
- width: root.cellWidth
- height: root.cellHeight
-
- onPressAndHold: {
- // prevent editing if lock layout is enabled
- if (folio.FolioSettings.lockLayout) return;
-
- const mappedCoords = root.homeScreen.prepareStartDelegateDrag(model.delegate, appDelegate.delegateItem, true, true);
- folio.HomeScreenState.closeAppDrawer();
- haptics.buttonVibrate();
-
- // we need to adjust because app drawer delegates have a different size than regular homescreen delegates
- const centerX = mappedCoords.x + root.cellWidth / 2;
- const centerY = mappedCoords.y + root.cellHeight / 2;
-
- folio.HomeScreenState.startDelegateAppDrawerDrag(
- centerX - folio.HomeScreenState.pageCellWidth / 2,
- centerY - folio.HomeScreenState.pageCellHeight / 2,
- appDelegate.pressPosition.x * (folio.HomeScreenState.pageCellWidth / root.cellWidth),
- appDelegate.pressPosition.y * (folio.HomeScreenState.pageCellHeight / root.cellHeight),
- model.delegate.application.storageId
- );
- }
- }
-
PC3.ScrollBar.vertical: PC3.ScrollBar {
id: scrollBar
interactive: true
@@ -139,7 +99,6 @@ MobileShell.GridView {
easing.type: Easing.InOutQuad
}
}
-
contentItem: Rectangle {
radius: width / 2
color: Qt.rgba(1, 1, 1, 0.3)