mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Folio/Halcyon: Expand Background Blur Effect using a MaskLayer
This merge request expands upon the folio and halcyon background blur effects, making the folio background blur include the backgrounds of folder icons, the favorites bar, and wallpaper selector, and for halcyon, it now includes the folder icons, app library, search, and wallpaper selector. To accomplish this, a mask layer plugin was created to easily attach to these elements. This way, we can use a `OpacityMask` to cut out from the existing blur layer, thus hopefully keeping the performance cost low. And with my limited testing, it does at least seems to run about the same on my oneplus 6t, though it is not really a low end device, so I can not fairly judge the impact for something slower (eg. PinePhone). To be on the safe side, a third option was also added to the folio settings, allowing for the ability to toggle back to the old functionality if needed.    
This commit is contained in:
parent
d4f1c78d61
commit
d4eaf693c6
33 changed files with 890 additions and 240 deletions
|
|
@ -11,9 +11,12 @@ set(mobileshellplugin_SRCS
|
||||||
notifications/notificationthumbnailer.cpp
|
notifications/notificationthumbnailer.cpp
|
||||||
notifications/notificationfilemenu.cpp
|
notifications/notificationfilemenu.cpp
|
||||||
notifications/notificationfileinfo.cpp
|
notifications/notificationfileinfo.cpp
|
||||||
|
masklayer/masklayer.cpp
|
||||||
|
masklayer/maskmanager.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(mobileshellplugin PRIVATE components)
|
target_include_directories(mobileshellplugin PRIVATE components)
|
||||||
target_include_directories(mobileshellplugin PRIVATE notifications)
|
target_include_directories(mobileshellplugin PRIVATE notifications)
|
||||||
|
target_include_directories(mobileshellplugin PRIVATE masklayer)
|
||||||
target_sources(mobileshellplugin PRIVATE ${mobileshellplugin_SRCS})
|
target_sources(mobileshellplugin PRIVATE ${mobileshellplugin_SRCS})
|
||||||
|
|
||||||
# Singleton declarations
|
# Singleton declarations
|
||||||
|
|
|
||||||
268
components/mobileshell/masklayer/masklayer.cpp
Normal file
268
components/mobileshell/masklayer/masklayer.cpp
Normal file
|
|
@ -0,0 +1,268 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "masklayer.h"
|
||||||
|
|
||||||
|
#include <QSGFlatColorMaterial>
|
||||||
|
|
||||||
|
// helper function for creating rounded rectangles
|
||||||
|
static void createRoundedRectGeometry(QSGGeometry *geometry, const QRectF &rect, qreal radius)
|
||||||
|
{
|
||||||
|
geometry->setDrawingMode(QSGGeometry::DrawTriangles);
|
||||||
|
radius = qMin(radius, qMin(rect.width(), rect.height()) / 2.0); // clamp radius
|
||||||
|
|
||||||
|
// if the radius is too small, draw a simple rectangle instead
|
||||||
|
if (radius < 0.1) {
|
||||||
|
// 4 vertices, 6 indices (2 triangles * 3 indices)
|
||||||
|
geometry->allocate(4, 6);
|
||||||
|
|
||||||
|
// fill vertex data
|
||||||
|
QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
|
||||||
|
vertices[0].set(rect.left(), rect.top());
|
||||||
|
vertices[1].set(rect.right(), rect.top());
|
||||||
|
vertices[2].set(rect.left(), rect.bottom());
|
||||||
|
vertices[3].set(rect.right(), rect.bottom());
|
||||||
|
|
||||||
|
// fill index data
|
||||||
|
quint16 *indices = geometry->indexDataAsUShort();
|
||||||
|
indices[0] = 0; indices[1] = 2; indices[2] = 1; // first triangle (TL, BL, TR)
|
||||||
|
indices[3] = 1; indices[4] = 2; indices[5] = 3; // second triangle (TR, BL, BR)
|
||||||
|
|
||||||
|
geometry->markVertexDataDirty();
|
||||||
|
geometry->markIndexDataDirty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int segments_per_corner = 16;
|
||||||
|
const int perimeter_verts = segments_per_corner * 4;
|
||||||
|
const int vertex_count = 1 + perimeter_verts;
|
||||||
|
const int index_count = perimeter_verts * 3;
|
||||||
|
|
||||||
|
geometry->allocate(vertex_count, index_count);
|
||||||
|
|
||||||
|
QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
|
||||||
|
quint16 *indices = geometry->indexDataAsUShort();
|
||||||
|
|
||||||
|
int vertIndex = 0;
|
||||||
|
int indexPos = 0;
|
||||||
|
|
||||||
|
// define the center vertex
|
||||||
|
const quint16 center_vert_index = vertIndex;
|
||||||
|
vertices[vertIndex++].set(rect.center().x(), rect.center().y());
|
||||||
|
|
||||||
|
// define the center of the corners
|
||||||
|
const QPointF tl_c = {rect.left() + radius, rect.top() + radius};
|
||||||
|
const QPointF tr_c = {rect.right() - radius, rect.top() + radius};
|
||||||
|
const QPointF br_c = {rect.right() - radius, rect.bottom() - radius};
|
||||||
|
const QPointF bl_c = {rect.left() + radius, rect.bottom() - radius};
|
||||||
|
|
||||||
|
// create all perimeter vertices
|
||||||
|
// top-right
|
||||||
|
for (int i = 0; i < segments_per_corner; ++i) {
|
||||||
|
const qreal angle = M_PI * 1.5 + (M_PI_2 * i / segments_per_corner);
|
||||||
|
vertices[vertIndex++].set(tr_c.x() + radius * cos(angle), tr_c.y() + radius * sin(angle));
|
||||||
|
}
|
||||||
|
// bottom-right
|
||||||
|
for (int i = 0; i < segments_per_corner; ++i) {
|
||||||
|
const qreal angle = (M_PI_2 * i / segments_per_corner);
|
||||||
|
vertices[vertIndex++].set(br_c.x() + radius * cos(angle), br_c.y() + radius * sin(angle));
|
||||||
|
}
|
||||||
|
// bottom-left
|
||||||
|
for (int i = 0; i < segments_per_corner; ++i) {
|
||||||
|
const qreal angle = M_PI_2 + (M_PI_2 * i / segments_per_corner);
|
||||||
|
vertices[vertIndex++].set(bl_c.x() + radius * cos(angle), bl_c.y() + radius * sin(angle));
|
||||||
|
}
|
||||||
|
// top-left
|
||||||
|
for (int i = 0; i < segments_per_corner; ++i) {
|
||||||
|
const qreal angle = M_PI + (M_PI_2 * i / segments_per_corner);
|
||||||
|
vertices[vertIndex++].set(tl_c.x() + radius * cos(angle), tl_c.y() + radius * sin(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the triangles using indices
|
||||||
|
// loop through all perimeter vertices and connect them to the center and the next vertex
|
||||||
|
for (quint16 i = 0; i < perimeter_verts; ++i) {
|
||||||
|
indices[indexPos++] = center_vert_index; // center vertex
|
||||||
|
indices[indexPos++] = center_vert_index + 1 + i; // current perimeter vertex
|
||||||
|
// the next perimeter vertex / wrapping around to the start at the end
|
||||||
|
indices[indexPos++] = center_vert_index + 1 + ((i + 1) % perimeter_verts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell renderer to mark all the data as dirty
|
||||||
|
geometry->markVertexDataDirty();
|
||||||
|
geometry->markIndexDataDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
MaskLayer::MaskLayer(QQuickItem *parent) : QQuickItem(parent)
|
||||||
|
{
|
||||||
|
setFlag(ItemHasContents, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaskLayer::~MaskLayer() = default;
|
||||||
|
|
||||||
|
void MaskLayer::addItem(QQuickItem* item)
|
||||||
|
{
|
||||||
|
if (!item || m_sourceItems.contains(item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sourceItems.append(item);
|
||||||
|
|
||||||
|
// we connect these signals so that any changes that affects the item's visual representation triggers an update
|
||||||
|
// we then store connections to be able to disconnect them later
|
||||||
|
auto& conns = m_connections[item];
|
||||||
|
conns.append(QObject::connect(item, &QQuickItem::xChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
conns.append(QObject::connect(item, &QQuickItem::yChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
conns.append(QObject::connect(item, &QQuickItem::visibleChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
conns.append(QObject::connect(item, &QQuickItem::opacityChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
conns.append(QObject::connect(item, &QObject::destroyed, this, [this, item]() {
|
||||||
|
removeItem(item);
|
||||||
|
}));
|
||||||
|
|
||||||
|
const QMetaObject* metaObject = item->metaObject();
|
||||||
|
|
||||||
|
// due to not being about to tell when the item's transform value changes
|
||||||
|
// we check for 'scaleAmountChanged()' to use as a sort of work around
|
||||||
|
int scaleAmountIndex = metaObject->indexOfProperty("scaleAmount");
|
||||||
|
if (scaleAmountIndex != -1 && metaObject->property(scaleAmountIndex).hasNotifySignal()) {
|
||||||
|
conns.append(QObject::connect(item, SIGNAL(scaleAmountChanged()), this, SLOT(scheduleUpdate())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect the parents signal changes, as this affects the final visible outcome
|
||||||
|
QQuickItem* currentParent = item->parentItem();
|
||||||
|
while (currentParent) {
|
||||||
|
conns.append(QObject::connect(currentParent, &QQuickItem::xChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
conns.append(QObject::connect(currentParent, &QQuickItem::yChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
conns.append(QObject::connect(currentParent, &QQuickItem::opacityChanged, this, &MaskLayer::scheduleUpdate));
|
||||||
|
|
||||||
|
const QMetaObject* metaObject = currentParent->metaObject();
|
||||||
|
|
||||||
|
// check for 'scaleAmountChanged()'
|
||||||
|
int scaleAmountIndex = metaObject->indexOfProperty("scaleAmount");
|
||||||
|
if (scaleAmountIndex != -1 && metaObject->property(scaleAmountIndex).hasNotifySignal()) {
|
||||||
|
conns.append(QObject::connect(currentParent, SIGNAL(scaleAmountChanged()), this, SLOT(scheduleUpdate())));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentParent = currentParent->parentItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaskLayer::removeItem(QQuickItem* item)
|
||||||
|
{
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
|
disconnectItemSignals(item);
|
||||||
|
m_connections.remove(item);
|
||||||
|
m_sourceItems.removeAll(item);
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaskLayer::disconnectItemSignals(QQuickItem* item)
|
||||||
|
{
|
||||||
|
if (m_connections.contains(item)) {
|
||||||
|
for (const auto &conn : m_connections.value(item)) {
|
||||||
|
QObject::disconnect(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaskLayer::scheduleUpdate()
|
||||||
|
{
|
||||||
|
// marks this item for an update.
|
||||||
|
// the renderer will call updatePaintNode before the next frame
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode *MaskLayer::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
|
||||||
|
{
|
||||||
|
// if oldNode is null, we need to create a new root node for our content
|
||||||
|
// otherwise, we can reuse it and manage its children
|
||||||
|
QSGNode *rootNode = oldNode;
|
||||||
|
if (!rootNode) {
|
||||||
|
rootNode = new QSGNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentChildIndex = 0;
|
||||||
|
|
||||||
|
for (const QPointer<QQuickItem>& itemPtr : m_sourceItems) {
|
||||||
|
QQuickItem* item = itemPtr.data();
|
||||||
|
// item was deleted
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate opacity and visibility
|
||||||
|
qreal accumulatedOpacity = item->opacity();
|
||||||
|
bool isVisible = item->isVisible();
|
||||||
|
QQuickItem* currentParent = item->parentItem();
|
||||||
|
while (currentParent) {
|
||||||
|
if (!currentParent->isVisible()) {
|
||||||
|
isVisible = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
accumulatedOpacity *= currentParent->opacity();
|
||||||
|
if (currentParent == this) break;
|
||||||
|
currentParent = currentParent->parentItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip this item if it is invisible or fully transparent
|
||||||
|
if (!isVisible || qFuzzyCompare(accumulatedOpacity, 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate position and size
|
||||||
|
bool transformOk = false;
|
||||||
|
const QTransform transform = item->itemTransform(this, &transformOk);
|
||||||
|
if (!transformOk) continue;
|
||||||
|
|
||||||
|
qreal radius = item->property("radius").toReal();
|
||||||
|
|
||||||
|
QSGTransformNode *transformNode = nullptr;
|
||||||
|
QSGGeometryNode *geometryNode = nullptr;
|
||||||
|
|
||||||
|
if (currentChildIndex < rootNode->childCount()) {
|
||||||
|
transformNode = static_cast<QSGTransformNode*>(rootNode->childAtIndex(currentChildIndex));
|
||||||
|
geometryNode = static_cast<QSGGeometryNode*>(transformNode->firstChild());
|
||||||
|
} else {
|
||||||
|
transformNode = new QSGTransformNode();
|
||||||
|
geometryNode = new QSGGeometryNode();
|
||||||
|
|
||||||
|
QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
|
||||||
|
|
||||||
|
geometryNode->setGeometry(geometry);
|
||||||
|
|
||||||
|
QSGFlatColorMaterial *material = new QSGFlatColorMaterial();
|
||||||
|
geometryNode->setMaterial(material);
|
||||||
|
geometryNode->setFlags(QSGNode::OwnsMaterial);
|
||||||
|
|
||||||
|
transformNode->appendChildNode(geometryNode);
|
||||||
|
rootNode->appendChildNode(transformNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
transformNode->setMatrix(QMatrix4x4(transform));
|
||||||
|
|
||||||
|
QSGFlatColorMaterial *material = static_cast<QSGFlatColorMaterial*>(geometryNode->material());
|
||||||
|
QColor color = Qt::white;
|
||||||
|
color.setAlphaF(accumulatedOpacity);
|
||||||
|
if (material->color() != color) material->setColor(color);
|
||||||
|
|
||||||
|
QRectF rect(0, 0, item->width(), item->height());
|
||||||
|
createRoundedRectGeometry(geometryNode->geometry(), rect, radius);
|
||||||
|
geometryNode->markDirty(QSGNode::DirtyGeometry);
|
||||||
|
|
||||||
|
|
||||||
|
currentChildIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have more nodes than items this frame, remove the extras
|
||||||
|
if (currentChildIndex < rootNode->childCount()) {
|
||||||
|
for (int i = rootNode->childCount() - 1; i >= currentChildIndex; --i) {
|
||||||
|
QSGNode *nodeToRemove = rootNode->childAtIndex(i);
|
||||||
|
rootNode->removeChildNode(nodeToRemove);
|
||||||
|
delete nodeToRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootNode;
|
||||||
|
}
|
||||||
33
components/mobileshell/masklayer/masklayer.h
Normal file
33
components/mobileshell/masklayer/masklayer.h
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
class QSGNode;
|
||||||
|
|
||||||
|
class MaskLayer : public QQuickItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MaskLayer(QQuickItem *parent = nullptr);
|
||||||
|
~MaskLayer() override;
|
||||||
|
|
||||||
|
Q_INVOKABLE void addItem(QQuickItem* item);
|
||||||
|
Q_INVOKABLE void removeItem(QQuickItem* item);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void scheduleUpdate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void disconnectItemSignals(QQuickItem* item);
|
||||||
|
|
||||||
|
QVector<QPointer<QQuickItem>> m_sourceItems;
|
||||||
|
QHash<QQuickItem*, QVector<QMetaObject::Connection>> m_connections;
|
||||||
|
};
|
||||||
43
components/mobileshell/masklayer/maskmanager.cpp
Normal file
43
components/mobileshell/masklayer/maskmanager.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "maskmanager.h"
|
||||||
|
#include "masklayer.h"
|
||||||
|
|
||||||
|
MaskManager::MaskManager(QQuickItem *parent)
|
||||||
|
: QQuickItem(parent),
|
||||||
|
m_maskLayer(new MaskLayer(this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MaskManager::~MaskManager() = default;
|
||||||
|
|
||||||
|
void MaskManager::componentComplete() {
|
||||||
|
QQuickItem::componentComplete();
|
||||||
|
// ensure the mask layers fill the dimensions
|
||||||
|
m_maskLayer->setX(0);
|
||||||
|
m_maskLayer->setY(0);
|
||||||
|
m_maskLayer->setWidth(width());
|
||||||
|
m_maskLayer->setHeight(height());
|
||||||
|
m_maskLayer->setZ(z());
|
||||||
|
|
||||||
|
connect(this, &QQuickItem::widthChanged, this, [this]() {
|
||||||
|
m_maskLayer->setWidth(width());
|
||||||
|
});
|
||||||
|
connect(this, &QQuickItem::heightChanged, this, [this]() {
|
||||||
|
m_maskLayer->setHeight(height());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickItem* MaskManager::maskLayer() const {
|
||||||
|
return m_maskLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaskManager::assignToMask(QQuickItem* item) {
|
||||||
|
if (!item) {
|
||||||
|
qWarning() << "Cannot assign a null item to a mask.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_maskLayer->addItem(item);
|
||||||
|
}
|
||||||
29
components/mobileshell/masklayer/maskmanager.h
Normal file
29
components/mobileshell/masklayer/maskmanager.h
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
class MaskLayer;
|
||||||
|
|
||||||
|
class MaskManager : public QQuickItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
Q_PROPERTY(QQuickItem* maskLayer READ maskLayer CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MaskManager(QQuickItem *parent = nullptr);
|
||||||
|
~MaskManager() override;
|
||||||
|
|
||||||
|
QQuickItem* maskLayer() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void assignToMask(QQuickItem* item);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void componentComplete() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MaskLayer* m_maskLayer;
|
||||||
|
};
|
||||||
90
components/mobileshell/qml/homescreen/BlurEffect.qml
Normal file
90
components/mobileshell/qml/homescreen/BlurEffect.qml
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023-2025 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property Item sourceLayer
|
||||||
|
property Item maskSourceLayer
|
||||||
|
// this value is used to switch between blurring the whole wallpaper or just behind the mask areas
|
||||||
|
property real fullBlur: 1
|
||||||
|
// gets multiplied against the screen size to set the texture size
|
||||||
|
readonly property real blurTextureQuality: 0.5
|
||||||
|
readonly property var textureSize: Qt.size(Math.round(root.width * root.blurTextureQuality), Math.round(root.height * root.blurTextureQuality))
|
||||||
|
readonly property int fastBlurRadius: 42
|
||||||
|
|
||||||
|
sourceComponent: Item {
|
||||||
|
// only take samples from wallpaper when we need the blur for performance
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: controlledWallpaperSource
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
// this layer will be blurred, so it looks fine to have a lower texture quality to help with performance
|
||||||
|
textureSize: root.textureSize
|
||||||
|
|
||||||
|
hideSource: false
|
||||||
|
opacity: root.fullBlur
|
||||||
|
visible: opacity > 0
|
||||||
|
|
||||||
|
// wallpaper blur
|
||||||
|
// we attempted to use MultiEffect in the past, but it had very poor performance on the PinePhone
|
||||||
|
sourceItem: FastBlur {
|
||||||
|
height: controlledWallpaperSource.textureSize.height
|
||||||
|
width: controlledWallpaperSource.textureSize.width
|
||||||
|
|
||||||
|
cached: true
|
||||||
|
radius: root.fastBlurRadius
|
||||||
|
|
||||||
|
source: ShaderEffectSource {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
textureSize: controlledWallpaperSource.textureSize
|
||||||
|
|
||||||
|
sourceItem: root.sourceLayer
|
||||||
|
hideSource: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load in the layer mask so we can utilize it with the OpacityMask
|
||||||
|
Item {
|
||||||
|
id: blurMask
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
layer.smooth: true
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
asynchronous: true
|
||||||
|
active: root.maskSourceLayer != null && root.fullBlur != 1
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
sourceComponent: maskSource
|
||||||
|
|
||||||
|
property Component maskSource: Item {
|
||||||
|
ShaderEffectSource {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
sourceItem: root.maskSourceLayer
|
||||||
|
hideSource: false
|
||||||
|
live: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// here we utilize the mask on the blur layer so we can blur behind the some homescreen items
|
||||||
|
OpacityMask {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: controlledWallpaperSource
|
||||||
|
maskSource: blurMask
|
||||||
|
visible: opacity > 0 && root.maskSourceLayer != null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//END API implementation
|
//END API implementation
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
// determine the margins used
|
// determine the margins used
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023-2025 Devin Lin <devin@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: root
|
|
||||||
property real blurOpacity
|
|
||||||
property Item wallpaperItem
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
id: wallpaper
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
// only take samples from wallpaper when we need the blur for performance
|
|
||||||
ShaderEffectSource {
|
|
||||||
id: controlledWallpaperSource
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
live: blur.visible
|
|
||||||
hideSource: false
|
|
||||||
visible: false
|
|
||||||
sourceItem: root.wallpaperItem
|
|
||||||
}
|
|
||||||
|
|
||||||
// wallpaper blur
|
|
||||||
// we attempted to use MultiEffect in the past, but it had very poor performance on the PinePhone
|
|
||||||
FastBlur {
|
|
||||||
id: blur
|
|
||||||
radius: 50
|
|
||||||
cached: true
|
|
||||||
source: controlledWallpaperSource
|
|
||||||
anchors.fill: parent
|
|
||||||
visible: opacity > 0
|
|
||||||
opacity: root.blurOpacity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,11 +11,14 @@ import org.kde.kirigami 2.20 as Kirigami
|
||||||
import org.kde.plasma.wallpapers.image 2.0 as Wallpaper
|
import org.kde.plasma.wallpapers.image 2.0 as Wallpaper
|
||||||
import org.kde.kquickcontrolsaddons 2.0 as Addons
|
import org.kde.kquickcontrolsaddons 2.0 as Addons
|
||||||
import org.kde.plasma.private.mobileshell.wallpaperimageplugin as WallpaperImagePlugin
|
import org.kde.plasma.private.mobileshell.wallpaperimageplugin as WallpaperImagePlugin
|
||||||
|
import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
|
|
||||||
Controls.Drawer {
|
Controls.Drawer {
|
||||||
id: imageWallpaperDrawer
|
id: imageWallpaperDrawer
|
||||||
dragMargin: 0
|
dragMargin: 0
|
||||||
|
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
required property bool horizontal
|
required property bool horizontal
|
||||||
|
|
||||||
signal wallpaperSettingsRequested()
|
signal wallpaperSettingsRequested()
|
||||||
|
|
@ -51,8 +54,8 @@ Controls.Drawer {
|
||||||
|
|
||||||
header: Controls.ItemDelegate {
|
header: Controls.ItemDelegate {
|
||||||
id: openSettings
|
id: openSettings
|
||||||
width: imageWallpaperDrawer.horizontal ? parent.width : height * (imageWallpaperDrawer.width / imageWallpaperDrawer.Screen.height)
|
width: imageWallpaperDrawer.horizontal ? wallpapersView.width : height * (imageWallpaperDrawer.width / imageWallpaperDrawer.Screen.height)
|
||||||
height: imageWallpaperDrawer.horizontal ? width / (imageWallpaperDrawer.Screen.width / imageWallpaperDrawer.Screen.height) : parent.height
|
height: imageWallpaperDrawer.horizontal ? width / (imageWallpaperDrawer.Screen.width / imageWallpaperDrawer.Screen.height) : wallpapersView.height
|
||||||
padding: Kirigami.Units.gridUnit / 2
|
padding: Kirigami.Units.gridUnit / 2
|
||||||
leftPadding: padding
|
leftPadding: padding
|
||||||
topPadding: padding
|
topPadding: padding
|
||||||
|
|
@ -62,6 +65,12 @@ Controls.Drawer {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: Kirigami.Units.cornerRadius
|
radius: Kirigami.Units.cornerRadius
|
||||||
color: Qt.rgba(255, 255, 255, (openSettings.down || openSettings.highlighted) ? 0.3 : 0.2)
|
color: Qt.rgba(255, 255, 255, (openSettings.down || openSettings.highlighted) ? 0.3 : 0.2)
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (maskManager) {
|
||||||
|
maskManager.assignToMask(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
|
|
@ -81,11 +90,11 @@ Controls.Drawer {
|
||||||
delegate: Controls.ItemDelegate {
|
delegate: Controls.ItemDelegate {
|
||||||
id: delegate
|
id: delegate
|
||||||
|
|
||||||
width: imageWallpaperDrawer.horizontal ? parent.width : height * (imageWallpaperDrawer.width / imageWallpaperDrawer.Screen.height)
|
width: imageWallpaperDrawer.horizontal ? wallpapersView.width : height * (imageWallpaperDrawer.width / imageWallpaperDrawer.Screen.height)
|
||||||
height: imageWallpaperDrawer.horizontal ? width / (imageWallpaperDrawer.Screen.width / imageWallpaperDrawer.Screen.height) : (parent ? parent.height : 0)
|
height: imageWallpaperDrawer.horizontal ? width / (imageWallpaperDrawer.Screen.width / imageWallpaperDrawer.Screen.height) : (wallpapersView ? wallpapersView.height : 0)
|
||||||
padding: Kirigami.Units.largeSpacing - (ListView.isCurrentItem ? Kirigami.Units.smallSpacing : 0)
|
padding: Kirigami.Units.largeSpacing - (wallpapersView.currentIndex === index ? Kirigami.Units.smallSpacing : 0)
|
||||||
property real inset: ListView.isCurrentItem ? 0 : Kirigami.Units.smallSpacing
|
property real scaleAmount: wallpapersView.currentIndex === index ? 0 : Kirigami.Units.smallSpacing
|
||||||
Behavior on inset {
|
Behavior on scaleAmount {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Kirigami.Units.longDuration
|
duration: Kirigami.Units.longDuration
|
||||||
easing.type: Easing.InOutQuad
|
easing.type: Easing.InOutQuad
|
||||||
|
|
@ -102,10 +111,10 @@ Controls.Drawer {
|
||||||
topPadding: padding
|
topPadding: padding
|
||||||
rightPadding: padding
|
rightPadding: padding
|
||||||
bottomPadding: padding
|
bottomPadding: padding
|
||||||
topInset: inset
|
topInset: scaleAmount
|
||||||
bottomInset: inset
|
bottomInset: scaleAmount
|
||||||
leftInset: inset
|
leftInset: scaleAmount
|
||||||
rightInset: inset
|
rightInset: scaleAmount
|
||||||
|
|
||||||
property bool isCurrent: WallpaperImagePlugin.WallpaperPlugin.homescreenWallpaperPath == model.path
|
property bool isCurrent: WallpaperImagePlugin.WallpaperPlugin.homescreenWallpaperPath == model.path
|
||||||
onIsCurrentChanged: {
|
onIsCurrentChanged: {
|
||||||
|
|
@ -143,6 +152,12 @@ Controls.Drawer {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: Qt.rgba(255, 255, 255, (delegate.down || delegate.highlighted) ? 0.4 : 0.2)
|
color: Qt.rgba(255, 255, 255, (delegate.down || delegate.highlighted) ? 0.4 : 0.2)
|
||||||
radius: Kirigami.Units.cornerRadius
|
radius: Kirigami.Units.cornerRadius
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (maskManager) {
|
||||||
|
maskManager.assignToMask(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ const QString CFG_KEY_LOCK_LAYOUT = QStringLiteral("lockLayout");
|
||||||
const QString CFG_KEY_DELEGATE_ICON_SIZE = QStringLiteral("delegateIconSize");
|
const QString CFG_KEY_DELEGATE_ICON_SIZE = QStringLiteral("delegateIconSize");
|
||||||
const QString CFG_KEY_SHOW_FAVORITES_BAR_BACKGROUND = QStringLiteral("showFavoritesBarBackground");
|
const QString CFG_KEY_SHOW_FAVORITES_BAR_BACKGROUND = QStringLiteral("showFavoritesBarBackground");
|
||||||
const QString CFG_KEY_PAGE_TRANSITION_EFFECT = QStringLiteral("pageTransitionEffect");
|
const QString CFG_KEY_PAGE_TRANSITION_EFFECT = QStringLiteral("pageTransitionEffect");
|
||||||
const QString CFG_KEY_SHOW_WALLPAPER_BLUR = QStringLiteral("showWallpaperBlur");
|
const QString CFG_KEY_SHOW_WALLPAPER_BLUR = QStringLiteral("wallpaperBlurEffect");
|
||||||
const QString CFG_KEY_DOUBLE_TAP_TO_LOCK = QStringLiteral("doubleTapToLock");
|
const QString CFG_KEY_DOUBLE_TAP_TO_LOCK = QStringLiteral("doubleTapToLock");
|
||||||
|
|
||||||
FolioSettings::FolioSettings(HomeScreen *parent)
|
FolioSettings::FolioSettings(HomeScreen *parent)
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
, m_homeScreen{parent}
|
, m_homeScreen{parent}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,16 +140,16 @@ void FolioSettings::setPageTransitionEffect(PageTransitionEffect pageTransitionE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FolioSettings::showWallpaperBlur() const
|
FolioSettings::WallpaperBlurEffect FolioSettings::wallpaperBlurEffect() const
|
||||||
{
|
{
|
||||||
return m_showWallpaperBlur;
|
return m_wallpaperBlurEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolioSettings::setShowWallpaperBlur(bool showWallpaperBlur)
|
void FolioSettings::setWallpaperBlurEffect(WallpaperBlurEffect wallpaperBlurEffect)
|
||||||
{
|
{
|
||||||
if (m_showWallpaperBlur != showWallpaperBlur) {
|
if (m_wallpaperBlurEffect != wallpaperBlurEffect) {
|
||||||
m_showWallpaperBlur = showWallpaperBlur;
|
m_wallpaperBlurEffect = wallpaperBlurEffect;
|
||||||
Q_EMIT showWallpaperBlurChanged();
|
Q_EMIT wallpaperBlurEffectChanged();
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +182,7 @@ void FolioSettings::save()
|
||||||
m_homeScreen->config().writeEntry(CFG_KEY_DELEGATE_ICON_SIZE, m_delegateIconSize);
|
m_homeScreen->config().writeEntry(CFG_KEY_DELEGATE_ICON_SIZE, m_delegateIconSize);
|
||||||
m_homeScreen->config().writeEntry(CFG_KEY_SHOW_FAVORITES_BAR_BACKGROUND, m_showFavouritesBarBackground);
|
m_homeScreen->config().writeEntry(CFG_KEY_SHOW_FAVORITES_BAR_BACKGROUND, m_showFavouritesBarBackground);
|
||||||
m_homeScreen->config().writeEntry(CFG_KEY_PAGE_TRANSITION_EFFECT, (int)m_pageTransitionEffect);
|
m_homeScreen->config().writeEntry(CFG_KEY_PAGE_TRANSITION_EFFECT, (int)m_pageTransitionEffect);
|
||||||
m_homeScreen->config().writeEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, m_showWallpaperBlur);
|
m_homeScreen->config().writeEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, (int)m_wallpaperBlurEffect);
|
||||||
m_homeScreen->config().writeEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, m_doubleTapToLock);
|
m_homeScreen->config().writeEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, m_doubleTapToLock);
|
||||||
|
|
||||||
Q_EMIT m_homeScreen->configNeedsSaving();
|
Q_EMIT m_homeScreen->configNeedsSaving();
|
||||||
|
|
@ -202,7 +202,7 @@ void FolioSettings::load()
|
||||||
m_delegateIconSize = m_homeScreen->config().readEntry(CFG_KEY_DELEGATE_ICON_SIZE, 48);
|
m_delegateIconSize = m_homeScreen->config().readEntry(CFG_KEY_DELEGATE_ICON_SIZE, 48);
|
||||||
m_showFavouritesBarBackground = m_homeScreen->config().readEntry(CFG_KEY_SHOW_FAVORITES_BAR_BACKGROUND, true);
|
m_showFavouritesBarBackground = m_homeScreen->config().readEntry(CFG_KEY_SHOW_FAVORITES_BAR_BACKGROUND, true);
|
||||||
m_pageTransitionEffect = static_cast<PageTransitionEffect>(m_homeScreen->config().readEntry(CFG_KEY_PAGE_TRANSITION_EFFECT, (int)SlideTransition));
|
m_pageTransitionEffect = static_cast<PageTransitionEffect>(m_homeScreen->config().readEntry(CFG_KEY_PAGE_TRANSITION_EFFECT, (int)SlideTransition));
|
||||||
m_showWallpaperBlur = m_homeScreen->config().readEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, true);
|
m_wallpaperBlurEffect = static_cast<WallpaperBlurEffect>(m_homeScreen->config().readEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, (int)Full));
|
||||||
m_doubleTapToLock = m_homeScreen->config().readEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, true);
|
m_doubleTapToLock = m_homeScreen->config().readEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, true);
|
||||||
|
|
||||||
Q_EMIT homeScreenRowsChanged();
|
Q_EMIT homeScreenRowsChanged();
|
||||||
|
|
@ -211,7 +211,7 @@ void FolioSettings::load()
|
||||||
Q_EMIT showFavouritesAppLabelsChanged();
|
Q_EMIT showFavouritesAppLabelsChanged();
|
||||||
Q_EMIT lockLayoutChanged();
|
Q_EMIT lockLayoutChanged();
|
||||||
Q_EMIT delegateIconSizeChanged();
|
Q_EMIT delegateIconSizeChanged();
|
||||||
Q_EMIT showWallpaperBlurChanged();
|
Q_EMIT wallpaperBlurEffectChanged();
|
||||||
Q_EMIT doubleTapToLockChanged();
|
Q_EMIT doubleTapToLockChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class FolioSettings : public QObject
|
||||||
Q_PROPERTY(bool showFavouritesBarBackground READ showFavouritesBarBackground WRITE setShowFavouritesBarBackground NOTIFY showFavouritesBarBackgroundChanged)
|
Q_PROPERTY(bool showFavouritesBarBackground READ showFavouritesBarBackground WRITE setShowFavouritesBarBackground NOTIFY showFavouritesBarBackgroundChanged)
|
||||||
Q_PROPERTY(
|
Q_PROPERTY(
|
||||||
FolioSettings::PageTransitionEffect pageTransitionEffect READ pageTransitionEffect WRITE setPageTransitionEffect NOTIFY pageTransitionEffectChanged)
|
FolioSettings::PageTransitionEffect pageTransitionEffect READ pageTransitionEffect WRITE setPageTransitionEffect NOTIFY pageTransitionEffectChanged)
|
||||||
Q_PROPERTY(bool showWallpaperBlur READ showWallpaperBlur WRITE setShowWallpaperBlur NOTIFY showWallpaperBlurChanged)
|
Q_PROPERTY(FolioSettings::WallpaperBlurEffect wallpaperBlurEffect READ wallpaperBlurEffect WRITE setWallpaperBlurEffect NOTIFY wallpaperBlurEffectChanged)
|
||||||
Q_PROPERTY(bool doubleTapToLock READ doubleTapToLock WRITE setDoubleTapToLock NOTIFY doubleTapToLockChanged)
|
Q_PROPERTY(bool doubleTapToLock READ doubleTapToLock WRITE setDoubleTapToLock NOTIFY doubleTapToLockChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -39,6 +39,13 @@ public:
|
||||||
};
|
};
|
||||||
Q_ENUM(PageTransitionEffect)
|
Q_ENUM(PageTransitionEffect)
|
||||||
|
|
||||||
|
enum WallpaperBlurEffect {
|
||||||
|
None = 0,
|
||||||
|
Simple = 1,
|
||||||
|
Full = 2,
|
||||||
|
};
|
||||||
|
Q_ENUM(WallpaperBlurEffect)
|
||||||
|
|
||||||
// number of rows and columns in the config for the homescreen
|
// number of rows and columns in the config for the homescreen
|
||||||
// NOTE: use HomeScreenState.pageRows() instead in UI logic since we may have the rows and
|
// NOTE: use HomeScreenState.pageRows() instead in UI logic since we may have the rows and
|
||||||
// columns swapped (in landscape layouts)
|
// columns swapped (in landscape layouts)
|
||||||
|
|
@ -66,8 +73,8 @@ public:
|
||||||
PageTransitionEffect pageTransitionEffect() const;
|
PageTransitionEffect pageTransitionEffect() const;
|
||||||
void setPageTransitionEffect(PageTransitionEffect pageTransitionEffect);
|
void setPageTransitionEffect(PageTransitionEffect pageTransitionEffect);
|
||||||
|
|
||||||
bool showWallpaperBlur() const;
|
WallpaperBlurEffect wallpaperBlurEffect() const;
|
||||||
void setShowWallpaperBlur(bool showWallpaperBlur);
|
void setWallpaperBlurEffect(WallpaperBlurEffect wallpaperBlurEffect);
|
||||||
|
|
||||||
bool doubleTapToLock() const;
|
bool doubleTapToLock() const;
|
||||||
void setDoubleTapToLock(bool doubleTapToLock);
|
void setDoubleTapToLock(bool doubleTapToLock);
|
||||||
|
|
@ -86,7 +93,7 @@ Q_SIGNALS:
|
||||||
void delegateIconSizeChanged();
|
void delegateIconSizeChanged();
|
||||||
void showFavouritesBarBackgroundChanged();
|
void showFavouritesBarBackgroundChanged();
|
||||||
void pageTransitionEffectChanged();
|
void pageTransitionEffectChanged();
|
||||||
void showWallpaperBlurChanged();
|
void wallpaperBlurEffectChanged();
|
||||||
void doubleTapToLockChanged();
|
void doubleTapToLockChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -102,6 +109,6 @@ private:
|
||||||
qreal m_delegateIconSize{48};
|
qreal m_delegateIconSize{48};
|
||||||
bool m_showFavouritesBarBackground{false};
|
bool m_showFavouritesBarBackground{false};
|
||||||
PageTransitionEffect m_pageTransitionEffect{SlideTransition};
|
PageTransitionEffect m_pageTransitionEffect{SlideTransition};
|
||||||
bool m_showWallpaperBlur{false};
|
WallpaperBlurEffect m_wallpaperBlurEffect{Full};
|
||||||
bool m_doubleTapToLock{false};
|
bool m_doubleTapToLock{false};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,14 @@ import QtQuick.Layouts
|
||||||
|
|
||||||
import org.kde.kirigami 2.20 as Kirigami
|
import org.kde.kirigami 2.20 as Kirigami
|
||||||
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
||||||
|
import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
|
|
||||||
import "./delegate"
|
import "./delegate"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
property Folio.FolioDelegate delegate
|
property Folio.FolioDelegate delegate
|
||||||
|
|
||||||
width: folio.HomeScreenState.pageCellWidth
|
width: folio.HomeScreenState.pageCellWidth
|
||||||
|
|
@ -34,7 +36,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
// animate drop x
|
// animate drop x
|
||||||
XAnimator on x {
|
NumberAnimation on x {
|
||||||
id: dragXAnim
|
id: dragXAnim
|
||||||
running: false
|
running: false
|
||||||
duration: Kirigami.Units.longDuration
|
duration: Kirigami.Units.longDuration
|
||||||
|
|
@ -46,7 +48,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
// animate drop y
|
// animate drop y
|
||||||
YAnimator on y {
|
NumberAnimation on y {
|
||||||
id: dragYAnim
|
id: dragYAnim
|
||||||
running: false
|
running: false
|
||||||
duration: Kirigami.Units.longDuration
|
duration: Kirigami.Units.longDuration
|
||||||
|
|
@ -158,6 +160,7 @@ Item {
|
||||||
DelegateIconLoader {
|
DelegateIconLoader {
|
||||||
id: loader
|
id: loader
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
Layout.minimumWidth: folio.FolioSettings.delegateIconSize
|
Layout.minimumWidth: folio.FolioSettings.delegateIconSize
|
||||||
Layout.minimumHeight: folio.FolioSettings.delegateIconSize
|
Layout.minimumHeight: folio.FolioSettings.delegateIconSize
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import "./delegate"
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property var homeScreen
|
property var homeScreen
|
||||||
|
|
||||||
|
|
@ -111,6 +112,7 @@ MouseArea {
|
||||||
AppDelegate {
|
AppDelegate {
|
||||||
id: appDelegate
|
id: appDelegate
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
application: delegate.delegateModel.application
|
application: delegate.delegateModel.application
|
||||||
name: folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.application.name : ""
|
name: folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.application.name : ""
|
||||||
shadow: true
|
shadow: true
|
||||||
|
|
@ -184,6 +186,7 @@ MouseArea {
|
||||||
AppFolderDelegate {
|
AppFolderDelegate {
|
||||||
id: appFolderDelegate
|
id: appFolderDelegate
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
shadow: true
|
shadow: true
|
||||||
folder: delegate.delegateModel.folder
|
folder: delegate.delegateModel.folder
|
||||||
name: folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.folder.name : ""
|
name: folio.FolioSettings.showFavouritesAppLabels ? delegate.delegateModel.folder.name : ""
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import "./settings"
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
property Folio.HomeScreenState homeScreenState: folio.HomeScreenState
|
property Folio.HomeScreenState homeScreenState: folio.HomeScreenState
|
||||||
|
|
||||||
property real topMargin: 0
|
property real topMargin: 0
|
||||||
|
|
@ -43,6 +44,8 @@ Item {
|
||||||
onLeftMarginChanged: folio.HomeScreenState.viewLeftPadding = root.leftMargin
|
onLeftMarginChanged: folio.HomeScreenState.viewLeftPadding = root.leftMargin
|
||||||
onRightMarginChanged: folio.HomeScreenState.viewRightPadding = root.rightMargin
|
onRightMarginChanged: folio.HomeScreenState.viewRightPadding = root.rightMargin
|
||||||
|
|
||||||
|
signal wallpaperSelectorTriggered()
|
||||||
|
|
||||||
// called by any delegates when starting drag
|
// called by any delegates when starting drag
|
||||||
// returns the mapped coordinates to be used in the home screen state
|
// returns the mapped coordinates to be used in the home screen state
|
||||||
function prepareStartDelegateDrag(delegate, item, skipSwipeThreshold) {
|
function prepareStartDelegateDrag(delegate, item, skipSwipeThreshold) {
|
||||||
|
|
@ -182,6 +185,7 @@ Item {
|
||||||
HomeScreenPages {
|
HomeScreenPages {
|
||||||
id: homeScreenPages
|
id: homeScreenPages
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
homeScreen: root
|
homeScreen: root
|
||||||
|
|
||||||
anchors.topMargin: root.topMargin
|
anchors.topMargin: root.topMargin
|
||||||
|
|
@ -247,6 +251,8 @@ Item {
|
||||||
id: favouritesBarScrim
|
id: favouritesBarScrim
|
||||||
color: Qt.rgba(255, 255, 255, 0.2)
|
color: Qt.rgba(255, 255, 255, 0.2)
|
||||||
|
|
||||||
|
Component.onCompleted: maskManager.assignToMask(this)
|
||||||
|
|
||||||
// don't show in settings mode
|
// don't show in settings mode
|
||||||
opacity: 1 - folio.HomeScreenState.settingsOpenProgress
|
opacity: 1 - folio.HomeScreenState.settingsOpenProgress
|
||||||
visible: folio.FolioSettings.showFavouritesBarBackground
|
visible: folio.FolioSettings.showFavouritesBarBackground
|
||||||
|
|
@ -266,6 +272,7 @@ Item {
|
||||||
FavouritesBar {
|
FavouritesBar {
|
||||||
id: favouritesBar
|
id: favouritesBar
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
homeScreen: root
|
homeScreen: root
|
||||||
|
|
||||||
// don't show in settings mode
|
// don't show in settings mode
|
||||||
|
|
@ -399,18 +406,6 @@ Item {
|
||||||
transform: Translate { y: folderView.opacity > 0 ? 0 : folderView.height }
|
transform: Translate { y: folderView.opacity > 0 ? 0 : folderView.height }
|
||||||
}
|
}
|
||||||
|
|
||||||
// drag and drop component
|
|
||||||
DelegateDragItem {
|
|
||||||
id: delegateDragItem
|
|
||||||
folio: root.folio
|
|
||||||
}
|
|
||||||
|
|
||||||
// drag and drop for widgets
|
|
||||||
WidgetDragItem {
|
|
||||||
id: widgetDragItem
|
|
||||||
folio: root.folio
|
|
||||||
}
|
|
||||||
|
|
||||||
// bottom app drawer
|
// bottom app drawer
|
||||||
AppDrawer {
|
AppDrawer {
|
||||||
id: appDrawer
|
id: appDrawer
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import "./private"
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property int pageNum
|
property int pageNum
|
||||||
|
|
||||||
|
|
@ -161,6 +162,7 @@ Item {
|
||||||
AppDelegate {
|
AppDelegate {
|
||||||
id: appDelegate
|
id: appDelegate
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
name: folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.application.name : ""
|
name: folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.application.name : ""
|
||||||
application: delegate.pageDelegate.application
|
application: delegate.pageDelegate.application
|
||||||
turnToFolder: delegate.isAppHoveredOver
|
turnToFolder: delegate.isAppHoveredOver
|
||||||
|
|
@ -238,6 +240,7 @@ Item {
|
||||||
AppFolderDelegate {
|
AppFolderDelegate {
|
||||||
id: appFolderDelegate
|
id: appFolderDelegate
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
name: folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.folder.name : ""
|
name: folio.FolioSettings.showPagesAppLabels ? delegate.pageDelegate.folder.name : ""
|
||||||
folder: delegate.pageDelegate.folder
|
folder: delegate.pageDelegate.folder
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property var homeScreen
|
property var homeScreen
|
||||||
|
|
||||||
|
|
@ -44,6 +45,7 @@ MouseArea {
|
||||||
delegate: HomeScreenPage {
|
delegate: HomeScreenPage {
|
||||||
id: homeScreenPage
|
id: homeScreenPage
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
pageNum: model.index
|
pageNum: model.index
|
||||||
pageModel: model.delegate
|
pageModel: model.delegate
|
||||||
homeScreen: root.homeScreen
|
homeScreen: root.homeScreen
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
Folio.DelegateTouchArea {
|
Folio.DelegateTouchArea {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property string name
|
property string name
|
||||||
property bool shadow: false
|
property bool shadow: false
|
||||||
|
|
@ -29,10 +30,10 @@ Folio.DelegateTouchArea {
|
||||||
signal afterClickAnimation()
|
signal afterClickAnimation()
|
||||||
|
|
||||||
// grow/shrink animation
|
// grow/shrink animation
|
||||||
property real zoomScale: 1
|
property real scaleAmount: 1
|
||||||
property bool clickRequested: false
|
property bool clickRequested: false
|
||||||
|
|
||||||
NumberAnimation on zoomScale {
|
NumberAnimation on scaleAmount {
|
||||||
id: shrinkAnim
|
id: shrinkAnim
|
||||||
running: false
|
running: false
|
||||||
duration: ShellSettings.Settings.animationsEnabled ? 80 : 1
|
duration: ShellSettings.Settings.animationsEnabled ? 80 : 1
|
||||||
|
|
@ -44,7 +45,7 @@ Folio.DelegateTouchArea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation on zoomScale {
|
NumberAnimation on scaleAmount {
|
||||||
id: growAnim
|
id: growAnim
|
||||||
running: false
|
running: false
|
||||||
duration: ShellSettings.Settings.animationsEnabled ? 80 : 1
|
duration: ShellSettings.Settings.animationsEnabled ? 80 : 1
|
||||||
|
|
@ -86,8 +87,8 @@ Folio.DelegateTouchArea {
|
||||||
transform: Scale {
|
transform: Scale {
|
||||||
origin.x: root.width / 2;
|
origin.x: root.width / 2;
|
||||||
origin.y: root.height / 2;
|
origin.y: root.height / 2;
|
||||||
xScale: root.zoomScale
|
xScale: root.scaleAmount
|
||||||
yScale: root.zoomScale
|
yScale: root.scaleAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileShell.BaseItem {
|
MobileShell.BaseItem {
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,12 @@ AbstractDelegate {
|
||||||
color: Qt.rgba(255, 255, 255, 0.3)
|
color: Qt.rgba(255, 255, 255, 0.3)
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (maskManager) {
|
||||||
|
maskManager.assignToMask(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
opacity: root.turnToFolder ? 1 : 0
|
opacity: root.turnToFolder ? 1 : 0
|
||||||
property real scaleAmount: root.turnToFolder ? 1.2 : 1.0
|
property real scaleAmount: root.turnToFolder ? 1.2 : 1.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ AbstractDelegate {
|
||||||
|
|
||||||
contentItem: DelegateFolderIcon {
|
contentItem: DelegateFolderIcon {
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
folder: root.folder
|
folder: root.folder
|
||||||
expandBackground: root.appHoveredOver
|
expandBackground: root.appHoveredOver
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ import QtQuick.Effects
|
||||||
import org.kde.kirigami 2.20 as Kirigami
|
import org.kde.kirigami 2.20 as Kirigami
|
||||||
|
|
||||||
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
||||||
|
import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property Folio.FolioApplicationFolder folder
|
property Folio.FolioApplicationFolder folder
|
||||||
|
|
||||||
|
|
@ -27,6 +29,12 @@ Item {
|
||||||
color: Qt.rgba(255, 255, 255, 0.3)
|
color: Qt.rgba(255, 255, 255, 0.3)
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (maskManager) {
|
||||||
|
maskManager.assignToMask(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property real scaleAmount: root.expandBackground ? 1.2 : 1.0
|
property real scaleAmount: root.expandBackground ? 1.2 : 1.0
|
||||||
|
|
||||||
Behavior on scaleAmount { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad } }
|
Behavior on scaleAmount { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad } }
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ import QtQuick.Effects
|
||||||
import org.kde.kirigami 2.20 as Kirigami
|
import org.kde.kirigami 2.20 as Kirigami
|
||||||
|
|
||||||
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
||||||
|
import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio
|
property Folio.HomeScreen folio
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
height: folio.FolioSettings.delegateIconSize
|
height: folio.FolioSettings.delegateIconSize
|
||||||
width: folio.FolioSettings.delegateIconSize
|
width: folio.FolioSettings.delegateIconSize
|
||||||
|
|
@ -50,6 +52,7 @@ Loader {
|
||||||
|
|
||||||
DelegateFolderIcon {
|
DelegateFolderIcon {
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
folder: delegate.folder
|
folder: delegate.folder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import org.kde.private.mobile.homescreen.folio 1.0 as Folio
|
||||||
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
|
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
|
||||||
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
||||||
|
|
||||||
|
import "./private"
|
||||||
|
|
||||||
ContainmentItem {
|
ContainmentItem {
|
||||||
id: root
|
id: root
|
||||||
property Folio.HomeScreen folio: root.plasmoid
|
property Folio.HomeScreen folio: root.plasmoid
|
||||||
|
|
@ -31,13 +33,25 @@ ContainmentItem {
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileShell.HomeScreenWallpaperBlur {
|
property MobileShell.MaskManager maskManager: MobileShell.MaskManager {
|
||||||
id: wallpaperBlur
|
height: root.height
|
||||||
active: folio.FolioSettings.showWallpaperBlur
|
width: root.width
|
||||||
anchors.fill: parent
|
}
|
||||||
wallpaperItem: Plasmoid.wallpaperGraphicsObject
|
|
||||||
|
|
||||||
blurOpacity: Math.min(1,
|
property MobileShell.MaskManager frontMaskManager: MobileShell.MaskManager {
|
||||||
|
height: root.height
|
||||||
|
width: root.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// wallpaper blur layer
|
||||||
|
MobileShell.BlurEffect {
|
||||||
|
id: wallpaperBlur
|
||||||
|
active: folio.FolioSettings.wallpaperBlurEffect > 0
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceLayer: Plasmoid.wallpaperGraphicsObject
|
||||||
|
maskSourceLayer: folio.FolioSettings.wallpaperBlurEffect > 1 ? maskManager.maskLayer : null
|
||||||
|
|
||||||
|
fullBlur: Math.min(1,
|
||||||
Math.max(
|
Math.max(
|
||||||
1 - homeScreen.contentOpacity,
|
1 - homeScreen.contentOpacity,
|
||||||
folio.HomeScreenState.appDrawerOpenProgress * 2, // blur faster during swipe
|
folio.HomeScreenState.appDrawerOpenProgress * 2, // blur faster during swipe
|
||||||
|
|
@ -144,12 +158,94 @@ ContainmentItem {
|
||||||
HomeScreen {
|
HomeScreen {
|
||||||
id: folioHomeScreen
|
id: folioHomeScreen
|
||||||
folio: root.folio
|
folio: root.folio
|
||||||
|
maskManager: root.maskManager
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
topMargin: homeScreen.topMargin
|
topMargin: homeScreen.topMargin
|
||||||
bottomMargin: homeScreen.bottomMargin
|
bottomMargin: homeScreen.bottomMargin
|
||||||
leftMargin: homeScreen.leftMargin
|
leftMargin: homeScreen.leftMargin
|
||||||
rightMargin: homeScreen.rightMargin
|
rightMargin: homeScreen.rightMargin
|
||||||
|
|
||||||
|
onWallpaperSelectorTriggered: wallpaperSelectorLoader.active = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// top blur layer for items on top of the base homescreen
|
||||||
|
MobileShell.BlurEffect {
|
||||||
|
id: homescreenBlur
|
||||||
|
anchors.fill: parent
|
||||||
|
active: folio.FolioSettings.wallpaperBlurEffect > 1 && ((delegateDragItem.visible && folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Folder) || wallpaperSelectorLoader.active)
|
||||||
|
visible: active
|
||||||
|
fullBlur: 0
|
||||||
|
|
||||||
|
sourceLayer: homeScreenLayer
|
||||||
|
maskSourceLayer: frontMaskManager.maskLayer
|
||||||
|
|
||||||
|
// stacking both wallpaper and homescreen layers so we can blur them in one pass
|
||||||
|
Item {
|
||||||
|
id: homeScreenLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
// wallpaper blur
|
||||||
|
ShaderEffectSource {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
textureSize: homescreenBlur.textureSize
|
||||||
|
sourceItem: Plasmoid.wallpaperGraphicsObject
|
||||||
|
hideSource: false
|
||||||
|
}
|
||||||
|
|
||||||
|
// homescreen blur
|
||||||
|
ShaderEffectSource {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
textureSize: homescreenBlur.textureSize
|
||||||
|
sourceItem: homeScreen
|
||||||
|
hideSource: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// drag and drop component
|
||||||
|
DelegateDragItem {
|
||||||
|
id: delegateDragItem
|
||||||
|
folio: root.folio
|
||||||
|
maskManager: root.frontMaskManager
|
||||||
|
}
|
||||||
|
|
||||||
|
// drag and drop for widgets
|
||||||
|
WidgetDragItem {
|
||||||
|
id: widgetDragItem
|
||||||
|
folio: root.folio
|
||||||
|
}
|
||||||
|
|
||||||
|
// loader for wallpaper selector
|
||||||
|
Loader {
|
||||||
|
id: wallpaperSelectorLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: true
|
||||||
|
active: false
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
wallpaperSelectorLoader.item.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: MobileShell.WallpaperSelector {
|
||||||
|
maskManager: root.frontMaskManager
|
||||||
|
horizontal: root.width > root.height
|
||||||
|
edge: horizontal ? Qt.LeftEdge : Qt.BottomEdge
|
||||||
|
bottomMargin: horizontal ? 0 : folioHomeScreen.bottomMargin
|
||||||
|
leftMargin: horizontal ? folioHomeScreen.leftMargin : 0
|
||||||
|
rightMargin: horizontal ? folioHomeScreen.rightMargin : 0
|
||||||
|
onClosed: {
|
||||||
|
wallpaperSelectorLoader.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onWallpaperSettingsRequested: {
|
||||||
|
close();
|
||||||
|
folioHomeScreen.openConfigure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
wallpaperSelectorLoader.active = true;
|
homeScreen.wallpaperSelectorTriggered();
|
||||||
folio.HomeScreenState.closeSettingsView();
|
folio.HomeScreenState.closeSettingsView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,30 +247,4 @@ Item {
|
||||||
homeScreen.openConfigure()
|
homeScreen.openConfigure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: wallpaperSelectorLoader
|
|
||||||
asynchronous: true
|
|
||||||
active: false
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
wallpaperSelectorLoader.item.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: MobileShell.WallpaperSelector {
|
|
||||||
horizontal: root.width > root.height
|
|
||||||
edge: horizontal ? Qt.LeftEdge : Qt.BottomEdge
|
|
||||||
bottomMargin: root.homeScreen.bottomMargin
|
|
||||||
leftMargin: root.homeScreen.leftMargin
|
|
||||||
rightMargin: root.homeScreen.rightMargin
|
|
||||||
onClosed: {
|
|
||||||
wallpaperSelectorLoader.active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
onWallpaperSettingsRequested: {
|
|
||||||
close();
|
|
||||||
homeScreen.openConfigure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,15 +269,24 @@ Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormCard {
|
FormCard.FormCard {
|
||||||
FormCard.FormSwitchDelegate {
|
FormCard.FormComboBoxDelegate {
|
||||||
id: showWallpaperBlur
|
id: wallpaperBlurCombobox
|
||||||
text: i18nc("@option:check", "Show wallpaper blur effect")
|
text: i18n("Wallpaper blur effect")
|
||||||
checked: folio.FolioSettings.showWallpaperBlur
|
|
||||||
onCheckedChanged: {
|
model: [
|
||||||
if (checked != folio.FolioSettings.showWallpaperBlur) {
|
{"name": i18nc("Wallpaper blur effect", "None"), "value": 0},
|
||||||
folio.FolioSettings.showWallpaperBlur = checked;
|
{"name": i18nc("Wallpaper blur effect", "Simple"), "value": 1},
|
||||||
}
|
{"name": i18nc("Wallpaper blur effect", "Full"), "value": 2}
|
||||||
|
]
|
||||||
|
|
||||||
|
textRole: "name"
|
||||||
|
valueRole: "value"
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
currentIndex = indexOfValue(folio.FolioSettings.wallpaperBlurEffect);
|
||||||
|
dialog.parent = root;
|
||||||
}
|
}
|
||||||
|
onCurrentValueChanged: folio.FolioSettings.wallpaperBlurEffect = currentValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,8 +332,7 @@ Window {
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
console.log('saving layout to ' + selectedFile);
|
console.log('saving layout to ' + selectedFile);
|
||||||
if (selectedFile) {
|
if (selectedFile) {
|
||||||
let status = folio.FolioSettings.saveLayoutToFile(selectedFile);
|
let status = folio.FolioSettings.saveLayoutToFile(selectedFile); if (status) {
|
||||||
if (status) {
|
|
||||||
exportedSuccessfullyPrompt.open();
|
exportedSuccessfullyPrompt.open();
|
||||||
} else {
|
} else {
|
||||||
exportFailedPrompt.open();
|
exportFailedPrompt.open();
|
||||||
|
|
|
||||||
|
|
@ -3,26 +3,26 @@
|
||||||
|
|
||||||
#include "halcyonsettings.h"
|
#include "halcyonsettings.h"
|
||||||
|
|
||||||
const QString CFG_KEY_SHOW_WALLPAPER_BLUR = QStringLiteral("showWallpaperBlur");
|
const QString CFG_KEY_SHOW_WALLPAPER_BLUR = QStringLiteral("wallpaperBlurEffect");
|
||||||
const QString CFG_KEY_DOUBLE_TAP_TO_LOCK = QStringLiteral("doubleTapToLock");
|
const QString CFG_KEY_DOUBLE_TAP_TO_LOCK = QStringLiteral("doubleTapToLock");
|
||||||
|
|
||||||
HalcyonSettings::HalcyonSettings(QObject *parent, KConfigGroup config)
|
HalcyonSettings::HalcyonSettings(QObject *parent, KConfigGroup config)
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
, m_config{config}
|
, m_config{config}
|
||||||
{
|
{
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HalcyonSettings::showWallpaperBlur() const
|
HalcyonSettings::WallpaperBlurEffect HalcyonSettings::wallpaperBlurEffect() const
|
||||||
{
|
{
|
||||||
return m_showWallpaperBlur;
|
return m_wallpaperBlurEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HalcyonSettings::setShowWallpaperBlur(bool showWallpaperBlur)
|
void HalcyonSettings::setWallpaperBlurEffect(WallpaperBlurEffect wallpaperBlurEffect)
|
||||||
{
|
{
|
||||||
if (m_showWallpaperBlur != showWallpaperBlur) {
|
if (m_wallpaperBlurEffect != wallpaperBlurEffect) {
|
||||||
m_showWallpaperBlur = showWallpaperBlur;
|
m_wallpaperBlurEffect = wallpaperBlurEffect;
|
||||||
Q_EMIT showWallpaperBlurChanged();
|
Q_EMIT wallpaperBlurEffectChanged();
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ void HalcyonSettings::setDoubleTapToLock(bool doubleTapToLock)
|
||||||
|
|
||||||
void HalcyonSettings::save()
|
void HalcyonSettings::save()
|
||||||
{
|
{
|
||||||
m_config.writeEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, m_showWallpaperBlur);
|
m_config.writeEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, (int)m_wallpaperBlurEffect);
|
||||||
m_config.writeEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, m_doubleTapToLock);
|
m_config.writeEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, m_doubleTapToLock);
|
||||||
|
|
||||||
m_config.sync();
|
m_config.sync();
|
||||||
|
|
@ -51,6 +51,9 @@ void HalcyonSettings::save()
|
||||||
|
|
||||||
void HalcyonSettings::load()
|
void HalcyonSettings::load()
|
||||||
{
|
{
|
||||||
m_showWallpaperBlur = m_config.readEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, false);
|
m_wallpaperBlurEffect = static_cast<WallpaperBlurEffect>(m_config.readEntry(CFG_KEY_SHOW_WALLPAPER_BLUR, (int)Full));
|
||||||
m_doubleTapToLock = m_config.readEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, true);
|
m_doubleTapToLock = m_config.readEntry(CFG_KEY_DOUBLE_TAP_TO_LOCK, true);
|
||||||
|
|
||||||
|
Q_EMIT doubleTapToLockChanged();
|
||||||
|
Q_EMIT wallpaperBlurEffectChanged();
|
||||||
}
|
}
|
||||||
|
|
@ -10,27 +10,34 @@
|
||||||
class HalcyonSettings : public QObject
|
class HalcyonSettings : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool showWallpaperBlur READ showWallpaperBlur WRITE setShowWallpaperBlur NOTIFY showWallpaperBlurChanged)
|
Q_PROPERTY(HalcyonSettings::WallpaperBlurEffect wallpaperBlurEffect READ wallpaperBlurEffect WRITE setWallpaperBlurEffect NOTIFY wallpaperBlurEffectChanged)
|
||||||
Q_PROPERTY(bool doubleTapToLock READ doubleTapToLock WRITE setDoubleTapToLock NOTIFY doubleTapToLockChanged)
|
Q_PROPERTY(bool doubleTapToLock READ doubleTapToLock WRITE setDoubleTapToLock NOTIFY doubleTapToLockChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HalcyonSettings(QObject *parent = nullptr, KConfigGroup config = {});
|
HalcyonSettings(QObject *parent = nullptr, KConfigGroup config = {});
|
||||||
|
|
||||||
bool showWallpaperBlur() const;
|
enum WallpaperBlurEffect {
|
||||||
void setShowWallpaperBlur(bool blurWallpaper);
|
None = 0,
|
||||||
|
Simple = 1,
|
||||||
|
Full = 2,
|
||||||
|
};
|
||||||
|
Q_ENUM(WallpaperBlurEffect)
|
||||||
|
|
||||||
|
WallpaperBlurEffect wallpaperBlurEffect() const;
|
||||||
|
void setWallpaperBlurEffect(WallpaperBlurEffect wallpaperBlurEffect);
|
||||||
|
|
||||||
bool doubleTapToLock() const;
|
bool doubleTapToLock() const;
|
||||||
void setDoubleTapToLock(bool doubleTapToLock);
|
void setDoubleTapToLock(bool doubleTapToLock);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void showWallpaperBlurChanged();
|
void wallpaperBlurEffectChanged();
|
||||||
void doubleTapToLockChanged();
|
void doubleTapToLockChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void save();
|
void save();
|
||||||
void load();
|
void load();
|
||||||
|
|
||||||
bool m_showWallpaperBlur{false};
|
WallpaperBlurEffect m_wallpaperBlurEffect{Full};
|
||||||
bool m_doubleTapToLock{true};
|
bool m_doubleTapToLock{true};
|
||||||
|
|
||||||
KConfigGroup m_config;
|
KConfigGroup m_config;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: delegate
|
id: delegate
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
property int visualIndex: 0
|
property int visualIndex: 0
|
||||||
property real dragFolderAnimationProgress: 0
|
property real dragFolderAnimationProgress: 0
|
||||||
|
|
@ -265,6 +266,12 @@ Item {
|
||||||
color: Qt.rgba(255, 255, 255, 0.2)
|
color: Qt.rgba(255, 255, 255, 0.2)
|
||||||
radius: Kirigami.Units.cornerRadius
|
radius: Kirigami.Units.cornerRadius
|
||||||
opacity: delegate.dragFolderAnimationProgress
|
opacity: delegate.dragFolderAnimationProgress
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (maskManager) {
|
||||||
|
maskManager.assignToMask(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Kirigami.Icon {
|
Kirigami.Icon {
|
||||||
|
|
@ -319,6 +326,12 @@ Item {
|
||||||
xScale: 1 + delegate.dragFolderAnimationProgress * 0.5
|
xScale: 1 + delegate.dragFolderAnimationProgress * 0.5
|
||||||
yScale: 1 + delegate.dragFolderAnimationProgress * 0.5
|
yScale: 1 + delegate.dragFolderAnimationProgress * 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (maskManager) {
|
||||||
|
maskManager.assignToMask(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid {
|
Grid {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import org.kde.private.mobile.homescreen.halcyon as Halcyon
|
||||||
|
|
||||||
MobileShell.GridView {
|
MobileShell.GridView {
|
||||||
id: root
|
id: root
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
required property var searchWidget
|
required property var searchWidget
|
||||||
|
|
||||||
// don't set anchors.margins since we want everywhere to be draggable
|
// don't set anchors.margins since we want everywhere to be draggable
|
||||||
|
|
@ -207,6 +208,7 @@ MobileShell.GridView {
|
||||||
// actual visual delegate
|
// actual visual delegate
|
||||||
FavoritesAppDelegate {
|
FavoritesAppDelegate {
|
||||||
id: appDelegate
|
id: appDelegate
|
||||||
|
maskManager: root.maskManager
|
||||||
visualIndex: delegateRoot.visualIndex
|
visualIndex: delegateRoot.visualIndex
|
||||||
|
|
||||||
isFolder: model.isFolder
|
isFolder: model.isFolder
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
required property bool interactive
|
required property bool interactive
|
||||||
required property var searchWidget
|
required property var searchWidget
|
||||||
|
|
@ -67,6 +68,7 @@ Item {
|
||||||
property real openFolderProgress: 0
|
property real openFolderProgress: 0
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
maskManager: root.maskManager
|
||||||
interactive: root.interactive
|
interactive: root.interactive
|
||||||
searchWidget: root.searchWidget
|
searchWidget: root.searchWidget
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import "settings" as Settings
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
property MobileShell.MaskManager maskManager
|
||||||
|
|
||||||
required property real topMargin
|
required property real topMargin
|
||||||
required property real bottomMargin
|
required property real bottomMargin
|
||||||
|
|
@ -33,6 +34,8 @@ Item {
|
||||||
property bool settingsOpen: false
|
property bool settingsOpen: false
|
||||||
property real settingsOpenFactor: settingsOpen ? 1 : 0
|
property real settingsOpenFactor: settingsOpen ? 1 : 0
|
||||||
|
|
||||||
|
signal wallpaperSelectorTriggered()
|
||||||
|
|
||||||
Behavior on settingsOpenFactor {
|
Behavior on settingsOpenFactor {
|
||||||
NumberAnimation { duration: 200 }
|
NumberAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
|
@ -121,6 +124,7 @@ Item {
|
||||||
FavoritesView {
|
FavoritesView {
|
||||||
id: favoritesView
|
id: favoritesView
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
maskManager: root.maskManager
|
||||||
searchWidget: root.searchWidget
|
searchWidget: root.searchWidget
|
||||||
interactive: root.interactive && swipeView.contentItem.contentX === 0
|
interactive: root.interactive && swipeView.contentItem.contentX === 0
|
||||||
onOpenConfigureRequested: root.openConfigure()
|
onOpenConfigureRequested: root.openConfigure()
|
||||||
|
|
|
||||||
|
|
@ -56,26 +56,42 @@ ContainmentItem {
|
||||||
screenGeometry: Plasmoid.containment.screenGeometry
|
screenGeometry: Plasmoid.containment.screenGeometry
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileShell.HomeScreenWallpaperBlur {
|
property MobileShell.MaskManager maskManager: MobileShell.MaskManager {
|
||||||
id: wallpaperBlur
|
height: root.height
|
||||||
active: Plasmoid.settings.showWallpaperBlur
|
width: root.width
|
||||||
anchors.fill: parent
|
}
|
||||||
wallpaperItem: Plasmoid.wallpaperGraphicsObject
|
|
||||||
|
|
||||||
blurOpacity: Math.min(1,
|
property MobileShell.MaskManager frontMaskManager: MobileShell.MaskManager {
|
||||||
|
height: root.height
|
||||||
|
width: root.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// wallpaper blur layer
|
||||||
|
MobileShell.BlurEffect {
|
||||||
|
id: wallpaperBlur
|
||||||
|
active: Plasmoid.settings.wallpaperBlurEffect > 0
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceLayer: Plasmoid.wallpaperGraphicsObject
|
||||||
|
maskSourceLayer: Plasmoid.settings.wallpaperBlurEffect > 1 ? maskManager.maskLayer : null
|
||||||
|
|
||||||
|
fullBlur: Math.min(1,
|
||||||
Math.max(1 - homeScreen.contentOpacity,
|
Math.max(1 - homeScreen.contentOpacity,
|
||||||
halcyonHomeScreen.settingsOpenFactor
|
halcyonHomeScreen.settingsOpenFactor,
|
||||||
|
root.darkenBackgroundFactor,
|
||||||
|
search.openFactor
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property real darkenBackgroundFactor: halcyonHomeScreen.page == 1 ? 1 : 0
|
||||||
|
Behavior on darkenBackgroundFactor {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.longDuration }
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: darkenBackground
|
id: darkenBackground
|
||||||
color: (halcyonHomeScreen.page == 1 ? Qt.rgba(0, 0, 0, 0.7) : Qt.rgba(0, 0, 0, 0.2))
|
color: Qt.rgba(0, 0, 0, 0.2 + (0.5 * root.darkenBackgroundFactor))
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation { duration: Kirigami.Units.longDuration }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -106,6 +122,7 @@ ContainmentItem {
|
||||||
HomeScreen {
|
HomeScreen {
|
||||||
id: halcyonHomeScreen
|
id: halcyonHomeScreen
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
maskManager: root.maskManager
|
||||||
|
|
||||||
topMargin: homeScreen.topMargin
|
topMargin: homeScreen.topMargin
|
||||||
bottomMargin: homeScreen.bottomMargin
|
bottomMargin: homeScreen.bottomMargin
|
||||||
|
|
@ -114,6 +131,8 @@ ContainmentItem {
|
||||||
|
|
||||||
searchWidget: search
|
searchWidget: search
|
||||||
interactive: true
|
interactive: true
|
||||||
|
|
||||||
|
onWallpaperSelectorTriggered: wallpaperSelectorLoader.active = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// search component
|
// search component
|
||||||
|
|
@ -131,6 +150,72 @@ ContainmentItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// top blur layer for items on top of the base homescreen
|
||||||
|
MobileShell.BlurEffect {
|
||||||
|
id: homescreenBlur
|
||||||
|
anchors.fill: parent
|
||||||
|
active: Plasmoid.settings.wallpaperBlurEffect > 1 && wallpaperSelectorLoader.active
|
||||||
|
visible: active
|
||||||
|
fullBlur: 0
|
||||||
|
|
||||||
|
sourceLayer: homeScreenLayer
|
||||||
|
maskSourceLayer: frontMaskManager.maskLayer
|
||||||
|
|
||||||
|
// stacking both wallpaper and homescreen layers so we can blur them in one pass
|
||||||
|
Item {
|
||||||
|
id: homeScreenLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
// wallpaper blur
|
||||||
|
ShaderEffectSource {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
textureSize: homescreenBlur.textureSize
|
||||||
|
sourceItem: Plasmoid.wallpaperGraphicsObject
|
||||||
|
hideSource: false
|
||||||
|
}
|
||||||
|
|
||||||
|
// homescreen blur
|
||||||
|
ShaderEffectSource {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
textureSize: homescreenBlur.textureSize
|
||||||
|
sourceItem: homeScreen
|
||||||
|
hideSource: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loader for wallpaper selector
|
||||||
|
Loader {
|
||||||
|
id: wallpaperSelectorLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: true
|
||||||
|
active: false
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
wallpaperSelectorLoader.item.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: MobileShell.WallpaperSelector {
|
||||||
|
maskManager: root.frontMaskManager
|
||||||
|
horizontal: root.width > root.height
|
||||||
|
edge: horizontal ? Qt.LeftEdge : Qt.BottomEdge
|
||||||
|
bottomMargin: horizontal ? 0 : halcyonHomeScreen.bottomMargin
|
||||||
|
leftMargin: horizontal ? halcyonHomeScreen.leftMargin : 0
|
||||||
|
rightMargin: horizontal ? halcyonHomeScreen.rightMargin : 0
|
||||||
|
onClosed: {
|
||||||
|
wallpaperSelectorLoader.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onWallpaperSettingsRequested: {
|
||||||
|
close();
|
||||||
|
halcyonHomeScreen.openContainmentSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ Item {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.homeScreen.settingsOpen = false;
|
root.homeScreen.settingsOpen = false;
|
||||||
wallpaperSelectorLoader.active = true;
|
root.homeScreen.wallpaperSelectorTriggered();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,30 +135,4 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only load wallpaper selector when visible
|
|
||||||
Loader {
|
|
||||||
id: wallpaperSelectorLoader
|
|
||||||
asynchronous: true
|
|
||||||
active: false
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
wallpaperSelectorLoader.item.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: MobileShell.WallpaperSelector {
|
|
||||||
horizontal: root.width > root.height
|
|
||||||
edge: horizontal ? Qt.LeftEdge : Qt.BottomEdge
|
|
||||||
bottomMargin: root.bottomMargin
|
|
||||||
leftMargin: root.leftMargin
|
|
||||||
rightMargin: root.rightMargin
|
|
||||||
onClosed: {
|
|
||||||
wallpaperSelectorLoader.active = false;
|
|
||||||
}
|
|
||||||
onWallpaperSettingsRequested: {
|
|
||||||
close();
|
|
||||||
root.homeScreen.openContainmentSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,18 +87,27 @@ Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormCard {
|
FormCard.FormCard {
|
||||||
FormCard.FormSwitchDelegate {
|
FormCard.FormComboBoxDelegate {
|
||||||
id: showWallpaperBlur
|
id: wallpaperBlurCombobox
|
||||||
text: i18nc("@option:check", "Show wallpaper blur effect")
|
text: i18n("Wallpaper blur effect")
|
||||||
checked: Plasmoid.settings.showWallpaperBlur
|
|
||||||
onCheckedChanged: {
|
model: [
|
||||||
if (checked != Plasmoid.settings.showWallpaperBlur) {
|
{"name": i18nc("Wallpaper blur effect", "None"), "value": 0},
|
||||||
Plasmoid.settings.showWallpaperBlur = checked;
|
{"name": i18nc("Wallpaper blur effect", "Simple"), "value": 1},
|
||||||
}
|
{"name": i18nc("Wallpaper blur effect", "Full"), "value": 2}
|
||||||
|
]
|
||||||
|
|
||||||
|
textRole: "name"
|
||||||
|
valueRole: "value"
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
currentIndex = indexOfValue(Plasmoid.settings.wallpaperBlurEffect);
|
||||||
|
dialog.parent = root;
|
||||||
}
|
}
|
||||||
|
onCurrentValueChanged: Plasmoid.settings.wallpaperBlurEffect = currentValue
|
||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator { above: showWallpaperBlur; below: doubleTapToSleepSwitch }
|
FormCard.FormDelegateSeparator { above: wallpaperBlurCombobox; below: doubleTapToSleepSwitch }
|
||||||
|
|
||||||
FormCard.FormSwitchDelegate {
|
FormCard.FormSwitchDelegate {
|
||||||
id: doubleTapToSleepSwitch
|
id: doubleTapToSleepSwitch
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue