From 467e44bb9fecb893220490df0e0e58b94ffe076d Mon Sep 17 00:00:00 2001 From: AramJonghu Date: Tue, 30 Jun 2026 02:04:24 +0200 Subject: [PATCH] tidy&format(all): all files formatted and relevant warnings resolved --- .clang-format | 6 +- Plugins/ZShell/Blobs/blobgroup.cpp | 40 +- Plugins/ZShell/Blobs/blobgroup.hpp | 70 +- Plugins/ZShell/Blobs/blobinvertedrect.cpp | 61 +- Plugins/ZShell/Blobs/blobinvertedrect.hpp | 82 ++- Plugins/ZShell/Blobs/blobmaterial.cpp | 35 +- Plugins/ZShell/Blobs/blobmaterial.hpp | 48 +- Plugins/ZShell/Blobs/blobrect.cpp | 128 ++-- Plugins/ZShell/Blobs/blobrect.hpp | 200 +++--- Plugins/ZShell/Blobs/blobshape.cpp | 206 ++++-- Plugins/ZShell/Blobs/blobshape.hpp | 121 ++-- Plugins/ZShell/Components/buttonrow.cpp | 62 +- Plugins/ZShell/Components/buttonrow.hpp | 39 +- Plugins/ZShell/Components/lazylistview.cpp | 454 +++++------- Plugins/ZShell/Components/lazylistview.hpp | 387 ++++++----- Plugins/ZShell/Components/wavyline.cpp | 8 +- Plugins/ZShell/Components/wavyline.hpp | 168 +++-- Plugins/ZShell/Internal/arcgauge.cpp | 24 +- Plugins/ZShell/Internal/arcgauge.hpp | 88 ++- .../ZShell/Internal/cachingimagemanager.cpp | 292 ++++---- .../ZShell/Internal/cachingimagemanager.hpp | 81 ++- Plugins/ZShell/Internal/circularbuffer.cpp | 25 +- Plugins/ZShell/Internal/circularbuffer.hpp | 51 +- .../Internal/circularindicatormanager.cpp | 57 +- .../Internal/circularindicatormanager.hpp | 102 +-- Plugins/ZShell/Internal/hyprdevices.cpp | 163 ++--- Plugins/ZShell/Internal/hyprdevices.hpp | 99 +-- Plugins/ZShell/Internal/hyprextras.cpp | 166 +++-- Plugins/ZShell/Internal/hyprextras.hpp | 71 +- Plugins/ZShell/Internal/lidwatcher.cpp | 58 +- Plugins/ZShell/Internal/lidwatcher.hpp | 26 +- .../Internal/linearindicatormanager.cpp | 53 +- .../Internal/linearindicatormanager.hpp | 100 +-- Plugins/ZShell/Internal/sparklineitem.cpp | 98 ++- Plugins/ZShell/Internal/sparklineitem.hpp | 139 ++-- Plugins/ZShell/Internal/visualizerbars.cpp | 35 +- Plugins/ZShell/Internal/visualizerbars.hpp | 96 +-- Plugins/ZShell/Internal/wallpaperimage.cpp | 75 +- Plugins/ZShell/Internal/wallpaperimage.hpp | 180 +++-- Plugins/ZShell/Models/filesystemmodel.cpp | 656 +++++++++--------- Plugins/ZShell/Models/filesystemmodel.hpp | 218 +++--- Plugins/ZShell/Services/audiocollector.cpp | 98 ++- Plugins/ZShell/Services/audiocollector.hpp | 70 +- Plugins/ZShell/Services/audioprovider.cpp | 30 +- Plugins/ZShell/Services/audioprovider.hpp | 44 +- Plugins/ZShell/Services/beattracker.cpp | 13 +- Plugins/ZShell/Services/beattracker.hpp | 48 +- Plugins/ZShell/Services/cavaprovider.cpp | 30 +- Plugins/ZShell/Services/cavaprovider.hpp | 68 +- Plugins/ZShell/Services/cpu.cpp | 19 +- Plugins/ZShell/Services/cpu.hpp | 56 +- Plugins/ZShell/Services/desktopmodel.hpp | 94 +-- .../ZShell/Services/desktopstatemanager.cpp | 10 +- .../ZShell/Services/desktopstatemanager.hpp | 18 +- Plugins/ZShell/Services/diskinfo.cpp | 17 +- Plugins/ZShell/Services/diskinfo.hpp | 63 +- Plugins/ZShell/Services/gpu.hpp | 128 ++-- Plugins/ZShell/Services/hyprsunsetmanager.cpp | 45 +- Plugins/ZShell/Services/hyprsunsetmanager.hpp | 97 +-- Plugins/ZShell/Services/memory.cpp | 10 +- Plugins/ZShell/Services/memory.hpp | 40 +- Plugins/ZShell/Services/sensorslib.cpp | 51 +- Plugins/ZShell/Services/service.cpp | 4 +- Plugins/ZShell/Services/service.hpp | 18 +- Plugins/ZShell/Services/serviceref.cpp | 3 +- Plugins/ZShell/Services/serviceref.hpp | 24 +- Plugins/ZShell/Services/storage.cpp | 80 ++- Plugins/ZShell/Services/storage.hpp | 67 +- Plugins/ZShell/Services/tickingservice.hpp | 33 +- Plugins/ZShell/Services/usagefmt.cpp | 10 +- Plugins/ZShell/Services/usagefmt.hpp | 13 +- Plugins/ZShell/appdb.cpp | 326 ++++----- Plugins/ZShell/appdb.hpp | 144 ++-- Plugins/ZShell/imageanalyser.cpp | 340 +++++---- Plugins/ZShell/imageanalyser.hpp | 74 +- Plugins/ZShell/qalculator.cpp | 9 +- Plugins/ZShell/qalculator.hpp | 13 +- Plugins/ZShell/requests.cpp | 14 +- Plugins/ZShell/requests.hpp | 19 +- Plugins/ZShell/toaster.cpp | 29 +- Plugins/ZShell/toaster.hpp | 109 +-- Plugins/ZShell/writefile.cpp | 262 ++++--- Plugins/ZShell/writefile.hpp | 42 +- Plugins/ZShell/zutils.cpp | 90 ++- Plugins/ZShell/zutils.hpp | 37 +- 85 files changed, 4139 insertions(+), 3738 deletions(-) diff --git a/.clang-format b/.clang-format index a2cde00..a931072 100644 --- a/.clang-format +++ b/.clang-format @@ -1,15 +1,15 @@ --- BasedOnStyle: LLVM AccessModifierOffset: 0 -AlignAfterOpenBracket: Align +AlignAfterOpenBracket: AlwaysBreak AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignOperands: Align AllowAllParametersOfDeclarationOnNextLine: true AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: Never +AllowShortIfStatementsOnASingleLine: WithoutElse AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: Yes +AlwaysBreakTemplateDeclarations: MultiLine BinPackArguments: false BinPackParameters: false BreakBeforeBraces: Attach diff --git a/Plugins/ZShell/Blobs/blobgroup.cpp b/Plugins/ZShell/Blobs/blobgroup.cpp index e77cf05..86ef2ff 100644 --- a/Plugins/ZShell/Blobs/blobgroup.cpp +++ b/Plugins/ZShell/Blobs/blobgroup.cpp @@ -2,9 +2,7 @@ #include "blobinvertedrect.hpp" #include "blobshape.hpp" -BlobGroup::BlobGroup(QObject* parent) - : QObject(parent) { -} +BlobGroup::BlobGroup(QObject* parent) : QObject(parent) {} BlobGroup::~BlobGroup() { for (auto* shape : std::as_const(m_shapes)) @@ -14,24 +12,21 @@ BlobGroup::~BlobGroup() { } void BlobGroup::setSmoothing(qreal s) { - if (qFuzzyCompare(m_smoothing, s)) - return; + if (qFuzzyCompare(m_smoothing, s)) return; m_smoothing = s; emit smoothingChanged(); markDirty(); } void BlobGroup::setColor(const QColor& c) { - if (m_color == c) - return; + if (m_color == c) return; m_color = c; emit colorChanged(); markDirty(); } void BlobGroup::addShape(BlobShape* shape) { - if (!shape || m_shapes.contains(shape)) - return; + if (!shape || m_shapes.contains(shape)) return; m_shapes.append(shape); markDirty(); } @@ -42,15 +37,13 @@ void BlobGroup::removeShape(BlobShape* shape) { } void BlobGroup::setInvertedRect(BlobInvertedRect* rect) { - if (m_invertedRect == rect) - return; + if (m_invertedRect == rect) return; m_invertedRect = rect; markDirty(); } void BlobGroup::clearInvertedRect(BlobInvertedRect* rect) { - if (m_invertedRect != rect) - return; + if (m_invertedRect != rect) return; m_invertedRect = nullptr; markDirty(); } @@ -75,15 +68,19 @@ void BlobGroup::markShapeDirty(BlobShape* source) { // Use cached padded rects to find spatial neighbors const float pad = static_cast(m_smoothing) * 2.0f; - const QRectF srcRect(static_cast(source->m_cachedPaddedX - pad), - static_cast(source->m_cachedPaddedY - pad), static_cast(source->m_cachedPaddedW + pad * 2.0f), - static_cast(source->m_cachedPaddedH + pad * 2.0f)); + const QRectF srcRect( + static_cast(source->m_cachedPaddedX - pad), + static_cast(source->m_cachedPaddedY - pad), + static_cast(source->m_cachedPaddedW + pad * 2.0f), + static_cast(source->m_cachedPaddedH + pad * 2.0f)); for (auto* shape : std::as_const(m_shapes)) { - if (shape == source) - continue; - const QRectF otherRect(static_cast(shape->m_cachedPaddedX), static_cast(shape->m_cachedPaddedY), - static_cast(shape->m_cachedPaddedW), static_cast(shape->m_cachedPaddedH)); + if (shape == source) continue; + const QRectF otherRect( + static_cast(shape->m_cachedPaddedX), + static_cast(shape->m_cachedPaddedY), + static_cast(shape->m_cachedPaddedW), + static_cast(shape->m_cachedPaddedH)); if (srcRect.intersects(otherRect)) { shape->polish(); shape->update(); @@ -97,8 +94,7 @@ void BlobGroup::markShapeDirty(BlobShape* source) { } void BlobGroup::ensurePhysicsUpdated() { - if (m_physicsUpdated) - return; + if (m_physicsUpdated) return; m_physicsUpdated = true; for (auto* shape : std::as_const(m_shapes)) shape->updatePhysics(); diff --git a/Plugins/ZShell/Blobs/blobgroup.hpp b/Plugins/ZShell/Blobs/blobgroup.hpp index e917804..c90ed7e 100644 --- a/Plugins/ZShell/Blobs/blobgroup.hpp +++ b/Plugins/ZShell/Blobs/blobgroup.hpp @@ -9,53 +9,49 @@ class BlobShape; class BlobInvertedRect; class BlobGroup : public QObject { -Q_OBJECT -QML_ELEMENT -Q_PROPERTY(qreal smoothing READ smoothing WRITE setSmoothing NOTIFY smoothingChanged) -Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_OBJECT + QML_ELEMENT + Q_PROPERTY( + qreal smoothing READ smoothing WRITE setSmoothing NOTIFY + smoothingChanged) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) -public: -explicit BlobGroup(QObject* parent = nullptr); -~BlobGroup() override; + public: + explicit BlobGroup(QObject* parent = nullptr); + ~BlobGroup() override; -[[nodiscard]] qreal smoothing() const { - return m_smoothing; -} + [[nodiscard]] qreal smoothing() const { return m_smoothing; } -void setSmoothing(qreal s); + void setSmoothing(qreal s); -[[nodiscard]] QColor color() const { - return m_color; -} + [[nodiscard]] QColor color() const { return m_color; } -void setColor(const QColor& c); + void setColor(const QColor& c); -void addShape(BlobShape* shape); -void removeShape(BlobShape* shape); + void addShape(BlobShape* shape); + void removeShape(BlobShape* shape); -void setInvertedRect(BlobInvertedRect* rect); -void clearInvertedRect(BlobInvertedRect* rect); + void setInvertedRect(BlobInvertedRect* rect); + void clearInvertedRect(BlobInvertedRect* rect); -[[nodiscard]] const QList& shapes() const { - return m_shapes; -} + [[nodiscard]] const QList& shapes() const { return m_shapes; } -[[nodiscard]] BlobInvertedRect* invertedRect() const { - return m_invertedRect; -} + [[nodiscard]] BlobInvertedRect* invertedRect() const { + return m_invertedRect; + } -void markDirty(); -void markShapeDirty(BlobShape* source); -void ensurePhysicsUpdated(); + void markDirty(); + void markShapeDirty(BlobShape* source); + void ensurePhysicsUpdated(); -signals: -void smoothingChanged(); -void colorChanged(); + signals: + void smoothingChanged(); + void colorChanged(); -private: -qreal m_smoothing = 32.0; -QColor m_color{ 0x44, 0x88, 0xff }; -QList m_shapes; -BlobInvertedRect* m_invertedRect = nullptr; -bool m_physicsUpdated = false; + private: + qreal m_smoothing = 32.0; + QColor m_color{0x44, 0x88, 0xff}; + QList m_shapes; + BlobInvertedRect* m_invertedRect = nullptr; + bool m_physicsUpdated = false; }; diff --git a/Plugins/ZShell/Blobs/blobinvertedrect.cpp b/Plugins/ZShell/Blobs/blobinvertedrect.cpp index a8b85f4..328cbf3 100644 --- a/Plugins/ZShell/Blobs/blobinvertedrect.cpp +++ b/Plugins/ZShell/Blobs/blobinvertedrect.cpp @@ -5,12 +5,9 @@ #include #include -#include #include -BlobInvertedRect::BlobInvertedRect(QQuickItem* parent) - : BlobShape(parent) { -} +BlobInvertedRect::BlobInvertedRect(QQuickItem* parent) : BlobShape(parent) {} static void setFrameIndices(quint16* idx) { // Top strip: 0-1-4, 1-5-4 @@ -43,7 +40,8 @@ static void setFrameIndices(quint16* idx) { idx[23] = 7; } -QSGNode* BlobInvertedRect::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { +QSGNode* BlobInvertedRect::updatePaintNode( + QSGNode* oldNode, UpdatePaintNodeData*) { if (!m_group) { delete oldNode; return nullptr; @@ -71,8 +69,11 @@ QSGNode* BlobInvertedRect::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData delete oldNode; node = new QSGGeometryNode; - auto* geometry = - new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 8, 24, QSGGeometry::UnsignedShortType); + auto* geometry = new QSGGeometry( + QSGGeometry::defaultAttributes_TexturedPoint2D(), + 8, + 24, + QSGGeometry::UnsignedShortType); geometry->setDrawingMode(QSGGeometry::DrawTriangles); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); @@ -120,10 +121,17 @@ QSGNode* BlobInvertedRect::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData material->m_color = m_group->color(); material->m_hasInverted = m_cachedHasInverted ? 1 : 0; material->m_invertedRadius = m_cachedInvertedRadius; - memcpy(material->m_invertedOuter, m_cachedInvertedOuter, sizeof(m_cachedInvertedOuter)); - memcpy(material->m_invertedInner, m_cachedInvertedInner, sizeof(m_cachedInvertedInner)); + memcpy( + material->m_invertedOuter, + m_cachedInvertedOuter, + sizeof(m_cachedInvertedOuter)); + memcpy( + material->m_invertedInner, + m_cachedInvertedInner, + sizeof(m_cachedInvertedInner)); - const int count = static_cast(qMin(m_cachedRects.size(), qsizetype(16))); + const int count = + static_cast(qMin(m_cachedRects.size(), qsizetype(16))); material->m_rectCount = count; for (int i = 0; i < count; ++i) material->m_rects[i] = m_cachedRects[i]; @@ -134,52 +142,41 @@ QSGNode* BlobInvertedRect::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData } BlobInvertedRect::~BlobInvertedRect() { - if (m_group) - m_group->clearInvertedRect(this); + if (m_group) m_group->clearInvertedRect(this); } void BlobInvertedRect::setBorderLeft(qreal v) { - if (qFuzzyCompare(m_borderLeft, v)) - return; + if (qFuzzyCompare(m_borderLeft, v)) return; m_borderLeft = v; emit borderLeftChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } void BlobInvertedRect::setBorderRight(qreal v) { - if (qFuzzyCompare(m_borderRight, v)) - return; + if (qFuzzyCompare(m_borderRight, v)) return; m_borderRight = v; emit borderRightChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } void BlobInvertedRect::setBorderTop(qreal v) { - if (qFuzzyCompare(m_borderTop, v)) - return; + if (qFuzzyCompare(m_borderTop, v)) return; m_borderTop = v; emit borderTopChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } void BlobInvertedRect::setBorderBottom(qreal v) { - if (qFuzzyCompare(m_borderBottom, v)) - return; + if (qFuzzyCompare(m_borderBottom, v)) return; m_borderBottom = v; emit borderBottomChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } void BlobInvertedRect::registerWithGroup() { - if (m_group) - m_group->setInvertedRect(this); + if (m_group) m_group->setInvertedRect(this); } void BlobInvertedRect::unregisterFromGroup() { - if (m_group) - m_group->clearInvertedRect(this); + if (m_group) m_group->clearInvertedRect(this); } diff --git a/Plugins/ZShell/Blobs/blobinvertedrect.hpp b/Plugins/ZShell/Blobs/blobinvertedrect.hpp index 0a36ef8..0fe0695 100644 --- a/Plugins/ZShell/Blobs/blobinvertedrect.hpp +++ b/Plugins/ZShell/Blobs/blobinvertedrect.hpp @@ -5,60 +5,58 @@ #include class BlobInvertedRect : public BlobShape { -Q_OBJECT -QML_ELEMENT -Q_PROPERTY(qreal borderLeft READ borderLeft WRITE setBorderLeft NOTIFY borderLeftChanged) -Q_PROPERTY(qreal borderRight READ borderRight WRITE setBorderRight NOTIFY borderRightChanged) -Q_PROPERTY(qreal borderTop READ borderTop WRITE setBorderTop NOTIFY borderTopChanged) -Q_PROPERTY(qreal borderBottom READ borderBottom WRITE setBorderBottom NOTIFY borderBottomChanged) + Q_OBJECT + QML_ELEMENT + Q_PROPERTY( + qreal borderLeft READ borderLeft WRITE setBorderLeft NOTIFY + borderLeftChanged) + Q_PROPERTY( + qreal borderRight READ borderRight WRITE setBorderRight NOTIFY + borderRightChanged) + Q_PROPERTY( + qreal borderTop READ borderTop WRITE setBorderTop NOTIFY + borderTopChanged) + Q_PROPERTY( + qreal borderBottom READ borderBottom WRITE setBorderBottom NOTIFY + borderBottomChanged) -public: -explicit BlobInvertedRect(QQuickItem* parent = nullptr); -~BlobInvertedRect() override; + public: + explicit BlobInvertedRect(QQuickItem* parent = nullptr); + ~BlobInvertedRect() override; -[[nodiscard]] qreal borderLeft() const { - return m_borderLeft; -} + [[nodiscard]] qreal borderLeft() const { return m_borderLeft; } -void setBorderLeft(qreal v); + void setBorderLeft(qreal v); -[[nodiscard]] qreal borderRight() const { - return m_borderRight; -} + [[nodiscard]] qreal borderRight() const { return m_borderRight; } -void setBorderRight(qreal v); + void setBorderRight(qreal v); -[[nodiscard]] qreal borderTop() const { - return m_borderTop; -} + [[nodiscard]] qreal borderTop() const { return m_borderTop; } -void setBorderTop(qreal v); + void setBorderTop(qreal v); -[[nodiscard]] qreal borderBottom() const { - return m_borderBottom; -} + [[nodiscard]] qreal borderBottom() const { return m_borderBottom; } -void setBorderBottom(qreal v); + void setBorderBottom(qreal v); -signals: -void borderLeftChanged(); -void borderRightChanged(); -void borderTopChanged(); -void borderBottomChanged(); + signals: + void borderLeftChanged(); + void borderRightChanged(); + void borderTopChanged(); + void borderBottomChanged(); -protected: -[[nodiscard]] bool isInvertedRect() const override { - return true; -} + protected: + [[nodiscard]] bool isInvertedRect() const override { return true; } -QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) override; + QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) override; -void registerWithGroup() override; -void unregisterFromGroup() override; + void registerWithGroup() override; + void unregisterFromGroup() override; -private: -qreal m_borderLeft = 0; -qreal m_borderRight = 0; -qreal m_borderTop = 0; -qreal m_borderBottom = 0; + private: + qreal m_borderLeft = 0; + qreal m_borderRight = 0; + qreal m_borderTop = 0; + qreal m_borderBottom = 0; }; diff --git a/Plugins/ZShell/Blobs/blobmaterial.cpp b/Plugins/ZShell/Blobs/blobmaterial.cpp index 8bb85b3..e32b25e 100644 --- a/Plugins/ZShell/Blobs/blobmaterial.cpp +++ b/Plugins/ZShell/Blobs/blobmaterial.cpp @@ -1,24 +1,26 @@ #include "blobmaterial.hpp" +#include + #include -static_assert(sizeof(decltype(BlobRectData::excludeMask)) == sizeof(float), - "BlobMaterial packs excludeMask into a float slot via memcpy"); +static_assert( + sizeof(decltype(BlobRectData::excludeMask)) == sizeof(float), + "BlobMaterial packs excludeMask into a float slot via memcpy"); QSGMaterialType* BlobMaterial::type() const { static QSGMaterialType s_type; return &s_type; } -QSGMaterialShader* BlobMaterial::createShader(QSGRendererInterface::RenderMode) const { +QSGMaterialShader* BlobMaterial::createShader( + QSGRendererInterface::RenderMode) const { return new BlobMaterialShader; } int BlobMaterial::compare(const QSGMaterial* other) const { - if (this < other) - return -1; - if (this > other) - return 1; + if (this < other) return -1; + if (this > other) return 1; return 0; } @@ -27,7 +29,8 @@ BlobMaterialShader::BlobMaterialShader() { setShaderFileName(FragmentStage, QStringLiteral(":/shaders/blob.frag.qsb")); } -bool BlobMaterialShader::updateUniformData(RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) { +bool BlobMaterialShader::updateUniformData( + RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) { Q_UNUSED(oldMaterial); auto* mat = static_cast(newMaterial); QByteArray* buf = state.uniformData(); @@ -59,10 +62,10 @@ bool BlobMaterialShader::updateUniformData(RenderState& state, QSGMaterial* newM // Color as vec4 (offset 96, 16 bytes) const float color[4] = { - static_cast(mat->m_color.redF()), - static_cast(mat->m_color.greenF()), - static_cast(mat->m_color.blueF()), - static_cast(mat->m_color.alphaF()), + mat->m_color.redF(), + mat->m_color.greenF(), + mat->m_color.blueF(), + mat->m_color.alphaF(), }; memcpy(buf->data() + 96, color, 16); @@ -86,11 +89,11 @@ bool BlobMaterialShader::updateUniformData(RenderState& state, QSGMaterial* newM const auto& r = mat->m_rects[i]; const int base = 160 + i * 80; // Pack excludeMask into props.x via bit-cast (read in shader with floatBitsToInt) - float maskAsFloat; + float maskAsFloat = NAN; memcpy(&maskAsFloat, &r.excludeMask, sizeof(float)); - const float d0[4] = { r.cx, r.cy, r.hw, r.hh }; - const float d1[4] = { maskAsFloat, r.offsetX, r.offsetY, r.minEig }; - const float d3[4] = { r.screenHalfX, r.screenHalfY, 0.0f, 0.0f }; + const float d0[4] = {r.cx, r.cy, r.hw, r.hh}; + const float d1[4] = {maskAsFloat, r.offsetX, r.offsetY, r.minEig}; + const float d3[4] = {r.screenHalfX, r.screenHalfY, 0.0f, 0.0f}; memcpy(buf->data() + base, d0, 16); memcpy(buf->data() + base + 16, d1, 16); memcpy(buf->data() + base + 32, r.invDeform, 16); diff --git a/Plugins/ZShell/Blobs/blobmaterial.hpp b/Plugins/ZShell/Blobs/blobmaterial.hpp index 0d49d9f..4a30448 100644 --- a/Plugins/ZShell/Blobs/blobmaterial.hpp +++ b/Plugins/ZShell/Blobs/blobmaterial.hpp @@ -9,39 +9,43 @@ struct BlobRectData { float offsetX = 0, offsetY = 0; float minEig = 1.0f; // Inverse of 2x2 deformation matrix, column-major for GLSL - float invDeform[4] = { 1, 0, 0, 1 }; + float invDeform[4] = {1, 0, 0, 1}; // Screen-space AABB half-extents of the deformed rect float screenHalfX = 0, screenHalfY = 0; // Effective per-corner radii (tr, br, bl, tl), pre-computed on CPU - float radius[4] = { 0, 0, 0, 0 }; + float radius[4] = {0, 0, 0, 0}; // Bitmask of indices in this rect's m_cachedRects that mutually exclude (or are excluded by) this rect. // Used by the shader to skip smin between excluded pairs. int excludeMask = 0; }; class BlobMaterial : public QSGMaterial { -public: -[[nodiscard]] QSGMaterialType* type() const override; -[[nodiscard]] QSGMaterialShader* createShader(QSGRendererInterface::RenderMode) const override; -int compare(const QSGMaterial* other) const override; + public: + [[nodiscard]] QSGMaterialType* type() const override; + [[nodiscard]] QSGMaterialShader* createShader( + QSGRendererInterface::RenderMode) const override; + int compare(const QSGMaterial* other) const override; -float m_paddedX = 0; -float m_paddedY = 0; -float m_paddedW = 0; -float m_paddedH = 0; -float m_smoothFactor = 32.0f; -int m_rectCount = 0; -int m_myIndex = -2; -QColor m_color{ 0x44, 0x88, 0xff }; -int m_hasInverted = 0; -float m_invertedRadius = 0; -float m_invertedOuter[4] = {}; -float m_invertedInner[4] = {}; -BlobRectData m_rects[16] = {}; + float m_paddedX = 0; + float m_paddedY = 0; + float m_paddedW = 0; + float m_paddedH = 0; + float m_smoothFactor = 32.0f; + int m_rectCount = 0; + int m_myIndex = -2; + QColor m_color{0x44, 0x88, 0xff}; + int m_hasInverted = 0; + float m_invertedRadius = 0; + float m_invertedOuter[4] = {}; + float m_invertedInner[4] = {}; + BlobRectData m_rects[16] = {}; }; class BlobMaterialShader : public QSGMaterialShader { -public: -BlobMaterialShader(); -bool updateUniformData(RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) override; + public: + BlobMaterialShader(); + bool updateUniformData( + RenderState& state, + QSGMaterial* newMaterial, + QSGMaterial* oldMaterial) override; }; diff --git a/Plugins/ZShell/Blobs/blobrect.cpp b/Plugins/ZShell/Blobs/blobrect.cpp index 5847fa4..c141afc 100644 --- a/Plugins/ZShell/Blobs/blobrect.cpp +++ b/Plugins/ZShell/Blobs/blobrect.cpp @@ -4,19 +4,18 @@ #include #include -BlobRect::BlobRect(QQuickItem* parent) - : BlobShape(parent) { -} +BlobRect::BlobRect(QQuickItem* parent) : BlobShape(parent) {} BlobRect::~BlobRect() { - if (m_group) - m_group->removeShape(this); + if (m_group) m_group->removeShape(this); } void BlobRect::updatePolish() { if (m_physicsActive) { - float totalDelta = std::abs(m_dm00 - 1.0f) + std::abs(m_dm01) + std::abs(m_dm11 - 1.0f); - float totalVel = std::abs(m_dmVel00) + std::abs(m_dmVel01) + std::abs(m_dmVel11); + float totalDelta = std::abs(m_dm00 - 1.0f) + std::abs(m_dm01) + + std::abs(m_dm11 - 1.0f); + float totalVel = + std::abs(m_dmVel00) + std::abs(m_dmVel01) + std::abs(m_dmVel11); if (totalDelta < 0.004f && totalVel < 0.05f) { m_dm00 = 1.0f; @@ -32,18 +31,16 @@ void BlobRect::updatePolish() { QMetaObject::invokeMethod( this, [this]() { - if (m_group) - m_group->markDirty(); - }, + if (m_group) m_group->markDirty(); + }, Qt::QueuedConnection); } } else { QMetaObject::invokeMethod( this, [this]() { - if (m_physicsActive && m_group) - m_group->markDirty(); - }, + if (m_physicsActive && m_group) m_group->markDirty(); + }, Qt::QueuedConnection); } } @@ -64,20 +61,20 @@ void BlobRect::updatePhysics() { const float dt = static_cast(m_elapsed.restart()) / 1000.0f; if (dt > 0.1f || dt < 0.001f) { m_prevScenePos = scenePos; - if (m_physicsActive) - checkAtRest(0.0f); + if (m_physicsActive) checkAtRest(0.0f); return; } - const float velX = static_cast(scenePos.x() - m_prevScenePos.x()) / dt; - const float velY = static_cast(scenePos.y() - m_prevScenePos.y()) / dt; + const float velX = + static_cast(scenePos.x() - m_prevScenePos.x()) / dt; + const float velY = + static_cast(scenePos.y() - m_prevScenePos.y()) / dt; m_prevScenePos = scenePos; const float speed = std::sqrt(velX * velX + velY * velY); if (!m_physicsActive) { - if (speed < 5.0f) - return; + if (speed < 5.0f) return; m_physicsActive = true; } @@ -89,7 +86,8 @@ void BlobRect::updatePhysics() { float target11 = 1.0f; if (speed > 5.0f) { - const float targetStretch = 1.0f + std::min(speed * kStretchFactor, kMaxStretch); + const float targetStretch = + 1.0f + std::min(speed * kStretchFactor, kMaxStretch); const float targetCompress = 1.0f / targetStretch; const float cosA = velX / speed; @@ -106,19 +104,23 @@ void BlobRect::updatePhysics() { const float kStiffness = static_cast(m_stiffness); const float kDamping = static_cast(m_damping); - const float accel00 = -kStiffness * (m_dm00 - target00) - kDamping * m_dmVel00; + const float accel00 = + -kStiffness * (m_dm00 - target00) - kDamping * m_dmVel00; m_dmVel00 += accel00 * dt; m_dm00 += m_dmVel00 * dt; - const float accel01 = -kStiffness * (m_dm01 - target01) - kDamping * m_dmVel01; + const float accel01 = + -kStiffness * (m_dm01 - target01) - kDamping * m_dmVel01; m_dmVel01 += accel01 * dt; m_dm01 += m_dmVel01 * dt; - const float accel11 = -kStiffness * (m_dm11 - target11) - kDamping * m_dmVel11; + const float accel11 = + -kStiffness * (m_dm11 - target11) - kDamping * m_dmVel11; m_dmVel11 += accel11 * dt; m_dm11 += m_dmVel11 * dt; - m_deformMatrix = QMatrix4x4(m_dm00, m_dm01, 0, 0, m_dm01, m_dm11, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + m_deformMatrix = QMatrix4x4( + m_dm00, m_dm01, 0, 0, m_dm01, m_dm11, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); emit rawDeformMatrixChanged(); updateCenteredDeformMatrix(); @@ -129,8 +131,7 @@ void BlobRect::setTopLeftRadius(qreal r) { if (!qFuzzyCompare(m_topLeftRadius, r)) { m_topLeftRadius = r; emit topLeftRadiusChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } } @@ -138,8 +139,7 @@ void BlobRect::setTopRightRadius(qreal r) { if (!qFuzzyCompare(m_topRightRadius, r)) { m_topRightRadius = r; emit topRightRadiusChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } } @@ -147,8 +147,7 @@ void BlobRect::setBottomLeftRadius(qreal r) { if (!qFuzzyCompare(m_bottomLeftRadius, r)) { m_bottomLeftRadius = r; emit bottomLeftRadiusChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } } @@ -156,38 +155,51 @@ void BlobRect::setBottomRightRadius(qreal r) { if (!qFuzzyCompare(m_bottomRightRadius, r)) { m_bottomRightRadius = r; emit bottomRightRadiusChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } } void BlobRect::cornerRadii(float out[4]) const { const auto maxR = static_cast(std::min(width(), height())) * 0.5f; const auto base = std::min(static_cast(m_radius), maxR); - out[0] = std::min(m_topRightRadius >= 0 ? static_cast(m_topRightRadius) : base, maxR); - out[1] = std::min(m_bottomRightRadius >= 0 ? static_cast(m_bottomRightRadius) : base, maxR); - out[2] = std::min(m_bottomLeftRadius >= 0 ? static_cast(m_bottomLeftRadius) : base, maxR); - out[3] = std::min(m_topLeftRadius >= 0 ? static_cast(m_topLeftRadius) : base, maxR); + out[0] = std::min( + m_topRightRadius >= 0 ? static_cast(m_topRightRadius) : base, + maxR); + out[1] = std::min( + m_bottomRightRadius >= 0 ? static_cast(m_bottomRightRadius) + : base, + maxR); + out[2] = std::min( + m_bottomLeftRadius >= 0 ? static_cast(m_bottomLeftRadius) : base, + maxR); + out[3] = std::min( + m_topLeftRadius >= 0 ? static_cast(m_topLeftRadius) : base, + maxR); } bool BlobRect::isExcluded(const BlobShape* other) const { for (const auto& ptr : m_exclude) { - if (ptr == other) - return true; + if (ptr == other) return true; } return false; } QQmlListProperty BlobRect::exclude() { return QQmlListProperty( - this, nullptr, &excludeAppend, &excludeCount, &excludeAt, &excludeClear, &excludeReplace, &excludeRemoveLast); + this, + nullptr, + &excludeAppend, + &excludeCount, + &excludeAt, + &excludeClear, + &excludeReplace, + &excludeRemoveLast); } void BlobRect::excludeAppend(QQmlListProperty* prop, BlobRect* rect) { auto* self = static_cast(prop->object); self->m_exclude.append(rect); - if (self->m_group) - self->m_group->markDirty(); + if (self->m_group) self->m_group->markDirty(); emit self->excludeChanged(); } @@ -196,44 +208,43 @@ qsizetype BlobRect::excludeCount(QQmlListProperty* prop) { return self->m_exclude.size(); } -BlobRect* BlobRect::excludeAt(QQmlListProperty* prop, qsizetype index) { +BlobRect* BlobRect::excludeAt( + QQmlListProperty* prop, qsizetype index) { auto* self = static_cast(prop->object); return self->m_exclude.at(index); } void BlobRect::excludeClear(QQmlListProperty* prop) { auto* self = static_cast(prop->object); - if (self->m_exclude.isEmpty()) - return; + if (self->m_exclude.isEmpty()) return; self->m_exclude.clear(); - if (self->m_group) - self->m_group->markDirty(); + if (self->m_group) self->m_group->markDirty(); emit self->excludeChanged(); } -void BlobRect::excludeReplace(QQmlListProperty* prop, qsizetype index, BlobRect* rect) { +void BlobRect::excludeReplace( + QQmlListProperty* prop, qsizetype index, BlobRect* rect) { auto* self = static_cast(prop->object); self->m_exclude[index] = rect; - if (self->m_group) - self->m_group->markDirty(); + if (self->m_group) self->m_group->markDirty(); emit self->excludeChanged(); } void BlobRect::excludeRemoveLast(QQmlListProperty* prop) { auto* self = static_cast(prop->object); - if (self->m_exclude.isEmpty()) - return; + if (self->m_exclude.isEmpty()) return; self->m_exclude.removeLast(); - if (self->m_group) - self->m_group->markDirty(); + if (self->m_group) self->m_group->markDirty(); emit self->excludeChanged(); } void BlobRect::checkAtRest(float speed) { constexpr float kEpsilon = 0.002f; - const bool atRest = std::abs(m_dm00 - 1.0f) < kEpsilon && std::abs(m_dm01) < kEpsilon && - std::abs(m_dm11 - 1.0f) < kEpsilon && std::abs(m_dmVel00) < kEpsilon && - std::abs(m_dmVel01) < kEpsilon && std::abs(m_dmVel11) < kEpsilon && speed < 5.0f; + const bool atRest = + std::abs(m_dm00 - 1.0f) < kEpsilon && std::abs(m_dm01) < kEpsilon && + std::abs(m_dm11 - 1.0f) < kEpsilon && std::abs(m_dmVel00) < kEpsilon && + std::abs(m_dmVel01) < kEpsilon && std::abs(m_dmVel11) < kEpsilon && + speed < 5.0f; if (atRest) { m_dm00 = 1.0f; @@ -251,9 +262,8 @@ void BlobRect::checkAtRest(float speed) { QMetaObject::invokeMethod( this, [this]() { - if (m_group) - m_group->markDirty(); - }, + if (m_group) m_group->markDirty(); + }, Qt::QueuedConnection); } } diff --git a/Plugins/ZShell/Blobs/blobrect.hpp b/Plugins/ZShell/Blobs/blobrect.hpp index 11d9910..a8d9d40 100644 --- a/Plugins/ZShell/Blobs/blobrect.hpp +++ b/Plugins/ZShell/Blobs/blobrect.hpp @@ -8,133 +8,135 @@ #include class BlobRect : public BlobShape { -Q_OBJECT -QML_ELEMENT -Q_PROPERTY(qreal stiffness READ stiffness WRITE setStiffness NOTIFY stiffnessChanged) -Q_PROPERTY(qreal damping READ damping WRITE setDamping NOTIFY dampingChanged) -Q_PROPERTY(qreal deformScale READ deformScale WRITE setDeformScale NOTIFY deformScaleChanged) -Q_PROPERTY(QQmlListProperty exclude READ exclude NOTIFY excludeChanged) -Q_PROPERTY(qreal topLeftRadius READ topLeftRadius WRITE setTopLeftRadius NOTIFY topLeftRadiusChanged) -Q_PROPERTY(qreal topRightRadius READ topRightRadius WRITE setTopRightRadius NOTIFY topRightRadiusChanged) -Q_PROPERTY(qreal bottomLeftRadius READ bottomLeftRadius WRITE setBottomLeftRadius NOTIFY bottomLeftRadiusChanged) -Q_PROPERTY( - qreal bottomRightRadius READ bottomRightRadius WRITE setBottomRightRadius NOTIFY bottomRightRadiusChanged) + Q_OBJECT + QML_ELEMENT + Q_PROPERTY( + qreal stiffness READ stiffness WRITE setStiffness NOTIFY + stiffnessChanged) + Q_PROPERTY(qreal damping READ damping WRITE setDamping NOTIFY dampingChanged) + Q_PROPERTY( + qreal deformScale READ deformScale WRITE setDeformScale NOTIFY + deformScaleChanged) + Q_PROPERTY( + QQmlListProperty exclude READ exclude NOTIFY excludeChanged) + Q_PROPERTY( + qreal topLeftRadius READ topLeftRadius WRITE setTopLeftRadius NOTIFY + topLeftRadiusChanged) + Q_PROPERTY( + qreal topRightRadius READ topRightRadius WRITE setTopRightRadius NOTIFY + topRightRadiusChanged) + Q_PROPERTY( + qreal bottomLeftRadius READ bottomLeftRadius WRITE setBottomLeftRadius + NOTIFY bottomLeftRadiusChanged) + Q_PROPERTY( + qreal bottomRightRadius READ bottomRightRadius WRITE + setBottomRightRadius NOTIFY bottomRightRadiusChanged) -public: -explicit BlobRect(QQuickItem* parent = nullptr); -~BlobRect() override; + public: + explicit BlobRect(QQuickItem* parent = nullptr); + ~BlobRect() override; -[[nodiscard]] qreal stiffness() const { - return m_stiffness; -} + [[nodiscard]] qreal stiffness() const { return m_stiffness; } -void setStiffness(qreal s) { - if (!qFuzzyCompare(m_stiffness, s)) { - m_stiffness = s; - emit stiffnessChanged(); + void setStiffness(qreal s) { + if (!qFuzzyCompare(m_stiffness, s)) { + m_stiffness = s; + emit stiffnessChanged(); + } } -} -[[nodiscard]] qreal damping() const { - return m_damping; -} + [[nodiscard]] qreal damping() const { return m_damping; } -void setDamping(qreal d) { - if (!qFuzzyCompare(m_damping, d)) { - m_damping = d; - emit dampingChanged(); + void setDamping(qreal d) { + if (!qFuzzyCompare(m_damping, d)) { + m_damping = d; + emit dampingChanged(); + } } -} -[[nodiscard]] qreal deformScale() const { - return m_deformScale; -} + [[nodiscard]] qreal deformScale() const { return m_deformScale; } -void setDeformScale(qreal s) { - if (!qFuzzyCompare(m_deformScale, s)) { - m_deformScale = s; - emit deformScaleChanged(); + void setDeformScale(qreal s) { + if (!qFuzzyCompare(m_deformScale, s)) { + m_deformScale = s; + emit deformScaleChanged(); + } } -} -QQmlListProperty exclude(); + QQmlListProperty exclude(); -bool isExcluded(const BlobShape* other) const override; -void cornerRadii(float out[4]) const override; + bool isExcluded(const BlobShape* other) const override; + void cornerRadii(float out[4]) const override; -[[nodiscard]] qreal topLeftRadius() const { - return m_topLeftRadius; -} + [[nodiscard]] qreal topLeftRadius() const { return m_topLeftRadius; } -void setTopLeftRadius(qreal r); + void setTopLeftRadius(qreal r); -[[nodiscard]] qreal topRightRadius() const { - return m_topRightRadius; -} + [[nodiscard]] qreal topRightRadius() const { return m_topRightRadius; } -void setTopRightRadius(qreal r); + void setTopRightRadius(qreal r); -[[nodiscard]] qreal bottomLeftRadius() const { - return m_bottomLeftRadius; -} + [[nodiscard]] qreal bottomLeftRadius() const { return m_bottomLeftRadius; } -void setBottomLeftRadius(qreal r); + void setBottomLeftRadius(qreal r); -[[nodiscard]] qreal bottomRightRadius() const { - return m_bottomRightRadius; -} + [[nodiscard]] qreal bottomRightRadius() const { + return m_bottomRightRadius; + } -void setBottomRightRadius(qreal r); + void setBottomRightRadius(qreal r); -signals: -void stiffnessChanged(); -void dampingChanged(); -void deformScaleChanged(); -void excludeChanged(); -void topLeftRadiusChanged(); -void topRightRadiusChanged(); -void bottomLeftRadiusChanged(); -void bottomRightRadiusChanged(); + signals: + void stiffnessChanged(); + void dampingChanged(); + void deformScaleChanged(); + void excludeChanged(); + void topLeftRadiusChanged(); + void topRightRadiusChanged(); + void bottomLeftRadiusChanged(); + void bottomRightRadiusChanged(); -protected: -void updatePolish() override; -void updatePhysics() override; + protected: + void updatePolish() override; + void updatePhysics() override; -private: -void checkAtRest(float speed); + private: + void checkAtRest(float speed); -// Physics state -QPointF m_prevScenePos; -QElapsedTimer m_elapsed; -bool m_physicsActive = false; -bool m_hasPrevPos = false; + // Physics state + QPointF m_prevScenePos; + QElapsedTimer m_elapsed; + bool m_physicsActive = false; + bool m_hasPrevPos = false; -// Symmetric 2x2 deformation matrix components (3 independent: m00, m01, -// m11) Rest state is identity: m00=1, m01=0, m11=1 -float m_dm00 = 1.0f; -float m_dm01 = 0.0f; -float m_dm11 = 1.0f; + // Symmetric 2x2 deformation matrix components (3 independent: m00, m01, + // m11) Rest state is identity: m00=1, m01=0, m11=1 + float m_dm00 = 1.0f; + float m_dm01 = 0.0f; + float m_dm11 = 1.0f; -// Spring velocities for each component -float m_dmVel00 = 0.0f; -float m_dmVel01 = 0.0f; -float m_dmVel11 = 0.0f; + // Spring velocities for each component + float m_dmVel00 = 0.0f; + float m_dmVel01 = 0.0f; + float m_dmVel11 = 0.0f; -qreal m_stiffness = 200.0; -qreal m_damping = 16.0; -qreal m_deformScale = 0.0005; + qreal m_stiffness = 200.0; + qreal m_damping = 16.0; + qreal m_deformScale = 0.0005; -qreal m_topLeftRadius = -1; -qreal m_topRightRadius = -1; -qreal m_bottomLeftRadius = -1; -qreal m_bottomRightRadius = -1; + qreal m_topLeftRadius = -1; + qreal m_topRightRadius = -1; + qreal m_bottomLeftRadius = -1; + qreal m_bottomRightRadius = -1; -QList > m_exclude; + QList> m_exclude; -static void excludeAppend(QQmlListProperty* prop, BlobRect* rect); -static qsizetype excludeCount(QQmlListProperty* prop); -static BlobRect* excludeAt(QQmlListProperty* prop, qsizetype index); -static void excludeClear(QQmlListProperty* prop); -static void excludeReplace(QQmlListProperty* prop, qsizetype index, BlobRect* rect); -static void excludeRemoveLast(QQmlListProperty* prop); + static void excludeAppend(QQmlListProperty* prop, BlobRect* rect); + static qsizetype excludeCount(QQmlListProperty* prop); + static BlobRect* excludeAt( + QQmlListProperty* prop, qsizetype index); + static void excludeClear(QQmlListProperty* prop); + static void excludeReplace( + QQmlListProperty* prop, qsizetype index, BlobRect* rect); + static void excludeRemoveLast(QQmlListProperty* prop); }; diff --git a/Plugins/ZShell/Blobs/blobshape.cpp b/Plugins/ZShell/Blobs/blobshape.cpp index 68ff191..bd69822 100644 --- a/Plugins/ZShell/Blobs/blobshape.cpp +++ b/Plugins/ZShell/Blobs/blobshape.cpp @@ -18,7 +18,8 @@ static float deformPadding(const QMatrix4x4& dm, float hw, float hh) { return std::max(extraX, extraY); } -static float cpuSdBox(float px, float py, float cx, float cy, float hw, float hh) { +static float cpuSdBox( + float px, float py, float cx, float cy, float hw, float hh) { const float dx = std::abs(px - cx) - hw; const float dy = std::abs(py - cy) - hh; const float mdx = std::max(dx, 0.0f); @@ -31,54 +32,53 @@ static float cpuSmoothstep(float edge0, float edge1, float x) { return t * t * (3.0f - 2.0f * t); } -BlobShape::BlobShape(QQuickItem* parent) - : QQuickItem(parent) { +BlobShape::BlobShape(QQuickItem* parent) : QQuickItem(parent) { setFlag(ItemHasContents); } void BlobShape::setGroup(BlobGroup* g) { - if (m_group == g) - return; - if (m_group && isComponentComplete()) - unregisterFromGroup(); + if (m_group == g) return; + if (m_group && isComponentComplete()) unregisterFromGroup(); m_group = g; - if (m_group && isComponentComplete()) - registerWithGroup(); + if (m_group && isComponentComplete()) registerWithGroup(); emit groupChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } void BlobShape::setRadius(qreal r) { - if (qFuzzyCompare(m_radius, r)) - return; + if (qFuzzyCompare(m_radius, r)) return; m_radius = r; emit radiusChanged(); - if (m_group) - m_group->markDirty(); + if (m_group) m_group->markDirty(); } void BlobShape::componentComplete() { QQuickItem::componentComplete(); - if (m_group) - registerWithGroup(); + if (m_group) registerWithGroup(); } -void BlobShape::geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry) { +void BlobShape::geometryChange( + const QRectF& newGeometry, const QRectF& oldGeometry) { QQuickItem::geometryChange(newGeometry, oldGeometry); updateCenteredDeformMatrix(); if (m_group) { m_pendingDx += static_cast(newGeometry.x() - oldGeometry.x()); m_pendingDy += static_cast(newGeometry.y() - oldGeometry.y()); - m_pendingDw += static_cast(newGeometry.width() - oldGeometry.width()); - m_pendingDh += static_cast(newGeometry.height() - oldGeometry.height()); + m_pendingDw += + static_cast(newGeometry.width() - oldGeometry.width()); + m_pendingDh += + static_cast(newGeometry.height() - oldGeometry.height()); - const float deformMag = std::abs(m_deformMatrix(0, 0) - 1.0f) + std::abs(m_deformMatrix(0, 1)) + - std::abs(m_deformMatrix(1, 0)) + std::abs(m_deformMatrix(1, 1) - 1.0f); + const float deformMag = std::abs(m_deformMatrix(0, 0) - 1.0f) + + std::abs(m_deformMatrix(0, 1)) + + std::abs(m_deformMatrix(1, 0)) + + std::abs(m_deformMatrix(1, 1) - 1.0f); const float syncThreshold = deformMag > 0.001f ? 0.05f : 0.5f; - if (std::abs(m_pendingDx) > syncThreshold || std::abs(m_pendingDy) > syncThreshold || - std::abs(m_pendingDw) > syncThreshold || std::abs(m_pendingDh) > syncThreshold) { + if (std::abs(m_pendingDx) > syncThreshold || + std::abs(m_pendingDy) > syncThreshold || + std::abs(m_pendingDw) > syncThreshold || + std::abs(m_pendingDh) > syncThreshold) { m_pendingDx = 0; m_pendingDy = 0; m_pendingDw = 0; @@ -111,18 +111,15 @@ void BlobShape::cornerRadii(float out[4]) const { } void BlobShape::registerWithGroup() { - if (m_group) - m_group->addShape(this); + if (m_group) m_group->addShape(this); } void BlobShape::unregisterFromGroup() { - if (m_group) - m_group->removeShape(this); + if (m_group) m_group->removeShape(this); } void BlobShape::updatePolish() { - if (!m_group) - return; + if (!m_group) return; m_group->ensurePhysicsUpdated(); @@ -144,27 +141,30 @@ void BlobShape::updatePolish() { m_cachedPaddedY = static_cast(scenePos.y()) - totalPad; m_cachedPaddedW = static_cast(width()) + 2.0f * totalPad; m_cachedPaddedH = static_cast(height()) + 2.0f * totalPad; - m_localPaddedRect = QRectF(static_cast(-totalPad), static_cast(-totalPad), - width() + 2.0 * static_cast(totalPad), height() + 2.0 * static_cast(totalPad)); + m_localPaddedRect = QRectF( + static_cast(-totalPad), + static_cast(-totalPad), + width() + 2.0 * static_cast(totalPad), + height() + 2.0 * static_cast(totalPad)); } m_cachedRects.clear(); m_cachedMyIndex = -2; - const QRectF myPadded(static_cast(m_cachedPaddedX), static_cast(m_cachedPaddedY), - static_cast(m_cachedPaddedW), static_cast(m_cachedPaddedH)); + const QRectF myPadded( + static_cast(m_cachedPaddedX), + static_cast(m_cachedPaddedY), + static_cast(m_cachedPaddedW), + static_cast(m_cachedPaddedH)); QVector rectShapes; rectShapes.reserve(m_group->shapes().size()); for (BlobShape* other : m_group->shapes()) { - if (other->isInvertedRect()) - continue; + if (other->isInvertedRect()) continue; - if (other->width() <= 0 || other->height() <= 0) - continue; + if (other->width() <= 0 || other->height() <= 0) continue; - if (isExcluded(other)) - continue; + if (isExcluded(other)) continue; const QPointF otherScene = other->mapToScene(QPointF(0, 0)); @@ -174,10 +174,13 @@ void BlobShape::updatePolish() { } else { const float otherHW = static_cast(other->width()) * 0.5f; const float otherHH = static_cast(other->height()) * 0.5f; - const float otherPad = pad + deformPadding(other->m_deformMatrix, otherHW, otherHH); - const QRectF otherPadded(otherScene.x() - static_cast(otherPad), - otherScene.y() - static_cast(otherPad), other->width() + 2.0 * static_cast(otherPad), - other->height() + 2.0 * static_cast(otherPad)); + const float otherPad = + pad + deformPadding(other->m_deformMatrix, otherHW, otherHH); + const QRectF otherPadded( + otherScene.x() - static_cast(otherPad), + otherScene.y() - static_cast(otherPad), + other->width() + 2.0 * static_cast(otherPad), + other->height() + 2.0 * static_cast(otherPad)); include = myPadded.intersects(otherPadded); } @@ -217,19 +220,16 @@ void BlobShape::updatePolish() { } } - if (isInvertedRect()) - m_cachedMyIndex = -1; + if (isInvertedRect()) m_cachedMyIndex = -1; const auto cachedCount = m_cachedRects.size(); for (qsizetype i = 0; i < cachedCount; ++i) { int mask = 0; BlobShape* si = rectShapes[i]; for (qsizetype j = 0; j < cachedCount; ++j) { - if (j == i) - continue; + if (j == i) continue; BlobShape* sj = rectShapes[j]; - if (si->isExcluded(sj) || sj->isExcluded(si)) - mask |= (1 << j); + if (si->isExcluded(sj) || sj->isExcluded(si)) mask |= (1 << j); } m_cachedRects[i].excludeMask = mask; } @@ -242,15 +242,25 @@ void BlobShape::updatePolish() { auto* inv = m_group->invertedRect(); if (inv) { const QPointF invScene = inv->mapToScene(QPointF(0, 0)); - const float outerCX = static_cast(invScene.x() + inv->width() / 2.0); - const float outerCY = static_cast(invScene.y() + inv->height() / 2.0); + const float outerCX = + static_cast(invScene.x() + inv->width() / 2.0); + const float outerCY = + static_cast(invScene.y() + inv->height() / 2.0); const float outerHW = static_cast(inv->width() / 2.0); const float outerHH = static_cast(inv->height() / 2.0); - const float innerCX = outerCX + static_cast((inv->borderLeft() - inv->borderRight()) / 2.0); - const float innerCY = outerCY + static_cast((inv->borderTop() - inv->borderBottom()) / 2.0); - const float innerHW = outerHW - static_cast((inv->borderLeft() + inv->borderRight()) / 2.0); - const float innerHH = outerHH - static_cast((inv->borderTop() + inv->borderBottom()) / 2.0); + const float innerCX = + outerCX + + static_cast((inv->borderLeft() - inv->borderRight()) / 2.0); + const float innerCY = + outerCY + + static_cast((inv->borderTop() - inv->borderBottom()) / 2.0); + const float innerHW = + outerHW - + static_cast((inv->borderLeft() + inv->borderRight()) / 2.0); + const float innerHH = + outerHH - + static_cast((inv->borderTop() + inv->borderBottom()) / 2.0); bool nearBorder = isInvertedRect(); if (!nearBorder) { @@ -259,8 +269,10 @@ void BlobShape::updatePolish() { const float myCY = m_cachedPaddedY + m_cachedPaddedH * 0.5f; const float myHW = m_cachedPaddedW * 0.5f; const float myHH = m_cachedPaddedH * 0.5f; - nearBorder = (myCX - myHW < innerCX - innerHW + margin) || (myCX + myHW > innerCX + innerHW - margin) || - (myCY - myHH < innerCY - innerHH + margin) || (myCY + myHH > innerCY + innerHH - margin); + nearBorder = (myCX - myHW < innerCX - innerHW + margin) || + (myCX + myHW > innerCX + innerHW - margin) || + (myCY - myHH < innerCY - innerHH + margin) || + (myCY + myHH > innerCY + innerHH - margin); } if (nearBorder) { @@ -293,15 +305,33 @@ void BlobShape::updatePolish() { const float cTlX = ri.cx - ri.hw, cTlY = ri.cy - ri.hh; for (qsizetype j = 0; j < rectCount; ++j) { - if (j == i) - continue; - if (riExcludeMask & (1 << j)) - continue; + if (j == i) continue; + if (riExcludeMask & (1 << j)) continue; const auto& rj = m_cachedRects[j]; - fTr = std::min(fTr, cpuSmoothstep(0.0f, smoothFactor, cpuSdBox(cTrX, cTrY, rj.cx, rj.cy, rj.hw, rj.hh))); - fBr = std::min(fBr, cpuSmoothstep(0.0f, smoothFactor, cpuSdBox(cBrX, cBrY, rj.cx, rj.cy, rj.hw, rj.hh))); - fBl = std::min(fBl, cpuSmoothstep(0.0f, smoothFactor, cpuSdBox(cBlX, cBlY, rj.cx, rj.cy, rj.hw, rj.hh))); - fTl = std::min(fTl, cpuSmoothstep(0.0f, smoothFactor, cpuSdBox(cTlX, cTlY, rj.cx, rj.cy, rj.hw, rj.hh))); + fTr = std::min( + fTr, + cpuSmoothstep( + 0.0f, + smoothFactor, + cpuSdBox(cTrX, cTrY, rj.cx, rj.cy, rj.hw, rj.hh))); + fBr = std::min( + fBr, + cpuSmoothstep( + 0.0f, + smoothFactor, + cpuSdBox(cBrX, cBrY, rj.cx, rj.cy, rj.hw, rj.hh))); + fBl = std::min( + fBl, + cpuSmoothstep( + 0.0f, + smoothFactor, + cpuSdBox(cBlX, cBlY, rj.cx, rj.cy, rj.hw, rj.hh))); + fTl = std::min( + fTl, + cpuSmoothstep( + 0.0f, + smoothFactor, + cpuSdBox(cTlX, cTlY, rj.cx, rj.cy, rj.hw, rj.hh))); } if (m_cachedHasInverted) { @@ -309,10 +339,30 @@ void BlobShape::updatePolish() { const float icy = m_cachedInvertedInner[1]; const float ihw = m_cachedInvertedInner[2]; const float ihh = m_cachedInvertedInner[3]; - fTr = std::min(fTr, cpuSmoothstep(0.0f, smoothFactor, -cpuSdBox(cTrX, cTrY, icx, icy, ihw, ihh))); - fBr = std::min(fBr, cpuSmoothstep(0.0f, smoothFactor, -cpuSdBox(cBrX, cBrY, icx, icy, ihw, ihh))); - fBl = std::min(fBl, cpuSmoothstep(0.0f, smoothFactor, -cpuSdBox(cBlX, cBlY, icx, icy, ihw, ihh))); - fTl = std::min(fTl, cpuSmoothstep(0.0f, smoothFactor, -cpuSdBox(cTlX, cTlY, icx, icy, ihw, ihh))); + fTr = std::min( + fTr, + cpuSmoothstep( + 0.0f, + smoothFactor, + -cpuSdBox(cTrX, cTrY, icx, icy, ihw, ihh))); + fBr = std::min( + fBr, + cpuSmoothstep( + 0.0f, + smoothFactor, + -cpuSdBox(cBrX, cBrY, icx, icy, ihw, ihh))); + fBl = std::min( + fBl, + cpuSmoothstep( + 0.0f, + smoothFactor, + -cpuSdBox(cBlX, cBlY, icx, icy, ihw, ihh))); + fTl = std::min( + fTl, + cpuSmoothstep( + 0.0f, + smoothFactor, + -cpuSdBox(cTlX, cTlY, icx, icy, ihw, ihh))); } ri.radius[0] = std::max(ri.radius[0] * fTr, minR); @@ -332,7 +382,8 @@ QSGNode* BlobShape::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { if (!node) { node = new QSGGeometryNode; - auto* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); + auto* geometry = + new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); geometry->setDrawingMode(QSGGeometry::DrawTriangleStrip); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); @@ -368,10 +419,17 @@ QSGNode* BlobShape::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { material->m_color = m_group->color(); material->m_hasInverted = m_cachedHasInverted ? 1 : 0; material->m_invertedRadius = m_cachedInvertedRadius; - memcpy(material->m_invertedOuter, m_cachedInvertedOuter, sizeof(m_cachedInvertedOuter)); - memcpy(material->m_invertedInner, m_cachedInvertedInner, sizeof(m_cachedInvertedInner)); + memcpy( + material->m_invertedOuter, + m_cachedInvertedOuter, + sizeof(m_cachedInvertedOuter)); + memcpy( + material->m_invertedInner, + m_cachedInvertedInner, + sizeof(m_cachedInvertedInner)); - const int count = static_cast(qMin(m_cachedRects.size(), qsizetype(16))); + const int count = + static_cast(qMin(m_cachedRects.size(), qsizetype(16))); material->m_rectCount = count; for (int i = 0; i < count; ++i) material->m_rects[i] = m_cachedRects[i]; diff --git a/Plugins/ZShell/Blobs/blobshape.hpp b/Plugins/ZShell/Blobs/blobshape.hpp index 12c8747..55fb592 100644 --- a/Plugins/ZShell/Blobs/blobshape.hpp +++ b/Plugins/ZShell/Blobs/blobshape.hpp @@ -9,85 +9,78 @@ class BlobGroup; class BlobShape : public QQuickItem { -Q_OBJECT -Q_PROPERTY(BlobGroup* group READ group WRITE setGroup NOTIFY groupChanged) -Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) -Q_PROPERTY(QMatrix4x4 deformMatrix READ deformMatrix NOTIFY deformMatrixChanged) -Q_PROPERTY(QMatrix4x4 rawDeformMatrix READ rawDeformMatrix NOTIFY rawDeformMatrixChanged) + Q_OBJECT + Q_PROPERTY(BlobGroup* group READ group WRITE setGroup NOTIFY groupChanged) + Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) + Q_PROPERTY( + QMatrix4x4 deformMatrix READ deformMatrix NOTIFY deformMatrixChanged) + Q_PROPERTY( + QMatrix4x4 rawDeformMatrix READ rawDeformMatrix NOTIFY + rawDeformMatrixChanged) -friend class BlobGroup; + friend class BlobGroup; -public: -explicit BlobShape(QQuickItem* parent = nullptr); -~BlobShape() override = default; + public: + explicit BlobShape(QQuickItem* parent = nullptr); + ~BlobShape() override = default; -[[nodiscard]] BlobGroup* group() const { - return m_group; -} + [[nodiscard]] BlobGroup* group() const { return m_group; } -void setGroup(BlobGroup* g); + void setGroup(BlobGroup* g); -[[nodiscard]] qreal radius() const { - return m_radius; -} + [[nodiscard]] qreal radius() const { return m_radius; } -void setRadius(qreal r); + void setRadius(qreal r); -[[nodiscard]] QMatrix4x4 deformMatrix() const { - return m_centeredDeformMatrix; -} + [[nodiscard]] QMatrix4x4 deformMatrix() const { + return m_centeredDeformMatrix; + } -[[nodiscard]] QMatrix4x4 rawDeformMatrix() const { - return m_deformMatrix; -} + [[nodiscard]] QMatrix4x4 rawDeformMatrix() const { return m_deformMatrix; } -signals: -void groupChanged(); -void radiusChanged(); -void deformMatrixChanged(); -void rawDeformMatrixChanged(); + signals: + void groupChanged(); + void radiusChanged(); + void deformMatrixChanged(); + void rawDeformMatrixChanged(); -protected: -void componentComplete() override; -void geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry) override; -void updatePolish() override; -QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) override; + protected: + void componentComplete() override; + void geometryChange( + const QRectF& newGeometry, const QRectF& oldGeometry) override; + void updatePolish() override; + QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) override; -[[nodiscard]] virtual bool isInvertedRect() const { - return false; -} + [[nodiscard]] virtual bool isInvertedRect() const { return false; } -virtual bool isExcluded(const BlobShape* /*other*/) const { - return false; -} + virtual bool isExcluded(const BlobShape*) const { return false; } -virtual void cornerRadii(float out[4]) const; + virtual void cornerRadii(float out[4]) const; -virtual void updatePhysics() { -} + virtual void updatePhysics() {} -virtual void registerWithGroup(); -virtual void unregisterFromGroup(); -void updateCenteredDeformMatrix(); + virtual void registerWithGroup(); + virtual void unregisterFromGroup(); + void updateCenteredDeformMatrix(); -BlobGroup* m_group = nullptr; -qreal m_radius = 0; -QMatrix4x4 m_deformMatrix; -QMatrix4x4 m_centeredDeformMatrix; + BlobGroup* m_group = nullptr; + qreal m_radius = 0; + QMatrix4x4 m_deformMatrix; + QMatrix4x4 m_centeredDeformMatrix; -float m_cachedPaddedX = 0; -float m_cachedPaddedY = 0; -float m_cachedPaddedW = 0; -float m_cachedPaddedH = 0; -QRectF m_localPaddedRect; -QVector m_cachedRects; -int m_cachedMyIndex = -2; -float m_pendingDx = 0; -float m_pendingDy = 0; -float m_pendingDw = 0; -float m_pendingDh = 0; -bool m_cachedHasInverted = false; -float m_cachedInvertedRadius = 0; -float m_cachedInvertedOuter[4] = {}; -float m_cachedInvertedInner[4] = {}; + float m_cachedPaddedX = 0; + float m_cachedPaddedY = 0; + float m_cachedPaddedW = 0; + float m_cachedPaddedH = 0; + QRectF m_localPaddedRect; + QVector m_cachedRects; + int m_cachedMyIndex = -2; + float m_pendingDx = 0; + float m_pendingDy = 0; + float m_pendingDw = 0; + float m_pendingDh = 0; + bool m_cachedHasInverted = false; + float m_cachedInvertedRadius = 0; + float m_cachedInvertedOuter[4] = {}; + float m_cachedInvertedInner[4] = {}; }; diff --git a/Plugins/ZShell/Components/buttonrow.cpp b/Plugins/ZShell/Components/buttonrow.cpp index a56ad33..7da35c9 100644 --- a/Plugins/ZShell/Components/buttonrow.cpp +++ b/Plugins/ZShell/Components/buttonrow.cpp @@ -3,11 +3,10 @@ namespace ZShell::components { ButtonRow::ButtonRow(QQuickItem* parent) - : QQuickItem(parent) - , m_dirty(false) - , m_spacing(0.0) { + : QQuickItem(parent), m_dirty(false), m_spacing(0.0) { setFlag(QQuickItem::ItemHasContents, true); - QObject::connect(this, &ButtonRow::widthChanged, this, &ButtonRow::invalidate); + QObject::connect( + this, &ButtonRow::widthChanged, this, &ButtonRow::invalidate); } qreal ButtonRow::spacing() const { @@ -15,8 +14,7 @@ qreal ButtonRow::spacing() const { } void ButtonRow::setSpacing(qreal spacing) { - if (qFuzzyCompare(m_spacing + 1.0, spacing + 1.0)) - return; + if (qFuzzyCompare(m_spacing + 1.0, spacing + 1.0)) return; m_spacing = spacing; emit spacingChanged(); @@ -24,18 +22,33 @@ void ButtonRow::setSpacing(qreal spacing) { invalidate(); } -void ButtonRow::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData& data) { +void ButtonRow::itemChange( + QQuickItem::ItemChange change, const QQuickItem::ItemChangeData& data) { if (change == QQuickItem::ItemChildAddedChange) { auto* const child = data.item; - QObject::connect(child, &QQuickItem::implicitWidthChanged, this, &ButtonRow::invalidate); - QObject::connect(child, &QQuickItem::implicitHeightChanged, this, &ButtonRow::invalidate); - QObject::connect(child, &QQuickItem::visibleChanged, this, &ButtonRow::invalidate); + QObject::connect( + child, + &QQuickItem::implicitWidthChanged, + this, + &ButtonRow::invalidate); + QObject::connect( + child, + &QQuickItem::implicitHeightChanged, + this, + &ButtonRow::invalidate); + QObject::connect( + child, &QQuickItem::visibleChanged, this, &ButtonRow::invalidate); const auto* childMeta = child->metaObject(); - const auto morphSignalIdx = childMeta->indexOfSignal("shapeMorphExpansionChanged()"); + const auto morphSignalIdx = + childMeta->indexOfSignal("shapeMorphExpansionChanged()"); if (morphSignalIdx != -1) - QObject::connect(child, childMeta->method(morphSignalIdx), this, - metaObject()->method(metaObject()->indexOfSlot("invalidate()"))); + QObject::connect( + child, + childMeta->method(morphSignalIdx), + this, + metaObject()->method( + metaObject()->indexOfSlot("invalidate()"))); invalidate(); } else if (change == QQuickItem::ItemChildRemovedChange) { @@ -77,8 +90,7 @@ void ButtonRow::relayout() { maxHeight = qMax(maxHeight, child->implicitHeight()); const auto prop = child->property("fillWidth"); - if (!prop.isValid()) - continue; + if (!prop.isValid()) continue; if (prop.toBool()) { fillWidthCount++; @@ -88,15 +100,17 @@ void ButtonRow::relayout() { } } - if (fillWidthCount == 0) - fillWidthCount = 1; // Avoid divide by 0 + if (fillWidthCount == 0) fillWidthCount = 1; // Avoid divide by 0 - const auto widthPerItem = (width() - totalSpacing - reservedWidth) / static_cast(fillWidthCount); + const auto widthPerItem = (width() - totalSpacing - reservedWidth) / + static_cast(fillWidthCount); QList baseWidths; baseWidths.reserve(nChildren); for (auto* const child : validChildren) - baseWidths.append(child->property("fillWidth").toBool() ? widthPerItem : child->implicitWidth()); + baseWidths.append( + child->property("fillWidth").toBool() ? widthPerItem + : child->implicitWidth()); qreal accX = 0; for (int i = 0; i < nChildren; ++i) { @@ -108,12 +122,12 @@ void ButtonRow::relayout() { // clang-format on // Items at edges push by full amount, items in middle push by half - if (i > 1) - prevExtraWidth /= 2; - if (i < nChildren - 2) - nextExtraWidth /= 2; + if (i > 1) prevExtraWidth /= 2; + if (i < nChildren - 2) nextExtraWidth /= 2; - child->setWidth(baseWidths[i] + getMorphExpansion(child) - prevExtraWidth - nextExtraWidth); + child->setWidth( + baseWidths[i] + getMorphExpansion(child) - prevExtraWidth - + nextExtraWidth); child->setHeight(maxHeight); child->setX(accX); diff --git a/Plugins/ZShell/Components/buttonrow.hpp b/Plugins/ZShell/Components/buttonrow.hpp index 4c5f13d..e2417e6 100644 --- a/Plugins/ZShell/Components/buttonrow.hpp +++ b/Plugins/ZShell/Components/buttonrow.hpp @@ -5,33 +5,34 @@ namespace ZShell::components { class ButtonRow : public QQuickItem { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) -public: -explicit ButtonRow(QQuickItem* parent = nullptr); + public: + explicit ButtonRow(QQuickItem* parent = nullptr); -[[nodiscard]] qreal spacing() const; -void setSpacing(qreal spacing); + [[nodiscard]] qreal spacing() const; + void setSpacing(qreal spacing); -signals: -void spacingChanged(); + signals: + void spacingChanged(); -protected: -void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData& data) override; -void updatePolish() override; + protected: + void itemChange( + QQuickItem::ItemChange change, + const QQuickItem::ItemChangeData& data) override; + void updatePolish() override; -private slots: -void invalidate(); + private slots: + void invalidate(); -private: -void relayout(); -static qreal getMorphExpansion(const QQuickItem* item); + void relayout(); + static qreal getMorphExpansion(const QQuickItem* item); -bool m_dirty; -qreal m_spacing; + bool m_dirty; + qreal m_spacing; }; } // namespace ZShell::components diff --git a/Plugins/ZShell/Components/lazylistview.cpp b/Plugins/ZShell/Components/lazylistview.cpp index 0fc9438..ede9d62 100644 --- a/Plugins/ZShell/Components/lazylistview.cpp +++ b/Plugins/ZShell/Components/lazylistview.cpp @@ -21,8 +21,7 @@ qreal LazyListViewAttached::preferredHeight() const { } void LazyListViewAttached::setPreferredHeight(qreal height) { - if (qFuzzyCompare(m_preferredHeight + 1.0, height + 1.0)) - return; + if (qFuzzyCompare(m_preferredHeight + 1.0, height + 1.0)) return; m_preferredHeight = height; emit preferredHeightChanged(); } @@ -32,8 +31,7 @@ qreal LazyListViewAttached::visibleHeight() const { } void LazyListViewAttached::setVisibleHeight(qreal height) { - if (qFuzzyCompare(m_visibleHeight + 1.0, height + 1.0)) - return; + if (qFuzzyCompare(m_visibleHeight + 1.0, height + 1.0)) return; m_visibleHeight = height; emit visibleHeightChanged(); } @@ -43,8 +41,7 @@ bool LazyListViewAttached::ready() const { } void LazyListViewAttached::setReady(bool ready) { - if (m_ready == ready) - return; + if (m_ready == ready) return; m_ready = ready; emit readyChanged(); } @@ -54,8 +51,7 @@ bool LazyListViewAttached::adding() const { } void LazyListViewAttached::setAdding(bool adding) { - if (m_adding == adding) - return; + if (m_adding == adding) return; m_adding = adding; emit addingChanged(); } @@ -65,8 +61,7 @@ bool LazyListViewAttached::removing() const { } void LazyListViewAttached::setRemoving(bool removing) { - if (m_removing == removing) - return; + if (m_removing == removing) return; m_removing = removing; emit removingChanged(); } @@ -76,8 +71,7 @@ bool LazyListViewAttached::trackViewport() const { } void LazyListViewAttached::setTrackViewport(bool track) { - if (m_trackViewport == track) - return; + if (m_trackViewport == track) return; m_trackViewport = track; emit trackViewportChanged(); } @@ -102,16 +96,13 @@ QAbstractItemModel* LazyListView::model() const { } void LazyListView::setModel(QAbstractItemModel* model) { - if (m_model == model) - return; + if (m_model == model) return; - if (m_model) - disconnectModel(); + if (m_model) disconnectModel(); m_model = model; - if (m_model) - connectModel(); + if (m_model) connectModel(); resetContent(); emit modelChanged(); @@ -122,8 +113,7 @@ QQmlComponent* LazyListView::delegate() const { } void LazyListView::setDelegate(QQmlComponent* delegate) { - if (m_delegate == delegate) - return; + if (m_delegate == delegate) return; m_delegate = delegate; resetContent(); @@ -135,8 +125,7 @@ qreal LazyListView::spacing() const { } void LazyListView::setSpacing(qreal spacing) { - if (qFuzzyCompare(m_spacing, spacing)) - return; + if (qFuzzyCompare(m_spacing, spacing)) return; m_spacing = spacing; emit spacingChanged(); polish(); @@ -155,8 +144,7 @@ qreal LazyListView::contentY() const { } void LazyListView::setContentY(qreal contentY) { - if (qFuzzyCompare(m_contentY, contentY)) - return; + if (qFuzzyCompare(m_contentY, contentY)) return; m_contentY = contentY; emit contentYChanged(); polish(); @@ -167,12 +155,10 @@ QRectF LazyListView::viewport() const { } void LazyListView::setViewport(const QRectF& viewport) { - if (m_viewport == viewport) - return; + if (m_viewport == viewport) return; m_viewport = viewport; emit viewportChanged(); - if (m_useCustomViewport) - polish(); + if (m_useCustomViewport) polish(); } bool LazyListView::useCustomViewport() const { @@ -180,8 +166,7 @@ bool LazyListView::useCustomViewport() const { } void LazyListView::setUseCustomViewport(bool use) { - if (m_useCustomViewport == use) - return; + if (m_useCustomViewport == use) return; m_useCustomViewport = use; emit useCustomViewportChanged(); polish(); @@ -192,8 +177,7 @@ qreal LazyListView::cacheBuffer() const { } void LazyListView::setCacheBuffer(qreal buffer) { - if (qFuzzyCompare(m_cacheBuffer, buffer)) - return; + if (qFuzzyCompare(m_cacheBuffer, buffer)) return; m_cacheBuffer = buffer; emit cacheBufferChanged(); polish(); @@ -204,8 +188,7 @@ qreal LazyListView::estimatedHeight() const { } void LazyListView::setEstimatedHeight(qreal height) { - if (qFuzzyCompare(m_estimatedHeight, height)) - return; + if (qFuzzyCompare(m_estimatedHeight, height)) return; m_estimatedHeight = height; emit estimatedHeightChanged(); polish(); @@ -216,17 +199,14 @@ bool LazyListView::asynchronous() const { } void LazyListView::setAsynchronous(bool async) { - if (m_asynchronous == async) - return; + if (m_asynchronous == async) return; m_asynchronous = async; emit asynchronousChanged(); } qreal LazyListView::effectiveEstimatedHeight() const { - if (m_estimatedHeight >= 0) - return m_estimatedHeight; - if (m_knownHeightCount > 0) - return m_knownHeightSum / m_knownHeightCount; + if (m_estimatedHeight >= 0) return m_estimatedHeight; + if (m_knownHeightCount > 0) return m_knownHeightSum / m_knownHeightCount; return 40; } @@ -241,8 +221,7 @@ void LazyListView::untrackHeight(qreal height) { } qreal LazyListView::delegateHeight(QQuickItem* item) { - if (!item) - return 0; + if (!item) return 0; auto* attached = qobject_cast( qmlAttachedPropertiesObject(item, false)); @@ -253,14 +232,12 @@ qreal LazyListView::delegateHeight(QQuickItem* item) { } qreal LazyListView::delegateVisibleHeight(QQuickItem* item) { - if (!item) - return 0; + if (!item) return 0; auto* attached = qobject_cast( qmlAttachedPropertiesObject(item, false)); if (attached) { - if (attached->visibleHeight() >= 0) - return attached->visibleHeight(); + if (attached->visibleHeight() >= 0) return attached->visibleHeight(); if (attached->preferredHeight() >= 0) return attached->preferredHeight(); } @@ -269,8 +246,7 @@ qreal LazyListView::delegateVisibleHeight(QQuickItem* item) { } bool LazyListView::isDelegateReady(QQuickItem* item) { - if (!item) - return false; + if (!item) return false; auto* att = qobject_cast( qmlAttachedPropertiesObject(item, false)); return !att || att->ready(); @@ -281,8 +257,7 @@ int LazyListView::removeDuration() const { } void LazyListView::setRemoveDuration(int duration) { - if (m_removeDuration == duration) - return; + if (m_removeDuration == duration) return; m_removeDuration = duration; emit removeDurationChanged(); } @@ -292,8 +267,7 @@ int LazyListView::readyDelay() const { } void LazyListView::setReadyDelay(int delay) { - if (m_readyDelay == delay) - return; + if (m_readyDelay == delay) return; m_readyDelay = delay; emit readyDelayChanged(); } @@ -308,17 +282,15 @@ void LazyListView::componentComplete() { resetContent(); } -void LazyListView::geometryChange(const QRectF& newGeometry, - const QRectF& oldGeometry) { +void LazyListView::geometryChange( + const QRectF& newGeometry, const QRectF& oldGeometry) { QQuickItem::geometryChange(newGeometry, oldGeometry); - if (!m_componentComplete) - return; + if (!m_componentComplete) return; if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) { for (auto& entry : m_delegates) { - if (entry.item) - entry.item->setWidth(newGeometry.width()); + if (entry.item) entry.item->setWidth(newGeometry.width()); } } @@ -326,8 +298,7 @@ void LazyListView::geometryChange(const QRectF& newGeometry, } void LazyListView::updatePolish() { - if (!m_componentComplete || !m_model || !m_delegate) - return; + if (!m_componentComplete || !m_model || !m_delegate) return; // Flush pending inserts — make items visible and clear the adding flag // so enter animations begin. When readyDelay > 0 the entire insert is @@ -335,9 +306,9 @@ void LazyListView::updatePolish() { // Collect pending indices first — avoids scanning the entire hash each frame QList pendingIndices; - for (auto it = m_delegates.constBegin(); it != m_delegates.constEnd(); ++it) { - if (it->pendingInsert && it->item) - pendingIndices.append(it.key()); + for (auto it = m_delegates.constBegin(); it != m_delegates.constEnd(); + ++it) { + if (it->pendingInsert && it->item) pendingIndices.append(it.key()); } for (int pendingIdx : pendingIndices) { @@ -349,8 +320,7 @@ void LazyListView::updatePolish() { auto* item = entry.item; QTimer::singleShot(m_readyDelay, this, [this, item] { auto indexIt = m_itemToIndex.find(item); - if (indexIt == m_itemToIndex.end()) - return; + if (indexIt == m_itemToIndex.end()) return; const int idx = indexIt.value(); auto it = m_delegates.find(idx); if (it == m_delegates.end() || it->item != item || @@ -375,14 +345,11 @@ void LazyListView::updatePolish() { ? m_layout[i].height : effectiveEstimatedHeight(); if (h > 0) { - if (hasVisItem) - visualY += m_spacing; + if (hasVisItem) visualY += m_spacing; hasVisItem = true; } - if (i == idx) - break; - if (h > 0) - visualY += h; + if (i == idx) break; + if (h > 0) visualY += h; } item->setY(visualY - m_contentY); } @@ -397,8 +364,8 @@ void LazyListView::updatePolish() { // Animate from visual position to layout position if (idx >= 0 && idx < static_cast(m_layout.size())) - item->setProperty("y", - m_layout[idx].targetY - m_contentY); + item->setProperty( + "y", m_layout[idx].targetY - m_contentY); polish(); }); @@ -432,8 +399,7 @@ void LazyListView::updatePolish() { continue; const int idx = entry.modelIndex; - if (idx < 0 || idx >= layoutSize) - continue; + if (idx < 0 || idx >= layoutSize) continue; if (m_layout[idx].heightKnown && qFuzzyIsNull(m_layout[idx].height)) continue; @@ -444,8 +410,6 @@ void LazyListView::updatePolish() { } } -// --- Layout Engine --- - void LazyListView::relayout() { // Layout positioning uses preferredHeight (final/non-animated). // Only add spacing between items with non-zero height. @@ -455,8 +419,7 @@ void LazyListView::relayout() { const qreal layoutH = record.heightKnown ? record.height : effectiveEstimatedHeight(); if (layoutH > 0) { - if (hasLayoutItem) - y += m_spacing; + if (hasLayoutItem) y += m_spacing; hasLayoutItem = true; record.targetY = y; y += layoutH; @@ -483,8 +446,7 @@ void LazyListView::relayout() { h = m_layout[i].heightKnown ? m_layout[i].height : effectiveEstimatedHeight(); if (h > 0) { - if (hasVisItem) - visY += m_spacing; + if (hasVisItem) visY += m_spacing; hasVisItem = true; visY += h; } @@ -492,11 +454,9 @@ void LazyListView::relayout() { // Account for dying delegates still visually present for (const auto& dying : std::as_const(m_dyingDelegates)) { - if (!dying.item) - continue; + if (!dying.item) continue; const qreal dyingH = delegateVisibleHeight(dying.item); - if (dyingH > 0) - visY = std::max(visY, dying.item->y() + dyingH); + if (dyingH > 0) visY = std::max(visY, dying.item->y() + dyingH); } if (!qFuzzyCompare(m_contentHeight + 1.0, visY + 1.0)) { @@ -519,8 +479,7 @@ QRectF LazyListView::effectiveViewport() const { if (!m_useCustomViewport && m_layoutHeight > 0) { const qreal top = std::min(vp.y(), m_layoutHeight); const qreal bottom = std::max(vp.y() + vp.height(), 0.0); - if (bottom > top) - vp = QRectF(vp.x(), top, vp.width(), bottom - top); + if (bottom > top) vp = QRectF(vp.x(), top, vp.width(), bottom - top); } vp.adjust(0, -m_cacheBuffer, 0, m_cacheBuffer); @@ -541,12 +500,10 @@ QRectF LazyListView::effectiveViewport() const { } std::pair LazyListView::computeVisibleRange() const { - if (m_layout.isEmpty()) - return {-1, -1}; + if (m_layout.isEmpty()) return {-1, -1}; const auto vp = effectiveViewport(); - if (vp.isEmpty()) - return {-1, -1}; + if (vp.isEmpty()) return {-1, -1}; const qreal vpTop = vp.y(); const qreal vpBottom = vp.y() + vp.height(); @@ -571,22 +528,18 @@ std::pair LazyListView::computeVisibleRange() const { } } - if (first >= static_cast(m_layout.size())) - return {-1, -1}; + if (first >= static_cast(m_layout.size())) return {-1, -1}; // Linear scan for last visible item int last = first; for (int i = first; i < static_cast(m_layout.size()); ++i) { - if (m_layout[i].targetY > vpBottom) - break; + if (m_layout[i].targetY > vpBottom) break; last = i; } return {first, last}; } -// --- Delegate Lifecycle --- - void LazyListView::syncDelegates() { const auto [first, last] = computeVisibleRange(); @@ -601,8 +554,7 @@ void LazyListView::syncDelegates() { const auto vp = effectiveViewport(); QList toRemove; for (auto it = m_delegates.begin(); it != m_delegates.end(); ++it) { - if (visibleIndices.contains(it.key())) - continue; + if (visibleIndices.contains(it.key())) continue; if (!it->item || vp.isEmpty()) { toRemove.append(it.key()); continue; @@ -622,11 +574,9 @@ void LazyListView::syncDelegates() { std::min(destroyBudget, static_cast(toRemove.size()))); int destroyed = 0; for (int idx : toRemove) { - if (destroyed >= destroyBudget) - break; + if (destroyed >= destroyBudget) break; auto entry = m_delegates.take(idx); - if (entry.item) - m_itemToIndex.remove(entry.item); + if (entry.item) m_itemToIndex.remove(entry.item); removedEntries.append(std::move(entry)); ++destroyed; } @@ -637,8 +587,7 @@ void LazyListView::syncDelegates() { QList toCreate; if (first >= 0) { for (int i = first; i <= last; ++i) { - if (!m_delegates.contains(i)) - toCreate.append(i); + if (!m_delegates.contains(i)) toCreate.append(i); } } @@ -647,8 +596,7 @@ void LazyListView::syncDelegates() { : static_cast(toCreate.size()); int created = 0; for (int i : toCreate) { - if (created >= createBudget) - break; + if (created >= createBudget) break; auto entry = createDelegate(i); if (entry.item) { @@ -674,25 +622,21 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) { DelegateEntry entry; entry.modelIndex = modelIndex; - if (!m_delegate || !m_model) - return entry; + if (!m_delegate || !m_model) return entry; const auto roleNames = m_model->roleNames(); // Use the delegate component's creation context for beginCreate // so bound components (pragma ComponentBehavior: Bound) are accepted. auto* compContext = m_delegate->creationContext(); - if (!compContext) - compContext = qmlContext(this); - if (!compContext) - return entry; + if (!compContext) compContext = qmlContext(this); + if (!compContext) return entry; auto* obj = m_delegate->beginCreate(compContext); entry.item = qobject_cast(obj); if (!entry.item) { - if (obj) - m_delegate->completeCreate(); + if (obj) m_delegate->completeCreate(); delete obj; return entry; } @@ -705,16 +649,15 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) { for (auto it = roleNames.constBegin(); it != roleNames.constEnd(); ++it) { const auto name = QString::fromUtf8(it.value()); initialProps.insert(name, m_model->data(index, it.key())); - if (name == QStringLiteral("modelData")) - hasModelData = true; + if (name == QStringLiteral("modelData")) hasModelData = true; } initialProps.insert(QStringLiteral("index"), modelIndex); if (!hasModelData) { const auto role = roleNames.isEmpty() ? Qt::DisplayRole : roleNames.constBegin().key(); - initialProps.insert(QStringLiteral("modelData"), - m_model->data(index, role)); + initialProps.insert( + QStringLiteral("modelData"), m_model->data(index, role)); } m_delegate->setInitialProperties(entry.item, initialProps); @@ -728,8 +671,7 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) { m_layout[modelIndex].isNew) { auto* addingAttached = qobject_cast( qmlAttachedPropertiesObject(entry.item, true)); - if (addingAttached) - addingAttached->setAdding(true); + if (addingAttached) addingAttached->setAdding(true); } m_delegate->completeCreate(); @@ -740,15 +682,12 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) { // Height-change handler — uses m_itemToIndex for O(1) lookup. // Ignored while the delegate is not yet ready. auto onHeightChanged = [this, item = entry.item] { - if (!isDelegateReady(item)) - return; + if (!isDelegateReady(item)) return; auto indexIt = m_itemToIndex.find(item); - if (indexIt == m_itemToIndex.end()) - return; + if (indexIt == m_itemToIndex.end()) return; const int idx = indexIt.value(); auto delegateIt = m_delegates.find(idx); - if (delegateIt == m_delegates.end() || delegateIt->item != item) - return; + if (delegateIt == m_delegates.end() || delegateIt->item != item) return; const qreal h = delegateHeight(item); if (idx < static_cast(m_layout.size()) && !qFuzzyCompare(m_layout[idx].height + 1.0, h + 1.0)) { @@ -756,8 +695,7 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) { const bool wasKnown = m_layout[idx].heightKnown; m_layout[idx].height = h; m_layout[idx].heightKnown = true; - if (wasKnown) - untrackHeight(oldH); + if (wasKnown) untrackHeight(oldH); trackHeight(h); // If this tracked item is above the viewport, emit a @@ -785,58 +723,56 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) { }; // Watch implicitHeight as fallback - connect(entry.item, - &QQuickItem::implicitHeightChanged, - this, - onHeightChanged); + connect( + entry.item, &QQuickItem::implicitHeightChanged, this, onHeightChanged); // Watch attached properties if the delegate uses them auto* attached = qobject_cast( qmlAttachedPropertiesObject(entry.item, false)); if (attached) { - connect(attached, - &LazyListViewAttached::preferredHeightChanged, - this, - onHeightChanged); - connect(attached, - &LazyListViewAttached::visibleHeightChanged, - this, - [this] { polish(); }); - connect(attached, - &LazyListViewAttached::readyChanged, - this, - [this, item = entry.item] { - auto indexIt = m_itemToIndex.find(item); - if (indexIt == m_itemToIndex.end()) - return; - const int idx = indexIt.value(); - if (idx >= static_cast(m_layout.size())) - return; - auto* att = qobject_cast( - qmlAttachedPropertiesObject(item, false)); - if (!att || !att->ready()) - return; + connect( + attached, + &LazyListViewAttached::preferredHeightChanged, + this, + onHeightChanged); + connect( + attached, + &LazyListViewAttached::visibleHeightChanged, + this, + [this] { polish(); }); + connect( + attached, + &LazyListViewAttached::readyChanged, + this, + [this, item = entry.item] { + auto indexIt = m_itemToIndex.find(item); + if (indexIt == m_itemToIndex.end()) return; + const int idx = indexIt.value(); + if (idx >= static_cast(m_layout.size())) return; + auto* att = qobject_cast( + qmlAttachedPropertiesObject(item, false)); + if (!att || !att->ready()) return; - const qreal h = delegateHeight(item); - const qreal oldLayoutH = m_layout[idx].heightKnown - ? m_layout[idx].height - : effectiveEstimatedHeight(); - if (m_layout[idx].heightKnown) - untrackHeight(m_layout[idx].height); - m_layout[idx].height = h; - m_layout[idx].heightKnown = true; - trackHeight(h); + const qreal h = delegateHeight(item); + const qreal oldLayoutH = m_layout[idx].heightKnown + ? m_layout[idx].height + : effectiveEstimatedHeight(); + if (m_layout[idx].heightKnown) + untrackHeight(m_layout[idx].height); + m_layout[idx].height = h; + m_layout[idx].heightKnown = true; + trackHeight(h); - if (att->trackViewport() && - !qFuzzyCompare(h + 1.0, oldLayoutH + 1.0)) { - const qreal vpTop = m_useCustomViewport ? m_viewport.y() - : m_contentY; - if (m_layout[idx].targetY < vpTop) - emit viewportAdjustNeeded(h - oldLayoutH); - } + if (att->trackViewport() && + !qFuzzyCompare(h + 1.0, oldLayoutH + 1.0)) { + const qreal vpTop = m_useCustomViewport ? m_viewport.y() + : m_contentY; + if (m_layout[idx].targetY < vpTop) + emit viewportAdjustNeeded(h - oldLayoutH); + } - polish(); - }); + polish(); + }); } return entry; @@ -852,8 +788,7 @@ void LazyListView::destroyDelegate(DelegateEntry& entry) { } void LazyListView::updateDelegateData(DelegateEntry& entry) { - if (!m_model || !entry.item) - return; + if (!m_model || !entry.item) return; const auto roleNames = m_model->roleNames(); const auto index = m_model->index(entry.modelIndex, 0); @@ -861,10 +796,9 @@ void LazyListView::updateDelegateData(DelegateEntry& entry) { for (auto it = roleNames.constBegin(); it != roleNames.constEnd(); ++it) { const auto name = QString::fromUtf8(it.value()); - entry.item->setProperty(name.toUtf8().constData(), - m_model->data(index, it.key())); - if (name == QStringLiteral("modelData")) - hasModelData = true; + entry.item->setProperty( + name.toUtf8().constData(), m_model->data(index, it.key())); + if (name == QStringLiteral("modelData")) hasModelData = true; } entry.item->setProperty("index", entry.modelIndex); @@ -876,53 +810,58 @@ void LazyListView::updateDelegateData(DelegateEntry& entry) { } } -// --- Model Connection --- - void LazyListView::connectModel() { - if (!m_model) - return; + if (!m_model) return; m_modelConnections = { - connect(m_model, - &QAbstractItemModel::rowsInserted, - this, - &LazyListView::onRowsInserted), - connect(m_model, - &QAbstractItemModel::rowsAboutToBeRemoved, - this, - &LazyListView::onRowsAboutToBeRemoved), - connect(m_model, - &QAbstractItemModel::rowsRemoved, - this, - &LazyListView::onRowsRemoved), - connect(m_model, - &QAbstractItemModel::rowsMoved, - this, - &LazyListView::onRowsMoved), - connect(m_model, - &QAbstractItemModel::dataChanged, - this, - &LazyListView::onDataChanged), - connect(m_model, - &QAbstractItemModel::modelReset, - this, - &LazyListView::onModelReset), - connect(m_model, - &QAbstractItemModel::layoutChanged, - this, - [this] { - for (auto& entry : m_delegates) - updateDelegateData(entry); - polish(); - }), - connect(m_model, - &QObject::destroyed, - this, - [this] { - m_model = nullptr; - resetContent(); - emit modelChanged(); - }), + connect( + m_model, + &QAbstractItemModel::rowsInserted, + this, + &LazyListView::onRowsInserted), + connect( + m_model, + &QAbstractItemModel::rowsAboutToBeRemoved, + this, + &LazyListView::onRowsAboutToBeRemoved), + connect( + m_model, + &QAbstractItemModel::rowsRemoved, + this, + &LazyListView::onRowsRemoved), + connect( + m_model, + &QAbstractItemModel::rowsMoved, + this, + &LazyListView::onRowsMoved), + connect( + m_model, + &QAbstractItemModel::dataChanged, + this, + &LazyListView::onDataChanged), + connect( + m_model, + &QAbstractItemModel::modelReset, + this, + &LazyListView::onModelReset), + connect( + m_model, + &QAbstractItemModel::layoutChanged, + this, + [this] { + for (auto& entry : m_delegates) + updateDelegateData(entry); + polish(); + }), + connect( + m_model, + &QObject::destroyed, + this, + [this] { + m_model = nullptr; + resetContent(); + emit modelChanged(); + }), }; } @@ -962,11 +901,9 @@ void LazyListView::resetContent() { polish(); } -void LazyListView::onRowsInserted(const QModelIndex& parent, - int first, - int last) { - if (parent.isValid()) - return; +void LazyListView::onRowsInserted( + const QModelIndex& parent, int first, int last) { + if (parent.isValid()) return; const int insertCount = last - first + 1; // Insert new layout records @@ -990,19 +927,15 @@ void LazyListView::onRowsInserted(const QModelIndex& parent, polish(); } -void LazyListView::onRowsAboutToBeRemoved(const QModelIndex& parent, - int first, - int last) { - if (parent.isValid()) - return; +void LazyListView::onRowsAboutToBeRemoved( + const QModelIndex& parent, int first, int last) { + if (parent.isValid()) return; for (int i = first; i <= last; ++i) { - if (!m_delegates.contains(i)) - continue; + if (!m_delegates.contains(i)) continue; auto entry = m_delegates.take(i); - if (entry.item) - m_itemToIndex.remove(entry.item); + if (entry.item) m_itemToIndex.remove(entry.item); entry.pendingRemoval = true; // Never made visible — skip remove animation @@ -1014,8 +947,7 @@ void LazyListView::onRowsAboutToBeRemoved(const QModelIndex& parent, if (m_removeDuration > 0 && entry.item) { auto* attached = qobject_cast( qmlAttachedPropertiesObject(entry.item, false)); - if (attached) - attached->setRemoving(true); + if (attached) attached->setRemoving(true); // Schedule destruction after the remove animation duration auto* item = entry.item; @@ -1037,18 +969,15 @@ void LazyListView::onRowsAboutToBeRemoved(const QModelIndex& parent, } } -void LazyListView::onRowsRemoved(const QModelIndex& parent, - int first, - int last) { - if (parent.isValid()) - return; +void LazyListView::onRowsRemoved( + const QModelIndex& parent, int first, int last) { + if (parent.isValid()) return; const int removeCount = last - first + 1; // Untrack known heights being removed for (int i = first; i <= last; ++i) { - if (m_layout[i].heightKnown) - untrackHeight(m_layout[i].height); + if (m_layout[i].heightKnown) untrackHeight(m_layout[i].height); } // Remove layout records @@ -1072,13 +1001,13 @@ void LazyListView::onRowsRemoved(const QModelIndex& parent, polish(); } -void LazyListView::onRowsMoved(const QModelIndex& parent, - int start, - int end, - const QModelIndex& destination, - int row) { - if (parent.isValid() || destination.isValid()) - return; +void LazyListView::onRowsMoved( + const QModelIndex& parent, + int start, + int end, + const QModelIndex& destination, + int row) { + if (parent.isValid() || destination.isValid()) return; const int count = end - start + 1; const int dest = row > start ? row - count : row; @@ -1101,10 +1030,8 @@ void LazyListView::onRowsMoved(const QModelIndex& parent, if (oldIdx >= start && oldIdx <= end) { newIdx = dest + (oldIdx - start); } else { - if (oldIdx > end) - newIdx -= count; - if (newIdx >= dest) - newIdx += count; + if (oldIdx > end) newIdx -= count; + if (newIdx >= dest) newIdx += count; } auto entry = std::move(it.value()); @@ -1120,17 +1047,16 @@ void LazyListView::onRowsMoved(const QModelIndex& parent, polish(); } -void LazyListView::onDataChanged(const QModelIndex& topLeft, - const QModelIndex& bottomRight, - const QList& roles) { +void LazyListView::onDataChanged( + const QModelIndex& topLeft, + const QModelIndex& bottomRight, + const QList& roles) { Q_UNUSED(roles) - if (topLeft.parent().isValid()) - return; + if (topLeft.parent().isValid()) return; for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { - if (m_delegates.contains(i)) - updateDelegateData(m_delegates[i]); + if (m_delegates.contains(i)) updateDelegateData(m_delegates[i]); } } diff --git a/Plugins/ZShell/Components/lazylistview.hpp b/Plugins/ZShell/Components/lazylistview.hpp index c1bc987..e0077c4 100644 --- a/Plugins/ZShell/Components/lazylistview.hpp +++ b/Plugins/ZShell/Components/lazylistview.hpp @@ -12,232 +12,265 @@ namespace ZShell::components { class LazyListViewAttached : public QObject { -Q_OBJECT + Q_OBJECT -Q_PROPERTY(qreal preferredHeight READ preferredHeight WRITE setPreferredHeight NOTIFY preferredHeightChanged) -Q_PROPERTY(qreal visibleHeight READ visibleHeight WRITE setVisibleHeight NOTIFY visibleHeightChanged) -Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) -Q_PROPERTY(bool adding READ adding NOTIFY addingChanged) -Q_PROPERTY(bool removing READ removing NOTIFY removingChanged) -Q_PROPERTY(bool trackViewport READ trackViewport WRITE setTrackViewport NOTIFY trackViewportChanged) + Q_PROPERTY( + qreal preferredHeight READ preferredHeight WRITE setPreferredHeight + NOTIFY preferredHeightChanged) + Q_PROPERTY( + qreal visibleHeight READ visibleHeight WRITE setVisibleHeight NOTIFY + visibleHeightChanged) + Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) + Q_PROPERTY(bool adding READ adding NOTIFY addingChanged) + Q_PROPERTY(bool removing READ removing NOTIFY removingChanged) + Q_PROPERTY( + bool trackViewport READ trackViewport WRITE setTrackViewport NOTIFY + trackViewportChanged) -public: -explicit LazyListViewAttached(QObject* parent = nullptr); + public: + explicit LazyListViewAttached(QObject* parent = nullptr); -[[nodiscard]] qreal preferredHeight() const; -void setPreferredHeight(qreal height); + [[nodiscard]] qreal preferredHeight() const; + void setPreferredHeight(qreal height); -[[nodiscard]] qreal visibleHeight() const; -void setVisibleHeight(qreal height); + [[nodiscard]] qreal visibleHeight() const; + void setVisibleHeight(qreal height); -[[nodiscard]] bool ready() const; -void setReady(bool ready); + [[nodiscard]] bool ready() const; + void setReady(bool ready); -[[nodiscard]] bool adding() const; -void setAdding(bool adding); + [[nodiscard]] bool adding() const; + void setAdding(bool adding); -[[nodiscard]] bool removing() const; -void setRemoving(bool removing); + [[nodiscard]] bool removing() const; + void setRemoving(bool removing); -[[nodiscard]] bool trackViewport() const; -void setTrackViewport(bool track); + [[nodiscard]] bool trackViewport() const; + void setTrackViewport(bool track); -signals: -void preferredHeightChanged(); -void visibleHeightChanged(); -void readyChanged(); -void addingChanged(); -void removingChanged(); -void trackViewportChanged(); + signals: + void preferredHeightChanged(); + void visibleHeightChanged(); + void readyChanged(); + void addingChanged(); + void removingChanged(); + void trackViewportChanged(); -private: -qreal m_preferredHeight = -1; -qreal m_visibleHeight = -1; -bool m_ready = false; -bool m_adding = false; -bool m_removing = false; -bool m_trackViewport = false; + private: + qreal m_preferredHeight = -1; + qreal m_visibleHeight = -1; + bool m_ready = false; + bool m_adding = false; + bool m_removing = false; + bool m_trackViewport = false; }; class LazyListView : public QQuickItem { -Q_OBJECT -QML_ELEMENT -QML_ATTACHED(LazyListViewAttached) + Q_OBJECT + QML_ELEMENT + QML_ATTACHED(LazyListViewAttached) -// Model & Delegate -Q_PROPERTY(QAbstractItemModel* model READ model WRITE setModel NOTIFY modelChanged) -Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) + // Model & Delegate + Q_PROPERTY( + QAbstractItemModel* model READ model WRITE setModel NOTIFY modelChanged) + Q_PROPERTY( + QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY + delegateChanged) -// Layout -Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) -Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentHeightChanged) -Q_PROPERTY(qreal layoutHeight READ layoutHeight NOTIFY layoutHeightChanged) -Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged) + // Layout + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) + Q_PROPERTY( + qreal contentHeight READ contentHeight NOTIFY contentHeightChanged) + Q_PROPERTY(qreal layoutHeight READ layoutHeight NOTIFY layoutHeightChanged) + Q_PROPERTY( + qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged) -// Viewport & Lazy Loading -Q_PROPERTY(QRectF viewport READ viewport WRITE setViewport NOTIFY viewportChanged) -Q_PROPERTY(bool useCustomViewport READ useCustomViewport WRITE setUseCustomViewport NOTIFY useCustomViewportChanged) -Q_PROPERTY(qreal cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged) + // Viewport & Lazy Loading + Q_PROPERTY( + QRectF viewport READ viewport WRITE setViewport NOTIFY viewportChanged) + Q_PROPERTY( + bool useCustomViewport READ useCustomViewport WRITE setUseCustomViewport + NOTIFY useCustomViewportChanged) + Q_PROPERTY( + qreal cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY + cacheBufferChanged) -// Sizing -Q_PROPERTY(qreal estimatedHeight READ estimatedHeight WRITE setEstimatedHeight NOTIFY estimatedHeightChanged) + // Sizing + Q_PROPERTY( + qreal estimatedHeight READ estimatedHeight WRITE setEstimatedHeight + NOTIFY estimatedHeightChanged) -// Async -Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged) + // Async + Q_PROPERTY( + bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY + asynchronousChanged) -// Animation Durations -Q_PROPERTY(int removeDuration READ removeDuration WRITE setRemoveDuration NOTIFY removeDurationChanged) -Q_PROPERTY(int readyDelay READ readyDelay WRITE setReadyDelay NOTIFY readyDelayChanged) + // Animation Durations + Q_PROPERTY( + int removeDuration READ removeDuration WRITE setRemoveDuration NOTIFY + removeDurationChanged) + Q_PROPERTY( + int readyDelay READ readyDelay WRITE setReadyDelay NOTIFY + readyDelayChanged) -// State -Q_PROPERTY(int count READ count NOTIFY countChanged) + // State + Q_PROPERTY(int count READ count NOTIFY countChanged) -public: -explicit LazyListView(QQuickItem* parent = nullptr); -~LazyListView() override; + public: + explicit LazyListView(QQuickItem* parent = nullptr); + ~LazyListView() override; -static LazyListViewAttached* qmlAttachedProperties(QObject* object); + static LazyListViewAttached* qmlAttachedProperties(QObject* object); -// Model & Delegate -[[nodiscard]] QAbstractItemModel* model() const; -void setModel(QAbstractItemModel* model); + // Model & Delegate + [[nodiscard]] QAbstractItemModel* model() const; + void setModel(QAbstractItemModel* model); -[[nodiscard]] QQmlComponent* delegate() const; -void setDelegate(QQmlComponent* delegate); + [[nodiscard]] QQmlComponent* delegate() const; + void setDelegate(QQmlComponent* delegate); -// Layout -[[nodiscard]] qreal spacing() const; -void setSpacing(qreal spacing); + // Layout + [[nodiscard]] qreal spacing() const; + void setSpacing(qreal spacing); -[[nodiscard]] qreal contentHeight() const; -[[nodiscard]] qreal layoutHeight() const; + [[nodiscard]] qreal contentHeight() const; + [[nodiscard]] qreal layoutHeight() const; -[[nodiscard]] qreal contentY() const; -void setContentY(qreal contentY); + [[nodiscard]] qreal contentY() const; + void setContentY(qreal contentY); -// Viewport -[[nodiscard]] QRectF viewport() const; -void setViewport(const QRectF& viewport); + // Viewport + [[nodiscard]] QRectF viewport() const; + void setViewport(const QRectF& viewport); -[[nodiscard]] bool useCustomViewport() const; -void setUseCustomViewport(bool use); + [[nodiscard]] bool useCustomViewport() const; + void setUseCustomViewport(bool use); -[[nodiscard]] qreal cacheBuffer() const; -void setCacheBuffer(qreal buffer); + [[nodiscard]] qreal cacheBuffer() const; + void setCacheBuffer(qreal buffer); -// Sizing -[[nodiscard]] qreal estimatedHeight() const; -void setEstimatedHeight(qreal height); + // Sizing + [[nodiscard]] qreal estimatedHeight() const; + void setEstimatedHeight(qreal height); -// Async -[[nodiscard]] bool asynchronous() const; -void setAsynchronous(bool async); + // Async + [[nodiscard]] bool asynchronous() const; + void setAsynchronous(bool async); -// Animation Durations -[[nodiscard]] int removeDuration() const; -void setRemoveDuration(int duration); + // Animation Durations + [[nodiscard]] int removeDuration() const; + void setRemoveDuration(int duration); -[[nodiscard]] int readyDelay() const; -void setReadyDelay(int delay); + [[nodiscard]] int readyDelay() const; + void setReadyDelay(int delay); -// State -[[nodiscard]] int count() const; -signals: -void modelChanged(); -void delegateChanged(); -void spacingChanged(); -void contentHeightChanged(); -void layoutHeightChanged(); -void contentYChanged(); -void viewportChanged(); -void useCustomViewportChanged(); -void cacheBufferChanged(); -void estimatedHeightChanged(); -void asynchronousChanged(); -void removeDurationChanged(); -void readyDelayChanged(); -void countChanged(); -void viewportAdjustNeeded(qreal delta); + // State + [[nodiscard]] int count() const; + signals: + void modelChanged(); + void delegateChanged(); + void spacingChanged(); + void contentHeightChanged(); + void layoutHeightChanged(); + void contentYChanged(); + void viewportChanged(); + void useCustomViewportChanged(); + void cacheBufferChanged(); + void estimatedHeightChanged(); + void asynchronousChanged(); + void removeDurationChanged(); + void readyDelayChanged(); + void countChanged(); + void viewportAdjustNeeded(qreal delta); -protected: -void componentComplete() override; -void geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry) override; -void updatePolish() override; + protected: + void componentComplete() override; + void geometryChange( + const QRectF& newGeometry, const QRectF& oldGeometry) override; + void updatePolish() override; -private: -struct ItemRecord { - qreal targetY = 0; - qreal height = 0; - bool heightKnown = false; - bool isNew = false; -}; + private: + struct ItemRecord { + qreal targetY = 0; + qreal height = 0; + bool heightKnown = false; + bool isNew = false; + }; -struct DelegateEntry { - int modelIndex = -1; - QQuickItem* item = nullptr; - bool pendingRemoval = false; - bool pendingInsert = false; - bool readyDelayStarted = false; -}; + struct DelegateEntry { + int modelIndex = -1; + QQuickItem* item = nullptr; + bool pendingRemoval = false; + bool pendingInsert = false; + bool readyDelayStarted = false; + }; -// Layout -void relayout(); -[[nodiscard]] std::pair computeVisibleRange() const; -[[nodiscard]] QRectF effectiveViewport() const; -[[nodiscard]] qreal effectiveEstimatedHeight() const; -[[nodiscard]] static qreal delegateHeight(QQuickItem* item); -[[nodiscard]] static qreal delegateVisibleHeight(QQuickItem* item); -[[nodiscard]] static bool isDelegateReady(QQuickItem* item); -void trackHeight(qreal height); -void untrackHeight(qreal height); + // Layout + void relayout(); + [[nodiscard]] std::pair computeVisibleRange() const; + [[nodiscard]] QRectF effectiveViewport() const; + [[nodiscard]] qreal effectiveEstimatedHeight() const; + [[nodiscard]] static qreal delegateHeight(QQuickItem* item); + [[nodiscard]] static qreal delegateVisibleHeight(QQuickItem* item); + [[nodiscard]] static bool isDelegateReady(QQuickItem* item); + void trackHeight(qreal height); + void untrackHeight(qreal height); -// Delegate lifecycle -void syncDelegates(); -DelegateEntry createDelegate(int modelIndex); -void destroyDelegate(DelegateEntry& entry); -void updateDelegateData(DelegateEntry& entry); + // Delegate lifecycle + void syncDelegates(); + DelegateEntry createDelegate(int modelIndex); + void destroyDelegate(DelegateEntry& entry); + void updateDelegateData(DelegateEntry& entry); -// Model connection -void connectModel(); -void disconnectModel(); -void resetContent(); -void onRowsInserted(const QModelIndex& parent, int first, int last); -void onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last); -void onRowsRemoved(const QModelIndex& parent, int first, int last); -void onRowsMoved(const QModelIndex& parent, int start, int end, const QModelIndex& destination, int row); -void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QList& roles); -void onModelReset(); + // Model connection + void connectModel(); + void disconnectModel(); + void resetContent(); + void onRowsInserted(const QModelIndex& parent, int first, int last); + void onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last); + void onRowsRemoved(const QModelIndex& parent, int first, int last); + void onRowsMoved( + const QModelIndex& parent, + int start, + int end, + const QModelIndex& destination, + int row); + void onDataChanged( + const QModelIndex& topLeft, + const QModelIndex& bottomRight, + const QList& roles); + void onModelReset(); -// Members -QAbstractItemModel* m_model = nullptr; -QQmlComponent* m_delegate = nullptr; + // Members + QAbstractItemModel* m_model = nullptr; + QQmlComponent* m_delegate = nullptr; -qreal m_spacing = 0; -qreal m_contentHeight = 0; -qreal m_layoutHeight = 0; -qreal m_contentY = 0; + qreal m_spacing = 0; + qreal m_contentHeight = 0; + qreal m_layoutHeight = 0; + qreal m_contentY = 0; -QRectF m_viewport; -bool m_useCustomViewport = false; -qreal m_cacheBuffer = 0; + QRectF m_viewport; + bool m_useCustomViewport = false; + qreal m_cacheBuffer = 0; -qreal m_estimatedHeight = -1; -qreal m_knownHeightSum = 0; -int m_knownHeightCount = 0; -bool m_asynchronous = false; + qreal m_estimatedHeight = -1; + qreal m_knownHeightSum = 0; + int m_knownHeightCount = 0; + bool m_asynchronous = false; -int m_removeDuration = 300; -int m_readyDelay = 0; + int m_removeDuration = 300; + int m_readyDelay = 0; -QVector m_layout; -QHash m_delegates; -QHash m_itemToIndex; -QVector m_dyingDelegates; + QVector m_layout; + QHash m_delegates; + QHash m_itemToIndex; + QVector m_dyingDelegates; -bool m_componentComplete = false; -bool m_relayoutPending = false; + bool m_componentComplete = false; + bool m_relayoutPending = false; -QList m_modelConnections; + QList m_modelConnections; }; } // namespace ZShell::components diff --git a/Plugins/ZShell/Components/wavyline.cpp b/Plugins/ZShell/Components/wavyline.cpp index 757b7a2..8619f05 100644 --- a/Plugins/ZShell/Components/wavyline.cpp +++ b/Plugins/ZShell/Components/wavyline.cpp @@ -194,7 +194,8 @@ void WavyLine::paintLinear(QPainter* painter) { bool first = true; for (int x = m_lineWidth / 2; x <= drawEnd; ++x) { - const auto theta = m_frequency * 2 * M_PI * (x + m_startX) / len + phase; + const auto theta = + m_frequency * 2 * M_PI * (x + m_startX) / len + phase; const auto waveY = centerY + amplitude * qSin(theta); if (first) { path.moveTo(x, waveY); @@ -215,7 +216,10 @@ void WavyLine::paintArc(QPainter* painter) { const auto amplitude = m_lineWidth * m_amplitudeMultiplier; const auto cx = width() / 2.0; const auto cy = height() / 2.0; - const auto radius = m_radius > 0 ? m_radius : (qMin(width(), height()) - m_lineWidth - 2 * amplitude) / 2.0; + const auto radius = + m_radius > 0 + ? m_radius + : (qMin(width(), height()) - m_lineWidth - 2 * amplitude) / 2.0; if (radius <= 0) { return; diff --git a/Plugins/ZShell/Components/wavyline.hpp b/Plugins/ZShell/Components/wavyline.hpp index e9fab48..8f25589 100644 --- a/Plugins/ZShell/Components/wavyline.hpp +++ b/Plugins/ZShell/Components/wavyline.hpp @@ -6,102 +6,116 @@ namespace ZShell::controls { class WavyLine : public QQuickPaintedItem { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(int lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged FINAL) -Q_PROPERTY(qreal amplitudeMultiplier READ amplitudeMultiplier WRITE setAmplitudeMultiplier NOTIFY - amplitudeMultiplierChanged FINAL) -Q_PROPERTY(int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged FINAL) -Q_PROPERTY(qreal startX READ startX WRITE setStartX NOTIFY startXChanged FINAL) -Q_PROPERTY(qreal fullLength READ fullLength WRITE setFullLength NOTIFY fullLengthChanged FINAL) -Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) -Q_PROPERTY(qreal waveProgress READ waveProgress WRITE setWaveProgress NOTIFY waveProgressChanged FINAL) -Q_PROPERTY(PathType pathType READ pathType WRITE setPathType NOTIFY pathTypeChanged FINAL) -Q_PROPERTY(qreal startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged FINAL) -Q_PROPERTY(qreal fullAngle READ fullAngle WRITE setFullAngle NOTIFY fullAngleChanged FINAL) -Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged FINAL) -Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged FINAL) + Q_PROPERTY( + int lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged + FINAL) + Q_PROPERTY( + qreal amplitudeMultiplier READ amplitudeMultiplier WRITE + setAmplitudeMultiplier NOTIFY amplitudeMultiplierChanged FINAL) + Q_PROPERTY( + int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged + FINAL) + Q_PROPERTY( + qreal startX READ startX WRITE setStartX NOTIFY startXChanged FINAL) + Q_PROPERTY( + qreal fullLength READ fullLength WRITE setFullLength NOTIFY + fullLengthChanged FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + Q_PROPERTY( + qreal waveProgress READ waveProgress WRITE setWaveProgress NOTIFY + waveProgressChanged FINAL) + Q_PROPERTY( + PathType pathType READ pathType WRITE setPathType NOTIFY pathTypeChanged + FINAL) + Q_PROPERTY( + qreal startAngle READ startAngle WRITE setStartAngle NOTIFY + startAngleChanged FINAL) + Q_PROPERTY( + qreal fullAngle READ fullAngle WRITE setFullAngle NOTIFY + fullAngleChanged FINAL) + Q_PROPERTY( + qreal radius READ radius WRITE setRadius NOTIFY radiusChanged FINAL) + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged FINAL) -public: -enum PathType { - Linear, - Arc -}; -Q_ENUM(PathType) + public: + enum PathType { Linear, Arc }; + Q_ENUM(PathType) -explicit WavyLine(QQuickItem* parent = nullptr); + explicit WavyLine(QQuickItem* parent = nullptr); -[[nodiscard]] int lineWidth() const; -void setLineWidth(int lineWidth); + [[nodiscard]] int lineWidth() const; + void setLineWidth(int lineWidth); -[[nodiscard]] qreal amplitudeMultiplier() const; -void setAmplitudeMultiplier(qreal amplitudeMultiplier); + [[nodiscard]] qreal amplitudeMultiplier() const; + void setAmplitudeMultiplier(qreal amplitudeMultiplier); -[[nodiscard]] int frequency() const; -void setFrequency(int frequency); + [[nodiscard]] int frequency() const; + void setFrequency(int frequency); -[[nodiscard]] qreal startX() const; -void setStartX(qreal startX); + [[nodiscard]] qreal startX() const; + void setStartX(qreal startX); -[[nodiscard]] qreal fullLength() const; -void setFullLength(qreal fullLength); + [[nodiscard]] qreal fullLength() const; + void setFullLength(qreal fullLength); -[[nodiscard]] QColor color() const; -void setColor(const QColor& color); + [[nodiscard]] QColor color() const; + void setColor(const QColor& color); -[[nodiscard]] qreal waveProgress() const; -void setWaveProgress(qreal progress); + [[nodiscard]] qreal waveProgress() const; + void setWaveProgress(qreal progress); -[[nodiscard]] PathType pathType() const; -void setPathType(PathType pathType); + [[nodiscard]] PathType pathType() const; + void setPathType(PathType pathType); -[[nodiscard]] qreal startAngle() const; -void setStartAngle(qreal startAngle); + [[nodiscard]] qreal startAngle() const; + void setStartAngle(qreal startAngle); -[[nodiscard]] qreal fullAngle() const; -void setFullAngle(qreal fullAngle); + [[nodiscard]] qreal fullAngle() const; + void setFullAngle(qreal fullAngle); -[[nodiscard]] qreal radius() const; -void setRadius(qreal radius); + [[nodiscard]] qreal radius() const; + void setRadius(qreal radius); -[[nodiscard]] qreal value() const; -void setValue(qreal value); + [[nodiscard]] qreal value() const; + void setValue(qreal value); -void paint(QPainter* painter) override; + void paint(QPainter* painter) override; -signals: -void lineWidthChanged(); -void amplitudeMultiplierChanged(); -void frequencyChanged(); -void startXChanged(); -void fullLengthChanged(); -void colorChanged(); -void waveProgressChanged(); -void pathTypeChanged(); -void startAngleChanged(); -void fullAngleChanged(); -void radiusChanged(); -void valueChanged(); + signals: + void lineWidthChanged(); + void amplitudeMultiplierChanged(); + void frequencyChanged(); + void startXChanged(); + void fullLengthChanged(); + void colorChanged(); + void waveProgressChanged(); + void pathTypeChanged(); + void startAngleChanged(); + void fullAngleChanged(); + void radiusChanged(); + void valueChanged(); -private: -void paintLinear(QPainter* painter); -void paintArc(QPainter* painter); + private: + void paintLinear(QPainter* painter); + void paintArc(QPainter* painter); -int m_lineWidth; -qreal m_amplitudeMultiplier; -int m_frequency; -qreal m_startX; -qreal m_fullLength; -QColor m_color; -qreal m_waveProgress; -PathType m_pathType; -qreal m_startAngle; -qreal m_fullAngle; -qreal m_radius; -qreal m_value; -qreal m_startAngleRad; -qreal m_fullAngleRad; + int m_lineWidth; + qreal m_amplitudeMultiplier; + int m_frequency; + qreal m_startX; + qreal m_fullLength; + QColor m_color; + qreal m_waveProgress; + PathType m_pathType; + qreal m_startAngle; + qreal m_fullAngle; + qreal m_radius; + qreal m_value; + qreal m_startAngleRad; + qreal m_fullAngleRad; }; } // namespace ZShell::controls diff --git a/Plugins/ZShell/Internal/arcgauge.cpp b/Plugins/ZShell/Internal/arcgauge.cpp index 4f77b50..571f3b7 100644 --- a/Plugins/ZShell/Internal/arcgauge.cpp +++ b/Plugins/ZShell/Internal/arcgauge.cpp @@ -6,8 +6,7 @@ namespace ZShell::internal { -ArcGauge::ArcGauge(QQuickItem* parent) - : QQuickPaintedItem(parent) { +ArcGauge::ArcGauge(QQuickItem* parent) : QQuickPaintedItem(parent) { setAntialiasing(true); } @@ -36,7 +35,8 @@ void ArcGauge::paint(QPainter* painter) { // Draw value arc if (m_percentage > 0.0) { - const int valueSweep16 = qRound(static_cast(sweepAngle16) * m_percentage); + const int valueSweep16 = + qRound(static_cast(sweepAngle16) * m_percentage); QPen valuePen(m_accentColor, m_lineWidth); valuePen.setCapStyle(Qt::RoundCap); painter->setPen(valuePen); @@ -49,8 +49,7 @@ qreal ArcGauge::percentage() const { } void ArcGauge::setPercentage(qreal percentage) { - if (qFuzzyCompare(m_percentage, percentage)) - return; + if (qFuzzyCompare(m_percentage, percentage)) return; m_percentage = percentage; emit percentageChanged(); update(); @@ -61,8 +60,7 @@ QColor ArcGauge::accentColor() const { } void ArcGauge::setAccentColor(const QColor& color) { - if (m_accentColor == color) - return; + if (m_accentColor == color) return; m_accentColor = color; emit accentColorChanged(); update(); @@ -73,8 +71,7 @@ QColor ArcGauge::trackColor() const { } void ArcGauge::setTrackColor(const QColor& color) { - if (m_trackColor == color) - return; + if (m_trackColor == color) return; m_trackColor = color; emit trackColorChanged(); update(); @@ -85,8 +82,7 @@ qreal ArcGauge::startAngle() const { } void ArcGauge::setStartAngle(qreal angle) { - if (qFuzzyCompare(m_startAngle, angle)) - return; + if (qFuzzyCompare(m_startAngle, angle)) return; m_startAngle = angle; emit startAngleChanged(); update(); @@ -97,8 +93,7 @@ qreal ArcGauge::sweepAngle() const { } void ArcGauge::setSweepAngle(qreal angle) { - if (qFuzzyCompare(m_sweepAngle, angle)) - return; + if (qFuzzyCompare(m_sweepAngle, angle)) return; m_sweepAngle = angle; emit sweepAngleChanged(); update(); @@ -109,8 +104,7 @@ qreal ArcGauge::lineWidth() const { } void ArcGauge::setLineWidth(qreal width) { - if (qFuzzyCompare(m_lineWidth, width)) - return; + if (qFuzzyCompare(m_lineWidth, width)) return; m_lineWidth = width; emit lineWidthChanged(); update(); diff --git a/Plugins/ZShell/Internal/arcgauge.hpp b/Plugins/ZShell/Internal/arcgauge.hpp index f10f47f..697f5c4 100644 --- a/Plugins/ZShell/Internal/arcgauge.hpp +++ b/Plugins/ZShell/Internal/arcgauge.hpp @@ -8,54 +8,66 @@ namespace ZShell::internal { class ArcGauge : public QQuickPaintedItem { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(qreal percentage READ percentage WRITE setPercentage NOTIFY percentageChanged) -Q_PROPERTY(QColor accentColor READ accentColor WRITE setAccentColor NOTIFY accentColorChanged) -Q_PROPERTY(QColor trackColor READ trackColor WRITE setTrackColor NOTIFY trackColorChanged) -Q_PROPERTY(qreal startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged) -Q_PROPERTY(qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY sweepAngleChanged) -Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged) + Q_PROPERTY( + qreal percentage READ percentage WRITE setPercentage NOTIFY + percentageChanged) + Q_PROPERTY( + QColor accentColor READ accentColor WRITE setAccentColor NOTIFY + accentColorChanged) + Q_PROPERTY( + QColor trackColor READ trackColor WRITE setTrackColor NOTIFY + trackColorChanged) + Q_PROPERTY( + qreal startAngle READ startAngle WRITE setStartAngle NOTIFY + startAngleChanged) + Q_PROPERTY( + qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY + sweepAngleChanged) + Q_PROPERTY( + qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY + lineWidthChanged) -public: -explicit ArcGauge(QQuickItem* parent = nullptr); + public: + explicit ArcGauge(QQuickItem* parent = nullptr); -void paint(QPainter* painter) override; + void paint(QPainter* painter) override; -[[nodiscard]] qreal percentage() const; -void setPercentage(qreal percentage); + [[nodiscard]] qreal percentage() const; + void setPercentage(qreal percentage); -[[nodiscard]] QColor accentColor() const; -void setAccentColor(const QColor& color); + [[nodiscard]] QColor accentColor() const; + void setAccentColor(const QColor& color); -[[nodiscard]] QColor trackColor() const; -void setTrackColor(const QColor& color); + [[nodiscard]] QColor trackColor() const; + void setTrackColor(const QColor& color); -[[nodiscard]] qreal startAngle() const; -void setStartAngle(qreal angle); + [[nodiscard]] qreal startAngle() const; + void setStartAngle(qreal angle); -[[nodiscard]] qreal sweepAngle() const; -void setSweepAngle(qreal angle); + [[nodiscard]] qreal sweepAngle() const; + void setSweepAngle(qreal angle); -[[nodiscard]] qreal lineWidth() const; -void setLineWidth(qreal width); + [[nodiscard]] qreal lineWidth() const; + void setLineWidth(qreal width); -signals: -void percentageChanged(); -void accentColorChanged(); -void trackColorChanged(); -void startAngleChanged(); -void sweepAngleChanged(); -void lineWidthChanged(); + signals: + void percentageChanged(); + void accentColorChanged(); + void trackColorChanged(); + void startAngleChanged(); + void sweepAngleChanged(); + void lineWidthChanged(); -private: -qreal m_percentage = 0.0; -QColor m_accentColor; -QColor m_trackColor; -qreal m_startAngle = 0.75 * M_PI; -qreal m_sweepAngle = 1.5 * M_PI; -qreal m_lineWidth = 10.0; + private: + qreal m_percentage = 0.0; + QColor m_accentColor; + QColor m_trackColor; + qreal m_startAngle = 0.75 * M_PI; + qreal m_sweepAngle = 1.5 * M_PI; + qreal m_lineWidth = 10.0; }; -} // namespace ZShell::Internal +} // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/cachingimagemanager.cpp b/Plugins/ZShell/Internal/cachingimagemanager.cpp index 493b405..e53bf42 100644 --- a/Plugins/ZShell/Internal/cachingimagemanager.cpp +++ b/Plugins/ZShell/Internal/cachingimagemanager.cpp @@ -12,212 +12,232 @@ namespace ZShell::internal { qreal CachingImageManager::effectiveScale() const { - if (m_item && m_item->window()) { - return m_item->window()->devicePixelRatio(); - } + if (m_item && m_item->window()) { + return m_item->window()->devicePixelRatio(); + } - return 1.0; + return 1.0; } QSize CachingImageManager::effectiveSize() const { - if (!m_item) { - return QSize(); - } + if (!m_item) { + return QSize(); + } - const qreal scale = effectiveScale(); - const QSize size = QSizeF(m_item->width() * scale, m_item->height() * scale).toSize(); - m_item->setProperty("sourceSize", size); - return size; + const qreal scale = effectiveScale(); + const QSize size = + QSizeF(m_item->width() * scale, m_item->height() * scale).toSize(); + m_item->setProperty("sourceSize", size); + return size; } QQuickItem* CachingImageManager::item() const { - return m_item; + return m_item; } void CachingImageManager::setItem(QQuickItem* item) { - if (m_item == item) { - return; - } + if (m_item == item) { + return; + } - if (m_widthConn) { - disconnect(m_widthConn); - } - if (m_heightConn) { - disconnect(m_heightConn); - } + if (m_widthConn) { + disconnect(m_widthConn); + } + if (m_heightConn) { + disconnect(m_heightConn); + } - m_item = item; - emit itemChanged(); + m_item = item; + emit itemChanged(); - if (item) { - m_widthConn = connect(item, &QQuickItem::widthChanged, this, [this]() { - updateSource(); - }); - m_heightConn = connect(item, &QQuickItem::heightChanged, this, [this]() { - updateSource(); - }); - updateSource(); - } + if (item) { + m_widthConn = connect(item, &QQuickItem::widthChanged, this, [this]() { + updateSource(); + }); + m_heightConn = + connect(item, &QQuickItem::heightChanged, this, [this]() { + updateSource(); + }); + updateSource(); + } } QUrl CachingImageManager::cacheDir() const { - return m_cacheDir; + return m_cacheDir; } void CachingImageManager::setCacheDir(const QUrl& cacheDir) { - if (m_cacheDir == cacheDir) { - return; - } + if (m_cacheDir == cacheDir) { + return; + } - m_cacheDir = cacheDir; - if (!m_cacheDir.path().endsWith("/")) { - m_cacheDir.setPath(m_cacheDir.path() + "/"); - } - emit cacheDirChanged(); + m_cacheDir = cacheDir; + if (!m_cacheDir.path().endsWith("/")) { + m_cacheDir.setPath(m_cacheDir.path() + "/"); + } + emit cacheDirChanged(); } QString CachingImageManager::path() const { - return m_path; + return m_path; } void CachingImageManager::setPath(const QString& path) { - if (m_path == path) { - return; - } + if (m_path == path) { + return; + } - m_path = path; - emit pathChanged(); + m_path = path; + emit pathChanged(); - if (!path.isEmpty()) { - updateSource(path); - } + if (!path.isEmpty()) { + updateSource(path); + } } void CachingImageManager::updateSource() { - updateSource(m_path); + updateSource(m_path); } void CachingImageManager::updateSource(const QString& path) { - if (path.isEmpty() || path == m_shaPath) { - // Path is empty or already calculating sha for path - return; - } + if (path.isEmpty() || path == m_shaPath) { + // Path is empty or already calculating sha for path + return; + } - m_shaPath = path; + m_shaPath = path; - const auto future = QtConcurrent::run(&CachingImageManager::sha256sum, path); + const auto future = + QtConcurrent::run(&CachingImageManager::sha256sum, path); - const auto watcher = new QFutureWatcher(this); + const auto watcher = new QFutureWatcher(this); - connect(watcher, &QFutureWatcher::finished, this, [watcher, path, this]() { - if (m_path != path) { - // Object is destroyed or path has changed, ignore - watcher->deleteLater(); - return; - } + connect( + watcher, + &QFutureWatcher::finished, + this, + [watcher, path, this]() { + if (m_path != path) { + // Object is destroyed or path has changed, ignore + watcher->deleteLater(); + return; + } - const QSize size = effectiveSize(); + const QSize size = effectiveSize(); - if (!m_item || !size.width() || !size.height()) { - watcher->deleteLater(); - return; - } + if (!m_item || !size.width() || !size.height()) { + watcher->deleteLater(); + return; + } - const QString fillMode = m_item->property("fillMode").toString(); - // clang-format off + const QString fillMode = m_item->property("fillMode").toString(); + // clang-format off const QString filename = QString("%1@%2x%3-%4.png") .arg(watcher->result()).arg(size.width()).arg(size.height()) .arg(fillMode == "PreserveAspectCrop" ? "crop" : fillMode == "PreserveAspectFit" ? "fit" : "stretch"); - // clang-format on + // clang-format on - const QUrl cache = m_cacheDir.resolved(QUrl(filename)); - if (m_cachePath == cache) { - watcher->deleteLater(); - return; - } + const QUrl cache = m_cacheDir.resolved(QUrl(filename)); + if (m_cachePath == cache) { + watcher->deleteLater(); + return; + } - m_cachePath = cache; - emit cachePathChanged(); + m_cachePath = cache; + emit cachePathChanged(); - if (!cache.isLocalFile()) { - qWarning() << "CachingImageManager::updateSource: cachePath" << cache << "is not a local file"; - watcher->deleteLater(); - return; - } + if (!cache.isLocalFile()) { + qWarning() << "CachingImageManager::updateSource: cachePath" + << cache << "is not a local file"; + watcher->deleteLater(); + return; + } - const QImageReader reader(cache.toLocalFile()); - if (reader.canRead()) { - m_item->setProperty("source", cache); - } else { - m_item->setProperty("source", QUrl::fromLocalFile(path)); - createCache(path, cache.toLocalFile(), fillMode, size); - } + const QImageReader reader(cache.toLocalFile()); + if (reader.canRead()) { + m_item->setProperty("source", cache); + } else { + m_item->setProperty("source", QUrl::fromLocalFile(path)); + createCache(path, cache.toLocalFile(), fillMode, size); + } - // Clear current running sha if same - if (m_shaPath == path) { - m_shaPath = QString(); - } + // Clear current running sha if same + if (m_shaPath == path) { + m_shaPath = QString(); + } - watcher->deleteLater(); - }); + watcher->deleteLater(); + }); - watcher->setFuture(future); + watcher->setFuture(future); } QUrl CachingImageManager::cachePath() const { - return m_cachePath; + return m_cachePath; } void CachingImageManager::createCache( - const QString& path, const QString& cache, const QString& fillMode, const QSize& size) const { - QThreadPool::globalInstance()->start([path, cache, fillMode, size] { - QImage image(path); + const QString& path, + const QString& cache, + const QString& fillMode, + const QSize& size) const { + QThreadPool::globalInstance()->start([path, cache, fillMode, size] { + QImage image(path); - if (image.isNull()) { - qWarning() << "CachingImageManager::createCache: failed to read" << path; - return; - } + if (image.isNull()) { + qWarning() << "CachingImageManager::createCache: failed to read" + << path; + return; + } - image.convertTo(QImage::Format_ARGB32); + image.convertTo(QImage::Format_ARGB32); - if (fillMode == "PreserveAspectCrop") { - image = image.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - } else if (fillMode == "PreserveAspectFit") { - image = image.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); - } else { - image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } + if (fillMode == "PreserveAspectCrop") { + image = image.scaled( + size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + } else if (fillMode == "PreserveAspectFit") { + image = image.scaled( + size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } else { + image = image.scaled( + size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } - if (fillMode == "PreserveAspectCrop" || fillMode == "PreserveAspectFit") { - QImage canvas(size, QImage::Format_ARGB32); - canvas.fill(Qt::transparent); + if (fillMode == "PreserveAspectCrop" || + fillMode == "PreserveAspectFit") { + QImage canvas(size, QImage::Format_ARGB32); + canvas.fill(Qt::transparent); - QPainter painter(&canvas); - painter.drawImage((size.width() - image.width()) / 2, (size.height() - image.height()) / 2, image); - painter.end(); + QPainter painter(&canvas); + painter.drawImage( + (size.width() - image.width()) / 2, + (size.height() - image.height()) / 2, + image); + painter.end(); - image = canvas; - } + image = canvas; + } - const QString parent = QFileInfo(cache).absolutePath(); - if (!QDir().mkpath(parent) || !image.save(cache)) { - qWarning() << "CachingImageManager::createCache: failed to save to" << cache; - } - }); + const QString parent = QFileInfo(cache).absolutePath(); + if (!QDir().mkpath(parent) || !image.save(cache)) { + qWarning() << "CachingImageManager::createCache: failed to save to" + << cache; + } + }); } QString CachingImageManager::sha256sum(const QString& path) { - QFile file(path); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "CachingImageManager::sha256sum: failed to open" << path; - return ""; - } + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "CachingImageManager::sha256sum: failed to open" << path; + return ""; + } - QCryptographicHash hash(QCryptographicHash::Sha256); - hash.addData(&file); - file.close(); + QCryptographicHash hash(QCryptographicHash::Sha256); + hash.addData(&file); + file.close(); - return hash.result().toHex(); + return hash.result().toHex(); } } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/cachingimagemanager.hpp b/Plugins/ZShell/Internal/cachingimagemanager.hpp index a4f0b93..587d9a6 100644 --- a/Plugins/ZShell/Internal/cachingimagemanager.hpp +++ b/Plugins/ZShell/Internal/cachingimagemanager.hpp @@ -7,60 +7,65 @@ namespace ZShell::internal { class CachingImageManager : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(QQuickItem* item READ item WRITE setItem NOTIFY itemChanged REQUIRED) -Q_PROPERTY(QUrl cacheDir READ cacheDir WRITE setCacheDir NOTIFY cacheDirChanged REQUIRED) + Q_PROPERTY( + QQuickItem* item READ item WRITE setItem NOTIFY itemChanged REQUIRED) + Q_PROPERTY( + QUrl cacheDir READ cacheDir WRITE setCacheDir NOTIFY cacheDirChanged + REQUIRED) -Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) -Q_PROPERTY(QUrl cachePath READ cachePath NOTIFY cachePathChanged) + Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) + Q_PROPERTY(QUrl cachePath READ cachePath NOTIFY cachePathChanged) -public: -explicit CachingImageManager(QObject* parent = nullptr) - : QObject(parent) - , m_item(nullptr) { -} + public: + explicit CachingImageManager(QObject* parent = nullptr) + : QObject(parent), m_item(nullptr) {} -[[nodiscard]] QQuickItem* item() const; -void setItem(QQuickItem* item); + [[nodiscard]] QQuickItem* item() const; + void setItem(QQuickItem* item); -[[nodiscard]] QUrl cacheDir() const; -void setCacheDir(const QUrl& cacheDir); + [[nodiscard]] QUrl cacheDir() const; + void setCacheDir(const QUrl& cacheDir); -[[nodiscard]] QString path() const; -void setPath(const QString& path); + [[nodiscard]] QString path() const; + void setPath(const QString& path); -[[nodiscard]] QUrl cachePath() const; + [[nodiscard]] QUrl cachePath() const; -Q_INVOKABLE void updateSource(); -Q_INVOKABLE void updateSource(const QString& path); + Q_INVOKABLE void updateSource(); + Q_INVOKABLE void updateSource(const QString& path); -signals: -void itemChanged(); -void cacheDirChanged(); + signals: + void itemChanged(); + void cacheDirChanged(); -void pathChanged(); -void cachePathChanged(); -void usingCacheChanged(); + void pathChanged(); + void cachePathChanged(); + void usingCacheChanged(); -private: -QString m_shaPath; + private: + QString m_shaPath; -QQuickItem* m_item; -QUrl m_cacheDir; + QQuickItem* m_item; + QUrl m_cacheDir; -QString m_path; -QUrl m_cachePath; + QString m_path; + QUrl m_cachePath; -QMetaObject::Connection m_widthConn; -QMetaObject::Connection m_heightConn; + QMetaObject::Connection m_widthConn; + QMetaObject::Connection m_heightConn; -[[nodiscard]] qreal effectiveScale() const; -[[nodiscard]] QSize effectiveSize() const; + [[nodiscard]] qreal effectiveScale() const; + [[nodiscard]] QSize effectiveSize() const; -void createCache(const QString& path, const QString& cache, const QString& fillMode, const QSize& size) const; -[[nodiscard]] static QString sha256sum(const QString& path); + void createCache( + const QString& path, + const QString& cache, + const QString& fillMode, + const QSize& size) const; + [[nodiscard]] static QString sha256sum(const QString& path); }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/circularbuffer.cpp b/Plugins/ZShell/Internal/circularbuffer.cpp index 0703f2c..b1c12bc 100644 --- a/Plugins/ZShell/Internal/circularbuffer.cpp +++ b/Plugins/ZShell/Internal/circularbuffer.cpp @@ -4,19 +4,15 @@ namespace ZShell::internal { -CircularBuffer::CircularBuffer(QObject* parent) - : QObject(parent) { -} +CircularBuffer::CircularBuffer(QObject* parent) : QObject(parent) {} int CircularBuffer::capacity() const { return m_capacity; } void CircularBuffer::setCapacity(int capacity) { - if (capacity < 0) - capacity = 0; - if (m_capacity == capacity) - return; + if (capacity < 0) capacity = 0; + if (m_capacity == capacity) return; const auto old = values(); @@ -52,8 +48,7 @@ QList CircularBuffer::values() const { } qreal CircularBuffer::maximum() const { - if (m_count == 0) - return 0.0; + if (m_count == 0) return 0.0; qreal maxVal = at(0); for (int i = 1; i < m_count; ++i) @@ -62,8 +57,7 @@ qreal CircularBuffer::maximum() const { } void CircularBuffer::push(qreal value) { - if (m_capacity <= 0) - return; + if (m_capacity <= 0) return; m_data[m_head] = value; m_head = (m_head + 1) % m_capacity; @@ -75,8 +69,7 @@ void CircularBuffer::push(qreal value) { } void CircularBuffer::clear() { - if (m_count == 0) - return; + if (m_count == 0) return; m_head = 0; m_count = 0; @@ -85,10 +78,10 @@ void CircularBuffer::clear() { } qreal CircularBuffer::at(int index) const { - if (index < 0 || index >= m_count) - return 0.0; + if (index < 0 || index >= m_count) return 0.0; - const int actualIndex = (m_head - m_count + index + m_capacity) % m_capacity; + const int actualIndex = + (m_head - m_count + index + m_capacity) % m_capacity; return m_data[actualIndex]; } diff --git a/Plugins/ZShell/Internal/circularbuffer.hpp b/Plugins/ZShell/Internal/circularbuffer.hpp index 763500e..a2496f5 100644 --- a/Plugins/ZShell/Internal/circularbuffer.hpp +++ b/Plugins/ZShell/Internal/circularbuffer.hpp @@ -7,38 +7,39 @@ namespace ZShell::internal { class CircularBuffer : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(int capacity READ capacity WRITE setCapacity NOTIFY capacityChanged) -Q_PROPERTY(int count READ count NOTIFY countChanged) -Q_PROPERTY(QList values READ values NOTIFY valuesChanged) -Q_PROPERTY(qreal maximum READ maximum NOTIFY valuesChanged) + Q_PROPERTY( + int capacity READ capacity WRITE setCapacity NOTIFY capacityChanged) + Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(QList values READ values NOTIFY valuesChanged) + Q_PROPERTY(qreal maximum READ maximum NOTIFY valuesChanged) -public: -explicit CircularBuffer(QObject* parent = nullptr); + public: + explicit CircularBuffer(QObject* parent = nullptr); -[[nodiscard]] int capacity() const; -void setCapacity(int capacity); + [[nodiscard]] int capacity() const; + void setCapacity(int capacity); -[[nodiscard]] int count() const; -[[nodiscard]] QList values() const; -[[nodiscard]] qreal maximum() const; + [[nodiscard]] int count() const; + [[nodiscard]] QList values() const; + [[nodiscard]] qreal maximum() const; -Q_INVOKABLE void push(qreal value); -Q_INVOKABLE void clear(); -Q_INVOKABLE [[nodiscard]] qreal at(int index) const; + Q_INVOKABLE void push(qreal value); + Q_INVOKABLE void clear(); + Q_INVOKABLE [[nodiscard]] qreal at(int index) const; -signals: -void capacityChanged(); -void countChanged(); -void valuesChanged(); + signals: + void capacityChanged(); + void countChanged(); + void valuesChanged(); -private: -QVector m_data; -int m_head = 0; -int m_count = 0; -int m_capacity = 0; + private: + QVector m_data; + int m_head = 0; + int m_count = 0; + int m_capacity = 0; }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/circularindicatormanager.cpp b/Plugins/ZShell/Internal/circularindicatormanager.cpp index da09c7c..15ce0f2 100644 --- a/Plugins/ZShell/Internal/circularindicatormanager.cpp +++ b/Plugins/ZShell/Internal/circularindicatormanager.cpp @@ -15,8 +15,10 @@ constexpr qint32 TAIL_DEGREES_OFFSET = -20; constexpr qint32 EXTRA_DEGREES_PER_CYCLE = 250; constexpr qint32 CONSTANT_ROTATION_DEGREES = 1520; -constexpr std::array DELAY_TO_EXPAND_IN_MS = { 0, 1350, 2700, 4050 }; -constexpr std::array DELAY_TO_COLLAPSE_IN_MS = { 667, 2017, 3367, 4717 }; +constexpr std::array DELAY_TO_EXPAND_IN_MS = + {0, 1350, 2700, 4050}; +constexpr std::array DELAY_TO_COLLAPSE_IN_MS = { + 667, 2017, 3367, 4717}; } // namespace advance @@ -26,7 +28,7 @@ constexpr qint32 TOTAL_DURATION_IN_MS = 6000; constexpr qint32 DURATION_SPIN_IN_MS = 500; constexpr qint32 DURATION_GROW_ACTIVE_IN_MS = 3000; constexpr qint32 DURATION_SHRINK_ACTIVE_IN_MS = 3000; -constexpr std::array DELAY_SPINS_IN_MS = { 0, 1500, 3000, 4500 }; +constexpr std::array DELAY_SPINS_IN_MS = {0, 1500, 3000, 4500}; constexpr qint32 DELAY_GROW_ACTIVE_IN_MS = 0; constexpr qint32 DELAY_SHRINK_ACTIVE_IN_MS = 3000; constexpr qint32 DURATION_TO_COMPLETE_END_IN_MS = 500; @@ -38,7 +40,7 @@ constexpr qint32 CONSTANT_ROTATION_DEGREES = 1080; // Despite of the constant rotation, there are also 5 extra rotations the entire animation. The // total degrees that each extra rotation goes by. constexpr qint32 SPIN_ROTATION_DEGREES = 90; -constexpr std::array END_FRACTION_RANGE = { 0.10, 0.87 }; +constexpr std::array END_FRACTION_RANGE = {0.10, 0.87}; } // namespace retreat @@ -61,7 +63,7 @@ CircularIndicatorManager::CircularIndicatorManager(QObject* parent) , m_rotation(0) , m_completeEndProgress(0) { // Fast out slow in - m_curve.addCubicBezierSegment({ 0.4, 0.0 }, { 0.2, 1.0 }, { 1.0, 1.0 }); + m_curve.addCubicBezierSegment({0.4, 0.0}, {0.2, 1.0}, {1.0, 1.0}); } qreal CircularIndicatorManager::startFraction() const { @@ -100,11 +102,13 @@ qreal CircularIndicatorManager::completeEndDuration() const { } } -CircularIndicatorManager::IndeterminateAnimationType CircularIndicatorManager::indeterminateAnimationType() const { +CircularIndicatorManager::IndeterminateAnimationType +CircularIndicatorManager::indeterminateAnimationType() const { return m_type; } -void CircularIndicatorManager::setIndeterminateAnimationType(IndeterminateAnimationType t) { +void CircularIndicatorManager::setIndeterminateAnimationType( + IndeterminateAnimationType t) { if (m_type != t) { m_type = t; emit indeterminateAnimationTypeChanged(); @@ -150,24 +154,27 @@ void CircularIndicatorManager::updateRetreat(qreal progress) { // Extra rotation for the faster spinning. qreal spinRotation = 0; for (const int spinDelay : DELAY_SPINS_IN_MS) { - spinRotation += m_curve.valueForProgress(getFractionInRange(playtime, spinDelay, DURATION_SPIN_IN_MS)) * - SPIN_ROTATION_DEGREES; + spinRotation += + m_curve.valueForProgress( + getFractionInRange(playtime, spinDelay, DURATION_SPIN_IN_MS)) * + SPIN_ROTATION_DEGREES; } m_rotation = constantRotation + spinRotation; emit rotationChanged(); // Grow active indicator. - qreal fraction = - m_curve.valueForProgress(getFractionInRange(playtime, DELAY_GROW_ACTIVE_IN_MS, DURATION_GROW_ACTIVE_IN_MS)); - fraction -= - m_curve.valueForProgress(getFractionInRange(playtime, DELAY_SHRINK_ACTIVE_IN_MS, DURATION_SHRINK_ACTIVE_IN_MS)); + qreal fraction = m_curve.valueForProgress(getFractionInRange( + playtime, DELAY_GROW_ACTIVE_IN_MS, DURATION_GROW_ACTIVE_IN_MS)); + fraction -= m_curve.valueForProgress(getFractionInRange( + playtime, DELAY_SHRINK_ACTIVE_IN_MS, DURATION_SHRINK_ACTIVE_IN_MS)); if (!qFuzzyIsNull(m_startFraction)) { m_startFraction = 0.0; emit startFractionChanged(); } const auto oldEndFrac = m_endFraction; - m_endFraction = std::lerp(END_FRACTION_RANGE[0], END_FRACTION_RANGE[1], fraction); + m_endFraction = + std::lerp(END_FRACTION_RANGE[0], END_FRACTION_RANGE[1], fraction); // Completing animation. if (m_completeEndProgress > 0) { @@ -184,22 +191,32 @@ void CircularIndicatorManager::updateAdvance(qreal progress) { const auto playtime = progress * TOTAL_DURATION_IN_MS; // Adds constant rotation to segment positions. - m_startFraction = CONSTANT_ROTATION_DEGREES * progress + TAIL_DEGREES_OFFSET; + m_startFraction = + CONSTANT_ROTATION_DEGREES * progress + TAIL_DEGREES_OFFSET; m_endFraction = CONSTANT_ROTATION_DEGREES * progress; // Adds cycle specific rotation to segment positions. for (size_t cycleIndex = 0; cycleIndex < TOTAL_CYCLES; ++cycleIndex) { // While expanding. - qreal fraction = getFractionInRange(playtime, DELAY_TO_EXPAND_IN_MS[cycleIndex], DURATION_TO_EXPAND_IN_MS); - m_endFraction += m_curve.valueForProgress(fraction) * EXTRA_DEGREES_PER_CYCLE; + qreal fraction = getFractionInRange( + playtime, + DELAY_TO_EXPAND_IN_MS[cycleIndex], + DURATION_TO_EXPAND_IN_MS); + m_endFraction += + m_curve.valueForProgress(fraction) * EXTRA_DEGREES_PER_CYCLE; // While collapsing. - fraction = getFractionInRange(playtime, DELAY_TO_COLLAPSE_IN_MS[cycleIndex], DURATION_TO_COLLAPSE_IN_MS); - m_startFraction += m_curve.valueForProgress(fraction) * EXTRA_DEGREES_PER_CYCLE; + fraction = getFractionInRange( + playtime, + DELAY_TO_COLLAPSE_IN_MS[cycleIndex], + DURATION_TO_COLLAPSE_IN_MS); + m_startFraction += + m_curve.valueForProgress(fraction) * EXTRA_DEGREES_PER_CYCLE; } // Closes the gap between head and tail for complete end. - m_startFraction += (m_endFraction - m_startFraction) * m_completeEndProgress; + m_startFraction += + (m_endFraction - m_startFraction) * m_completeEndProgress; m_startFraction /= 360.0; m_endFraction /= 360.0; diff --git a/Plugins/ZShell/Internal/circularindicatormanager.hpp b/Plugins/ZShell/Internal/circularindicatormanager.hpp index 0411ca1..d8c78c5 100644 --- a/Plugins/ZShell/Internal/circularindicatormanager.hpp +++ b/Plugins/ZShell/Internal/circularindicatormanager.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -8,66 +7,71 @@ namespace ZShell::internal { class CircularIndicatorManager : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(qreal startFraction READ startFraction NOTIFY startFractionChanged) -Q_PROPERTY(qreal endFraction READ endFraction NOTIFY endFractionChanged) -Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged) -Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged) -Q_PROPERTY(qreal completeEndProgress READ completeEndProgress WRITE setCompleteEndProgress NOTIFY - completeEndProgressChanged) -Q_PROPERTY(qreal duration READ duration NOTIFY indeterminateAnimationTypeChanged) -Q_PROPERTY(qreal completeEndDuration READ completeEndDuration NOTIFY indeterminateAnimationTypeChanged) -Q_PROPERTY(IndeterminateAnimationType indeterminateAnimationType READ indeterminateAnimationType WRITE - setIndeterminateAnimationType NOTIFY indeterminateAnimationTypeChanged) + Q_PROPERTY( + qreal startFraction READ startFraction NOTIFY startFractionChanged) + Q_PROPERTY(qreal endFraction READ endFraction NOTIFY endFractionChanged) + Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged) + Q_PROPERTY( + qreal progress READ progress WRITE setProgress NOTIFY progressChanged) + Q_PROPERTY( + qreal completeEndProgress READ completeEndProgress WRITE + setCompleteEndProgress NOTIFY completeEndProgressChanged) + Q_PROPERTY( + qreal duration READ duration NOTIFY indeterminateAnimationTypeChanged) + Q_PROPERTY( + qreal completeEndDuration READ completeEndDuration NOTIFY + indeterminateAnimationTypeChanged) + Q_PROPERTY( + IndeterminateAnimationType indeterminateAnimationType READ + indeterminateAnimationType WRITE setIndeterminateAnimationType + NOTIFY indeterminateAnimationTypeChanged) -public: -explicit CircularIndicatorManager(QObject* parent = nullptr); + public: + explicit CircularIndicatorManager(QObject* parent = nullptr); -enum IndeterminateAnimationType { - Advance = 0, - Retreat -}; -Q_ENUM(IndeterminateAnimationType) + enum IndeterminateAnimationType { Advance = 0, Retreat }; + Q_ENUM(IndeterminateAnimationType) -[[nodiscard]] qreal startFraction() const; -[[nodiscard]] qreal endFraction() const; -[[nodiscard]] qreal rotation() const; + [[nodiscard]] qreal startFraction() const; + [[nodiscard]] qreal endFraction() const; + [[nodiscard]] qreal rotation() const; -[[nodiscard]] qreal progress() const; -void setProgress(qreal progress); + [[nodiscard]] qreal progress() const; + void setProgress(qreal progress); -[[nodiscard]] qreal completeEndProgress() const; -void setCompleteEndProgress(qreal progress); + [[nodiscard]] qreal completeEndProgress() const; + void setCompleteEndProgress(qreal progress); -[[nodiscard]] qreal duration() const; -[[nodiscard]] qreal completeEndDuration() const; + [[nodiscard]] qreal duration() const; + [[nodiscard]] qreal completeEndDuration() const; -[[nodiscard]] IndeterminateAnimationType indeterminateAnimationType() const; -void setIndeterminateAnimationType(IndeterminateAnimationType t); + [[nodiscard]] IndeterminateAnimationType indeterminateAnimationType() const; + void setIndeterminateAnimationType(IndeterminateAnimationType t); -signals: -void startFractionChanged(); -void endFractionChanged(); -void rotationChanged(); -void progressChanged(); -void completeEndProgressChanged(); -void indeterminateAnimationTypeChanged(); + signals: + void startFractionChanged(); + void endFractionChanged(); + void rotationChanged(); + void progressChanged(); + void completeEndProgressChanged(); + void indeterminateAnimationTypeChanged(); -private: -IndeterminateAnimationType m_type; -QEasingCurve m_curve; + private: + IndeterminateAnimationType m_type; + QEasingCurve m_curve; -qreal m_progress; -qreal m_startFraction; -qreal m_endFraction; -qreal m_rotation; -qreal m_completeEndProgress; + qreal m_progress; + qreal m_startFraction; + qreal m_endFraction; + qreal m_rotation; + qreal m_completeEndProgress; -void update(qreal progress); -void updateAdvance(qreal progress); -void updateRetreat(qreal progress); + void update(qreal progress); + void updateAdvance(qreal progress); + void updateRetreat(qreal progress); }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/hyprdevices.cpp b/Plugins/ZShell/Internal/hyprdevices.cpp index 7b877dc..487ce8e 100644 --- a/Plugins/ZShell/Internal/hyprdevices.cpp +++ b/Plugins/ZShell/Internal/hyprdevices.cpp @@ -5,130 +5,131 @@ namespace ZShell::internal::hypr { HyprKeyboard::HyprKeyboard(QJsonObject ipcObject, QObject* parent) - : QObject(parent) - , m_lastIpcObject(ipcObject) {} + : QObject(parent), m_lastIpcObject(ipcObject) {} QVariantHash HyprKeyboard::lastIpcObject() const { - return m_lastIpcObject.toVariantHash(); + return m_lastIpcObject.toVariantHash(); } QString HyprKeyboard::address() const { - return m_lastIpcObject.value("address").toString(); + return m_lastIpcObject.value("address").toString(); } QString HyprKeyboard::name() const { - return m_lastIpcObject.value("name").toString(); + return m_lastIpcObject.value("name").toString(); } QString HyprKeyboard::layout() const { - return m_lastIpcObject.value("layout").toString(); + return m_lastIpcObject.value("layout").toString(); } QString HyprKeyboard::activeKeymap() const { - return m_lastIpcObject.value("active_keymap").toString(); + return m_lastIpcObject.value("active_keymap").toString(); } bool HyprKeyboard::capsLock() const { - return m_lastIpcObject.value("capsLock").toBool(); + return m_lastIpcObject.value("capsLock").toBool(); } bool HyprKeyboard::numLock() const { - return m_lastIpcObject.value("numLock").toBool(); + return m_lastIpcObject.value("numLock").toBool(); } bool HyprKeyboard::main() const { - return m_lastIpcObject.value("main").toBool(); + return m_lastIpcObject.value("main").toBool(); } bool HyprKeyboard::updateLastIpcObject(QJsonObject object) { - if (m_lastIpcObject == object) { - return false; - } + if (m_lastIpcObject == object) { + return false; + } - const auto last = m_lastIpcObject; + const auto last = m_lastIpcObject; - m_lastIpcObject = object; - emit lastIpcObjectChanged(); + m_lastIpcObject = object; + emit lastIpcObjectChanged(); - bool dirty = false; - if (last.value("address") != object.value("address")) { - dirty = true; - emit addressChanged(); - } - if (last.value("name") != object.value("name")) { - dirty = true; - emit nameChanged(); - } - if (last.value("layout") != object.value("layout")) { - dirty = true; - emit layoutChanged(); - } - if (last.value("active_keymap") != object.value("active_keymap")) { - dirty = true; - emit activeKeymapChanged(); - } - if (last.value("capsLock") != object.value("capsLock")) { - dirty = true; - emit capsLockChanged(); - } - if (last.value("numLock") != object.value("numLock")) { - dirty = true; - emit numLockChanged(); - } - if (last.value("main") != object.value("main")) { - dirty = true; - emit mainChanged(); - } - return dirty; + bool dirty = false; + if (last.value("address") != object.value("address")) { + dirty = true; + emit addressChanged(); + } + if (last.value("name") != object.value("name")) { + dirty = true; + emit nameChanged(); + } + if (last.value("layout") != object.value("layout")) { + dirty = true; + emit layoutChanged(); + } + if (last.value("active_keymap") != object.value("active_keymap")) { + dirty = true; + emit activeKeymapChanged(); + } + if (last.value("capsLock") != object.value("capsLock")) { + dirty = true; + emit capsLockChanged(); + } + if (last.value("numLock") != object.value("numLock")) { + dirty = true; + emit numLockChanged(); + } + if (last.value("main") != object.value("main")) { + dirty = true; + emit mainChanged(); + } + return dirty; } -HyprDevices::HyprDevices(QObject* parent) - : QObject(parent) {} +HyprDevices::HyprDevices(QObject* parent) : QObject(parent) {} QQmlListProperty HyprDevices::keyboards() { - return QQmlListProperty(this, &m_keyboards); + return QQmlListProperty(this, &m_keyboards); } bool HyprDevices::updateLastIpcObject(QJsonObject object) { - const auto val = object.value("keyboards").toArray(); - bool dirty = false; + const auto val = object.value("keyboards").toArray(); + bool dirty = false; - for (auto it = m_keyboards.begin(); it != m_keyboards.end();) { - auto* const keyboard = *it; - const auto inNewValues = std::any_of(val.begin(), val.end(), [keyboard](const QJsonValue& o) { - return o.toObject().value("address").toString() == keyboard->address(); - }); + for (auto it = m_keyboards.begin(); it != m_keyboards.end();) { + auto* const keyboard = *it; + const auto inNewValues = + std::any_of(val.begin(), val.end(), [keyboard](const QJsonValue& o) { + return o.toObject().value("address").toString() == + keyboard->address(); + }); - if (!inNewValues) { - dirty = true; - it = m_keyboards.erase(it); - keyboard->deleteLater(); - } else { - ++it; - } - } + if (!inNewValues) { + dirty = true; + it = m_keyboards.erase(it); + keyboard->deleteLater(); + } else { + ++it; + } + } - for (const auto& o : val) { - const auto obj = o.toObject(); - const auto addr = obj.value("address").toString(); + for (const auto& o : val) { + const auto obj = o.toObject(); + const auto addr = obj.value("address").toString(); - auto it = std::find_if(m_keyboards.begin(), m_keyboards.end(), [addr](const HyprKeyboard* kb) { - return kb->address() == addr; - }); + auto it = std::find_if( + m_keyboards.begin(), + m_keyboards.end(), + [addr](const HyprKeyboard* kb) { return kb->address() == addr; }); - if (it != m_keyboards.end()) { - dirty |= (*it)->updateLastIpcObject(obj); - } else { - dirty = true; - m_keyboards << new HyprKeyboard(obj, this); - } - } + if (it != m_keyboards.end()) { + dirty |= (*it)->updateLastIpcObject(obj); + } else { + dirty = true; + m_keyboards << new HyprKeyboard(obj, this); + } + } - if (dirty) { - emit keyboardsChanged(); - } + if (dirty) { + emit keyboardsChanged(); + } - return dirty; + return dirty; } } // namespace ZShell::internal::hypr diff --git a/Plugins/ZShell/Internal/hyprdevices.hpp b/Plugins/ZShell/Internal/hyprdevices.hpp index 285823d..b554240 100644 --- a/Plugins/ZShell/Internal/hyprdevices.hpp +++ b/Plugins/ZShell/Internal/hyprdevices.hpp @@ -8,67 +8,72 @@ namespace ZShell::internal::hypr { class HyprKeyboard : public QObject { -Q_OBJECT -QML_ELEMENT - QML_UNCREATABLE("HyprKeyboard instances can only be retrieved from a HyprDevices") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE( + "HyprKeyboard instances can only be retrieved from a HyprDevices") -Q_PROPERTY(QVariantHash lastIpcObject READ lastIpcObject NOTIFY lastIpcObjectChanged) -Q_PROPERTY(QString address READ address NOTIFY addressChanged) -Q_PROPERTY(QString name READ name NOTIFY nameChanged) -Q_PROPERTY(QString layout READ layout NOTIFY layoutChanged) -Q_PROPERTY(QString activeKeymap READ activeKeymap NOTIFY activeKeymapChanged) -Q_PROPERTY(bool capsLock READ capsLock NOTIFY capsLockChanged) -Q_PROPERTY(bool numLock READ numLock NOTIFY numLockChanged) -Q_PROPERTY(bool main READ main NOTIFY mainChanged) + Q_PROPERTY( + QVariantHash lastIpcObject READ lastIpcObject NOTIFY + lastIpcObjectChanged) + Q_PROPERTY(QString address READ address NOTIFY addressChanged) + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(QString layout READ layout NOTIFY layoutChanged) + Q_PROPERTY(QString activeKeymap READ activeKeymap NOTIFY activeKeymapChanged) + Q_PROPERTY(bool capsLock READ capsLock NOTIFY capsLockChanged) + Q_PROPERTY(bool numLock READ numLock NOTIFY numLockChanged) + Q_PROPERTY(bool main READ main NOTIFY mainChanged) -public: -explicit HyprKeyboard(QJsonObject ipcObject, QObject* parent = nullptr); + public: + explicit HyprKeyboard(QJsonObject ipcObject, QObject* parent = nullptr); -[[nodiscard]] QVariantHash lastIpcObject() const; -[[nodiscard]] QString address() const; -[[nodiscard]] QString name() const; -[[nodiscard]] QString layout() const; -[[nodiscard]] QString activeKeymap() const; -[[nodiscard]] bool capsLock() const; -[[nodiscard]] bool numLock() const; -[[nodiscard]] bool main() const; + [[nodiscard]] QVariantHash lastIpcObject() const; + [[nodiscard]] QString address() const; + [[nodiscard]] QString name() const; + [[nodiscard]] QString layout() const; + [[nodiscard]] QString activeKeymap() const; + [[nodiscard]] bool capsLock() const; + [[nodiscard]] bool numLock() const; + [[nodiscard]] bool main() const; -bool updateLastIpcObject(QJsonObject object); + bool updateLastIpcObject(QJsonObject object); -signals: -void lastIpcObjectChanged(); -void addressChanged(); -void nameChanged(); -void layoutChanged(); -void activeKeymapChanged(); -void capsLockChanged(); -void numLockChanged(); -void mainChanged(); + signals: + void lastIpcObjectChanged(); + void addressChanged(); + void nameChanged(); + void layoutChanged(); + void activeKeymapChanged(); + void capsLockChanged(); + void numLockChanged(); + void mainChanged(); -private: -QJsonObject m_lastIpcObject; + private: + QJsonObject m_lastIpcObject; }; class HyprDevices : public QObject { -Q_OBJECT -QML_ELEMENT - QML_UNCREATABLE("HyprDevices instances can only be retrieved from a HyprExtras") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE( + "HyprDevices instances can only be retrieved from a HyprExtras") -Q_PROPERTY( - QQmlListProperty keyboards READ keyboards NOTIFY keyboardsChanged) + Q_PROPERTY( + QQmlListProperty keyboards READ + keyboards NOTIFY keyboardsChanged) -public: -explicit HyprDevices(QObject* parent = nullptr); + public: + explicit HyprDevices(QObject* parent = nullptr); -[[nodiscard]] QQmlListProperty keyboards(); + [[nodiscard]] QQmlListProperty keyboards(); -bool updateLastIpcObject(QJsonObject object); + bool updateLastIpcObject(QJsonObject object); -signals: -void keyboardsChanged(); + signals: + void keyboardsChanged(); -private: -QList m_keyboards; + private: + QList m_keyboards; }; -} // namespace ZShell::internal::hypr +} diff --git a/Plugins/ZShell/Internal/hyprextras.cpp b/Plugins/ZShell/Internal/hyprextras.cpp index 60805d4..7adea83 100644 --- a/Plugins/ZShell/Internal/hyprextras.cpp +++ b/Plugins/ZShell/Internal/hyprextras.cpp @@ -64,7 +64,8 @@ static QString luaArray(const QVariantList& list) { parts << luaValue(item); } - return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }"); + return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + + QLatin1String(" }"); } static QString luaArray(const QStringList& list) { @@ -75,7 +76,8 @@ static QString luaArray(const QStringList& list) { parts << luaEscapeString(item); } - return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }"); + return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + + QLatin1String(" }"); } static QString luaMapFromHash(const QVariantHash& hash) { @@ -83,10 +85,12 @@ static QString luaMapFromHash(const QVariantHash& hash) { parts.reserve(hash.size()); for (auto it = hash.cbegin(); it != hash.cend(); ++it) { - parts << luaEscapeString(it.key()) + QLatin1String(" = ") + luaValue(it.value()); + parts << luaEscapeString(it.key()) + QLatin1String(" = ") + + luaValue(it.value()); } - return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }"); + return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + + QLatin1String(" }"); } static QString luaMap(const QVariantMap& map) { @@ -94,10 +98,12 @@ static QString luaMap(const QVariantMap& map) { parts.reserve(map.size()); for (auto it = map.cbegin(); it != map.cend(); ++it) { - parts << luaEscapeString(it.key()) + QLatin1String(" = ") + luaValue(it.value()); + parts << luaEscapeString(it.key()) + QLatin1String(" = ") + + luaValue(it.value()); } - return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }"); + return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + + QLatin1String(" }"); } static QString luaValue(const QVariant& v) { @@ -143,7 +149,8 @@ static QString normalizeOptionPath(QString key) { } static QString buildHlConfigCall(const QString& key, const QVariant& value) { - const auto parts = normalizeOptionPath(key).split(QLatin1Char('.'), Qt::SkipEmptyParts); + const auto parts = + normalizeOptionPath(key).split(QLatin1Char('.'), Qt::SkipEmptyParts); if (parts.isEmpty()) { return {}; } @@ -189,7 +196,8 @@ static QVariant parseGetOptionValue(const QJsonObject& obj) { const auto option = obj.value(QStringLiteral("option")).toString(); - if (option.contains(QStringLiteral("color")) || option.contains(QStringLiteral("col."))) { + if (option.contains(QStringLiteral("color")) || + option.contains(QStringLiteral("col."))) { return colorFromInt(static_cast(value)); } @@ -234,7 +242,8 @@ static QVariant parseGetOptionValue(const QJsonObject& obj) { return {}; } -static void insertNestedValue(QVariantMap& root, const QStringList& path, const QVariant& value) { +static void insertNestedValue( + QVariantMap& root, const QStringList& path, const QVariant& value) { if (path.isEmpty()) { return; } @@ -261,16 +270,19 @@ HyprExtras::HyprExtras(QObject* parent) , m_devices(new HyprDevices(this)) { const auto his = qEnvironmentVariable("HYPRLAND_INSTANCE_SIGNATURE"); if (his.isEmpty()) { - qCWarning(lcHypr) << "$HYPRLAND_INSTANCE_SIGNATURE is unset. Unable to connect to Hyprland socket."; + qCWarning(lcHypr) << "$HYPRLAND_INSTANCE_SIGNATURE is unset. Unable to " + "connect to Hyprland socket."; return; } - auto hyprDir = QString("%1/hypr/%2").arg(qEnvironmentVariable("XDG_RUNTIME_DIR"), his); + auto hyprDir = + QString("%1/hypr/%2").arg(qEnvironmentVariable("XDG_RUNTIME_DIR"), his); if (!QDir(hyprDir).exists()) { hyprDir = QStringLiteral("/tmp/hypr/") + his; if (!QDir(hyprDir).exists()) { - qCWarning(lcHypr) << "Hyprland socket directory does not exist. Unable to connect to Hyprland socket."; + qCWarning(lcHypr) << "Hyprland socket directory does not exist. " + "Unable to connect to Hyprland socket."; return; } } @@ -283,9 +295,15 @@ HyprExtras::HyprExtras(QObject* parent) m_socket = new QLocalSocket(this); - QObject::connect(m_socket, &QLocalSocket::errorOccurred, this, &HyprExtras::socketError); - QObject::connect(m_socket, &QLocalSocket::stateChanged, this, &HyprExtras::socketStateChanged); - QObject::connect(m_socket, &QLocalSocket::readyRead, this, &HyprExtras::readEvent); + QObject::connect( + m_socket, &QLocalSocket::errorOccurred, this, &HyprExtras::socketError); + QObject::connect( + m_socket, + &QLocalSocket::stateChanged, + this, + &HyprExtras::socketStateChanged); + QObject::connect( + m_socket, &QLocalSocket::readyRead, this, &HyprExtras::readEvent); m_socket->connectToServer(m_eventSocket, QLocalSocket::ReadOnly); } @@ -304,10 +322,11 @@ void HyprExtras::message(const QString& message) { } makeRequest(message, [](bool success, const QByteArray& res) { - if (!success) { - qCWarning(lcHypr) << "message: request error:" << QString::fromUtf8(res); - } - }); + if (!success) { + qCWarning(lcHypr) + << "message: request error:" << QString::fromUtf8(res); + } + }); } void HyprExtras::batchMessage(const QStringList& messages) { @@ -315,10 +334,12 @@ void HyprExtras::batchMessage(const QStringList& messages) { return; } - makeRequest(QStringLiteral("[[BATCH]]") + messages.join(QLatin1Char(';')), - [](bool success, const QByteArray& res) { + makeRequest( + QStringLiteral("[[BATCH]]") + messages.join(QLatin1Char(';')), + [](bool success, const QByteArray& res) { if (!success) { - qCWarning(lcHypr) << "batchMessage: request error:" << QString::fromUtf8(res); + qCWarning(lcHypr) + << "batchMessage: request error:" << QString::fromUtf8(res); } }); } @@ -342,11 +363,14 @@ void HyprExtras::applyOptions(const QVariantHash& options) { return; } - makeRequest(QStringLiteral("eval ") + calls.join(QLatin1String("; ")), [this](bool success, const QByteArray& res) { + makeRequest( + QStringLiteral("eval ") + calls.join(QLatin1String("; ")), + [this](bool success, const QByteArray& res) { if (success) { refreshOptions(); } else { - qCWarning(lcHypr) << "applyOptions: request error" << QString::fromUtf8(res); + qCWarning(lcHypr) + << "applyOptions: request error" << QString::fromUtf8(res); } }); } @@ -372,26 +396,26 @@ void HyprExtras::refreshOptions() { auto nextOptions = std::make_shared(); - auto step = std::make_shared >(); + auto step = std::make_shared>(); *step = [this, generation, nextOptions, step](int index) { - if (generation != m_optionsRefreshGeneration) { - return; + if (generation != m_optionsRefreshGeneration) { + return; + } + + if (index >= optionKeys.size()) { + if (m_options != *nextOptions) { + m_options = *nextOptions; + emit optionsChanged(); } + return; + } - if (index >= optionKeys.size()) { - if (m_options != *nextOptions) { - m_options = *nextOptions; - emit optionsChanged(); - } - return; - } + const QString key = optionKeys.at(index); - const QString key = optionKeys.at(index); - - m_optionsRefresh = makeRequestJson( - QStringLiteral("getoption ") + key, - [this, generation, nextOptions, step, index, key](bool success, const QJsonDocument& response) - { + m_optionsRefresh = makeRequestJson( + QStringLiteral("getoption ") + key, + [this, generation, nextOptions, step, index, key]( + bool success, const QJsonDocument& response) { m_optionsRefresh.reset(); if (generation != m_optionsRefreshGeneration) { @@ -399,19 +423,26 @@ void HyprExtras::refreshOptions() { } if (success && response.isObject()) { - const QVariant value = parseGetOptionValue(response.object()); + const QVariant value = + parseGetOptionValue(response.object()); if (value.isValid()) { - insertNestedValue(*nextOptions, key.split(QLatin1Char(':'), Qt::SkipEmptyParts), value); + insertNestedValue( + *nextOptions, + key.split(QLatin1Char(':'), Qt::SkipEmptyParts), + value); } else { - qCWarning(lcHypr) << "refreshOptions: getoption returned no usable value for" << key; + qCWarning(lcHypr) << "refreshOptions: getoption " + "returned no usable value for" + << key; } } else if (!success) { - qCWarning(lcHypr) << "refreshOptions: getoption request error for" << key; + qCWarning(lcHypr) + << "refreshOptions: getoption request error for" << key; } (*step)(index + 1); }); - }; + }; (*step)(0); } @@ -421,7 +452,9 @@ void HyprExtras::refreshDevices() { m_devicesRefresh->close(); } - m_devicesRefresh = makeRequestJson(QStringLiteral("devices"), [this](bool success, const QJsonDocument& response) { + m_devicesRefresh = makeRequestJson( + QStringLiteral("devices"), + [this](bool success, const QJsonDocument& response) { m_devicesRefresh.reset(); if (success) { m_devices->updateLastIpcObject(response.object()); @@ -431,15 +464,19 @@ void HyprExtras::refreshDevices() { void HyprExtras::socketError(QLocalSocket::LocalSocketError error) const { if (!m_socketValid) { - qCWarning(lcHypr) << "socketError: unable to connect to Hyprland event socket:" << error; + qCWarning(lcHypr) + << "socketError: unable to connect to Hyprland event socket:" + << error; } else { - qCWarning(lcHypr) << "socketError: Hyprland event socket error:" << error; + qCWarning(lcHypr) << "socketError: Hyprland event socket error:" + << error; } } void HyprExtras::socketStateChanged(QLocalSocket::LocalSocketState state) { if (state == QLocalSocket::UnconnectedState && m_socketValid) { - qCWarning(lcHypr) << "socketStateChanged: Hyprland event socket disconnected."; + qCWarning(lcHypr) + << "socketStateChanged: Hyprland event socket disconnected."; } m_socketValid = state == QLocalSocket::ConnectedState; @@ -452,7 +489,8 @@ void HyprExtras::readEvent() { break; } rawEvent.truncate(rawEvent.length() - 1); - const auto event = QByteArrayView(rawEvent.data(), rawEvent.indexOf(">>")); + const auto event = + QByteArrayView(rawEvent.data(), rawEvent.indexOf(">>")); handleEvent(QString::fromUtf8(event)); } } @@ -466,14 +504,18 @@ void HyprExtras::handleEvent(const QString& event) { } HyprExtras::SocketPtr HyprExtras::makeRequestJson( - const QString& request, const std::function& callback) { - return makeRequest(QStringLiteral("j/") + request, [callback](bool success, const QByteArray& response) { + const QString& request, + const std::function& callback) { + return makeRequest( + QStringLiteral("j/") + request, + [callback](bool success, const QByteArray& response) { callback(success, QJsonDocument::fromJson(response)); }); } HyprExtras::SocketPtr HyprExtras::makeRequest( - const QString& request, const std::function& callback) { + const QString& request, + const std::function& callback) { if (m_requestSocket.isEmpty()) { return SocketPtr(); } @@ -481,18 +523,24 @@ HyprExtras::SocketPtr HyprExtras::makeRequest( auto socket = SocketPtr::create(this); QObject::connect(socket.data(), &QLocalSocket::connected, this, [=, this]() { - QObject::connect(socket.data(), &QLocalSocket::readyRead, this, [socket, callback]() { + QObject::connect( + socket.data(), &QLocalSocket::readyRead, this, [socket, callback]() { const auto response = socket->readAll(); callback(true, std::move(response)); socket->close(); }); - socket->write(request.toUtf8()); - socket->flush(); - }); + socket->write(request.toUtf8()); + socket->flush(); + }); - QObject::connect(socket.data(), &QLocalSocket::errorOccurred, this, [=](QLocalSocket::LocalSocketError err) { - qCWarning(lcHypr) << "makeRequest: error making request:" << err << "| request:" << request; + QObject::connect( + socket.data(), + &QLocalSocket::errorOccurred, + this, + [=](QLocalSocket::LocalSocketError err) { + qCWarning(lcHypr) << "makeRequest: error making request:" << err + << "| request:" << request; callback(false, {}); socket->close(); }); diff --git a/Plugins/ZShell/Internal/hyprextras.hpp b/Plugins/ZShell/Internal/hyprextras.hpp index afcac8d..2fc9aac 100644 --- a/Plugins/ZShell/Internal/hyprextras.hpp +++ b/Plugins/ZShell/Internal/hyprextras.hpp @@ -15,51 +15,56 @@ namespace ZShell::internal::hypr { class HyprDevices; class HyprExtras : public QObject { -Q_OBJECT -QML_ELEMENT - Q_MOC_INCLUDE("hyprdevices.hpp") + Q_OBJECT + QML_ELEMENT + Q_MOC_INCLUDE("hyprdevices.hpp") -Q_PROPERTY(QVariantMap options READ options NOTIFY optionsChanged) -Q_PROPERTY(ZShell::internal::hypr::HyprDevices* devices READ devices CONSTANT) + Q_PROPERTY(QVariantMap options READ options NOTIFY optionsChanged) + Q_PROPERTY( + ZShell::internal::hypr::HyprDevices* devices READ devices CONSTANT) -public: -explicit HyprExtras(QObject* parent = nullptr); + public: + explicit HyprExtras(QObject* parent = nullptr); -[[nodiscard]] QVariantMap options() const; -[[nodiscard]] HyprDevices* devices() const; + [[nodiscard]] QVariantMap options() const; + [[nodiscard]] HyprDevices* devices() const; -Q_INVOKABLE void message(const QString& message); -Q_INVOKABLE void batchMessage(const QStringList& messages); -Q_INVOKABLE void applyOptions(const QVariantHash& options); + Q_INVOKABLE void message(const QString& message); + Q_INVOKABLE void batchMessage(const QStringList& messages); + Q_INVOKABLE void applyOptions(const QVariantHash& options); -Q_INVOKABLE void refreshOptions(); -Q_INVOKABLE void refreshDevices(); + Q_INVOKABLE void refreshOptions(); + Q_INVOKABLE void refreshDevices(); -signals: -void optionsChanged(); + signals: + void optionsChanged(); -private: -using SocketPtr = QSharedPointer; + private: + using SocketPtr = QSharedPointer; -QString m_requestSocket; -QString m_eventSocket; -QLocalSocket* m_socket; -bool m_socketValid; + QString m_requestSocket; + QString m_eventSocket; + QLocalSocket* m_socket; + bool m_socketValid; -QVariantMap m_options; -HyprDevices* const m_devices; + QVariantMap m_options; + HyprDevices* const m_devices; -SocketPtr m_optionsRefresh; -SocketPtr m_devicesRefresh; -quint64 m_optionsRefreshGeneration = 0; + SocketPtr m_optionsRefresh; + SocketPtr m_devicesRefresh; + quint64 m_optionsRefreshGeneration = 0; -void socketError(QLocalSocket::LocalSocketError error) const; -void socketStateChanged(QLocalSocket::LocalSocketState state); -void readEvent(); -void handleEvent(const QString& event); + void socketError(QLocalSocket::LocalSocketError error) const; + void socketStateChanged(QLocalSocket::LocalSocketState state); + void readEvent(); + void handleEvent(const QString& event); -SocketPtr makeRequestJson(const QString& request, const std::function& callback); -SocketPtr makeRequest(const QString& request, const std::function& callback); + SocketPtr makeRequestJson( + const QString& request, + const std::function& callback); + SocketPtr makeRequest( + const QString& request, + const std::function& callback); }; } // namespace ZShell::internal::hypr diff --git a/Plugins/ZShell/Internal/lidwatcher.cpp b/Plugins/ZShell/Internal/lidwatcher.cpp index 108da0b..8f3a689 100644 --- a/Plugins/ZShell/Internal/lidwatcher.cpp +++ b/Plugins/ZShell/Internal/lidwatcher.cpp @@ -14,27 +14,29 @@ LidWatcher::LidWatcher(QObject* parent) : QObject(parent) { auto bus = QDBusConnection::systemBus(); if (!bus.isConnected()) { qCWarning(lcLidWatcher) - << "Failed to connect to system bus:" << bus.lastError().message(); + << "Failed to connect to system bus:" << bus.lastError().message(); return; } - bool ok = bus.connect("org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "PrepareForSleep", - this, - SLOT(handlePrepareForSleep(bool))); + bool ok = bus.connect( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + this, + SLOT(handlePrepareForSleep(bool))); if (!ok) { qCWarning(lcLidWatcher) - << "Failed to connect to PrepareForSleep signal:" - << bus.lastError().message(); + << "Failed to connect to PrepareForSleep signal:" + << bus.lastError().message(); } - QDBusInterface login1("org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - bus); + QDBusInterface login1( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + bus); const QDBusReply reply = login1.call("GetSession", "auto"); if (!reply.isValid()) { qCWarning(lcLidWatcher) << "Failed to get session path"; @@ -42,28 +44,30 @@ LidWatcher::LidWatcher(QObject* parent) : QObject(parent) { } const auto sessionPath = reply.value().path(); - ok = bus.connect("org.freedesktop.login1", - sessionPath, - "org.freedesktop.login1.Session", - "Lock", - this, - SLOT(handleLockRequested())); + ok = bus.connect( + "org.freedesktop.login1", + sessionPath, + "org.freedesktop.login1.Session", + "Lock", + this, + SLOT(handleLockRequested())); if (!ok) { qCWarning(lcLidWatcher) - << "Failed to connect to Lock signal:" << bus.lastError().message(); + << "Failed to connect to Lock signal:" << bus.lastError().message(); } - ok = bus.connect("org.freedesktop.login1", - sessionPath, - "org.freedesktop.login1.Session", - "Unlock", - this, - SLOT(handleUnlockRequested())); + ok = bus.connect( + "org.freedesktop.login1", + sessionPath, + "org.freedesktop.login1.Session", + "Unlock", + this, + SLOT(handleUnlockRequested())); if (!ok) { qCWarning(lcLidWatcher) << "Failed to connect to Unlock signal:" - << bus.lastError().message(); + << bus.lastError().message(); } } diff --git a/Plugins/ZShell/Internal/lidwatcher.hpp b/Plugins/ZShell/Internal/lidwatcher.hpp index 4016f16..6a6f4dc 100644 --- a/Plugins/ZShell/Internal/lidwatcher.hpp +++ b/Plugins/ZShell/Internal/lidwatcher.hpp @@ -6,22 +6,22 @@ namespace ZShell::internal { class LidWatcher : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -public: -explicit LidWatcher(QObject* parent = nullptr); + public: + explicit LidWatcher(QObject* parent = nullptr); -signals: -void aboutToSleep(); -void resumed(); -void lockRequested(); -void unlockRequested(); + signals: + void aboutToSleep(); + void resumed(); + void lockRequested(); + void unlockRequested(); -private slots: -void handlePrepareForSleep(bool sleep); -void handleLockRequested(); -void handleUnlockRequested(); + private slots: + void handlePrepareForSleep(bool sleep); + void handleLockRequested(); + void handleUnlockRequested(); }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/linearindicatormanager.cpp b/Plugins/ZShell/Internal/linearindicatormanager.cpp index 655ed80..0a3ee38 100644 --- a/Plugins/ZShell/Internal/linearindicatormanager.cpp +++ b/Plugins/ZShell/Internal/linearindicatormanager.cpp @@ -5,12 +5,12 @@ namespace { constexpr int TOTAL_DURATION_IN_MS = 1800; -constexpr std::array DURATION_TO_MOVE_SEGMENT_ENDS = { 533, 567, 850, 750 }; -constexpr std::array DELAY_TO_MOVE_SEGMENT_ENDS = { 1267, 1000, 333, 0 }; +constexpr std::array DURATION_TO_MOVE_SEGMENT_ENDS = {533, 567, 850, 750}; +constexpr std::array DELAY_TO_MOVE_SEGMENT_ENDS = {1267, 1000, 333, 0}; QEasingCurve curve(const QPointF& c1, const QPointF& c2) { QEasingCurve curve(QEasingCurve::BezierSpline); - curve.addCubicBezierSegment(c1, c2, { 1.0, 1.0 }); + curve.addCubicBezierSegment(c1, c2, {1.0, 1.0}); return curve; } @@ -24,11 +24,7 @@ qreal getFractionInRange(qreal playtime, int start, int duration) { namespace ZShell::controls { LinearIndicatorSegment::LinearIndicatorSegment(int gap, QObject* parent) - : QObject(parent) - , m_startFraction(0) - , m_endFraction(0) - , m_gapSize(gap) { -} + : QObject(parent), m_startFraction(0), m_endFraction(0), m_gapSize(gap) {} qreal LinearIndicatorSegment::startFraction() const { return m_startFraction; @@ -45,24 +41,28 @@ int LinearIndicatorSegment::gapSize() const { LinearIndicatorManager::LinearIndicatorManager(QObject* parent) : QObject(parent) , m_interpolators({ - curve({ 0.2, 0.0 }, { 0.8, 1.0 }), - curve({ 0.4, 0.0 }, { 1.0, 1.0 }), - curve({ 0.0, 0.0 }, { 0.65, 1.0 }), - curve({ 0.1, 0.0 }, { 0.45, 1.0 }), - }) + curve({0.2, 0.0}, {0.8, 1.0}), + curve({0.4, 0.0}, {1.0, 1.0}), + curve({0.0, 0.0}, {0.65, 1.0}), + curve({0.1, 0.0}, {0.45, 1.0}), + }) , m_progress(0) , m_completeEndProgress(0) , m_gap(4) , m_activeIndicators({ - new LinearIndicatorSegment(m_gap, this), - new LinearIndicatorSegment(m_gap, this), - }) { + new LinearIndicatorSegment(m_gap, this), + new LinearIndicatorSegment(m_gap, this), + }) { for (auto el : m_activeIndicators) - QObject::connect(this, &LinearIndicatorManager::updated, el, &LinearIndicatorSegment::updated); + QObject::connect( + this, + &LinearIndicatorManager::updated, + el, + &LinearIndicatorSegment::updated); } QList LinearIndicatorManager::activeIndicators() const { - return { m_activeIndicators.cbegin(), m_activeIndicators.cend() }; + return {m_activeIndicators.cbegin(), m_activeIndicators.cend()}; } qreal LinearIndicatorManager::progress() const { @@ -98,12 +98,19 @@ void LinearIndicatorManager::update(qreal progress) { const auto di = i * 2; auto* const indicator = m_activeIndicators[i]; - auto fraction = getFractionInRange(playtime, DELAY_TO_MOVE_SEGMENT_ENDS[di], DURATION_TO_MOVE_SEGMENT_ENDS[di]); - indicator->m_startFraction = std::clamp(m_interpolators[di].valueForProgress(fraction), 0.0, 1.0); + auto fraction = getFractionInRange( + playtime, + DELAY_TO_MOVE_SEGMENT_ENDS[di], + DURATION_TO_MOVE_SEGMENT_ENDS[di]); + indicator->m_startFraction = + std::clamp(m_interpolators[di].valueForProgress(fraction), 0.0, 1.0); - fraction = - getFractionInRange(playtime, DELAY_TO_MOVE_SEGMENT_ENDS[di + 1], DURATION_TO_MOVE_SEGMENT_ENDS[di + 1]); - indicator->m_endFraction = std::clamp(m_interpolators[di + 1].valueForProgress(fraction), 0.0, 1.0); + fraction = getFractionInRange( + playtime, + DELAY_TO_MOVE_SEGMENT_ENDS[di + 1], + DURATION_TO_MOVE_SEGMENT_ENDS[di + 1]); + indicator->m_endFraction = std::clamp( + m_interpolators[di + 1].valueForProgress(fraction), 0.0, 1.0); } m_progress = progress; diff --git a/Plugins/ZShell/Internal/linearindicatormanager.hpp b/Plugins/ZShell/Internal/linearindicatormanager.hpp index dd2f48c..0eea258 100644 --- a/Plugins/ZShell/Internal/linearindicatormanager.hpp +++ b/Plugins/ZShell/Internal/linearindicatormanager.hpp @@ -11,76 +11,80 @@ namespace ZShell::controls { class LinearIndicatorManager; class LinearIndicatorSegment : public QObject { -Q_OBJECT -QML_ELEMENT - QML_UNCREATABLE("LinearIndicatorSegments can only be retrieved from a " - "LinearIndicatorManager.") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE( + "LinearIndicatorSegments can only be retrieved from a " + "LinearIndicatorManager.") -Q_PROPERTY(qreal startFraction READ startFraction NOTIFY updated FINAL) -Q_PROPERTY(qreal endFraction READ endFraction NOTIFY updated FINAL) -Q_PROPERTY(int gapSize READ gapSize NOTIFY updated FINAL) + Q_PROPERTY(qreal startFraction READ startFraction NOTIFY updated FINAL) + Q_PROPERTY(qreal endFraction READ endFraction NOTIFY updated FINAL) + Q_PROPERTY(int gapSize READ gapSize NOTIFY updated FINAL) -public: -explicit LinearIndicatorSegment(int gap, QObject* parent = nullptr); + public: + explicit LinearIndicatorSegment(int gap, QObject* parent = nullptr); -qreal startFraction() const; -qreal endFraction() const; -int gapSize() const; + qreal startFraction() const; + qreal endFraction() const; + int gapSize() const; -signals: -void updated(); + signals: + void updated(); -private: -qreal m_startFraction; -qreal m_endFraction; -int m_gapSize; + private: + qreal m_startFraction; + qreal m_endFraction; + int m_gapSize; -friend LinearIndicatorManager; + friend LinearIndicatorManager; }; class LinearIndicatorManager : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY( - QList activeIndicators READ activeIndicators CONSTANT FINAL) + Q_PROPERTY( + QList activeIndicators READ + activeIndicators CONSTANT FINAL) -Q_PROPERTY(qreal progress READ progress WRITE update NOTIFY updated FINAL) -Q_PROPERTY(qreal completeEndProgress READ completeEndProgress WRITE updateCompleteEndProgress NOTIFY updated FINAL) -Q_PROPERTY(int gap READ gap WRITE setGap NOTIFY updated FINAL) + Q_PROPERTY(qreal progress READ progress WRITE update NOTIFY updated FINAL) + Q_PROPERTY( + qreal completeEndProgress READ completeEndProgress WRITE + updateCompleteEndProgress NOTIFY updated FINAL) + Q_PROPERTY(int gap READ gap WRITE setGap NOTIFY updated FINAL) -Q_PROPERTY(qreal duration READ duration CONSTANT FINAL) -Q_PROPERTY(qreal completeEndDuration READ completeEndDuration CONSTANT FINAL) + Q_PROPERTY(qreal duration READ duration CONSTANT FINAL) + Q_PROPERTY(qreal completeEndDuration READ completeEndDuration CONSTANT FINAL) -public: -explicit LinearIndicatorManager(QObject* parent = nullptr); + public: + explicit LinearIndicatorManager(QObject* parent = nullptr); -QList activeIndicators() const; + QList activeIndicators() const; -qreal progress() const; -qreal completeEndProgress() const; + qreal progress() const; + qreal completeEndProgress() const; -int gap() const; -void setGap(int gap); + int gap() const; + void setGap(int gap); -int duration() const; -int completeEndDuration() const; + int duration() const; + int completeEndDuration() const; -void update(qreal progress); -void updateCompleteEndProgress(qreal progress); + void update(qreal progress); + void updateCompleteEndProgress(qreal progress); -signals: -void updated(); + signals: + void updated(); -private: -static constexpr int SEGMENTS = 2; + private: + static constexpr int SEGMENTS = 2; -std::array m_interpolators; -qreal m_progress; -qreal m_completeEndProgress; -int m_gap; + std::array m_interpolators; + qreal m_progress; + qreal m_completeEndProgress; + int m_gap; -std::array m_activeIndicators; + std::array m_activeIndicators; }; } // namespace ZShell::controls diff --git a/Plugins/ZShell/Internal/sparklineitem.cpp b/Plugins/ZShell/Internal/sparklineitem.cpp index 830926f..c4f2314 100644 --- a/Plugins/ZShell/Internal/sparklineitem.cpp +++ b/Plugins/ZShell/Internal/sparklineitem.cpp @@ -7,47 +7,46 @@ namespace ZShell::internal { -SparklineItem::SparklineItem(QQuickItem* parent) - : QQuickPaintedItem(parent) { +SparklineItem::SparklineItem(QQuickItem* parent) : QQuickPaintedItem(parent) { setAntialiasing(true); } void SparklineItem::paint(QPainter* painter) { const bool has1 = m_line1 && m_line1->count() >= 2; const bool has2 = m_line2 && m_line2->count() >= 2; - if (!has1 && !has2) - return; + if (!has1 && !has2) return; painter->setRenderHint(QPainter::Antialiasing, true); // Draw line1 first (behind), then line2 (in front) - if (has1) - drawLine(painter, m_line1, m_line1Color, m_line1FillAlpha); - if (has2) - drawLine(painter, m_line2, m_line2Color, m_line2FillAlpha); + if (has1) drawLine(painter, m_line1, m_line1Color, m_line1FillAlpha); + if (has2) drawLine(painter, m_line2, m_line2Color, m_line2FillAlpha); } -void SparklineItem::drawLine(QPainter* painter, CircularBuffer* buffer, const QColor& color, qreal fillAlpha) { - if (m_historyLength < 2) - return; +void SparklineItem::drawLine( + QPainter* painter, + CircularBuffer* buffer, + const QColor& color, + qreal fillAlpha) { + if (m_historyLength < 2) return; const qreal w = width(); const qreal h = height(); const int len = buffer->count(); - if (len < 2 || m_maxValue <= 0.0) - return; + if (len < 2 || m_maxValue <= 0.0) return; const qreal stepX = w / static_cast(m_historyLength - 1); - const qreal startX = w - (len - 1) * stepX - stepX * m_slideProgress + stepX; + const qreal startX = + w - (len - 1) * stepX - stepX * m_slideProgress + stepX; const qreal strokePad = qCeil(m_lineWidth / 2); - const qreal curvePad = 3.0; - const qreal topPad = strokePad + curvePad; + const qreal curvePad = 3.0; + const qreal topPad = strokePad + curvePad; const qreal bottomPad = strokePad; - const qreal plotTop = topPad; + const qreal plotTop = topPad; const qreal plotBottom = h - bottomPad; const qreal fillBottom = h; - const qreal plotH = qMax(1.0, plotBottom - plotTop); + const qreal plotH = qMax(1.0, plotBottom - plotTop); QVector points; points.reserve(len); @@ -93,23 +92,22 @@ void SparklineItem::drawLine(QPainter* painter, CircularBuffer* buffer, const QC } void SparklineItem::connectBuffer(CircularBuffer* buffer) { - if (!buffer) - return; + if (!buffer) return; connect(buffer, &CircularBuffer::valuesChanged, this, [this]() { - update(); - }); + update(); + }); connect(buffer, &QObject::destroyed, this, [this, buffer]() { - if (m_line1 == buffer) { - m_line1 = nullptr; - emit line1Changed(); - } - if (m_line2 == buffer) { - m_line2 = nullptr; - emit line2Changed(); - } - update(); - }); + if (m_line1 == buffer) { + m_line1 = nullptr; + emit line1Changed(); + } + if (m_line2 == buffer) { + m_line2 = nullptr; + emit line2Changed(); + } + update(); + }); } CircularBuffer* SparklineItem::line1() const { @@ -117,10 +115,8 @@ CircularBuffer* SparklineItem::line1() const { } void SparklineItem::setLine1(CircularBuffer* buffer) { - if (m_line1 == buffer) - return; - if (m_line1) - disconnect(m_line1, nullptr, this, nullptr); + if (m_line1 == buffer) return; + if (m_line1) disconnect(m_line1, nullptr, this, nullptr); m_line1 = buffer; connectBuffer(buffer); emit line1Changed(); @@ -132,10 +128,8 @@ CircularBuffer* SparklineItem::line2() const { } void SparklineItem::setLine2(CircularBuffer* buffer) { - if (m_line2 == buffer) - return; - if (m_line2) - disconnect(m_line2, nullptr, this, nullptr); + if (m_line2 == buffer) return; + if (m_line2) disconnect(m_line2, nullptr, this, nullptr); m_line2 = buffer; connectBuffer(buffer); emit line2Changed(); @@ -147,8 +141,7 @@ QColor SparklineItem::line1Color() const { } void SparklineItem::setLine1Color(const QColor& color) { - if (m_line1Color == color) - return; + if (m_line1Color == color) return; m_line1Color = color; emit line1ColorChanged(); update(); @@ -159,8 +152,7 @@ QColor SparklineItem::line2Color() const { } void SparklineItem::setLine2Color(const QColor& color) { - if (m_line2Color == color) - return; + if (m_line2Color == color) return; m_line2Color = color; emit line2ColorChanged(); update(); @@ -171,8 +163,7 @@ qreal SparklineItem::line1FillAlpha() const { } void SparklineItem::setLine1FillAlpha(qreal alpha) { - if (qFuzzyCompare(m_line1FillAlpha, alpha)) - return; + if (qFuzzyCompare(m_line1FillAlpha, alpha)) return; m_line1FillAlpha = alpha; emit line1FillAlphaChanged(); update(); @@ -183,8 +174,7 @@ qreal SparklineItem::line2FillAlpha() const { } void SparklineItem::setLine2FillAlpha(qreal alpha) { - if (qFuzzyCompare(m_line2FillAlpha, alpha)) - return; + if (qFuzzyCompare(m_line2FillAlpha, alpha)) return; m_line2FillAlpha = alpha; emit line2FillAlphaChanged(); update(); @@ -195,8 +185,7 @@ qreal SparklineItem::maxValue() const { } void SparklineItem::setMaxValue(qreal value) { - if (qFuzzyCompare(m_maxValue, value)) - return; + if (qFuzzyCompare(m_maxValue, value)) return; m_maxValue = value; emit maxValueChanged(); update(); @@ -207,8 +196,7 @@ qreal SparklineItem::slideProgress() const { } void SparklineItem::setSlideProgress(qreal progress) { - if (qFuzzyCompare(m_slideProgress, progress)) - return; + if (qFuzzyCompare(m_slideProgress, progress)) return; m_slideProgress = progress; emit slideProgressChanged(); update(); @@ -219,8 +207,7 @@ int SparklineItem::historyLength() const { } void SparklineItem::setHistoryLength(int length) { - if (m_historyLength == length) - return; + if (m_historyLength == length) return; m_historyLength = length; emit historyLengthChanged(); update(); @@ -231,8 +218,7 @@ qreal SparklineItem::lineWidth() const { } void SparklineItem::setLineWidth(qreal width) { - if (qFuzzyCompare(m_lineWidth, width)) - return; + if (qFuzzyCompare(m_lineWidth, width)) return; m_lineWidth = width; emit lineWidthChanged(); update(); diff --git a/Plugins/ZShell/Internal/sparklineitem.hpp b/Plugins/ZShell/Internal/sparklineitem.hpp index 0583da8..3cea1ed 100644 --- a/Plugins/ZShell/Internal/sparklineitem.hpp +++ b/Plugins/ZShell/Internal/sparklineitem.hpp @@ -10,81 +10,102 @@ namespace ZShell::internal { class SparklineItem : public QQuickPaintedItem { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(CircularBuffer* line1 READ line1 WRITE setLine1 NOTIFY line1Changed) -Q_PROPERTY(CircularBuffer* line2 READ line2 WRITE setLine2 NOTIFY line2Changed) -Q_PROPERTY(QColor line1Color READ line1Color WRITE setLine1Color NOTIFY line1ColorChanged) -Q_PROPERTY(QColor line2Color READ line2Color WRITE setLine2Color NOTIFY line2ColorChanged) -Q_PROPERTY(qreal line1FillAlpha READ line1FillAlpha WRITE setLine1FillAlpha NOTIFY line1FillAlphaChanged) -Q_PROPERTY(qreal line2FillAlpha READ line2FillAlpha WRITE setLine2FillAlpha NOTIFY line2FillAlphaChanged) -Q_PROPERTY(qreal maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged) -Q_PROPERTY(qreal slideProgress READ slideProgress WRITE setSlideProgress NOTIFY slideProgressChanged) -Q_PROPERTY(int historyLength READ historyLength WRITE setHistoryLength NOTIFY historyLengthChanged) -Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged) + Q_PROPERTY( + CircularBuffer* line1 READ line1 WRITE setLine1 NOTIFY line1Changed) + Q_PROPERTY( + CircularBuffer* line2 READ line2 WRITE setLine2 NOTIFY line2Changed) + Q_PROPERTY( + QColor line1Color READ line1Color WRITE setLine1Color NOTIFY + line1ColorChanged) + Q_PROPERTY( + QColor line2Color READ line2Color WRITE setLine2Color NOTIFY + line2ColorChanged) + Q_PROPERTY( + qreal line1FillAlpha READ line1FillAlpha WRITE setLine1FillAlpha NOTIFY + line1FillAlphaChanged) + Q_PROPERTY( + qreal line2FillAlpha READ line2FillAlpha WRITE setLine2FillAlpha NOTIFY + line2FillAlphaChanged) + Q_PROPERTY( + qreal maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged) + Q_PROPERTY( + qreal slideProgress READ slideProgress WRITE setSlideProgress NOTIFY + slideProgressChanged) + Q_PROPERTY( + int historyLength READ historyLength WRITE setHistoryLength NOTIFY + historyLengthChanged) + Q_PROPERTY( + qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY + lineWidthChanged) -public: -explicit SparklineItem(QQuickItem* parent = nullptr); + public: + explicit SparklineItem(QQuickItem* parent = nullptr); -void paint(QPainter* painter) override; + void paint(QPainter* painter) override; -[[nodiscard]] CircularBuffer* line1() const; -void setLine1(CircularBuffer* buffer); + [[nodiscard]] CircularBuffer* line1() const; + void setLine1(CircularBuffer* buffer); -[[nodiscard]] CircularBuffer* line2() const; -void setLine2(CircularBuffer* buffer); + [[nodiscard]] CircularBuffer* line2() const; + void setLine2(CircularBuffer* buffer); -[[nodiscard]] QColor line1Color() const; -void setLine1Color(const QColor& color); + [[nodiscard]] QColor line1Color() const; + void setLine1Color(const QColor& color); -[[nodiscard]] QColor line2Color() const; -void setLine2Color(const QColor& color); + [[nodiscard]] QColor line2Color() const; + void setLine2Color(const QColor& color); -[[nodiscard]] qreal line1FillAlpha() const; -void setLine1FillAlpha(qreal alpha); + [[nodiscard]] qreal line1FillAlpha() const; + void setLine1FillAlpha(qreal alpha); -[[nodiscard]] qreal line2FillAlpha() const; -void setLine2FillAlpha(qreal alpha); + [[nodiscard]] qreal line2FillAlpha() const; + void setLine2FillAlpha(qreal alpha); -[[nodiscard]] qreal maxValue() const; -void setMaxValue(qreal value); + [[nodiscard]] qreal maxValue() const; + void setMaxValue(qreal value); -[[nodiscard]] qreal slideProgress() const; -void setSlideProgress(qreal progress); + [[nodiscard]] qreal slideProgress() const; + void setSlideProgress(qreal progress); -[[nodiscard]] int historyLength() const; -void setHistoryLength(int length); + [[nodiscard]] int historyLength() const; + void setHistoryLength(int length); -[[nodiscard]] qreal lineWidth() const; -void setLineWidth(qreal width); + [[nodiscard]] qreal lineWidth() const; + void setLineWidth(qreal width); -signals: -void line1Changed(); -void line2Changed(); -void line1ColorChanged(); -void line2ColorChanged(); -void line1FillAlphaChanged(); -void line2FillAlphaChanged(); -void maxValueChanged(); -void slideProgressChanged(); -void historyLengthChanged(); -void lineWidthChanged(); + signals: + void line1Changed(); + void line2Changed(); + void line1ColorChanged(); + void line2ColorChanged(); + void line1FillAlphaChanged(); + void line2FillAlphaChanged(); + void maxValueChanged(); + void slideProgressChanged(); + void historyLengthChanged(); + void lineWidthChanged(); -private: -void drawLine(QPainter* painter, CircularBuffer* buffer, const QColor& color, qreal fillAlpha); -void connectBuffer(CircularBuffer* buffer); + private: + void drawLine( + QPainter* painter, + CircularBuffer* buffer, + const QColor& color, + qreal fillAlpha); + void connectBuffer(CircularBuffer* buffer); -CircularBuffer* m_line1 = nullptr; -CircularBuffer* m_line2 = nullptr; -QColor m_line1Color; -QColor m_line2Color; -qreal m_line1FillAlpha = 0.15; -qreal m_line2FillAlpha = 0.2; -qreal m_maxValue = 1024.0; -qreal m_slideProgress = 0.0; -int m_historyLength = 30; -qreal m_lineWidth = 2.0; + CircularBuffer* m_line1 = nullptr; + CircularBuffer* m_line2 = nullptr; + QColor m_line1Color; + QColor m_line2Color; + qreal m_line1FillAlpha = 0.15; + qreal m_line2FillAlpha = 0.2; + qreal m_maxValue = 1024.0; + qreal m_slideProgress = 0.0; + int m_historyLength = 30; + qreal m_lineWidth = 2.0; }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/visualizerbars.cpp b/Plugins/ZShell/Internal/visualizerbars.cpp index fb77d70..25d0d8d 100644 --- a/Plugins/ZShell/Internal/visualizerbars.cpp +++ b/Plugins/ZShell/Internal/visualizerbars.cpp @@ -9,14 +9,12 @@ namespace ZShell::internal { -VisualizerBars::VisualizerBars(QQuickItem* parent) - : QQuickPaintedItem(parent) { +VisualizerBars::VisualizerBars(QQuickItem* parent) : QQuickPaintedItem(parent) { setAntialiasing(true); } void VisualizerBars::advance(qreal dt) { - if (m_displayValues.isEmpty() || m_settled) - return; + if (m_displayValues.isEmpty() || m_settled) return; // dt is in seconds (from FrameAnimation.frameTime), convert to ms const qreal dtMs = dt * 1000.0; @@ -45,8 +43,7 @@ void VisualizerBars::advance(qreal dt) { } void VisualizerBars::paint(QPainter* painter) { - if (m_displayValues.isEmpty()) - return; + if (m_displayValues.isEmpty()) return; painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); @@ -68,15 +65,13 @@ void VisualizerBars::drawSide(QPainter* painter, bool rightSide) { const qreal h = height(); const auto count = m_displayValues.size(); - if (count == 0) - return; + if (count == 0) return; const qreal sideWidth = w * 0.4; const qreal slotWidth = sideWidth / static_cast(count); const qreal barWidth = slotWidth - m_spacing; - if (barWidth <= 0) - return; + if (barWidth <= 0) return; const qreal sideOffset = rightSide ? w * 0.6 : 0; const qreal maxBarHeight = h * 0.4; @@ -86,12 +81,11 @@ void VisualizerBars::drawSide(QPainter* painter, bool rightSide) { const qreal value = std::clamp(m_displayValues[valueIndex], 0.0, 1.0); const qreal barHeight = value * maxBarHeight; - if (barHeight <= 0) - continue; + if (barHeight <= 0) continue; const qreal x = static_cast(i) * slotWidth + sideOffset; const qreal y = h - barHeight; - const qreal r = std::min({ m_rounding, barWidth / 2.0, barHeight }); + const qreal r = std::min({m_rounding, barWidth / 2.0, barHeight}); QPainterPath path; path.moveTo(x, h); @@ -141,8 +135,7 @@ QColor VisualizerBars::primaryColor() const { } void VisualizerBars::setPrimaryColor(const QColor& color) { - if (m_primaryColor == color) - return; + if (m_primaryColor == color) return; m_primaryColor = color; emit primaryColorChanged(); update(); @@ -153,8 +146,7 @@ QColor VisualizerBars::secondaryColor() const { } void VisualizerBars::setSecondaryColor(const QColor& color) { - if (m_secondaryColor == color) - return; + if (m_secondaryColor == color) return; m_secondaryColor = color; emit secondaryColorChanged(); update(); @@ -165,8 +157,7 @@ qreal VisualizerBars::rounding() const { } void VisualizerBars::setRounding(qreal rounding) { - if (qFuzzyCompare(m_rounding, rounding)) - return; + if (qFuzzyCompare(m_rounding, rounding)) return; m_rounding = rounding; emit roundingChanged(); update(); @@ -177,8 +168,7 @@ qreal VisualizerBars::spacing() const { } void VisualizerBars::setSpacing(qreal spacing) { - if (qFuzzyCompare(m_spacing, spacing)) - return; + if (qFuzzyCompare(m_spacing, spacing)) return; m_spacing = spacing; emit spacingChanged(); update(); @@ -189,8 +179,7 @@ int VisualizerBars::animationDuration() const { } void VisualizerBars::setAnimationDuration(int duration) { - if (m_animationDuration == duration) - return; + if (m_animationDuration == duration) return; m_animationDuration = duration; emit animationDurationChanged(); } diff --git a/Plugins/ZShell/Internal/visualizerbars.hpp b/Plugins/ZShell/Internal/visualizerbars.hpp index 64651cd..fafdb4b 100644 --- a/Plugins/ZShell/Internal/visualizerbars.hpp +++ b/Plugins/ZShell/Internal/visualizerbars.hpp @@ -9,64 +9,72 @@ namespace ZShell::internal { class VisualizerBars : public QQuickPaintedItem { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(QVector values READ values WRITE setValues NOTIFY valuesChanged) -Q_PROPERTY(QColor primaryColor READ primaryColor WRITE setPrimaryColor NOTIFY primaryColorChanged) -Q_PROPERTY(QColor secondaryColor READ secondaryColor WRITE setSecondaryColor NOTIFY secondaryColorChanged) -Q_PROPERTY(qreal rounding READ rounding WRITE setRounding NOTIFY roundingChanged) -Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) -Q_PROPERTY(int animationDuration READ animationDuration WRITE setAnimationDuration NOTIFY animationDurationChanged) -Q_PROPERTY(bool settled READ settled NOTIFY settledChanged) + Q_PROPERTY( + QVector values READ values WRITE setValues NOTIFY valuesChanged) + Q_PROPERTY( + QColor primaryColor READ primaryColor WRITE setPrimaryColor NOTIFY + primaryColorChanged) + Q_PROPERTY( + QColor secondaryColor READ secondaryColor WRITE setSecondaryColor NOTIFY + secondaryColorChanged) + Q_PROPERTY( + qreal rounding READ rounding WRITE setRounding NOTIFY roundingChanged) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) + Q_PROPERTY( + int animationDuration READ animationDuration WRITE setAnimationDuration + NOTIFY animationDurationChanged) + Q_PROPERTY(bool settled READ settled NOTIFY settledChanged) -public: -explicit VisualizerBars(QQuickItem* parent = nullptr); + public: + explicit VisualizerBars(QQuickItem* parent = nullptr); -void paint(QPainter* painter) override; + void paint(QPainter* painter) override; -Q_INVOKABLE void advance(qreal dt); + Q_INVOKABLE void advance(qreal dt); -[[nodiscard]] QVector values() const; -void setValues(const QVector& values); + [[nodiscard]] QVector values() const; + void setValues(const QVector& values); -[[nodiscard]] QColor primaryColor() const; -void setPrimaryColor(const QColor& color); + [[nodiscard]] QColor primaryColor() const; + void setPrimaryColor(const QColor& color); -[[nodiscard]] QColor secondaryColor() const; -void setSecondaryColor(const QColor& color); + [[nodiscard]] QColor secondaryColor() const; + void setSecondaryColor(const QColor& color); -[[nodiscard]] qreal rounding() const; -void setRounding(qreal rounding); + [[nodiscard]] qreal rounding() const; + void setRounding(qreal rounding); -[[nodiscard]] qreal spacing() const; -void setSpacing(qreal spacing); + [[nodiscard]] qreal spacing() const; + void setSpacing(qreal spacing); -[[nodiscard]] int animationDuration() const; -void setAnimationDuration(int duration); + [[nodiscard]] int animationDuration() const; + void setAnimationDuration(int duration); -[[nodiscard]] bool settled() const; + [[nodiscard]] bool settled() const; -signals: -void valuesChanged(); -void primaryColorChanged(); -void secondaryColorChanged(); -void roundingChanged(); -void spacingChanged(); -void animationDurationChanged(); -void settledChanged(); + signals: + void valuesChanged(); + void primaryColorChanged(); + void secondaryColorChanged(); + void roundingChanged(); + void spacingChanged(); + void animationDurationChanged(); + void settledChanged(); -private: -void drawSide(QPainter* painter, bool rightSide); + private: + void drawSide(QPainter* painter, bool rightSide); -QVector m_targetValues; -QVector m_displayValues; -QColor m_primaryColor; -QColor m_secondaryColor; -qreal m_rounding = 0.0; -qreal m_spacing = 0.0; -int m_animationDuration = 200; -bool m_settled = true; + QVector m_targetValues; + QVector m_displayValues; + QColor m_primaryColor; + QColor m_secondaryColor; + qreal m_rounding = 0.0; + qreal m_spacing = 0.0; + int m_animationDuration = 200; + bool m_settled = true; }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/wallpaperimage.cpp b/Plugins/ZShell/Internal/wallpaperimage.cpp index c48aab4..e0e6da9 100644 --- a/Plugins/ZShell/Internal/wallpaperimage.cpp +++ b/Plugins/ZShell/Internal/wallpaperimage.cpp @@ -7,15 +7,16 @@ #include #include #include -#include namespace ZShell::internal { -WallpaperImage::WallpaperImage(QQuickItem *parent) - : QQuickItem(parent) -{ +WallpaperImage::WallpaperImage(QQuickItem* parent) : QQuickItem(parent) { setFlag(ItemHasContents, true); - connect(&m_imageWatcher, &QFutureWatcher::finished, this, &WallpaperImage::handleImageLoaded); + connect( + &m_imageWatcher, + &QFutureWatcher::finished, + this, + &WallpaperImage::handleImageLoaded); } WallpaperImage::~WallpaperImage() { @@ -23,14 +24,13 @@ WallpaperImage::~WallpaperImage() { } void WallpaperImage::setStatus(const Status s) { - if (m_status == s) - return; + if (m_status == s) return; m_status = s; emit statusChanged(); } -void WallpaperImage::setSource(const QUrl &source) { +void WallpaperImage::setSource(const QUrl& source) { if (m_source == source) return; m_source = source; emit sourceChanged(); @@ -39,7 +39,7 @@ void WallpaperImage::setSource(const QUrl &source) { loadImage(); } -void WallpaperImage::setScreenResolution(const QSize &screenResolution) { +void WallpaperImage::setScreenResolution(const QSize& screenResolution) { if (m_screenResolution == screenResolution) return; m_screenResolution = screenResolution; emit screenResolutionChanged(); @@ -86,11 +86,16 @@ void WallpaperImage::setCropHeight(qreal h) { QString WallpaperImage::getCacheFilePath() const { if (m_source.isEmpty() || m_screenResolution.isEmpty()) return QString(); - QString cachePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/zshell/imagecache"; + QString cachePath = + QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + + "/zshell/imagecache"; QDir().mkpath(cachePath); - QString id = m_source.toString() + "_" + QString::number(m_screenResolution.width()) + "x" + QString::number(m_screenResolution.height()); - QByteArray hash = QCryptographicHash::hash(id.toUtf8(), QCryptographicHash::Md5).toHex(); + QString id = m_source.toString() + "_" + + QString::number(m_screenResolution.width()) + "x" + + QString::number(m_screenResolution.height()); + QByteArray hash = + QCryptographicHash::hash(id.toUtf8(), QCryptographicHash::Md5).toHex(); return cachePath + "/" + hash + ".png"; } @@ -102,7 +107,8 @@ void WallpaperImage::loadImage() { } QString cacheFile = getCacheFilePath(); - QString sourceFile = m_source.isLocalFile() ? m_source.toLocalFile() : m_source.toString(); + QString sourceFile = m_source.isLocalFile() ? m_source.toLocalFile() + : m_source.toString(); if (sourceFile.startsWith("qrc:/")) { sourceFile = sourceFile.mid(3); @@ -110,8 +116,10 @@ void WallpaperImage::loadImage() { QSize targetRes = m_screenResolution; - QFuture future = QtConcurrent::run([sourceFile, cacheFile, targetRes]() -> QImage { - if (!targetRes.isEmpty() && !cacheFile.isEmpty() && QFileInfo::exists(cacheFile)) { + QFuture future = + QtConcurrent::run([sourceFile, cacheFile, targetRes]() -> QImage { + if (!targetRes.isEmpty() && !cacheFile.isEmpty() && + QFileInfo::exists(cacheFile)) { QImage cached(cacheFile); if (!cached.isNull()) return cached; } @@ -123,8 +131,12 @@ void WallpaperImage::loadImage() { return original; } - if (original.width() > targetRes.width() || original.height() > targetRes.height()) { - QImage scaled = original.scaled(targetRes, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + if (original.width() > targetRes.width() || + original.height() > targetRes.height()) { + QImage scaled = original.scaled( + targetRes, + Qt::KeepAspectRatioByExpanding, + Qt::SmoothTransformation); if (!cacheFile.isEmpty()) scaled.save(cacheFile, "PNG"); return scaled; } @@ -145,8 +157,9 @@ void WallpaperImage::handleImageLoaded() { update(); } -QSGNode *WallpaperImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { - auto *node = static_cast(oldNode); +QSGNode* WallpaperImage::updatePaintNode( + QSGNode* oldNode, UpdatePaintNodeData*) { + auto* node = static_cast(oldNode); if (m_image.isNull()) { delete node; @@ -159,7 +172,8 @@ QSGNode *WallpaperImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * if (m_textureDirty) { if (m_texture) delete m_texture; - m_texture = window()->createTextureFromImage(m_image, QQuickWindow::TextureHasAlphaChannel); + m_texture = window()->createTextureFromImage( + m_image, QQuickWindow::TextureHasAlphaChannel); m_textureDirty = false; } @@ -175,8 +189,7 @@ QSGNode *WallpaperImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * m_cropX * m_texture->textureSize().width(), m_cropY * m_texture->textureSize().height(), cW * m_texture->textureSize().width(), - cH * m_texture->textureSize().height() - ); + cH * m_texture->textureSize().height()); QRectF bounds = boundingRect(); if (bounds.isEmpty() || reqRect.isEmpty()) return node; @@ -202,25 +215,23 @@ QSGNode *WallpaperImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * sourceRect.x() / m_texture->textureSize().width(), sourceRect.y() / m_texture->textureSize().height(), sourceRect.width() / m_texture->textureSize().width(), - sourceRect.height() / m_texture->textureSize().height() - ); + sourceRect.height() / m_texture->textureSize().height()); bool changed = false; - auto updateIfChanged = [&](qreal &dst, qreal value) { - if (!qFuzzyCompare(dst, value)) { - dst = value; - changed = true; - } - }; + auto updateIfChanged = [&](qreal& dst, qreal value) { + if (!qFuzzyCompare(dst, value)) { + dst = value; + changed = true; + } + }; updateIfChanged(m_actualCropX, normalizedActual.x()); updateIfChanged(m_actualCropY, normalizedActual.y()); updateIfChanged(m_actualCropWidth, normalizedActual.width()); updateIfChanged(m_actualCropHeight, normalizedActual.height()); - if (changed) - emit actualCropChanged(); + if (changed) emit actualCropChanged(); node->setSourceRect(sourceRect); } diff --git a/Plugins/ZShell/Internal/wallpaperimage.hpp b/Plugins/ZShell/Internal/wallpaperimage.hpp index 3c00fe4..9c0d2a9 100644 --- a/Plugins/ZShell/Internal/wallpaperimage.hpp +++ b/Plugins/ZShell/Internal/wallpaperimage.hpp @@ -11,129 +11,109 @@ namespace ZShell::internal { class WallpaperImage : public QQuickItem { -Q_OBJECT -QML_NAMED_ELEMENT(WallpaperImage) -Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) -Q_PROPERTY(QSize screenResolution READ screenResolution WRITE setScreenResolution NOTIFY screenResolutionChanged) -Q_PROPERTY(qreal zoom READ zoom WRITE setZoom NOTIFY zoomChanged) -Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_OBJECT + QML_NAMED_ELEMENT(WallpaperImage) + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY( + QSize screenResolution READ screenResolution WRITE setScreenResolution + NOTIFY screenResolutionChanged) + Q_PROPERTY(qreal zoom READ zoom WRITE setZoom NOTIFY zoomChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) -Q_PROPERTY(qreal actualCropX READ actualCropX NOTIFY actualCropChanged) -Q_PROPERTY(qreal actualCropY READ actualCropY NOTIFY actualCropChanged) -Q_PROPERTY(qreal actualCropWidth READ actualCropWidth NOTIFY actualCropChanged) -Q_PROPERTY(qreal actualCropHeight READ actualCropHeight NOTIFY actualCropChanged) + Q_PROPERTY(qreal actualCropX READ actualCropX NOTIFY actualCropChanged) + Q_PROPERTY(qreal actualCropY READ actualCropY NOTIFY actualCropChanged) + Q_PROPERTY( + qreal actualCropWidth READ actualCropWidth NOTIFY actualCropChanged) + Q_PROPERTY( + qreal actualCropHeight READ actualCropHeight NOTIFY actualCropChanged) -Q_PROPERTY(qreal cropX READ cropX WRITE setCropX NOTIFY cropXChanged) -Q_PROPERTY(qreal cropY READ cropY WRITE setCropY NOTIFY cropYChanged) -Q_PROPERTY(qreal cropWidth READ cropWidth WRITE setCropWidth NOTIFY cropWidthChanged) -Q_PROPERTY(qreal cropHeight READ cropHeight WRITE setCropHeight NOTIFY cropHeightChanged) + Q_PROPERTY(qreal cropX READ cropX WRITE setCropX NOTIFY cropXChanged) + Q_PROPERTY(qreal cropY READ cropY WRITE setCropY NOTIFY cropYChanged) + Q_PROPERTY( + qreal cropWidth READ cropWidth WRITE setCropWidth NOTIFY + cropWidthChanged) + Q_PROPERTY( + qreal cropHeight READ cropHeight WRITE setCropHeight NOTIFY + cropHeightChanged) -public: -explicit WallpaperImage(QQuickItem *parent = nullptr); -~WallpaperImage() override; + public: + explicit WallpaperImage(QQuickItem* parent = nullptr); + ~WallpaperImage() override; -enum Status { - Null, - Ready, - Loading, - Error -}; -Q_ENUM(Status) + enum Status { Null, Ready, Loading, Error }; + Q_ENUM(Status) -Status status() const { - return m_status; -} + Status status() const { return m_status; } -QUrl source() const { - return m_source; -} -void setSource(const QUrl &source); + QUrl source() const { return m_source; } + void setSource(const QUrl& source); -QSize screenResolution() const { - return m_screenResolution; -} -void setScreenResolution(const QSize &screenResolution); + QSize screenResolution() const { return m_screenResolution; } + void setScreenResolution(const QSize& screenResolution); -qreal zoom() const { - return m_zoom; -} -void setZoom(qreal zoom); + qreal zoom() const { return m_zoom; } + void setZoom(qreal zoom); -qreal actualCropX() const { - return m_actualCropX; -} + qreal actualCropX() const { return m_actualCropX; } -qreal actualCropY() const { - return m_actualCropY; -} + qreal actualCropY() const { return m_actualCropY; } -qreal actualCropWidth() const { - return m_actualCropWidth; -} + qreal actualCropWidth() const { return m_actualCropWidth; } -qreal actualCropHeight() const { - return m_actualCropHeight; -} + qreal actualCropHeight() const { return m_actualCropHeight; } -qreal cropX() const { - return m_cropX; -} -void setCropX(qreal x); + qreal cropX() const { return m_cropX; } + void setCropX(qreal x); -qreal cropY() const { - return m_cropY; -} -void setCropY(qreal y); + qreal cropY() const { return m_cropY; } + void setCropY(qreal y); -qreal cropWidth() const { - return m_cropWidth; -} -void setCropWidth(qreal w); + qreal cropWidth() const { return m_cropWidth; } + void setCropWidth(qreal w); -qreal cropHeight() const { - return m_cropHeight; -} -void setCropHeight(qreal h); + qreal cropHeight() const { return m_cropHeight; } + void setCropHeight(qreal h); -protected: -QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override; + protected: + QSGNode* updatePaintNode( + QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData) override; -signals: -void sourceChanged(); -void screenResolutionChanged(); -void zoomChanged(); -void actualCropChanged(); -void cropXChanged(); -void cropYChanged(); -void cropWidthChanged(); -void cropHeightChanged(); -void statusChanged(); + signals: + void sourceChanged(); + void screenResolutionChanged(); + void zoomChanged(); + void actualCropChanged(); + void cropXChanged(); + void cropYChanged(); + void cropWidthChanged(); + void cropHeightChanged(); + void statusChanged(); -private: -void loadImage(); -void handleImageLoaded(); -QString getCacheFilePath() const; -void setStatus(const Status s); + private: + void loadImage(); + void handleImageLoaded(); + QString getCacheFilePath() const; + void setStatus(const Status s); -Status m_status = Null; -QUrl m_source; -QSize m_screenResolution; -qreal m_zoom = 1.0; + Status m_status = Null; + QUrl m_source; + QSize m_screenResolution; + qreal m_zoom = 1.0; -qreal m_actualCropX = 0.0; -qreal m_actualCropY = 0.0; -qreal m_actualCropWidth = 1.0; -qreal m_actualCropHeight = 1.0; + qreal m_actualCropX = 0.0; + qreal m_actualCropY = 0.0; + qreal m_actualCropWidth = 1.0; + qreal m_actualCropHeight = 1.0; -qreal m_cropX = 0.0; -qreal m_cropY = 0.0; -qreal m_cropWidth = 1.0; -qreal m_cropHeight = 1.0; + qreal m_cropX = 0.0; + qreal m_cropY = 0.0; + qreal m_cropWidth = 1.0; + qreal m_cropHeight = 1.0; -QImage m_image; -QSGTexture *m_texture = nullptr; -bool m_textureDirty = false; -QFutureWatcher m_imageWatcher; + QImage m_image; + QSGTexture* m_texture = nullptr; + bool m_textureDirty = false; + QFutureWatcher m_imageWatcher; }; } // namespace ZShell::internal diff --git a/Plugins/ZShell/Models/filesystemmodel.cpp b/Plugins/ZShell/Models/filesystemmodel.cpp index 790cefa..d0769d5 100644 --- a/Plugins/ZShell/Models/filesystemmodel.cpp +++ b/Plugins/ZShell/Models/filesystemmodel.cpp @@ -6,474 +6,512 @@ namespace ZShell::models { -FileSystemEntry::FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent) - : QObject(parent) - , m_fileInfo(path) - , m_path(path) - , m_relativePath(relativePath) - , m_isImageInitialised(false) - , m_mimeTypeInitialised(false) {} +FileSystemEntry::FileSystemEntry( + const QString& path, const QString& relativePath, QObject* parent) + : QObject(parent) + , m_fileInfo(path) + , m_path(path) + , m_relativePath(relativePath) + , m_isImageInitialised(false) + , m_mimeTypeInitialised(false) {} QString FileSystemEntry::path() const { - return m_path; + return m_path; }; QString FileSystemEntry::relativePath() const { - return m_relativePath; + return m_relativePath; }; QString FileSystemEntry::name() const { - return m_fileInfo.fileName(); + return m_fileInfo.fileName(); }; QString FileSystemEntry::baseName() const { - return m_fileInfo.baseName(); + return m_fileInfo.baseName(); }; QString FileSystemEntry::parentDir() const { - return m_fileInfo.absolutePath(); + return m_fileInfo.absolutePath(); }; QString FileSystemEntry::suffix() const { - return m_fileInfo.completeSuffix(); + return m_fileInfo.completeSuffix(); }; qint64 FileSystemEntry::size() const { - return m_fileInfo.size(); + return m_fileInfo.size(); }; bool FileSystemEntry::isDir() const { - return m_fileInfo.isDir(); + return m_fileInfo.isDir(); }; bool FileSystemEntry::isImage() const { - if (!m_isImageInitialised) { - QImageReader reader(m_path); - m_isImage = reader.canRead(); - m_isImageInitialised = true; - } - return m_isImage; + if (!m_isImageInitialised) { + QImageReader reader(m_path); + m_isImage = reader.canRead(); + m_isImageInitialised = true; + } + return m_isImage; } QString FileSystemEntry::mimeType() const { - if (!m_mimeTypeInitialised) { - const QMimeDatabase db; - m_mimeType = db.mimeTypeForFile(m_path).name(); - m_mimeTypeInitialised = true; - } - return m_mimeType; + if (!m_mimeTypeInitialised) { + const QMimeDatabase db; + m_mimeType = db.mimeTypeForFile(m_path).name(); + m_mimeTypeInitialised = true; + } + return m_mimeType; } void FileSystemEntry::updateRelativePath(const QDir& dir) { - const auto relPath = dir.relativeFilePath(m_path); - if (m_relativePath != relPath) { - m_relativePath = relPath; - emit relativePathChanged(); - } + const auto relPath = dir.relativeFilePath(m_path); + if (m_relativePath != relPath) { + m_relativePath = relPath; + emit relativePathChanged(); + } } FileSystemModel::FileSystemModel(QObject* parent) - : QAbstractListModel(parent) - , m_recursive(false) - , m_watchChanges(true) - , m_showHidden(false) - , m_filter(NoFilter) { - connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &FileSystemModel::watchDirIfRecursive); - connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &FileSystemModel::updateEntriesForDir); + : QAbstractListModel(parent) + , m_recursive(false) + , m_watchChanges(true) + , m_showHidden(false) + , m_filter(NoFilter) { + connect( + &m_watcher, + &QFileSystemWatcher::directoryChanged, + this, + &FileSystemModel::watchDirIfRecursive); + connect( + &m_watcher, + &QFileSystemWatcher::directoryChanged, + this, + &FileSystemModel::updateEntriesForDir); } int FileSystemModel::rowCount(const QModelIndex& parent) const { - if (parent != QModelIndex()) { - return 0; - } - return static_cast(m_entries.size()); + if (parent != QModelIndex()) { + return 0; + } + return static_cast(m_entries.size()); } QVariant FileSystemModel::data(const QModelIndex& index, int role) const { - if (role != Qt::UserRole || !index.isValid() || index.row() >= m_entries.size()) { - return QVariant(); - } - return QVariant::fromValue(m_entries.at(index.row())); + if (role != Qt::UserRole || !index.isValid() || + index.row() >= m_entries.size()) { + return QVariant(); + } + return QVariant::fromValue(m_entries.at(index.row())); } QHash FileSystemModel::roleNames() const { - return { { Qt::UserRole, "modelData" } }; + return {{Qt::UserRole, "modelData"}}; } QString FileSystemModel::path() const { - return m_path; + return m_path; } void FileSystemModel::setPath(const QString& path) { - if (m_path == path) { - return; - } + if (m_path == path) { + return; + } - m_path = path; - emit pathChanged(); + m_path = path; + emit pathChanged(); - m_dir.setPath(m_path); + m_dir.setPath(m_path); - for (const auto& entry : std::as_const(m_entries)) { - entry->updateRelativePath(m_dir); - } + for (const auto& entry : std::as_const(m_entries)) { + entry->updateRelativePath(m_dir); + } - update(); + update(); } bool FileSystemModel::recursive() const { - return m_recursive; + return m_recursive; } void FileSystemModel::setRecursive(bool recursive) { - if (m_recursive == recursive) { - return; - } + if (m_recursive == recursive) { + return; + } - m_recursive = recursive; - emit recursiveChanged(); + m_recursive = recursive; + emit recursiveChanged(); - update(); + update(); } bool FileSystemModel::watchChanges() const { - return m_watchChanges; + return m_watchChanges; } void FileSystemModel::setWatchChanges(bool watchChanges) { - if (m_watchChanges == watchChanges) { - return; - } + if (m_watchChanges == watchChanges) { + return; + } - m_watchChanges = watchChanges; - emit watchChangesChanged(); + m_watchChanges = watchChanges; + emit watchChangesChanged(); - update(); + update(); } bool FileSystemModel::showHidden() const { - return m_showHidden; + return m_showHidden; } void FileSystemModel::setShowHidden(bool showHidden) { - if (m_showHidden == showHidden) { - return; - } + if (m_showHidden == showHidden) { + return; + } - m_showHidden = showHidden; - emit showHiddenChanged(); + m_showHidden = showHidden; + emit showHiddenChanged(); - update(); + update(); } bool FileSystemModel::sortReverse() const { - return m_sortReverse; + return m_sortReverse; } void FileSystemModel::setSortReverse(bool sortReverse) { - if (m_sortReverse == sortReverse) { - return; - } + if (m_sortReverse == sortReverse) { + return; + } - m_sortReverse = sortReverse; - emit sortReverseChanged(); + m_sortReverse = sortReverse; + emit sortReverseChanged(); - update(); + update(); } FileSystemModel::Filter FileSystemModel::filter() const { - return m_filter; + return m_filter; } void FileSystemModel::setFilter(Filter filter) { - if (m_filter == filter) { - return; - } + if (m_filter == filter) { + return; + } - m_filter = filter; - emit filterChanged(); + m_filter = filter; + emit filterChanged(); - update(); + update(); } QStringList FileSystemModel::nameFilters() const { - return m_nameFilters; + return m_nameFilters; } void FileSystemModel::setNameFilters(const QStringList& nameFilters) { - if (m_nameFilters == nameFilters) { - return; - } + if (m_nameFilters == nameFilters) { + return; + } - m_nameFilters = nameFilters; - emit nameFiltersChanged(); + m_nameFilters = nameFilters; + emit nameFiltersChanged(); - update(); + update(); } QQmlListProperty FileSystemModel::entries() { - return QQmlListProperty(this, &m_entries); + return QQmlListProperty(this, &m_entries); } void FileSystemModel::watchDirIfRecursive(const QString& path) { - if (m_recursive && m_watchChanges) { - const auto currentDir = m_dir; - const bool showHidden = m_showHidden; - const auto future = QtConcurrent::run([showHidden, path]() { - QDir::Filters filters = QDir::Dirs | QDir::NoDotAndDotDot; - if (showHidden) { - filters |= QDir::Hidden; - } + if (m_recursive && m_watchChanges) { + const auto currentDir = m_dir; + const bool showHidden = m_showHidden; + const auto future = QtConcurrent::run([showHidden, path]() { + QDir::Filters filters = QDir::Dirs | QDir::NoDotAndDotDot; + if (showHidden) { + filters |= QDir::Hidden; + } - QDirIterator iter(path, filters, QDirIterator::Subdirectories); - QStringList dirs; - while (iter.hasNext()) { - dirs << iter.next(); - } - return dirs; - }); - const auto watcher = new QFutureWatcher(this); - connect(watcher, &QFutureWatcher::finished, this, [currentDir, showHidden, watcher, this]() { - const auto paths = watcher->result(); - if (currentDir == m_dir && showHidden == m_showHidden && !paths.isEmpty()) { - // Ignore if dir or showHidden has changed - m_watcher.addPaths(paths); - } - watcher->deleteLater(); - }); - watcher->setFuture(future); - } + QDirIterator iter(path, filters, QDirIterator::Subdirectories); + QStringList dirs; + while (iter.hasNext()) { + dirs << iter.next(); + } + return dirs; + }); + const auto watcher = new QFutureWatcher(this); + connect( + watcher, + &QFutureWatcher::finished, + this, + [currentDir, showHidden, watcher, this]() { + const auto paths = watcher->result(); + if (currentDir == m_dir && showHidden == m_showHidden && + !paths.isEmpty()) { + // Ignore if dir or showHidden has changed + m_watcher.addPaths(paths); + } + watcher->deleteLater(); + }); + watcher->setFuture(future); + } } void FileSystemModel::update() { - updateWatcher(); - updateEntries(); + updateWatcher(); + updateEntries(); } void FileSystemModel::updateWatcher() { - if (!m_watcher.directories().isEmpty()) { - m_watcher.removePaths(m_watcher.directories()); - } + if (!m_watcher.directories().isEmpty()) { + m_watcher.removePaths(m_watcher.directories()); + } - if (!m_watchChanges || m_path.isEmpty()) { - return; - } + if (!m_watchChanges || m_path.isEmpty()) { + return; + } - m_watcher.addPath(m_path); - watchDirIfRecursive(m_path); + m_watcher.addPath(m_path); + watchDirIfRecursive(m_path); } void FileSystemModel::updateEntries() { - if (m_path.isEmpty()) { - if (!m_entries.isEmpty()) { - beginResetModel(); - qDeleteAll(m_entries); - m_entries.clear(); - endResetModel(); - emit entriesChanged(); - } + if (m_path.isEmpty()) { + if (!m_entries.isEmpty()) { + beginResetModel(); + qDeleteAll(m_entries); + m_entries.clear(); + endResetModel(); + emit entriesChanged(); + } - return; - } + return; + } - for (auto& future : m_futures) { - future.cancel(); - } - m_futures.clear(); + for (auto& future : m_futures) { + future.cancel(); + } + m_futures.clear(); - updateEntriesForDir(m_path); + updateEntriesForDir(m_path); } void FileSystemModel::updateEntriesForDir(const QString& dir) { - const auto recursive = m_recursive; - const auto showHidden = m_showHidden; - const auto filter = m_filter; - const auto nameFilters = m_nameFilters; + const auto recursive = m_recursive; + const auto showHidden = m_showHidden; + const auto filter = m_filter; + const auto nameFilters = m_nameFilters; - QSet oldPaths; - for (const auto& entry : std::as_const(m_entries)) { - oldPaths << entry->path(); - } + QSet oldPaths; + for (const auto& entry : std::as_const(m_entries)) { + oldPaths << entry->path(); + } - const auto future = QtConcurrent::run([=](QPromise, QSet>>& promise) { - const auto flags = recursive ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags; + const auto future = QtConcurrent::run( + [=](QPromise, QSet>>& promise) { + const auto flags = recursive ? QDirIterator::Subdirectories + : QDirIterator::NoIteratorFlags; - std::optional iter; + std::optional iter; - if (filter == Images) { - QStringList extraNameFilters = nameFilters; - const auto formats = QImageReader::supportedImageFormats(); - for (const auto& format : formats) { - extraNameFilters << "*." + format; - } + if (filter == Images) { + QStringList extraNameFilters = nameFilters; + const auto formats = QImageReader::supportedImageFormats(); + for (const auto& format : formats) { + extraNameFilters << "*." + format; + } - QDir::Filters filters = QDir::Files; - if (showHidden) { - filters |= QDir::Hidden; - } + QDir::Filters filters = QDir::Files; + if (showHidden) { + filters |= QDir::Hidden; + } - iter.emplace(dir, extraNameFilters, filters, flags); - } else { - QDir::Filters filters; + iter.emplace(dir, extraNameFilters, filters, flags); + } else { + QDir::Filters filters; - if (filter == Files) { - filters = QDir::Files; - } else if (filter == Dirs) { - filters = QDir::Dirs | QDir::NoDotAndDotDot; - } else { - filters = QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot; - } + if (filter == Files) { + filters = QDir::Files; + } else if (filter == Dirs) { + filters = QDir::Dirs | QDir::NoDotAndDotDot; + } else { + filters = QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot; + } - if (showHidden) { - filters |= QDir::Hidden; - } + if (showHidden) { + filters |= QDir::Hidden; + } - if (nameFilters.isEmpty()) { - iter.emplace(dir, filters, flags); - } else { - iter.emplace(dir, nameFilters, filters, flags); - } - } + if (nameFilters.isEmpty()) { + iter.emplace(dir, filters, flags); + } else { + iter.emplace(dir, nameFilters, filters, flags); + } + } - QSet newPaths; - while (iter->hasNext()) { - if (promise.isCanceled()) { - return; - } + QSet newPaths; + while (iter->hasNext()) { + if (promise.isCanceled()) { + return; + } - QString path = iter->next(); + QString path = iter->next(); - if (filter == Images) { - QImageReader reader(path); - if (!reader.canRead()) { - continue; - } - } + if (filter == Images) { + QImageReader reader(path); + if (!reader.canRead()) { + continue; + } + } - newPaths.insert(path); - } + newPaths.insert(path); + } - if (promise.isCanceled() || newPaths == oldPaths) { - return; - } + if (promise.isCanceled() || newPaths == oldPaths) { + return; + } - promise.addResult(qMakePair(oldPaths - newPaths, newPaths - oldPaths)); - }); + promise.addResult( + qMakePair(oldPaths - newPaths, newPaths - oldPaths)); + }); - if (m_futures.contains(dir)) { - m_futures[dir].cancel(); - } - m_futures.insert(dir, future); + if (m_futures.contains(dir)) { + m_futures[dir].cancel(); + } + m_futures.insert(dir, future); - const auto watcher = new QFutureWatcher, QSet>>(this); + const auto watcher = + new QFutureWatcher, QSet>>(this); - connect(watcher, &QFutureWatcher, QSet>>::finished, this, [dir, watcher, this]() { - m_futures.remove(dir); + connect( + watcher, + &QFutureWatcher, QSet>>::finished, + this, + [dir, watcher, this]() { + m_futures.remove(dir); - if (!watcher->future().isResultReadyAt(0)) { - watcher->deleteLater(); - return; - } + if (!watcher->future().isResultReadyAt(0)) { + watcher->deleteLater(); + return; + } - const auto result = watcher->result(); - applyChanges(result.first, result.second); + const auto result = watcher->result(); + applyChanges(result.first, result.second); - watcher->deleteLater(); - }); + watcher->deleteLater(); + }); - watcher->setFuture(future); + watcher->setFuture(future); } -void FileSystemModel::applyChanges(const QSet& removedPaths, const QSet& addedPaths) { - QList removedIndices; - for (int i = 0; i < m_entries.size(); ++i) { - if (removedPaths.contains(m_entries[i]->path())) { - removedIndices << i; - } - } - std::sort(removedIndices.begin(), removedIndices.end(), std::greater()); +void FileSystemModel::applyChanges( + const QSet& removedPaths, const QSet& addedPaths) { + QList removedIndices; + for (int i = 0; i < m_entries.size(); ++i) { + if (removedPaths.contains(m_entries[i]->path())) { + removedIndices << i; + } + } + std::sort(removedIndices.begin(), removedIndices.end(), std::greater()); - // Batch remove old entries - int start = -1; - int end = -1; - for (int idx : std::as_const(removedIndices)) { - if (start == -1) { - start = idx; - end = idx; - } else if (idx == end - 1) { - end = idx; - } else { - beginRemoveRows(QModelIndex(), end, start); - for (int i = start; i >= end; --i) { - m_entries.takeAt(i)->deleteLater(); - } - endRemoveRows(); + // Batch remove old entries + int start = -1; + int end = -1; + for (int idx : std::as_const(removedIndices)) { + if (start == -1) { + start = idx; + end = idx; + } else if (idx == end - 1) { + end = idx; + } else { + beginRemoveRows(QModelIndex(), end, start); + for (int i = start; i >= end; --i) { + m_entries.takeAt(i)->deleteLater(); + } + endRemoveRows(); - start = idx; - end = idx; - } - } - if (start != -1) { - beginRemoveRows(QModelIndex(), end, start); - for (int i = start; i >= end; --i) { - m_entries.takeAt(i)->deleteLater(); - } - endRemoveRows(); - } + start = idx; + end = idx; + } + } + if (start != -1) { + beginRemoveRows(QModelIndex(), end, start); + for (int i = start; i >= end; --i) { + m_entries.takeAt(i)->deleteLater(); + } + endRemoveRows(); + } - // Create new entries - QList newEntries; - for (const auto& path : addedPaths) { - newEntries << new FileSystemEntry(path, m_dir.relativeFilePath(path), this); - } - std::sort(newEntries.begin(), newEntries.end(), [this](const FileSystemEntry* a, const FileSystemEntry* b) { - return compareEntries(a, b); - }); + // Create new entries + QList newEntries; + for (const auto& path : addedPaths) { + newEntries << new FileSystemEntry( + path, m_dir.relativeFilePath(path), this); + } + std::sort( + newEntries.begin(), + newEntries.end(), + [this](const FileSystemEntry* a, const FileSystemEntry* b) { + return compareEntries(a, b); + }); - // Batch insert new entries - int insertStart = -1; - QList batchItems; - for (const auto& entry : std::as_const(newEntries)) { - const auto it = std::lower_bound( - m_entries.begin(), m_entries.end(), entry, [this](const FileSystemEntry* a, const FileSystemEntry* b) { - return compareEntries(a, b); - }); - const auto row = static_cast(it - m_entries.begin()); + // Batch insert new entries + int insertStart = -1; + QList batchItems; + for (const auto& entry : std::as_const(newEntries)) { + const auto it = std::lower_bound( + m_entries.begin(), + m_entries.end(), + entry, + [this](const FileSystemEntry* a, const FileSystemEntry* b) { + return compareEntries(a, b); + }); + const auto row = static_cast(it - m_entries.begin()); - if (insertStart == -1) { - insertStart = row; - batchItems << entry; - } else if (row == insertStart + batchItems.size()) { - batchItems << entry; - } else { - beginInsertRows(QModelIndex(), insertStart, insertStart + static_cast(batchItems.size()) - 1); - for (int i = 0; i < batchItems.size(); ++i) { - m_entries.insert(insertStart + i, batchItems[i]); - } - endInsertRows(); + if (insertStart == -1) { + insertStart = row; + batchItems << entry; + } else if (row == insertStart + batchItems.size()) { + batchItems << entry; + } else { + beginInsertRows( + QModelIndex(), + insertStart, + insertStart + static_cast(batchItems.size()) - 1); + for (int i = 0; i < batchItems.size(); ++i) { + m_entries.insert(insertStart + i, batchItems[i]); + } + endInsertRows(); - insertStart = row; - batchItems.clear(); - batchItems << entry; - } - } - if (!batchItems.isEmpty()) { - beginInsertRows(QModelIndex(), insertStart, insertStart + static_cast(batchItems.size()) - 1); - for (int i = 0; i < batchItems.size(); ++i) { - m_entries.insert(insertStart + i, batchItems[i]); - } - endInsertRows(); - } + insertStart = row; + batchItems.clear(); + batchItems << entry; + } + } + if (!batchItems.isEmpty()) { + beginInsertRows( + QModelIndex(), + insertStart, + insertStart + static_cast(batchItems.size()) - 1); + for (int i = 0; i < batchItems.size(); ++i) { + m_entries.insert(insertStart + i, batchItems[i]); + } + endInsertRows(); + } - emit entriesChanged(); + emit entriesChanged(); } -bool FileSystemModel::compareEntries(const FileSystemEntry* a, const FileSystemEntry* b) const { - if (a->isDir() != b->isDir()) { - return m_sortReverse ^ a->isDir(); - } - const auto cmp = a->relativePath().localeAwareCompare(b->relativePath()); - return m_sortReverse ? cmp > 0 : cmp < 0; +bool FileSystemModel::compareEntries( + const FileSystemEntry* a, const FileSystemEntry* b) const { + if (a->isDir() != b->isDir()) { + return m_sortReverse ^ a->isDir(); + } + const auto cmp = a->relativePath().localeAwareCompare(b->relativePath()); + return m_sortReverse ? cmp > 0 : cmp < 0; } } // namespace ZShell::models diff --git a/Plugins/ZShell/Models/filesystemmodel.hpp b/Plugins/ZShell/Models/filesystemmodel.hpp index f860c2a..94bb29a 100644 --- a/Plugins/ZShell/Models/filesystemmodel.hpp +++ b/Plugins/ZShell/Models/filesystemmodel.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -14,136 +13,151 @@ namespace ZShell::models { class FileSystemEntry : public QObject { -Q_OBJECT -QML_ELEMENT - QML_UNCREATABLE("FileSystemEntry instances can only be retrieved from a FileSystemModel") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE( + "FileSystemEntry instances can only be retrieved from a " + "FileSystemModel") -Q_PROPERTY(QString path READ path CONSTANT) -Q_PROPERTY(QString relativePath READ relativePath NOTIFY relativePathChanged) -Q_PROPERTY(QString name READ name CONSTANT) -Q_PROPERTY(QString baseName READ baseName CONSTANT) -Q_PROPERTY(QString parentDir READ parentDir CONSTANT) -Q_PROPERTY(QString suffix READ suffix CONSTANT) -Q_PROPERTY(qint64 size READ size CONSTANT) -Q_PROPERTY(bool isDir READ isDir CONSTANT) -Q_PROPERTY(bool isImage READ isImage CONSTANT) -Q_PROPERTY(QString mimeType READ mimeType CONSTANT) + Q_PROPERTY(QString path READ path CONSTANT) + Q_PROPERTY(QString relativePath READ relativePath NOTIFY relativePathChanged) + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString baseName READ baseName CONSTANT) + Q_PROPERTY(QString parentDir READ parentDir CONSTANT) + Q_PROPERTY(QString suffix READ suffix CONSTANT) + Q_PROPERTY(qint64 size READ size CONSTANT) + Q_PROPERTY(bool isDir READ isDir CONSTANT) + Q_PROPERTY(bool isImage READ isImage CONSTANT) + Q_PROPERTY(QString mimeType READ mimeType CONSTANT) -public: -explicit FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent = nullptr); + public: + explicit FileSystemEntry( + const QString& path, + const QString& relativePath, + QObject* parent = nullptr); -[[nodiscard]] QString path() const; -[[nodiscard]] QString relativePath() const; -[[nodiscard]] QString name() const; -[[nodiscard]] QString baseName() const; -[[nodiscard]] QString parentDir() const; -[[nodiscard]] QString suffix() const; -[[nodiscard]] qint64 size() const; -[[nodiscard]] bool isDir() const; -[[nodiscard]] bool isImage() const; -[[nodiscard]] QString mimeType() const; + [[nodiscard]] QString path() const; + [[nodiscard]] QString relativePath() const; + [[nodiscard]] QString name() const; + [[nodiscard]] QString baseName() const; + [[nodiscard]] QString parentDir() const; + [[nodiscard]] QString suffix() const; + [[nodiscard]] qint64 size() const; + [[nodiscard]] bool isDir() const; + [[nodiscard]] bool isImage() const; + [[nodiscard]] QString mimeType() const; -void updateRelativePath(const QDir& dir); + void updateRelativePath(const QDir& dir); -signals: -void relativePathChanged(); + signals: + void relativePathChanged(); -private: -const QFileInfo m_fileInfo; + private: + const QFileInfo m_fileInfo; -const QString m_path; -QString m_relativePath; + const QString m_path; + QString m_relativePath; -mutable bool m_isImage; -mutable bool m_isImageInitialised; + mutable bool m_isImage; + mutable bool m_isImageInitialised; -mutable QString m_mimeType; -mutable bool m_mimeTypeInitialised; + mutable QString m_mimeType; + mutable bool m_mimeTypeInitialised; }; class FileSystemModel : public QAbstractListModel { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) -Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) -Q_PROPERTY(bool watchChanges READ watchChanges WRITE setWatchChanges NOTIFY watchChangesChanged) -Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden NOTIFY showHiddenChanged) -Q_PROPERTY(bool sortReverse READ sortReverse WRITE setSortReverse NOTIFY sortReverseChanged) -Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged) -Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged) + Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) + Q_PROPERTY( + bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) + Q_PROPERTY( + bool watchChanges READ watchChanges WRITE setWatchChanges NOTIFY + watchChangesChanged) + Q_PROPERTY( + bool showHidden READ showHidden WRITE setShowHidden NOTIFY + showHiddenChanged) + Q_PROPERTY( + bool sortReverse READ sortReverse WRITE setSortReverse NOTIFY + sortReverseChanged) + Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged) + Q_PROPERTY( + QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY + nameFiltersChanged) -Q_PROPERTY(QQmlListProperty entries READ entries NOTIFY entriesChanged) + Q_PROPERTY( + QQmlListProperty entries READ entries + NOTIFY entriesChanged) -public: -enum Filter { - NoFilter, - Images, - Files, - Dirs -}; -Q_ENUM(Filter) + public: + enum Filter { NoFilter, Images, Files, Dirs }; + Q_ENUM(Filter) -explicit FileSystemModel(QObject* parent = nullptr); + explicit FileSystemModel(QObject* parent = nullptr); -[[nodiscard]] int rowCount(const QModelIndex& parent = QModelIndex()) const override; -[[nodiscard]] QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; -[[nodiscard]] QHash roleNames() const override; + [[nodiscard]] int rowCount( + const QModelIndex& parent = QModelIndex()) const override; + [[nodiscard]] QVariant data( + const QModelIndex& index, int role = Qt::DisplayRole) const override; + [[nodiscard]] QHash roleNames() const override; -[[nodiscard]] QString path() const; -void setPath(const QString& path); + [[nodiscard]] QString path() const; + void setPath(const QString& path); -[[nodiscard]] bool recursive() const; -void setRecursive(bool recursive); + [[nodiscard]] bool recursive() const; + void setRecursive(bool recursive); -[[nodiscard]] bool watchChanges() const; -void setWatchChanges(bool watchChanges); + [[nodiscard]] bool watchChanges() const; + void setWatchChanges(bool watchChanges); -[[nodiscard]] bool showHidden() const; -void setShowHidden(bool showHidden); + [[nodiscard]] bool showHidden() const; + void setShowHidden(bool showHidden); -[[nodiscard]] bool sortReverse() const; -void setSortReverse(bool sortReverse); + [[nodiscard]] bool sortReverse() const; + void setSortReverse(bool sortReverse); -[[nodiscard]] Filter filter() const; -void setFilter(Filter filter); + [[nodiscard]] Filter filter() const; + void setFilter(Filter filter); -[[nodiscard]] QStringList nameFilters() const; -void setNameFilters(const QStringList& nameFilters); + [[nodiscard]] QStringList nameFilters() const; + void setNameFilters(const QStringList& nameFilters); -[[nodiscard]] QQmlListProperty entries(); + [[nodiscard]] QQmlListProperty entries(); -signals: -void pathChanged(); -void recursiveChanged(); -void watchChangesChanged(); -void showHiddenChanged(); -void sortReverseChanged(); -void filterChanged(); -void nameFiltersChanged(); -void entriesChanged(); + signals: + void pathChanged(); + void recursiveChanged(); + void watchChangesChanged(); + void showHiddenChanged(); + void sortReverseChanged(); + void filterChanged(); + void nameFiltersChanged(); + void entriesChanged(); -private: -QDir m_dir; -QFileSystemWatcher m_watcher; -QList m_entries; -QHash, QSet > > > m_futures; + private: + QDir m_dir; + QFileSystemWatcher m_watcher; + QList m_entries; + QHash, QSet>>> m_futures; -QString m_path; -bool m_recursive; -bool m_watchChanges; -bool m_showHidden; -bool m_sortReverse; -Filter m_filter; -QStringList m_nameFilters; + QString m_path; + bool m_recursive; + bool m_watchChanges; + bool m_showHidden; + bool m_sortReverse; + Filter m_filter; + QStringList m_nameFilters; -void watchDirIfRecursive(const QString& path); -void update(); -void updateWatcher(); -void updateEntries(); -void updateEntriesForDir(const QString& dir); -void applyChanges(const QSet& removedPaths, const QSet& addedPaths); -[[nodiscard]] bool compareEntries(const FileSystemEntry* a, const FileSystemEntry* b) const; + void watchDirIfRecursive(const QString& path); + void update(); + void updateWatcher(); + void updateEntries(); + void updateEntriesForDir(const QString& dir); + void applyChanges( + const QSet& removedPaths, const QSet& addedPaths); + [[nodiscard]] bool compareEntries( + const FileSystemEntry* a, const FileSystemEntry* b) const; }; } // namespace ZShell::models diff --git a/Plugins/ZShell/Services/audiocollector.cpp b/Plugins/ZShell/Services/audiocollector.cpp index 770c499..a9382e3 100644 --- a/Plugins/ZShell/Services/audiocollector.cpp +++ b/Plugins/ZShell/Services/audiocollector.cpp @@ -23,20 +23,33 @@ PipeWireWorker::PipeWireWorker(std::stop_token token, AudioCollector* collector) m_loop = pw_main_loop_new(nullptr); if (!m_loop) { - qWarning() << "PipeWireWorker::init: failed to create PipeWire main loop"; + qWarning() + << "PipeWireWorker::init: failed to create PipeWire main loop"; pw_deinit(); return; } - timespec timeout = { 0, 10 * SPA_NSEC_PER_MSEC }; - m_timer = pw_loop_add_timer(pw_main_loop_get_loop(m_loop), handleTimeout, this); - pw_loop_update_timer(pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false); + timespec timeout = {0, 10 * SPA_NSEC_PER_MSEC}; + m_timer = + pw_loop_add_timer(pw_main_loop_get_loop(m_loop), handleTimeout, this); + pw_loop_update_timer( + pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false); auto props = pw_properties_new( - PW_KEY_MEDIA_TYPE, "Audio", PW_KEY_MEDIA_CATEGORY, "Capture", PW_KEY_MEDIA_ROLE, "Music", nullptr); + PW_KEY_MEDIA_TYPE, + "Audio", + PW_KEY_MEDIA_CATEGORY, + "Capture", + PW_KEY_MEDIA_ROLE, + "Music", + nullptr); pw_properties_set(props, PW_KEY_STREAM_CAPTURE_SINK, "true"); pw_properties_setf( - props, PW_KEY_NODE_LATENCY, "%u/%u", nextPowerOf2(512 * ac::SAMPLE_RATE / 48000), ac::SAMPLE_RATE); + props, + PW_KEY_NODE_LATENCY, + "%u/%u", + nextPowerOf2(512 * ac::SAMPLE_RATE / 48000), + ac::SAMPLE_RATE); pw_properties_set(props, PW_KEY_NODE_PASSIVE, "true"); pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); pw_properties_set(props, PW_KEY_STREAM_DONT_REMIX, "false"); @@ -55,21 +68,28 @@ PipeWireWorker::PipeWireWorker(std::stop_token token, AudioCollector* collector) params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info); pw_stream_events events{}; - events.state_changed = [](void* data, pw_stream_state, pw_stream_state state, const char*) { - auto* self = static_cast(data); - self->streamStateChanged(state); - }; + events.state_changed = + [](void* data, pw_stream_state, pw_stream_state state, const char*) { + auto* self = static_cast(data); + self->streamStateChanged(state); + }; events.process = [](void* data) { - auto* self = static_cast(data); - self->processStream(); - }; + auto* self = static_cast(data); + self->processStream(); + }; - m_stream = pw_stream_new_simple(pw_main_loop_get_loop(m_loop), "ZShell-shell", props, &events, this); + m_stream = pw_stream_new_simple( + pw_main_loop_get_loop(m_loop), "ZShell-shell", props, &events, this); - const int success = pw_stream_connect(m_stream, PW_DIRECTION_INPUT, PW_ID_ANY, - static_cast( - PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS), - params, 1); + const int success = pw_stream_connect( + m_stream, + PW_DIRECTION_INPUT, + PW_ID_ANY, + static_cast( + PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | + PW_STREAM_FLAG_RT_PROCESS), + params, + 1); if (success < 0) { qWarning() << "PipeWireWorker::init: failed to connect stream"; pw_stream_destroy(m_stream); @@ -98,8 +118,13 @@ void PipeWireWorker::handleTimeout(void* data, uint64_t expirations) { self->m_collector->clearBuffer(); } else { self->m_idle = true; - timespec timeout = { 0, 500 * SPA_NSEC_PER_MSEC }; - pw_loop_update_timer(pw_main_loop_get_loop(self->m_loop), self->m_timer, &timeout, &timeout, false); + timespec timeout = {0, 500 * SPA_NSEC_PER_MSEC}; + pw_loop_update_timer( + pw_main_loop_get_loop(self->m_loop), + self->m_timer, + &timeout, + &timeout, + false); } } } @@ -108,12 +133,14 @@ void PipeWireWorker::streamStateChanged(pw_stream_state state) { m_idle = false; switch (state) { case PW_STREAM_STATE_PAUSED: { - timespec timeout = { 0, 10 * SPA_NSEC_PER_MSEC }; - pw_loop_update_timer(pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false); + timespec timeout = {0, 10 * SPA_NSEC_PER_MSEC}; + pw_loop_update_timer( + pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false); break; } case PW_STREAM_STATE_STREAMING: - pw_loop_update_timer(pw_main_loop_get_loop(m_loop), m_timer, nullptr, nullptr, false); + pw_loop_update_timer( + pw_main_loop_get_loop(m_loop), m_timer, nullptr, nullptr, false); break; case PW_STREAM_STATE_ERROR: pw_main_loop_quit(m_loop); @@ -171,7 +198,8 @@ void AudioCollector::clearBuffer() { auto* writeBuffer = m_writeBuffer.load(std::memory_order_relaxed); std::fill(writeBuffer->begin(), writeBuffer->end(), 0.0f); - auto* oldRead = m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel); + auto* oldRead = + m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel); m_writeBuffer.store(oldRead, std::memory_order_release); } @@ -181,11 +209,13 @@ void AudioCollector::loadChunk(const qint16* samples, quint32 count) { } auto* writeBuffer = m_writeBuffer.load(std::memory_order_relaxed); - std::transform(samples, samples + count, writeBuffer->begin(), [](qint16 sample) { + std::transform( + samples, samples + count, writeBuffer->begin(), [](qint16 sample) { return sample / 32768.0f; }); - auto* oldRead = m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel); + auto* oldRead = + m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel); m_writeBuffer.store(oldRead, std::memory_order_release); } @@ -206,9 +236,11 @@ quint32 AudioCollector::readChunk(double* out, quint32 count) { } auto* readBuffer = m_readBuffer.load(std::memory_order_acquire); - std::transform(readBuffer->begin(), readBuffer->begin() + count, out, [](float sample) { - return static_cast(sample); - }); + std::transform( + readBuffer->begin(), + readBuffer->begin() + count, + out, + [](float sample) { return static_cast(sample); }); return count; } @@ -218,8 +250,7 @@ AudioCollector::AudioCollector(QObject* parent) , m_buffer1(ac::CHUNK_SIZE) , m_buffer2(ac::CHUNK_SIZE) , m_readBuffer(&m_buffer1) - , m_writeBuffer(&m_buffer2) { -} + , m_writeBuffer(&m_buffer2) {} AudioCollector::~AudioCollector() { stop(); @@ -232,9 +263,8 @@ void AudioCollector::start() { clearBuffer(); - m_thread = std::jthread([this](std::stop_token token) { - PipeWireWorker worker(token, this); - }); + m_thread = std::jthread( + [this](std::stop_token token) { PipeWireWorker worker(token, this); }); } void AudioCollector::stop() { diff --git a/Plugins/ZShell/Services/audiocollector.hpp b/Plugins/ZShell/Services/audiocollector.hpp index e0fe2f6..d235796 100644 --- a/Plugins/ZShell/Services/audiocollector.hpp +++ b/Plugins/ZShell/Services/audiocollector.hpp @@ -22,55 +22,55 @@ constexpr quint32 CHUNK_SIZE = 512; class AudioCollector; class PipeWireWorker { -public: -explicit PipeWireWorker(std::stop_token token, AudioCollector* collector); + public: + explicit PipeWireWorker(std::stop_token token, AudioCollector* collector); -void run(); + void run(); -private: -pw_main_loop* m_loop; -pw_stream* m_stream; -spa_source* m_timer; -bool m_idle; + private: + pw_main_loop* m_loop; + pw_stream* m_stream; + spa_source* m_timer; + bool m_idle; -std::stop_token m_token; -AudioCollector* m_collector; + std::stop_token m_token; + AudioCollector* m_collector; -static void handleTimeout(void* data, uint64_t expirations); -void streamStateChanged(pw_stream_state state); -void processStream(); + static void handleTimeout(void* data, uint64_t expirations); + void streamStateChanged(pw_stream_state state); + void processStream(); -[[nodiscard]] unsigned int nextPowerOf2(unsigned int n); + [[nodiscard]] unsigned int nextPowerOf2(unsigned int n); }; class AudioCollector : public Service { -Q_OBJECT + Q_OBJECT -public: -AudioCollector(const AudioCollector&) = delete; -AudioCollector& operator=(const AudioCollector&) = delete; + public: + AudioCollector(const AudioCollector&) = delete; + AudioCollector& operator=(const AudioCollector&) = delete; -static AudioCollector& instance(); + static AudioCollector& instance(); -void clearBuffer(); -void loadChunk(const qint16* samples, quint32 count); -quint32 readChunk(float* out, quint32 count = 0); -quint32 readChunk(double* out, quint32 count = 0); + void clearBuffer(); + void loadChunk(const qint16* samples, quint32 count); + quint32 readChunk(float* out, quint32 count = 0); + quint32 readChunk(double* out, quint32 count = 0); -private: -explicit AudioCollector(QObject* parent = nullptr); -~AudioCollector() override; + private: + explicit AudioCollector(QObject* parent = nullptr); + ~AudioCollector() override; -std::jthread m_thread; -std::vector m_buffer1; -std::vector m_buffer2; -std::atomic*> m_readBuffer; -std::atomic*> m_writeBuffer; -quint32 m_sampleCount; + std::jthread m_thread; + std::vector m_buffer1; + std::vector m_buffer2; + std::atomic*> m_readBuffer; + std::atomic*> m_writeBuffer; + quint32 m_sampleCount; -void reload(); -void start() override; -void stop() override; + void reload(); + void start() override; + void stop() override; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/audioprovider.cpp b/Plugins/ZShell/Services/audioprovider.cpp index dd99bf1..3957d3f 100644 --- a/Plugins/ZShell/Services/audioprovider.cpp +++ b/Plugins/ZShell/Services/audioprovider.cpp @@ -7,9 +7,7 @@ namespace ZShell::services { -AudioProcessor::AudioProcessor(QObject* parent) - : QObject(parent) { -} +AudioProcessor::AudioProcessor(QObject* parent) : QObject(parent) {} AudioProcessor::~AudioProcessor() { stop(); @@ -17,12 +15,17 @@ AudioProcessor::~AudioProcessor() { void AudioProcessor::init() { m_timer = new QTimer(this); - m_timer->setInterval(static_cast(ac::CHUNK_SIZE * 1000.0 / ac::SAMPLE_RATE)); + m_timer->setInterval( + static_cast(ac::CHUNK_SIZE * 1000.0 / ac::SAMPLE_RATE)); connect(m_timer, &QTimer::timeout, this, &AudioProcessor::process); } void AudioProcessor::start() { - QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::ref, Qt::QueuedConnection, this); + QMetaObject::invokeMethod( + &AudioCollector::instance(), + &AudioCollector::ref, + Qt::QueuedConnection, + this); if (m_timer) { m_timer->start(); } @@ -32,14 +35,15 @@ void AudioProcessor::stop() { if (m_timer) { m_timer->stop(); } - QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::unref, Qt::QueuedConnection, this); + QMetaObject::invokeMethod( + &AudioCollector::instance(), + &AudioCollector::unref, + Qt::QueuedConnection, + this); } AudioProvider::AudioProvider(QObject* parent) - : Service(parent) - , m_processor(nullptr) - , m_thread(nullptr) { -} + : Service(parent), m_processor(nullptr), m_thread(nullptr) {} AudioProvider::~AudioProvider() { if (m_thread) { @@ -50,7 +54,8 @@ AudioProvider::~AudioProvider() { void AudioProvider::init() { if (!m_processor) { - qWarning() << "AudioProvider::init: attempted to init with no processor set"; + qWarning() + << "AudioProvider::init: attempted to init with no processor set"; return; } @@ -58,7 +63,8 @@ void AudioProvider::init() { m_processor->moveToThread(m_thread); connect(m_thread, &QThread::started, m_processor, &AudioProcessor::init); - connect(m_thread, &QThread::finished, m_processor, &AudioProcessor::deleteLater); + connect( + m_thread, &QThread::finished, m_processor, &AudioProcessor::deleteLater); connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater); m_thread->start(); diff --git a/Plugins/ZShell/Services/audioprovider.hpp b/Plugins/ZShell/Services/audioprovider.hpp index 76d4614..4de6e04 100644 --- a/Plugins/ZShell/Services/audioprovider.hpp +++ b/Plugins/ZShell/Services/audioprovider.hpp @@ -7,41 +7,41 @@ namespace ZShell::services { class AudioProcessor : public QObject { -Q_OBJECT + Q_OBJECT -public: -explicit AudioProcessor(QObject* parent = nullptr); -~AudioProcessor() override; + public: + explicit AudioProcessor(QObject* parent = nullptr); + ~AudioProcessor() override; -void init(); + void init(); -void start(); -void stop(); + void start(); + void stop(); -protected: -virtual void process() = 0; + protected: + virtual void process() = 0; -private: -QTimer* m_timer; + private: + QTimer* m_timer; }; class AudioProvider : public Service { -Q_OBJECT + Q_OBJECT -public: -explicit AudioProvider(QObject* parent = nullptr); -~AudioProvider() override; + public: + explicit AudioProvider(QObject* parent = nullptr); + ~AudioProvider() override; -protected: -AudioProcessor* m_processor; + protected: + AudioProcessor* m_processor; -void init(); + void init(); -private: -QThread* m_thread; + private: + QThread* m_thread; -void start() override; -void stop() override; + void start() override; + void stop() override; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/beattracker.cpp b/Plugins/ZShell/Services/beattracker.cpp index 5e83770..498b5d0 100644 --- a/Plugins/ZShell/Services/beattracker.cpp +++ b/Plugins/ZShell/Services/beattracker.cpp @@ -10,8 +10,7 @@ BeatProcessor::BeatProcessor(QObject* parent) : AudioProcessor(parent) , m_tempo(new_aubio_tempo("default", 1024, ac::CHUNK_SIZE, ac::SAMPLE_RATE)) , m_in(new_fvec(ac::CHUNK_SIZE)) - , m_out(new_fvec(2)) { -}; + , m_out(new_fvec(2)) {}; BeatProcessor::~BeatProcessor() { if (m_tempo) { @@ -36,13 +35,15 @@ void BeatProcessor::process() { } } -BeatTracker::BeatTracker(QObject* parent) - : AudioProvider(parent) - , m_bpm(120) { +BeatTracker::BeatTracker(QObject* parent) : AudioProvider(parent), m_bpm(120) { m_processor = new BeatProcessor(); init(); - connect(static_cast(m_processor), &BeatProcessor::beat, this, &BeatTracker::updateBpm); + connect( + static_cast(m_processor), + &BeatProcessor::beat, + this, + &BeatTracker::updateBpm); } smpl_t BeatTracker::bpm() const { diff --git a/Plugins/ZShell/Services/beattracker.hpp b/Plugins/ZShell/Services/beattracker.hpp index 4982572..b04ba05 100644 --- a/Plugins/ZShell/Services/beattracker.hpp +++ b/Plugins/ZShell/Services/beattracker.hpp @@ -7,43 +7,43 @@ namespace ZShell::services { class BeatProcessor : public AudioProcessor { -Q_OBJECT + Q_OBJECT -public: -explicit BeatProcessor(QObject* parent = nullptr); -~BeatProcessor() override; + public: + explicit BeatProcessor(QObject* parent = nullptr); + ~BeatProcessor() override; -signals: -void beat(smpl_t bpm); + signals: + void beat(smpl_t bpm); -protected: -void process() override; + protected: + void process() override; -private: -aubio_tempo_t* m_tempo; -fvec_t* m_in; -fvec_t* m_out; + private: + aubio_tempo_t* m_tempo; + fvec_t* m_in; + fvec_t* m_out; }; class BeatTracker : public AudioProvider { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(smpl_t bpm READ bpm NOTIFY bpmChanged) + Q_PROPERTY(smpl_t bpm READ bpm NOTIFY bpmChanged) -public: -explicit BeatTracker(QObject* parent = nullptr); + public: + explicit BeatTracker(QObject* parent = nullptr); -[[nodiscard]] smpl_t bpm() const; + [[nodiscard]] smpl_t bpm() const; -signals: -void bpmChanged(); -void beat(smpl_t bpm); + signals: + void bpmChanged(); + void beat(smpl_t bpm); -private: -smpl_t m_bpm; + private: + smpl_t m_bpm; -void updateBpm(smpl_t bpm); + void updateBpm(smpl_t bpm); }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/cavaprovider.cpp b/Plugins/ZShell/Services/cavaprovider.cpp index ec64db2..21fb7bc 100644 --- a/Plugins/ZShell/Services/cavaprovider.cpp +++ b/Plugins/ZShell/Services/cavaprovider.cpp @@ -2,7 +2,6 @@ #include "audiocollector.hpp" #include "audioprovider.hpp" -#include #include #include #include @@ -14,8 +13,7 @@ CavaProcessor::CavaProcessor(QObject* parent) , m_plan(nullptr) , m_in(new double[ac::CHUNK_SIZE]) , m_out(nullptr) - , m_bars(0) { -}; + , m_bars(0) {}; CavaProcessor::~CavaProcessor() { cleanup(); @@ -27,7 +25,8 @@ void CavaProcessor::process() { return; } - const int count = static_cast(AudioCollector::instance().readChunk(m_in)); + const int count = + static_cast(AudioCollector::instance().readChunk(m_in)); // Process in data via cava cava_execute(m_in, count, m_out, m_plan); @@ -35,7 +34,7 @@ void CavaProcessor::process() { // Apply monstercat filter QVector values(m_bars); - for(int i = 0; i < m_bars; ++i) { + for (int i = 0; i < m_bars; ++i) { values[i] = m_out[i]; } @@ -63,7 +62,8 @@ void CavaProcessor::process() { void CavaProcessor::setBars(int bars) { if (bars < 0) { - qWarning() << "CavaProcessor::setBars: bars must be greater than 0. Setting to 0."; + qWarning() << "CavaProcessor::setBars: bars must be greater than 0. " + "Setting to 0."; bars = 0; } @@ -100,13 +100,15 @@ void CavaProcessor::initCava() { } CavaProvider::CavaProvider(QObject* parent) - : AudioProvider(parent) - , m_bars(0) - , m_values(m_bars, 0.0) { + : AudioProvider(parent), m_bars(0), m_values(m_bars, 0.0) { m_processor = new CavaProcessor(); init(); - connect(static_cast(m_processor), &CavaProcessor::valuesChanged, this, &CavaProvider::updateValues); + connect( + static_cast(m_processor), + &CavaProcessor::valuesChanged, + this, + &CavaProvider::updateValues); } int CavaProvider::bars() const { @@ -115,7 +117,8 @@ int CavaProvider::bars() const { void CavaProvider::setBars(int bars) { if (bars < 0) { - qWarning() << "CavaProvider::setBars: bars must be greater than 0. Setting to 0."; + qWarning() << "CavaProvider::setBars: bars must be greater than 0. " + "Setting to 0."; bars = 0; } @@ -129,7 +132,10 @@ void CavaProvider::setBars(int bars) { emit valuesChanged(); QMetaObject::invokeMethod( - static_cast(m_processor), &CavaProcessor::setBars, Qt::QueuedConnection, bars); + static_cast(m_processor), + &CavaProcessor::setBars, + Qt::QueuedConnection, + bars); } QVector CavaProvider::values() const { diff --git a/Plugins/ZShell/Services/cavaprovider.hpp b/Plugins/ZShell/Services/cavaprovider.hpp index 5bfd8e9..2d2aebc 100644 --- a/Plugins/ZShell/Services/cavaprovider.hpp +++ b/Plugins/ZShell/Services/cavaprovider.hpp @@ -7,58 +7,58 @@ namespace ZShell::services { class CavaProcessor : public AudioProcessor { -Q_OBJECT + Q_OBJECT -public: -explicit CavaProcessor(QObject* parent = nullptr); -~CavaProcessor() override; + public: + explicit CavaProcessor(QObject* parent = nullptr); + ~CavaProcessor() override; -void setBars(int bars); + void setBars(int bars); -signals: -void valuesChanged(QVector values); + signals: + void valuesChanged(QVector values); -protected: -void process() override; + protected: + void process() override; -private: -struct cava_plan* m_plan; -double* m_in; -double* m_out; + private: + struct cava_plan* m_plan; + double* m_in; + double* m_out; -int m_bars; -QVector m_values; + int m_bars; + QVector m_values; -void reload(); -void initCava(); -void cleanup(); + void reload(); + void initCava(); + void cleanup(); }; class CavaProvider : public AudioProvider { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(int bars READ bars WRITE setBars NOTIFY barsChanged) + Q_PROPERTY(int bars READ bars WRITE setBars NOTIFY barsChanged) -Q_PROPERTY(QVector values READ values NOTIFY valuesChanged) + Q_PROPERTY(QVector values READ values NOTIFY valuesChanged) -public: -explicit CavaProvider(QObject* parent = nullptr); + public: + explicit CavaProvider(QObject* parent = nullptr); -[[nodiscard]] int bars() const; -void setBars(int bars); + [[nodiscard]] int bars() const; + void setBars(int bars); -[[nodiscard]] QVector values() const; + [[nodiscard]] QVector values() const; -signals: -void barsChanged(); -void valuesChanged(); + signals: + void barsChanged(); + void valuesChanged(); -private: -int m_bars; -QVector m_values; + private: + int m_bars; + QVector m_values; -void updateValues(QVector values); + void updateValues(QVector values); }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/cpu.cpp b/Plugins/ZShell/Services/cpu.cpp index c04f356..d183da9 100644 --- a/Plugins/ZShell/Services/cpu.cpp +++ b/Plugins/ZShell/Services/cpu.cpp @@ -8,8 +8,7 @@ namespace ZShell::services { -Cpu::Cpu(QObject* parent) - : TickingService(parent) { +Cpu::Cpu(QObject* parent) : TickingService(parent) { readNameOnce(); } @@ -41,7 +40,8 @@ void Cpu::readNameOnce() { const QByteArray data = f.readAll(); f.close(); - static const QRegularExpression re(QStringLiteral("model name\\s*:\\s*(.+)")); + static const QRegularExpression re( + QStringLiteral("model name\\s*:\\s*(.+)")); const auto match = re.match(QString::fromLatin1(data)); if (!match.hasMatch()) { return; @@ -64,8 +64,9 @@ void Cpu::refreshPercentage() { const QByteArray data = f.readAll(); f.close(); - static const QRegularExpression re( - QStringLiteral("^cpu\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)")); + static const QRegularExpression re(QStringLiteral( + "^cpu\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" + "\\s+(\\d+)\\s+(\\d+)")); const auto match = re.match(QString::fromLatin1(data)); if (!match.hasMatch()) { return; @@ -83,7 +84,10 @@ void Cpu::refreshPercentage() { const quint64 totalDiff = total > m_lastTotal ? total - m_lastTotal : 0; const quint64 idleDiff = idle > m_lastIdle ? idle - m_lastIdle : 0; - const qreal newPerc = totalDiff > 0 ? 1.0 - static_cast(idleDiff) / static_cast(totalDiff) : 0.0; + const qreal newPerc = + totalDiff > 0 + ? 1.0 - static_cast(idleDiff) / static_cast(totalDiff) + : 0.0; m_lastTotal = total; m_lastIdle = idle; @@ -105,7 +109,8 @@ void Cpu::refreshTemperature() { QString Cpu::cleanName(QString s) { static const QRegularExpression noise( - QStringLiteral("\\(R\\)|\\(TM\\)|CPU|\\d+(?:th|nd|rd|st) Gen |Core |Processor"), + QStringLiteral( + "\\(R\\)|\\(TM\\)|CPU|\\d+(?:th|nd|rd|st) Gen |Core |Processor"), QRegularExpression::CaseInsensitiveOption); static const QRegularExpression spaces(QStringLiteral("\\s+")); diff --git a/Plugins/ZShell/Services/cpu.hpp b/Plugins/ZShell/Services/cpu.hpp index eb3909c..3fd7332 100644 --- a/Plugins/ZShell/Services/cpu.hpp +++ b/Plugins/ZShell/Services/cpu.hpp @@ -7,42 +7,42 @@ namespace ZShell::services { class Cpu : public TickingService { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -Q_PROPERTY(QString name READ name NOTIFY nameChanged) -Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged) -Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged) + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged) + Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged) -public: -explicit Cpu(QObject* parent = nullptr); + public: + explicit Cpu(QObject* parent = nullptr); -[[nodiscard]] QString name() const; -[[nodiscard]] qreal percentage() const; -[[nodiscard]] qreal temperature() const; + [[nodiscard]] QString name() const; + [[nodiscard]] qreal percentage() const; + [[nodiscard]] qreal temperature() const; -signals: -void nameChanged(); -void percentageChanged(); -void temperatureChanged(); + signals: + void nameChanged(); + void percentageChanged(); + void temperatureChanged(); -protected: -void tick() override; + protected: + void tick() override; -private: -void readNameOnce(); -void refreshPercentage(); -void refreshTemperature(); + private: + void readNameOnce(); + void refreshPercentage(); + void refreshTemperature(); -[[nodiscard]] static QString cleanName(QString s); + [[nodiscard]] static QString cleanName(QString s); -QString m_name; -qreal m_percentage = 0.0; -qreal m_temperature = 0.0; -quint64 m_lastIdle = 0; -quint64 m_lastTotal = 0; -bool m_nameLoaded = false; + QString m_name; + qreal m_percentage = 0.0; + qreal m_temperature = 0.0; + quint64 m_lastIdle = 0; + quint64 m_lastTotal = 0; + bool m_nameLoaded = false; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/desktopmodel.hpp b/Plugins/ZShell/Services/desktopmodel.hpp index 286b40a..4f47a00 100644 --- a/Plugins/ZShell/Services/desktopmodel.hpp +++ b/Plugins/ZShell/Services/desktopmodel.hpp @@ -17,49 +17,57 @@ struct DesktopItem { }; class DesktopModel : public QAbstractListModel { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -public: -enum DesktopRoles { - FileNameRole = Qt::UserRole + 1, - FilePathRole, - IsDirRole, - GridXRole, - GridYRole + public: + enum DesktopRoles { + FileNameRole = Qt::UserRole + 1, + FilePathRole, + IsDirRole, + GridXRole, + GridYRole + }; + + explicit DesktopModel(QObject* parent = nullptr); + + [[nodiscard]] int rowCount( + const QModelIndex& parent = QModelIndex()) const override; + [[nodiscard]] QVariant data( + const QModelIndex& index, int role = Qt::DisplayRole) const override; + [[nodiscard]] QHash roleNames() const override; + + Q_INVOKABLE void loadDirectory(const QString& path); + Q_INVOKABLE void moveIcon(int index, int newX, int newY); + Q_INVOKABLE void massMove( + const QVariantList& selectedPathsList, + const QString& leaderPath, + int targetX, + int targetY, + int maxCol, + int maxRow); + + Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) + + [[nodiscard]] int rows() const { return m_rows; } + void setRows(int r) { + if (m_rows != r) { + m_rows = r; + emit rowsChanged(); + } + } + + signals: + void rowsChanged(); + + private: + int m_rows = 1; + QList m_items; + QString m_watchedPath; + QFileSystemWatcher m_watcher; + void saveCurrentLayout(); + [[nodiscard]] QPoint getEmptySpot(const QSet& occupied) const; + void onDirectoryChanged(); }; -explicit DesktopModel(QObject *parent = nullptr); - -[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override; -[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; -[[nodiscard]] QHash roleNames() const override; - -Q_INVOKABLE void loadDirectory(const QString &path); -Q_INVOKABLE void moveIcon(int index, int newX, int newY); -Q_INVOKABLE void massMove(const QVariantList &selectedPathsList, const QString &leaderPath, int targetX, int targetY, int maxCol, int maxRow); - -Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) - -public: -[[nodiscard]] int rows() const { - return m_rows; -} -void setRows(int r) { - if (m_rows != r) { m_rows = r; emit rowsChanged(); } -} - -signals: -void rowsChanged(); - -private: -int m_rows = 1; -QList m_items; -QString m_watchedPath; -QFileSystemWatcher m_watcher; -void saveCurrentLayout(); -[[nodiscard]] QPoint getEmptySpot(const QSet &occupied) const; -void onDirectoryChanged(); -}; - -}; +}; // namespace ZShell::services diff --git a/Plugins/ZShell/Services/desktopstatemanager.cpp b/Plugins/ZShell/Services/desktopstatemanager.cpp index 820a1e6..84b0df0 100644 --- a/Plugins/ZShell/Services/desktopstatemanager.cpp +++ b/Plugins/ZShell/Services/desktopstatemanager.cpp @@ -9,11 +9,12 @@ namespace ZShell::services { -DesktopStateManager::DesktopStateManager(QObject *parent) : QObject(parent) { -} +DesktopStateManager::DesktopStateManager(QObject* parent) : QObject(parent) {} QString DesktopStateManager::getConfigFilePath() const { - QString configDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/zshell"; + QString configDir = + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + "/zshell"; QDir dir(configDir); if (!dir.exists()) { dir.mkpath("."); @@ -30,7 +31,8 @@ void DesktopStateManager::saveLayout(const QVariantMap& layout) { file.write(doc.toJson(QJsonDocument::Indented)); file.close(); } else { - qWarning() << "zshell: Cannot save desktop layout to" << getConfigFilePath(); + qWarning() << "zshell: Cannot save desktop layout to" + << getConfigFilePath(); } } diff --git a/Plugins/ZShell/Services/desktopstatemanager.hpp b/Plugins/ZShell/Services/desktopstatemanager.hpp index 6a0cdce..5c996ec 100644 --- a/Plugins/ZShell/Services/desktopstatemanager.hpp +++ b/Plugins/ZShell/Services/desktopstatemanager.hpp @@ -7,18 +7,18 @@ namespace ZShell::services { class DesktopStateManager : public QObject { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -public: -explicit DesktopStateManager(QObject *parent = nullptr); + public: + explicit DesktopStateManager(QObject* parent = nullptr); -Q_INVOKABLE void saveLayout(const QVariantMap& layout); -Q_INVOKABLE QVariantMap getLayout(); + Q_INVOKABLE void saveLayout(const QVariantMap& layout); + Q_INVOKABLE QVariantMap getLayout(); -private: -[[nodiscard]] QString getConfigFilePath() const; + private: + [[nodiscard]] QString getConfigFilePath() const; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/diskinfo.cpp b/Plugins/ZShell/Services/diskinfo.cpp index aca9bb8..dae8468 100644 --- a/Plugins/ZShell/Services/diskinfo.cpp +++ b/Plugins/ZShell/Services/diskinfo.cpp @@ -8,13 +8,17 @@ constexpr qreal kKib = 1024.0; } // namespace -DiskInfo::DiskInfo(QString mount, quint64 usedBytes, quint64 totalBytes, bool hasRoot, QObject* parent) +DiskInfo::DiskInfo( + QString mount, + quint64 usedBytes, + quint64 totalBytes, + bool hasRoot, + QObject* parent) : QObject(parent) , m_mount(std::move(mount)) , m_usedBytes(usedBytes) , m_totalBytes(totalBytes) - , m_hasRoot(hasRoot) { -} + , m_hasRoot(hasRoot) {} QString DiskInfo::mount() const { return m_mount; @@ -29,12 +33,15 @@ qreal DiskInfo::total() const { } qreal DiskInfo::free() const { - const quint64 freeBytes = m_totalBytes > m_usedBytes ? m_totalBytes - m_usedBytes : 0; + const quint64 freeBytes = + m_totalBytes > m_usedBytes ? m_totalBytes - m_usedBytes : 0; return static_cast(freeBytes) / kKib; } qreal DiskInfo::perc() const { - return m_totalBytes > 0 ? static_cast(m_usedBytes) / static_cast(m_totalBytes) : 0.0; + return m_totalBytes > 0 ? static_cast(m_usedBytes) / + static_cast(m_totalBytes) + : 0.0; } bool DiskInfo::hasRoot() const { diff --git a/Plugins/ZShell/Services/diskinfo.hpp b/Plugins/ZShell/Services/diskinfo.hpp index 34acdff..3b51b0b 100644 --- a/Plugins/ZShell/Services/diskinfo.hpp +++ b/Plugins/ZShell/Services/diskinfo.hpp @@ -6,41 +6,46 @@ namespace ZShell::services { class DiskInfo : public QObject { -Q_OBJECT -QML_ELEMENT - QML_UNCREATABLE("DiskInfo is created by DiskUsage") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("DiskInfo is created by DiskUsage") -Q_PROPERTY(QString mount READ mount CONSTANT) -Q_PROPERTY(qreal used READ used NOTIFY usedChanged) -Q_PROPERTY(qreal total READ total NOTIFY totalChanged) -Q_PROPERTY(qreal free READ free NOTIFY freeChanged) -Q_PROPERTY(qreal perc READ perc NOTIFY percChanged) -Q_PROPERTY(bool hasRoot READ hasRoot NOTIFY hasRootChanged) + Q_PROPERTY(QString mount READ mount CONSTANT) + Q_PROPERTY(qreal used READ used NOTIFY usedChanged) + Q_PROPERTY(qreal total READ total NOTIFY totalChanged) + Q_PROPERTY(qreal free READ free NOTIFY freeChanged) + Q_PROPERTY(qreal perc READ perc NOTIFY percChanged) + Q_PROPERTY(bool hasRoot READ hasRoot NOTIFY hasRootChanged) -public: -DiskInfo(QString mount, quint64 usedBytes, quint64 totalBytes, bool hasRoot, QObject* parent = nullptr); + public: + DiskInfo( + QString mount, + quint64 usedBytes, + quint64 totalBytes, + bool hasRoot, + QObject* parent = nullptr); -[[nodiscard]] QString mount() const; -[[nodiscard]] qreal used() const; -[[nodiscard]] qreal total() const; -[[nodiscard]] qreal free() const; -[[nodiscard]] qreal perc() const; -[[nodiscard]] bool hasRoot() const; + [[nodiscard]] QString mount() const; + [[nodiscard]] qreal used() const; + [[nodiscard]] qreal total() const; + [[nodiscard]] qreal free() const; + [[nodiscard]] qreal perc() const; + [[nodiscard]] bool hasRoot() const; -void update(quint64 usedBytes, quint64 totalBytes, bool hasRoot); + void update(quint64 usedBytes, quint64 totalBytes, bool hasRoot); -signals: -void usedChanged(); -void totalChanged(); -void freeChanged(); -void percChanged(); -void hasRootChanged(); + signals: + void usedChanged(); + void totalChanged(); + void freeChanged(); + void percChanged(); + void hasRootChanged(); -private: -QString m_mount; -quint64 m_usedBytes; -quint64 m_totalBytes; -bool m_hasRoot; + private: + QString m_mount; + quint64 m_usedBytes; + quint64 m_totalBytes; + bool m_hasRoot; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/gpu.hpp b/Plugins/ZShell/Services/gpu.hpp index e8cf84d..4b91122 100644 --- a/Plugins/ZShell/Services/gpu.hpp +++ b/Plugins/ZShell/Services/gpu.hpp @@ -8,81 +8,81 @@ namespace ZShell::services { class Gpu : public TickingService { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -public: -enum Type { - Auto, // user override is empty (config "") — defer to detected autoType - None, // no usable GPU - Nvidia, // queried via nvidia-smi - Generic, // queried via /sys/class/drm/card*/device/gpu_busy_percent -}; -Q_ENUM(Type) + public: + enum Type { + Auto, // user override is empty (config "") — defer to detected autoType + None, // no usable GPU + Nvidia, // queried via nvidia-smi + Generic, // queried via /sys/class/drm/card*/device/gpu_busy_percent + }; + Q_ENUM(Type) -private: -Q_PROPERTY(Type type READ type NOTIFY typeChanged) -Q_PROPERTY(Type userType READ userType NOTIFY userTypeChanged) -Q_PROPERTY(Type autoType READ autoType NOTIFY autoTypeChanged) -Q_PROPERTY(QString name READ name NOTIFY nameChanged) -Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged) -Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged) -Q_PROPERTY(qreal memoryUsed READ memoryUsed NOTIFY memoryUsedChanged) -Q_PROPERTY(qreal memoryTotal READ memoryTotal NOTIFY memoryTotalChanged) + private: + Q_PROPERTY(Type type READ type NOTIFY typeChanged) + Q_PROPERTY(Type userType READ userType NOTIFY userTypeChanged) + Q_PROPERTY(Type autoType READ autoType NOTIFY autoTypeChanged) + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged) + Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged) + Q_PROPERTY(qreal memoryUsed READ memoryUsed NOTIFY memoryUsedChanged) + Q_PROPERTY(qreal memoryTotal READ memoryTotal NOTIFY memoryTotalChanged) -public: -explicit Gpu(QObject* parent = nullptr); + public: + explicit Gpu(QObject* parent = nullptr); -[[nodiscard]] Type type() const; -[[nodiscard]] Type userType() const; -[[nodiscard]] Type autoType() const; -[[nodiscard]] QString name() const; -[[nodiscard]] qreal percentage() const; -[[nodiscard]] qreal temperature() const; -[[nodiscard]] qreal memoryUsed() const; -[[nodiscard]] qreal memoryTotal() const; + [[nodiscard]] Type type() const; + [[nodiscard]] Type userType() const; + [[nodiscard]] Type autoType() const; + [[nodiscard]] QString name() const; + [[nodiscard]] qreal percentage() const; + [[nodiscard]] qreal temperature() const; + [[nodiscard]] qreal memoryUsed() const; + [[nodiscard]] qreal memoryTotal() const; -signals: -void typeChanged(); -void userTypeChanged(); -void autoTypeChanged(); -void nameChanged(); -void percentageChanged(); -void temperatureChanged(); -void memoryUsedChanged(); -void memoryTotalChanged(); + signals: + void typeChanged(); + void userTypeChanged(); + void autoTypeChanged(); + void nameChanged(); + void percentageChanged(); + void temperatureChanged(); + void memoryUsedChanged(); + void memoryTotalChanged(); -protected: -void tick() override; + protected: + void tick() override; -private: -void detectTypeOnce(); -void detectNameOnce(); -void readGenericUsage(); -void startNvidiaUsage(); -void readGpuTemperature(); + private: + void detectTypeOnce(); + void detectNameOnce(); + void readGenericUsage(); + void startNvidiaUsage(); + void readGpuTemperature(); -void setUserType(Type value); -void setAutoType(Type value); -void setName(QString value); -void setMemoryUsed(qreal value); -void setMemoryTotal(qreal value); + void setUserType(Type value); + void setAutoType(Type value); + void setName(QString value); + void setMemoryUsed(qreal value); + void setMemoryTotal(qreal value); -[[nodiscard]] static Type parseType(const QString& s); -[[nodiscard]] static QString cleanName(QString s); + [[nodiscard]] static Type parseType(const QString& s); + [[nodiscard]] static QString cleanName(QString s); -Type m_userType = Auto; -Type m_autoType = None; -QString m_name; -qreal m_percentage = 0.0; -qreal m_temperature = 0.0; -qreal m_memoryUsed = 0.0; -qreal m_memoryTotal = 0.0; + Type m_userType = Auto; + Type m_autoType = None; + QString m_name; + qreal m_percentage = 0.0; + qreal m_temperature = 0.0; + qreal m_memoryUsed = 0.0; + qreal m_memoryTotal = 0.0; -QProcess* m_typeProc = nullptr; -QProcess* m_nameProc = nullptr; -QProcess* m_nvidiaProc = nullptr; + QProcess* m_typeProc = nullptr; + QProcess* m_nameProc = nullptr; + QProcess* m_nvidiaProc = nullptr; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/hyprsunsetmanager.cpp b/Plugins/ZShell/Services/hyprsunsetmanager.cpp index 40aa81f..0b33f6f 100644 --- a/Plugins/ZShell/Services/hyprsunsetmanager.cpp +++ b/Plugins/ZShell/Services/hyprsunsetmanager.cpp @@ -9,14 +9,14 @@ namespace ZShell::services { HyprsunsetManager::HyprsunsetManager(QObject* parent) : QObject(parent) { connect(&m_timer, &QTimer::timeout, this, &HyprsunsetManager::apply); connect(&m_manualTimer, &QTimer::timeout, this, [this] { - m_manualToggle = false; - emit manualToggleChanged(); - apply(); - }); + m_manualToggle = false; + emit manualToggleChanged(); + apply(); + }); connect(&m_startCooldown, &QTimer::timeout, this, [this] { - m_startAllowed = true; - apply(); - }); + m_startAllowed = true; + apply(); + }); m_startCooldown.start(2000); m_manualTimer.setSingleShot(true); @@ -51,16 +51,14 @@ int HyprsunsetManager::temp() const { } void HyprsunsetManager::setActiveAuto(bool activeAuto) { - if (activeAuto == m_activeAuto) - return; + if (activeAuto == m_activeAuto) return; m_activeAuto = activeAuto; emit activeAutoChanged(); } void HyprsunsetManager::setManualToggle(bool toggle) { - if (toggle == m_manualToggle) - return; + if (toggle == m_manualToggle) return; m_manualToggle = toggle; emit manualToggleChanged(); @@ -69,8 +67,7 @@ void HyprsunsetManager::setManualToggle(bool toggle) { } void HyprsunsetManager::setEndTime(const int& time) { - if (time == m_endTime) - return; + if (time == m_endTime) return; m_endTime = time; emit endTimeChanged(); @@ -78,8 +75,7 @@ void HyprsunsetManager::setEndTime(const int& time) { } void HyprsunsetManager::setStartTime(const int& time) { - if (time == m_startTime) - return; + if (time == m_startTime) return; m_startTime = time; emit startTimeChanged(); @@ -87,8 +83,7 @@ void HyprsunsetManager::setStartTime(const int& time) { } void HyprsunsetManager::setTemp(const int& temp) { - if (temp == m_temp) - return; + if (temp == m_temp) return; m_temp = temp; emit tempChanged(); @@ -104,8 +99,7 @@ void HyprsunsetManager::toggle() { } void HyprsunsetManager::start() { - if (m_enabled && m_initialized) - return; + if (m_enabled && m_initialized) return; m_initialized = true; m_enabled = true; @@ -113,13 +107,13 @@ void HyprsunsetManager::start() { emit enabledChanged(); m_process.setProgram("hyprctl"); - m_process.setArguments({"hyprsunset", "temperature", QString::number(m_temp)}); + m_process.setArguments( + {"hyprsunset", "temperature", QString::number(m_temp)}); m_process.startDetached(); } void HyprsunsetManager::end() { - if (!m_enabled && m_initialized) - return; + if (!m_enabled && m_initialized) return; m_initialized = true; m_enabled = false; @@ -132,12 +126,11 @@ void HyprsunsetManager::end() { } void HyprsunsetManager::apply() { - if (m_manualToggle || !m_activeAuto || !m_startAllowed) - return; + if (m_manualToggle || !m_activeAuto || !m_startAllowed) return; const auto current = QTime::currentTime(); const auto currentMin = current.hour() * 60 + current.minute(); - bool isDarkTime; + bool isDarkTime = false; if (m_startTime <= m_endTime) { isDarkTime = (currentMin >= m_startTime && currentMin < m_endTime); @@ -152,4 +145,4 @@ void HyprsunsetManager::apply() { } } -}; +}; // namespace ZShell::services diff --git a/Plugins/ZShell/Services/hyprsunsetmanager.hpp b/Plugins/ZShell/Services/hyprsunsetmanager.hpp index ebdbda9..7241c0d 100644 --- a/Plugins/ZShell/Services/hyprsunsetmanager.hpp +++ b/Plugins/ZShell/Services/hyprsunsetmanager.hpp @@ -10,57 +10,62 @@ namespace ZShell::services { class HyprsunsetManager : public QObject { -Q_OBJECT -QML_ELEMENT -Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) -Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) -Q_PROPERTY(int endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged) -Q_PROPERTY(int temp READ temp WRITE setTemp NOTIFY tempChanged) -Q_PROPERTY(bool activeAuto READ activeAuto WRITE setActiveAuto NOTIFY activeAutoChanged) -Q_PROPERTY(bool manualToggle READ manualToggle WRITE setManualToggle NOTIFY manualToggleChanged) + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) + Q_PROPERTY( + int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) + Q_PROPERTY(int endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged) + Q_PROPERTY(int temp READ temp WRITE setTemp NOTIFY tempChanged) + Q_PROPERTY( + bool activeAuto READ activeAuto WRITE setActiveAuto NOTIFY + activeAutoChanged) + Q_PROPERTY( + bool manualToggle READ manualToggle WRITE setManualToggle NOTIFY + manualToggleChanged) -public: -explicit HyprsunsetManager(QObject* parent = nullptr); + public: + explicit HyprsunsetManager(QObject* parent = nullptr); -[[nodiscard]] int startTime() const; -[[nodiscard]] int endTime() const; -[[nodiscard]] bool enabled() const; -[[nodiscard]] int temp() const; -[[nodiscard]] bool activeAuto() const; -[[nodiscard]] bool manualToggle() const; + [[nodiscard]] int startTime() const; + [[nodiscard]] int endTime() const; + [[nodiscard]] bool enabled() const; + [[nodiscard]] int temp() const; + [[nodiscard]] bool activeAuto() const; + [[nodiscard]] bool manualToggle() const; -Q_INVOKABLE void toggle(); -Q_INVOKABLE void apply(); + Q_INVOKABLE void toggle(); + Q_INVOKABLE void apply(); -void setStartTime(const int& time); -void setEndTime(const int& time); -void setTemp(const int& temp); -void setActiveAuto(bool activeAuto); -void setManualToggle(bool toggle); + void setStartTime(const int& time); + void setEndTime(const int& time); + void setTemp(const int& temp); + void setActiveAuto(bool activeAuto); + void setManualToggle(bool toggle); -signals: -void enabledChanged(); -void startTimeChanged(); -void activeAutoChanged(); -void endTimeChanged(); -void tempChanged(); -void manualToggleChanged(); + signals: + void enabledChanged(); + void startTimeChanged(); + void activeAutoChanged(); + void endTimeChanged(); + void tempChanged(); + void manualToggleChanged(); -private: -int m_startTime; -int m_endTime; -bool m_enabled = false; -bool m_manualToggle = false; -bool m_activeAuto; -bool m_startAllowed = false; -bool m_initialized = false; -QTimer m_startCooldown; -int m_temp; -QProcess m_process; -QTimer m_timer; -QTimer m_manualTimer; -void start(); -void end(); + private: + int m_startTime; + int m_endTime; + bool m_enabled = false; + bool m_manualToggle = false; + bool m_activeAuto; + bool m_startAllowed = false; + bool m_initialized = false; + QTimer m_startCooldown; + int m_temp; + QProcess m_process; + QTimer m_timer; + QTimer m_manualTimer; + void start(); + void end(); }; -}; +}; // namespace ZShell::services diff --git a/Plugins/ZShell/Services/memory.cpp b/Plugins/ZShell/Services/memory.cpp index 50f5f77..eb8020c 100644 --- a/Plugins/ZShell/Services/memory.cpp +++ b/Plugins/ZShell/Services/memory.cpp @@ -5,9 +5,7 @@ namespace ZShell::services { -Memory::Memory(QObject* parent) - : TickingService(parent) { -} +Memory::Memory(QObject* parent) : TickingService(parent) {} qreal Memory::used() const { return m_used; @@ -29,8 +27,10 @@ void Memory::tick() { const QByteArray data = f.readAll(); f.close(); - static const QRegularExpression reTotal(QStringLiteral("MemTotal: *(\\d+)")); - static const QRegularExpression reAvail(QStringLiteral("MemAvailable: *(\\d+)")); + static const QRegularExpression reTotal( + QStringLiteral("MemTotal: *(\\d+)")); + static const QRegularExpression reAvail( + QStringLiteral("MemAvailable: *(\\d+)")); const QString text = QString::fromLatin1(data); const auto totalMatch = reTotal.match(text); diff --git a/Plugins/ZShell/Services/memory.hpp b/Plugins/ZShell/Services/memory.hpp index f5d0fb6..e21bbc5 100644 --- a/Plugins/ZShell/Services/memory.hpp +++ b/Plugins/ZShell/Services/memory.hpp @@ -8,32 +8,32 @@ namespace ZShell::services { class Memory : public TickingService { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -Q_PROPERTY(qreal used READ used NOTIFY changed) -Q_PROPERTY(qreal total READ total NOTIFY changed) -Q_PROPERTY(qreal percentage READ percentage NOTIFY changed) + Q_PROPERTY(qreal used READ used NOTIFY changed) + Q_PROPERTY(qreal total READ total NOTIFY changed) + Q_PROPERTY(qreal percentage READ percentage NOTIFY changed) -public: -explicit Memory(QObject* parent = nullptr); + public: + explicit Memory(QObject* parent = nullptr); -[[nodiscard]] qreal used() const; -[[nodiscard]] qreal total() const; -[[nodiscard]] qreal percentage() const; + [[nodiscard]] qreal used() const; + [[nodiscard]] qreal total() const; + [[nodiscard]] qreal percentage() const; -signals: -void changed(); + signals: + void changed(); -protected: -void tick() override; + protected: + void tick() override; -private: -qreal m_used = 0.0; -qreal m_total = 1.0; -quint64 m_lastUsed = 0; -quint64 m_lastTotal = 0; + private: + qreal m_used = 0.0; + qreal m_total = 1.0; + quint64 m_lastUsed = 0; + quint64 m_lastTotal = 0; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/sensorslib.cpp b/Plugins/ZShell/Services/sensorslib.cpp index 995434a..2e81315 100644 --- a/Plugins/ZShell/Services/sensorslib.cpp +++ b/Plugins/ZShell/Services/sensorslib.cpp @@ -14,7 +14,7 @@ namespace ZShell::services::sensorslib { namespace { -std::atomic g_initOk{ false }; +std::atomic g_initOk{false}; std::once_flag g_initFlag; void doInit() { @@ -25,14 +25,16 @@ void doInit() { } g_initOk.store(true, std::memory_order_release); std::atexit([] { - if (g_initOk.load(std::memory_order_acquire)) { - sensors_cleanup(); - } - }); + if (g_initOk.load(std::memory_order_acquire)) { + sensors_cleanup(); + } + }); } -[[nodiscard]] std::optional readTempInput(const sensors_chip_name* chip, const sensors_feature* feat) { - const sensors_subfeature* sf = sensors_get_subfeature(chip, feat, SENSORS_SUBFEATURE_TEMP_INPUT); +[[nodiscard]] std::optional readTempInput( + const sensors_chip_name* chip, const sensors_feature* feat) { + const sensors_subfeature* sf = + sensors_get_subfeature(chip, feat, SENSORS_SUBFEATURE_TEMP_INPUT); if (!sf) { return std::nullopt; } @@ -43,7 +45,8 @@ void doInit() { return value; } -[[nodiscard]] QByteArray featureLabel(const sensors_chip_name* chip, const sensors_feature* feat) { +[[nodiscard]] QByteArray featureLabel( + const sensors_chip_name* chip, const sensors_feature* feat) { char* raw = sensors_get_label(chip, feat); if (!raw) { return {}; @@ -59,7 +62,8 @@ bool labelEquals(const QByteArray& label, const char* literal) { bool labelStartsWith(const QByteArray& label, const char* prefix) { const auto n = std::strlen(prefix); - return static_cast(label.size()) >= n && std::memcmp(label.constData(), prefix, n) == 0; + return static_cast(label.size()) >= n && + std::memcmp(label.constData(), prefix, n) == 0; } } // namespace @@ -74,13 +78,15 @@ std::optional cpuPackageTemp() { return std::nullopt; } - std::optional primary; // Package id N / Tdie + std::optional primary; // Package id N / Tdie std::optional fallback; // Tctl int chipNr = 0; - while (const sensors_chip_name* chip = sensors_get_detected_chips(nullptr, &chipNr)) { + while (const sensors_chip_name* chip = + sensors_get_detected_chips(nullptr, &chipNr)) { int featNr = 0; - while (const sensors_feature* feat = sensors_get_features(chip, &featNr)) { + while (const sensors_feature* feat = + sensors_get_features(chip, &featNr)) { if (feat->type != SENSORS_FEATURE_TEMP) { continue; } @@ -89,7 +95,8 @@ std::optional cpuPackageTemp() { continue; } - if (labelStartsWith(label, "Package id ") || labelEquals(label, "Tdie")) { + if (labelStartsWith(label, "Package id ") || + labelEquals(label, "Tdie")) { if (auto v = readTempInput(chip, feat)) { primary = v; } @@ -116,13 +123,15 @@ std::optional gpuPciAverageTemp() { int countFallback = 0; int chipNr = 0; - while (const sensors_chip_name* chip = sensors_get_detected_chips(nullptr, &chipNr)) { + while (const sensors_chip_name* chip = + sensors_get_detected_chips(nullptr, &chipNr)) { if (chip->bus.type != SENSORS_BUS_TYPE_PCI) { continue; } int featNr = 0; - while (const sensors_feature* feat = sensors_get_features(chip, &featNr)) { + while (const sensors_feature* feat = + sensors_get_features(chip, &featNr)) { if (feat->type != SENSORS_FEATURE_TEMP) { continue; } @@ -131,10 +140,14 @@ std::optional gpuPciAverageTemp() { continue; } - const bool tempIndexed = labelStartsWith(label, "temp") && label.size() > 4 && - std::isdigit(static_cast(label[4])); - const bool isPrimary = tempIndexed || labelEquals(label, "GPU core") || labelEquals(label, "edge"); - const bool isFallback = labelEquals(label, "junction") || labelEquals(label, "mem"); + const bool tempIndexed = + labelStartsWith(label, "temp") && label.size() > 4 && + std::isdigit(static_cast(label[4])); + const bool isPrimary = tempIndexed || + labelEquals(label, "GPU core") || + labelEquals(label, "edge"); + const bool isFallback = labelEquals(label, "junction") || + labelEquals(label, "mem"); if (!isPrimary && !isFallback) { continue; diff --git a/Plugins/ZShell/Services/service.cpp b/Plugins/ZShell/Services/service.cpp index ef30d0a..6aa1e9f 100644 --- a/Plugins/ZShell/Services/service.cpp +++ b/Plugins/ZShell/Services/service.cpp @@ -5,9 +5,7 @@ namespace ZShell::services { -Service::Service(QObject* parent) - : QObject(parent) { -} +Service::Service(QObject* parent) : QObject(parent) {} void Service::ref(QObject* sender) { if (m_refs.isEmpty()) { diff --git a/Plugins/ZShell/Services/service.hpp b/Plugins/ZShell/Services/service.hpp index 3bb47b9..23679bb 100644 --- a/Plugins/ZShell/Services/service.hpp +++ b/Plugins/ZShell/Services/service.hpp @@ -6,19 +6,19 @@ namespace ZShell::services { class Service : public QObject { -Q_OBJECT + Q_OBJECT -public: -explicit Service(QObject* parent = nullptr); + public: + explicit Service(QObject* parent = nullptr); -void ref(QObject* sender); -void unref(QObject* sender); + void ref(QObject* sender); + void unref(QObject* sender); -private: -QSet m_refs; + private: + QSet m_refs; -virtual void start() = 0; -virtual void stop() = 0; + virtual void start() = 0; + virtual void stop() = 0; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/serviceref.cpp b/Plugins/ZShell/Services/serviceref.cpp index 69ae40c..42f9afd 100644 --- a/Plugins/ZShell/Services/serviceref.cpp +++ b/Plugins/ZShell/Services/serviceref.cpp @@ -5,8 +5,7 @@ namespace ZShell::services { ServiceRef::ServiceRef(Service* service, QObject* parent) - : QObject(parent) - , m_service(service) { + : QObject(parent), m_service(service) { if (m_service) { m_service->ref(this); } diff --git a/Plugins/ZShell/Services/serviceref.hpp b/Plugins/ZShell/Services/serviceref.hpp index 9fb9623..a0a5216 100644 --- a/Plugins/ZShell/Services/serviceref.hpp +++ b/Plugins/ZShell/Services/serviceref.hpp @@ -7,22 +7,24 @@ namespace ZShell::services { class ServiceRef : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(ZShell::services::Service* service READ service WRITE setService NOTIFY serviceChanged) + Q_PROPERTY( + ZShell::services::Service* service READ service WRITE setService NOTIFY + serviceChanged) -public: -explicit ServiceRef(Service* service = nullptr, QObject* parent = nullptr); + public: + explicit ServiceRef(Service* service = nullptr, QObject* parent = nullptr); -[[nodiscard]] Service* service() const; -void setService(Service* service); + [[nodiscard]] Service* service() const; + void setService(Service* service); -signals: -void serviceChanged(); + signals: + void serviceChanged(); -private: -QPointer m_service; + private: + QPointer m_service; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/storage.cpp b/Plugins/ZShell/Services/storage.cpp index f9973c6..4e9d52f 100644 --- a/Plugins/ZShell/Services/storage.cpp +++ b/Plugins/ZShell/Services/storage.cpp @@ -24,12 +24,14 @@ struct Accum { }; [[nodiscard]] QString sysfsRealPath(uint major, uint minor) { - const QString link = QStringLiteral("/sys/dev/block/%1:%2").arg(major).arg(minor); + const QString link = + QStringLiteral("/sys/dev/block/%1:%2").arg(major).arg(minor); const QString resolved = QFileInfo(link).canonicalFilePath(); return resolved; } -[[nodiscard]] bool readDevtFromSysfs(const QString& sysfsBlockDir, uint& major, uint& minor) { +[[nodiscard]] bool readDevtFromSysfs( + const QString& sysfsBlockDir, uint& major, uint& minor) { QFile f(sysfsBlockDir + QStringLiteral("/dev")); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; @@ -50,6 +52,7 @@ struct Accum { QStringList resolveByDevt(uint major, uint minor, int depth = 0); +// NOLINTNEXTLINE(misc-no-recursion) QStringList resolveAtNode(const QString& node, int depth) { if (node.isEmpty() || depth > 8) { return {}; @@ -62,18 +65,20 @@ QStringList resolveAtNode(const QString& node, int depth) { if (QFileInfo::exists(node + QStringLiteral("/partition"))) { const QString diskNode = nodeInfo.path(); - return { QFileInfo(diskNode).fileName() }; + return {QFileInfo(diskNode).fileName()}; } const QDir slavesDir(node + QStringLiteral("/slaves")); if (slavesDir.exists()) { - const QStringList slaves = slavesDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + const QStringList slaves = + slavesDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); if (!slaves.isEmpty()) { QStringList out; for (const QString& slave : slaves) { uint sm = 0; uint sn = 0; - const QString slaveDir = QStringLiteral("/sys/class/block/") + slave; + const QString slaveDir = + QStringLiteral("/sys/class/block/") + slave; if (!readDevtFromSysfs(slaveDir, sm, sn)) { continue; } @@ -88,18 +93,17 @@ QStringList resolveAtNode(const QString& node, int depth) { } } - return { nodeInfo.fileName() }; + return {nodeInfo.fileName()}; } +// NOLINTNEXTLINE(misc-no-recursion) QStringList resolveByDevt(uint major, uint minor, int depth) { return resolveAtNode(sysfsRealPath(major, minor), depth); } } // namespace -Storage::Storage(QObject* parent) - : TickingService(parent) { -} +Storage::Storage(QObject* parent) : TickingService(parent) {} qreal Storage::percentage() const { qreal totalUsed = 0.0; @@ -124,7 +128,8 @@ bool Storage::sameOrder(const QList& a, const QList& b) { } QQmlListProperty Storage::disksProp() { - return QQmlListProperty(this, nullptr, &Storage::disksCount, &Storage::disksAt); + return QQmlListProperty( + this, nullptr, &Storage::disksCount, &Storage::disksAt); } qsizetype Storage::disksCount(QQmlListProperty* prop) { @@ -157,30 +162,11 @@ DiskInfo* Storage::primaryDisk() const { bool Storage::isPseudoFs(QByteArrayView fsType) { static constexpr const char* kPseudo[] = { - "tmpfs", - "devtmpfs", - "proc", - "sysfs", - "cgroup", - "cgroup2", - "overlay", - "squashfs", - "devpts", - "mqueue", - "ramfs", - "rpc_pipefs", - "autofs", - "configfs", - "debugfs", - "tracefs", - "securityfs", - "pstore", - "bpf", - "binfmt_misc", - "hugetlbfs", - "fusectl", - "efivarfs", - "selinuxfs", + "tmpfs", "devtmpfs", "proc", "sysfs", "cgroup", + "cgroup2", "overlay", "squashfs", "devpts", "mqueue", + "ramfs", "rpc_pipefs", "autofs", "configfs", "debugfs", + "tracefs", "securityfs", "pstore", "bpf", "binfmt_misc", + "hugetlbfs", "fusectl", "efivarfs", "selinuxfs", }; for (const char* p : kPseudo) { if (fsType == QByteArrayView(p)) { @@ -194,7 +180,7 @@ QStringList Storage::resolveToPhysicalDisks(const QString& devicePath) { if (devicePath.isEmpty() || !devicePath.startsWith(QLatin1Char('/'))) { return {}; } - struct stat st {}; + struct stat st{}; if (::stat(devicePath.toLocal8Bit().constData(), &st) != 0) { return {}; } @@ -232,7 +218,8 @@ void Storage::tick() { const QByteArray device = v.device(); const auto totalBytes = static_cast(v.bytesTotal()); const auto availBytes = static_cast(v.bytesAvailable()); - const quint64 usedBytes = totalBytes > availBytes ? totalBytes - availBytes : 0; + const quint64 usedBytes = + totalBytes > availBytes ? totalBytes - availBytes : 0; const bool isRoot = v.rootPath() == QStringLiteral("/"); DeviceEntry& e = byDevice[device]; @@ -244,7 +231,8 @@ void Storage::tick() { for (auto it = byDevice.constBegin(); it != byDevice.constEnd(); ++it) { const DeviceEntry& e = it.value(); - const QStringList disks = resolveToPhysicalDisks(QString::fromLocal8Bit(e.device)); + const QStringList disks = + resolveToPhysicalDisks(QString::fromLocal8Bit(e.device)); if (disks.isEmpty()) { continue; } @@ -269,14 +257,23 @@ void Storage::tick() { next.reserve(byDisk.size()); for (auto it = byDisk.constBegin(); it != byDisk.constEnd(); ++it) { if (DiskInfo* survivor = existing.take(it.key())) { - survivor->update(it.value().usedBytes, it.value().totalBytes, it.value().hasRoot); + survivor->update( + it.value().usedBytes, + it.value().totalBytes, + it.value().hasRoot); next.append(survivor); } else { - next.append(new DiskInfo(it.key(), it.value().usedBytes, it.value().totalBytes, it.value().hasRoot, this)); + next.append(new DiskInfo( + it.key(), + it.value().usedBytes, + it.value().totalBytes, + it.value().hasRoot, + this)); } } - std::sort(next.begin(), next.end(), [](const DiskInfo* a, const DiskInfo* b) { + std::sort( + next.begin(), next.end(), [](const DiskInfo* a, const DiskInfo* b) { if (a->hasRoot() != b->hasRoot()) { return a->hasRoot(); } @@ -284,7 +281,8 @@ void Storage::tick() { }); bool manualCleared = false; - if (DiskInfo* m = m_manualPrimaryDisk.data(); m && existing.contains(m->mount())) { + if (DiskInfo* m = m_manualPrimaryDisk.data(); + m && existing.contains(m->mount())) { m_manualPrimaryDisk.clear(); manualCleared = true; } diff --git a/Plugins/ZShell/Services/storage.hpp b/Plugins/ZShell/Services/storage.hpp index 2138c04..0c61466 100644 --- a/Plugins/ZShell/Services/storage.hpp +++ b/Plugins/ZShell/Services/storage.hpp @@ -12,44 +12,51 @@ namespace ZShell::services { class Storage : public TickingService { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged) -Q_PROPERTY(QQmlListProperty disks READ disksProp NOTIFY disksChanged) -Q_PROPERTY(ZShell::services::DiskInfo* manualPrimaryDisk READ manualPrimaryDisk WRITE setManualPrimaryDisk NOTIFY - manualPrimaryDiskChanged) -Q_PROPERTY(ZShell::services::DiskInfo* primaryDisk READ primaryDisk NOTIFY primaryDiskChanged) + Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged) + Q_PROPERTY( + QQmlListProperty disks READ disksProp NOTIFY + disksChanged) + Q_PROPERTY( + ZShell::services::DiskInfo* manualPrimaryDisk READ manualPrimaryDisk + WRITE setManualPrimaryDisk NOTIFY manualPrimaryDiskChanged) + Q_PROPERTY( + ZShell::services::DiskInfo* primaryDisk READ primaryDisk NOTIFY + primaryDiskChanged) -public: -explicit Storage(QObject* parent = nullptr); + public: + explicit Storage(QObject* parent = nullptr); -[[nodiscard]] qreal percentage() const; -[[nodiscard]] QQmlListProperty disksProp(); -[[nodiscard]] DiskInfo* manualPrimaryDisk() const; -void setManualPrimaryDisk(DiskInfo* disk); -[[nodiscard]] DiskInfo* primaryDisk() const; + [[nodiscard]] qreal percentage() const; + [[nodiscard]] QQmlListProperty disksProp(); + [[nodiscard]] DiskInfo* manualPrimaryDisk() const; + void setManualPrimaryDisk(DiskInfo* disk); + [[nodiscard]] DiskInfo* primaryDisk() const; -signals: -void disksChanged(); -void percentageChanged(); -void manualPrimaryDiskChanged(); -void primaryDiskChanged(); + signals: + void disksChanged(); + void percentageChanged(); + void manualPrimaryDiskChanged(); + void primaryDiskChanged(); -protected: -void tick() override; + protected: + void tick() override; -private: -[[nodiscard]] static QStringList resolveToPhysicalDisks(const QString& devicePath); -[[nodiscard]] static bool isPseudoFs(QByteArrayView fsType); -[[nodiscard]] static bool sameOrder(const QList& a, const QList& b); + private: + [[nodiscard]] static QStringList resolveToPhysicalDisks( + const QString& devicePath); + [[nodiscard]] static bool isPseudoFs(QByteArrayView fsType); + [[nodiscard]] static bool sameOrder( + const QList& a, const QList& b); -static qsizetype disksCount(QQmlListProperty* prop); -static DiskInfo* disksAt(QQmlListProperty* prop, qsizetype i); + static qsizetype disksCount(QQmlListProperty* prop); + static DiskInfo* disksAt(QQmlListProperty* prop, qsizetype i); -QList m_disks; -QPointer m_manualPrimaryDisk; + QList m_disks; + QPointer m_manualPrimaryDisk; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/tickingservice.hpp b/Plugins/ZShell/Services/tickingservice.hpp index 95124eb..324707f 100644 --- a/Plugins/ZShell/Services/tickingservice.hpp +++ b/Plugins/ZShell/Services/tickingservice.hpp @@ -6,30 +6,31 @@ namespace ZShell::services { class TickingService : public Service { -Q_OBJECT + Q_OBJECT -Q_PROPERTY(int updateInterval READ updateInterval NOTIFY updateIntervalChanged) + Q_PROPERTY( + int updateInterval READ updateInterval NOTIFY updateIntervalChanged) -public: -explicit TickingService(QObject* parent = nullptr); + public: + explicit TickingService(QObject* parent = nullptr); -[[nodiscard]] int updateInterval() const; + [[nodiscard]] int updateInterval() const; -signals: -void updateIntervalChanged(); + signals: + void updateIntervalChanged(); -protected: -void start() final; -void stop() final; + protected: + void start() final; + void stop() final; -virtual void tick() = 0; + virtual void tick() = 0; -private: -void applyInterval(int ms); + private: + void applyInterval(int ms); -QTimer* m_timer; -int m_interval = 1000; -bool m_running = false; + QTimer* m_timer; + int m_interval = 1000; + bool m_running = false; }; } // namespace ZShell::services diff --git a/Plugins/ZShell/Services/usagefmt.cpp b/Plugins/ZShell/Services/usagefmt.cpp index e455fe8..1012da1 100644 --- a/Plugins/ZShell/Services/usagefmt.cpp +++ b/Plugins/ZShell/Services/usagefmt.cpp @@ -16,18 +16,18 @@ namespace ZShell::services::usagefmt { FormatResult UsageFmt::formatKib(qreal kib, qreal total) const { if (!finitePositive(kib) || !finitePositive(total)) { - return { 0.0, 0.0, "KiB" }; + return {0.0, 0.0, "KiB"}; } if (total >= kGib) { - return { kib / kGib, total / kGib, "TiB" }; + return {kib / kGib, total / kGib, "TiB"}; } if (total >= kMib) { - return { kib / kMib, total / kMib, "GiB" }; + return {kib / kMib, total / kMib, "GiB"}; } if (total >= kKib) { - return { kib / kKib, total / kKib, "MiB" }; + return {kib / kKib, total / kKib, "MiB"}; } - return { kib, total, "KiB" }; + return {kib, total, "KiB"}; } } // namespace ZShell::services::usagefmt diff --git a/Plugins/ZShell/Services/usagefmt.hpp b/Plugins/ZShell/Services/usagefmt.hpp index 97d38b7..ca910d4 100644 --- a/Plugins/ZShell/Services/usagefmt.hpp +++ b/Plugins/ZShell/Services/usagefmt.hpp @@ -15,19 +15,20 @@ struct FormatResult { Q_PROPERTY(qreal total MEMBER total CONSTANT) Q_PROPERTY(QString unit MEMBER unit CONSTANT) -public: + public: qreal value; qreal total; QString unit; }; class UsageFmt : public QObject { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -public: -Q_INVOKABLE [[nodiscard]] FormatResult formatKib(qreal kib, qreal total) const; + public: + Q_INVOKABLE [[nodiscard]] FormatResult formatKib( + qreal kib, qreal total) const; }; } // namespace ZShell::services::usagefmt diff --git a/Plugins/ZShell/appdb.cpp b/Plugins/ZShell/appdb.cpp index 8614df3..a62cf59 100644 --- a/Plugins/ZShell/appdb.cpp +++ b/Plugins/ZShell/appdb.cpp @@ -7,259 +7,271 @@ namespace ZShell { AppEntry::AppEntry(QObject* entry, unsigned int frequency, QObject* parent) - : QObject(parent) - , m_entry(entry) - , m_frequency(frequency) { - const auto mo = m_entry->metaObject(); - const auto tmo = metaObject(); + : QObject(parent), m_entry(entry), m_frequency(frequency) { + const auto mo = m_entry->metaObject(); + const auto tmo = metaObject(); - for (const auto& prop : - { "name", "comment", "execString", "startupClass", "genericName", "categories", "keywords" }) { - const auto metaProp = mo->property(mo->indexOfProperty(prop)); - const auto thisMetaProp = tmo->property(tmo->indexOfProperty(prop)); - QObject::connect(m_entry, metaProp.notifySignal(), this, thisMetaProp.notifySignal()); - } + for (const auto& prop : + {"name", + "comment", + "execString", + "startupClass", + "genericName", + "categories", + "keywords"}) { + const auto metaProp = mo->property(mo->indexOfProperty(prop)); + const auto thisMetaProp = tmo->property(tmo->indexOfProperty(prop)); + QObject::connect( + m_entry, metaProp.notifySignal(), this, thisMetaProp.notifySignal()); + } - QObject::connect(m_entry, &QObject::destroyed, this, [this]() { - m_entry = nullptr; - deleteLater(); - }); + QObject::connect(m_entry, &QObject::destroyed, this, [this]() { + m_entry = nullptr; + deleteLater(); + }); } QObject* AppEntry::entry() const { - return m_entry; + return m_entry; } quint32 AppEntry::frequency() const { - return m_frequency; + return m_frequency; } void AppEntry::setFrequency(unsigned int frequency) { - if (m_frequency != frequency) { - m_frequency = frequency; - emit frequencyChanged(); - } + if (m_frequency != frequency) { + m_frequency = frequency; + emit frequencyChanged(); + } } void AppEntry::incrementFrequency() { - m_frequency++; - emit frequencyChanged(); + m_frequency++; + emit frequencyChanged(); } QString AppEntry::id() const { - if (!m_entry) { - return ""; - } - return m_entry->property("id").toString(); + if (!m_entry) { + return ""; + } + return m_entry->property("id").toString(); } QString AppEntry::name() const { - if (!m_entry) { - return ""; - } - return m_entry->property("name").toString(); + if (!m_entry) { + return ""; + } + return m_entry->property("name").toString(); } QString AppEntry::comment() const { - if (!m_entry) { - return ""; - } - return m_entry->property("comment").toString(); + if (!m_entry) { + return ""; + } + return m_entry->property("comment").toString(); } QString AppEntry::execString() const { - if (!m_entry) { - return ""; - } - return m_entry->property("execString").toString(); + if (!m_entry) { + return ""; + } + return m_entry->property("execString").toString(); } QString AppEntry::startupClass() const { - if (!m_entry) { - return ""; - } - return m_entry->property("startupClass").toString(); + if (!m_entry) { + return ""; + } + return m_entry->property("startupClass").toString(); } QString AppEntry::genericName() const { - if (!m_entry) { - return ""; - } - return m_entry->property("genericName").toString(); + if (!m_entry) { + return ""; + } + return m_entry->property("genericName").toString(); } QString AppEntry::categories() const { - if (!m_entry) { - return ""; - } - return m_entry->property("categories").toStringList().join(" "); + if (!m_entry) { + return ""; + } + return m_entry->property("categories").toStringList().join(" "); } QString AppEntry::keywords() const { - if (!m_entry) { - return ""; - } - return m_entry->property("keywords").toStringList().join(" "); + if (!m_entry) { + return ""; + } + return m_entry->property("keywords").toStringList().join(" "); } AppDb::AppDb(QObject* parent) - : QObject(parent) - , m_timer(new QTimer(this)) - , m_uuid(QUuid::createUuid().toString()) { - m_timer->setSingleShot(true); - m_timer->setInterval(300); - QObject::connect(m_timer, &QTimer::timeout, this, &AppDb::updateApps); + : QObject(parent) + , m_timer(new QTimer(this)) + , m_uuid(QUuid::createUuid().toString()) { + m_timer->setSingleShot(true); + m_timer->setInterval(300); + QObject::connect(m_timer, &QTimer::timeout, this, &AppDb::updateApps); - auto db = QSqlDatabase::addDatabase("QSQLITE", m_uuid); - db.setDatabaseName(":memory:"); - db.open(); + auto db = QSqlDatabase::addDatabase("QSQLITE", m_uuid); + db.setDatabaseName(":memory:"); + db.open(); - QSqlQuery query(db); - query.exec("CREATE TABLE IF NOT EXISTS frequencies (id TEXT PRIMARY KEY, frequency INTEGER)"); + QSqlQuery query(db); + query.exec( + "CREATE TABLE IF NOT EXISTS frequencies (id TEXT PRIMARY KEY, " + "frequency INTEGER)"); } QString AppDb::uuid() const { - return m_uuid; + return m_uuid; } QString AppDb::path() const { - return m_path; + return m_path; } void AppDb::setPath(const QString& path) { - auto newPath = path.isEmpty() ? ":memory:" : path; + auto newPath = path.isEmpty() ? ":memory:" : path; - if (m_path == newPath) { - return; - } + if (m_path == newPath) { + return; + } - m_path = newPath; - emit pathChanged(); + m_path = newPath; + emit pathChanged(); - auto db = QSqlDatabase::database(m_uuid, false); - db.close(); - db.setDatabaseName(newPath); - db.open(); + auto db = QSqlDatabase::database(m_uuid, false); + db.close(); + db.setDatabaseName(newPath); + db.open(); - QSqlQuery query(db); - query.exec("CREATE TABLE IF NOT EXISTS frequencies (id TEXT PRIMARY KEY, frequency INTEGER)"); + QSqlQuery query(db); + query.exec( + "CREATE TABLE IF NOT EXISTS frequencies (id TEXT PRIMARY KEY, " + "frequency INTEGER)"); - updateAppFrequencies(); + updateAppFrequencies(); } QObjectList AppDb::entries() const { - return m_entries; + return m_entries; } void AppDb::setEntries(const QObjectList& entries) { - if (m_entries == entries) { - return; - } + if (m_entries == entries) { + return; + } - m_entries = entries; - emit entriesChanged(); + m_entries = entries; + emit entriesChanged(); - m_timer->start(); + m_timer->start(); } QQmlListProperty AppDb::apps() { - return QQmlListProperty(this, &getSortedApps()); + return QQmlListProperty(this, &getSortedApps()); } void AppDb::incrementFrequency(const QString& id) { - auto db = QSqlDatabase::database(m_uuid); - QSqlQuery query(db); + auto db = QSqlDatabase::database(m_uuid); + QSqlQuery query(db); - query.prepare("INSERT INTO frequencies (id, frequency) " - "VALUES (:id, 1) " - "ON CONFLICT (id) DO UPDATE SET frequency = frequency + 1"); - query.bindValue(":id", id); - query.exec(); + query.prepare( + "INSERT INTO frequencies (id, frequency) " + "VALUES (:id, 1) " + "ON CONFLICT (id) DO UPDATE SET frequency = frequency + 1"); + query.bindValue(":id", id); + query.exec(); - auto* app = m_apps.value(id); - if (app) { - const auto before = getSortedApps(); + auto* app = m_apps.value(id); + if (app) { + const auto before = getSortedApps(); - app->incrementFrequency(); + app->incrementFrequency(); - if (before != getSortedApps()) { - emit appsChanged(); - } - } else { - qWarning() << "AppDb::incrementFrequency: could not find app with id" << id; - } + if (before != getSortedApps()) { + emit appsChanged(); + } + } else { + qWarning() << "AppDb::incrementFrequency: could not find app with id" + << id; + } } QList& AppDb::getSortedApps() const { - m_sortedApps = m_apps.values(); - std::sort(m_sortedApps.begin(), m_sortedApps.end(), [](AppEntry* a, AppEntry* b) { - if (a->frequency() != b->frequency()) { - return a->frequency() > b->frequency(); - } - return a->name().localeAwareCompare(b->name()) < 0; - }); - return m_sortedApps; + m_sortedApps = m_apps.values(); + std::sort( + m_sortedApps.begin(), m_sortedApps.end(), [](AppEntry* a, AppEntry* b) { + if (a->frequency() != b->frequency()) { + return a->frequency() > b->frequency(); + } + return a->name().localeAwareCompare(b->name()) < 0; + }); + return m_sortedApps; } quint32 AppDb::getFrequency(const QString& id) const { - auto db = QSqlDatabase::database(m_uuid); - QSqlQuery query(db); + auto db = QSqlDatabase::database(m_uuid); + QSqlQuery query(db); - query.prepare("SELECT frequency FROM frequencies WHERE id = :id"); - query.bindValue(":id", id); + query.prepare("SELECT frequency FROM frequencies WHERE id = :id"); + query.bindValue(":id", id); - if (query.exec() && query.next()) { - return query.value(0).toUInt(); - } + if (query.exec() && query.next()) { + return query.value(0).toUInt(); + } - return 0; + return 0; } void AppDb::updateAppFrequencies() { - const auto before = getSortedApps(); + const auto before = getSortedApps(); - for (auto* app : std::as_const(m_apps)) { - app->setFrequency(getFrequency(app->id())); - } + for (auto* app : std::as_const(m_apps)) { + app->setFrequency(getFrequency(app->id())); + } - if (before != getSortedApps()) { - emit appsChanged(); - } + if (before != getSortedApps()) { + emit appsChanged(); + } } void AppDb::updateApps() { - bool dirty = false; + bool dirty = false; - for (const auto& entry : std::as_const(m_entries)) { - const auto id = entry->property("id").toString(); - if (!m_apps.contains(id)) { - dirty = true; - auto* const newEntry = new AppEntry(entry, getFrequency(id), this); - QObject::connect(newEntry, &QObject::destroyed, this, [id, this]() { - if (m_apps.remove(id)) { - emit appsChanged(); - } - }); - m_apps.insert(id, newEntry); - } - } + for (const auto& entry : std::as_const(m_entries)) { + const auto id = entry->property("id").toString(); + if (!m_apps.contains(id)) { + dirty = true; + auto* const newEntry = new AppEntry(entry, getFrequency(id), this); + QObject::connect(newEntry, &QObject::destroyed, this, [id, this]() { + if (m_apps.remove(id)) { + emit appsChanged(); + } + }); + m_apps.insert(id, newEntry); + } + } - QSet newIds; - for (const auto& entry : std::as_const(m_entries)) { - newIds.insert(entry->property("id").toString()); - } + QSet newIds; + for (const auto& entry : std::as_const(m_entries)) { + newIds.insert(entry->property("id").toString()); + } - for (auto it = m_apps.keyBegin(); it != m_apps.keyEnd(); ++it) { - const auto& id = *it; - if (!newIds.contains(id)) { - dirty = true; - m_apps.take(id)->deleteLater(); - } - } + for (auto it = m_apps.keyBegin(); it != m_apps.keyEnd(); ++it) { + const auto& id = *it; + if (!newIds.contains(id)) { + dirty = true; + m_apps.take(id)->deleteLater(); + } + } - if (dirty) { - emit appsChanged(); - } + if (dirty) { + emit appsChanged(); + } } } // namespace ZShell diff --git a/Plugins/ZShell/appdb.hpp b/Plugins/ZShell/appdb.hpp index 48c7187..00a9ece 100644 --- a/Plugins/ZShell/appdb.hpp +++ b/Plugins/ZShell/appdb.hpp @@ -9,98 +9,102 @@ namespace ZShell { class AppEntry : public QObject { -Q_OBJECT -QML_ELEMENT - QML_UNCREATABLE("AppEntry instances can only be retrieved from an AppDb") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("AppEntry instances can only be retrieved from an AppDb") -// The actual DesktopEntry, but we don't have access to the type so it's a QObject -Q_PROPERTY(QObject* entry READ entry CONSTANT) + // The actual DesktopEntry, but we don't have access to the type so it's a QObject + Q_PROPERTY(QObject* entry READ entry CONSTANT) -Q_PROPERTY(quint32 frequency READ frequency NOTIFY frequencyChanged) -Q_PROPERTY(QString id READ id CONSTANT) -Q_PROPERTY(QString name READ name NOTIFY nameChanged) -Q_PROPERTY(QString comment READ comment NOTIFY commentChanged) -Q_PROPERTY(QString execString READ execString NOTIFY execStringChanged) -Q_PROPERTY(QString startupClass READ startupClass NOTIFY startupClassChanged) -Q_PROPERTY(QString genericName READ genericName NOTIFY genericNameChanged) -Q_PROPERTY(QString categories READ categories NOTIFY categoriesChanged) -Q_PROPERTY(QString keywords READ keywords NOTIFY keywordsChanged) + Q_PROPERTY(quint32 frequency READ frequency NOTIFY frequencyChanged) + Q_PROPERTY(QString id READ id CONSTANT) + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(QString comment READ comment NOTIFY commentChanged) + Q_PROPERTY(QString execString READ execString NOTIFY execStringChanged) + Q_PROPERTY(QString startupClass READ startupClass NOTIFY startupClassChanged) + Q_PROPERTY(QString genericName READ genericName NOTIFY genericNameChanged) + Q_PROPERTY(QString categories READ categories NOTIFY categoriesChanged) + Q_PROPERTY(QString keywords READ keywords NOTIFY keywordsChanged) -public: -explicit AppEntry(QObject* entry, quint32 frequency, QObject* parent = nullptr); + public: + explicit AppEntry( + QObject* entry, quint32 frequency, QObject* parent = nullptr); -[[nodiscard]] QObject* entry() const; + [[nodiscard]] QObject* entry() const; -[[nodiscard]] quint32 frequency() const; -void setFrequency(quint32 frequency); -void incrementFrequency(); + [[nodiscard]] quint32 frequency() const; + void setFrequency(quint32 frequency); + void incrementFrequency(); -[[nodiscard]] QString id() const; -[[nodiscard]] QString name() const; -[[nodiscard]] QString comment() const; -[[nodiscard]] QString execString() const; -[[nodiscard]] QString startupClass() const; -[[nodiscard]] QString genericName() const; -[[nodiscard]] QString categories() const; -[[nodiscard]] QString keywords() const; + [[nodiscard]] QString id() const; + [[nodiscard]] QString name() const; + [[nodiscard]] QString comment() const; + [[nodiscard]] QString execString() const; + [[nodiscard]] QString startupClass() const; + [[nodiscard]] QString genericName() const; + [[nodiscard]] QString categories() const; + [[nodiscard]] QString keywords() const; -signals: -void frequencyChanged(); -void nameChanged(); -void commentChanged(); -void execStringChanged(); -void startupClassChanged(); -void genericNameChanged(); -void categoriesChanged(); -void keywordsChanged(); + signals: + void frequencyChanged(); + void nameChanged(); + void commentChanged(); + void execStringChanged(); + void startupClassChanged(); + void genericNameChanged(); + void categoriesChanged(); + void keywordsChanged(); -private: -QObject* m_entry; -quint32 m_frequency; + private: + QObject* m_entry; + quint32 m_frequency; }; class AppDb : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(QString uuid READ uuid CONSTANT) -Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REQUIRED) -Q_PROPERTY(QObjectList entries READ entries WRITE setEntries NOTIFY entriesChanged REQUIRED) -Q_PROPERTY(QQmlListProperty apps READ apps NOTIFY appsChanged) + Q_PROPERTY(QString uuid READ uuid CONSTANT) + Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REQUIRED) + Q_PROPERTY( + QObjectList entries READ entries WRITE setEntries NOTIFY entriesChanged + REQUIRED) + Q_PROPERTY( + QQmlListProperty apps READ apps NOTIFY appsChanged) -public: -explicit AppDb(QObject* parent = nullptr); + public: + explicit AppDb(QObject* parent = nullptr); -[[nodiscard]] QString uuid() const; + [[nodiscard]] QString uuid() const; -[[nodiscard]] QString path() const; -void setPath(const QString& path); + [[nodiscard]] QString path() const; + void setPath(const QString& path); -[[nodiscard]] QObjectList entries() const; -void setEntries(const QObjectList& entries); + [[nodiscard]] QObjectList entries() const; + void setEntries(const QObjectList& entries); -[[nodiscard]] QQmlListProperty apps(); + [[nodiscard]] QQmlListProperty apps(); -Q_INVOKABLE void incrementFrequency(const QString& id); + Q_INVOKABLE void incrementFrequency(const QString& id); -signals: -void pathChanged(); -void entriesChanged(); -void appsChanged(); + signals: + void pathChanged(); + void entriesChanged(); + void appsChanged(); -private: -QTimer* m_timer; + private: + QTimer* m_timer; -const QString m_uuid; -QString m_path; -QObjectList m_entries; -QHash m_apps; -mutable QList m_sortedApps; + const QString m_uuid; + QString m_path; + QObjectList m_entries; + QHash m_apps; + mutable QList m_sortedApps; -QList& getSortedApps() const; -quint32 getFrequency(const QString& id) const; -void updateAppFrequencies(); -void updateApps(); + QList& getSortedApps() const; + quint32 getFrequency(const QString& id) const; + void updateAppFrequencies(); + void updateApps(); }; } // namespace ZShell diff --git a/Plugins/ZShell/imageanalyser.cpp b/Plugins/ZShell/imageanalyser.cpp index 08e3eec..cbab4b5 100644 --- a/Plugins/ZShell/imageanalyser.cpp +++ b/Plugins/ZShell/imageanalyser.cpp @@ -9,215 +9,255 @@ namespace ZShell { ImageAnalyser::ImageAnalyser(QObject* parent) - : QObject(parent) - , m_futureWatcher(new QFutureWatcher(this)) - , m_source("") - , m_sourceItem(nullptr) - , m_rescaleSize(128) - , m_dominantColour(0, 0, 0) - , m_luminance(0) { - QObject::connect(m_futureWatcher, &QFutureWatcher::finished, this, [this]() { - if (!m_futureWatcher->future().isResultReadyAt(0)) { - return; - } + : QObject(parent) + , m_futureWatcher(new QFutureWatcher(this)) + , m_source("") + , m_sourceItem(nullptr) + , m_rescaleSize(128) + , m_dominantColour(0, 0, 0) + , m_luminance(0) { + QObject::connect( + m_futureWatcher, + &QFutureWatcher::finished, + this, + [this]() { + if (!m_futureWatcher->future().isResultReadyAt(0)) { + return; + } - const auto result = m_futureWatcher->result(); - if (m_dominantColour != result.first) { - m_dominantColour = result.first; - emit dominantColourChanged(); - } - if (!qFuzzyCompare(m_luminance + 1.0, result.second + 1.0)) { - m_luminance = result.second; - emit luminanceChanged(); - } - }); + const auto result = m_futureWatcher->result(); + if (m_dominantColour != result.first) { + m_dominantColour = result.first; + emit dominantColourChanged(); + } + if (!qFuzzyCompare(m_luminance + 1.0, result.second + 1.0)) { + m_luminance = result.second; + emit luminanceChanged(); + } + }); } QString ImageAnalyser::source() const { - return m_source; + return m_source; } void ImageAnalyser::setSource(const QString& source) { - if (m_source == source) { - return; - } + if (m_source == source) { + return; + } - m_source = source; - emit sourceChanged(); + m_source = source; + emit sourceChanged(); - if (m_sourceItem) { - m_sourceItem = nullptr; - emit sourceItemChanged(); - } + if (m_sourceItem) { + m_sourceItem = nullptr; + emit sourceItemChanged(); + } - requestUpdate(); + requestUpdate(); } QQuickItem* ImageAnalyser::sourceItem() const { - return m_sourceItem; + return m_sourceItem; } void ImageAnalyser::setSourceItem(QQuickItem* sourceItem) { - if (m_sourceItem == sourceItem) { - return; - } + if (m_sourceItem == sourceItem) { + return; + } - m_sourceItem = sourceItem; - emit sourceItemChanged(); + m_sourceItem = sourceItem; + emit sourceItemChanged(); - if (!m_source.isEmpty()) { - m_source = ""; - emit sourceChanged(); - } + if (!m_source.isEmpty()) { + m_source = ""; + emit sourceChanged(); + } - requestUpdate(); + requestUpdate(); } int ImageAnalyser::rescaleSize() const { - return m_rescaleSize; + return m_rescaleSize; } void ImageAnalyser::setRescaleSize(int rescaleSize) { - if (m_rescaleSize == rescaleSize) { - return; - } + if (m_rescaleSize == rescaleSize) { + return; + } - m_rescaleSize = rescaleSize; - emit rescaleSizeChanged(); + m_rescaleSize = rescaleSize; + emit rescaleSizeChanged(); - requestUpdate(); + requestUpdate(); } QColor ImageAnalyser::dominantColour() const { - return m_dominantColour; + return m_dominantColour; } qreal ImageAnalyser::luminance() const { - return m_luminance; + return m_luminance; } void ImageAnalyser::requestUpdate() { - if (m_source.isEmpty() && !m_sourceItem) { - return; - } + if (m_source.isEmpty() && !m_sourceItem) { + return; + } - if (!m_sourceItem || (m_sourceItem->window() && m_sourceItem->window()->isVisible() && m_sourceItem->width() > 0 && - m_sourceItem->height() > 0)) { - update(); - } else if (m_sourceItem) { - if (!m_sourceItem->window()) { - QObject::connect(m_sourceItem, &QQuickItem::windowChanged, this, &ImageAnalyser::requestUpdate, - Qt::SingleShotConnection); - } else if (!m_sourceItem->window()->isVisible()) { - QObject::connect(m_sourceItem->window(), &QQuickWindow::visibleChanged, this, &ImageAnalyser::requestUpdate, - Qt::SingleShotConnection); - } - if (m_sourceItem->width() <= 0) { - QObject::connect( - m_sourceItem, &QQuickItem::widthChanged, this, &ImageAnalyser::requestUpdate, Qt::SingleShotConnection); - } - if (m_sourceItem->height() <= 0) { - QObject::connect(m_sourceItem, &QQuickItem::heightChanged, this, &ImageAnalyser::requestUpdate, - Qt::SingleShotConnection); - } - } + if (!m_sourceItem || + (m_sourceItem->window() && m_sourceItem->window()->isVisible() && + m_sourceItem->width() > 0 && m_sourceItem->height() > 0)) { + update(); + } else if (m_sourceItem) { + if (!m_sourceItem->window()) { + QObject::connect( + m_sourceItem, + &QQuickItem::windowChanged, + this, + &ImageAnalyser::requestUpdate, + Qt::SingleShotConnection); + } else if (!m_sourceItem->window()->isVisible()) { + QObject::connect( + m_sourceItem->window(), + &QQuickWindow::visibleChanged, + this, + &ImageAnalyser::requestUpdate, + Qt::SingleShotConnection); + } + if (m_sourceItem->width() <= 0) { + QObject::connect( + m_sourceItem, + &QQuickItem::widthChanged, + this, + &ImageAnalyser::requestUpdate, + Qt::SingleShotConnection); + } + if (m_sourceItem->height() <= 0) { + QObject::connect( + m_sourceItem, + &QQuickItem::heightChanged, + this, + &ImageAnalyser::requestUpdate, + Qt::SingleShotConnection); + } + } } void ImageAnalyser::update() { - if (m_source.isEmpty() && !m_sourceItem) { - return; - } + if (m_source.isEmpty() && !m_sourceItem) { + return; + } - if (m_futureWatcher->isRunning()) { - m_futureWatcher->cancel(); - } + if (m_futureWatcher->isRunning()) { + m_futureWatcher->cancel(); + } - if (m_sourceItem) { - const QSharedPointer grabResult = m_sourceItem->grabToImage(); - QObject::connect(grabResult.data(), &QQuickItemGrabResult::ready, this, [grabResult, this]() { - m_futureWatcher->setFuture(QtConcurrent::run(&ImageAnalyser::analyse, grabResult->image(), m_rescaleSize)); - }); - } else { - m_futureWatcher->setFuture(QtConcurrent::run([=, this](QPromise& promise) { - const QImage image(m_source); - analyse(promise, image, m_rescaleSize); - })); - } + if (m_sourceItem) { + const QSharedPointer grabResult = + m_sourceItem->grabToImage(); + QObject::connect( + grabResult.data(), + &QQuickItemGrabResult::ready, + this, + [grabResult, this]() { + m_futureWatcher->setFuture( + QtConcurrent::run( + &ImageAnalyser::analyse, + grabResult->image(), + m_rescaleSize)); + }); + } else { + m_futureWatcher->setFuture( + QtConcurrent::run([=, this](QPromise& promise) { + const QImage image(m_source); + analyse(promise, image, m_rescaleSize); + })); + } } -void ImageAnalyser::analyse(QPromise& promise, const QImage& image, int rescaleSize) { - if (image.isNull()) { - qWarning() << "ImageAnalyser::analyse: image is null"; - return; - } +void ImageAnalyser::analyse( + QPromise& promise, const QImage& image, int rescaleSize) { + if (image.isNull()) { + qWarning() << "ImageAnalyser::analyse: image is null"; + return; + } - QImage img = image; + QImage img = image; - if (rescaleSize > 0 && (img.width() > rescaleSize || img.height() > rescaleSize)) { - img = img.scaled(rescaleSize, rescaleSize, Qt::KeepAspectRatio, Qt::FastTransformation); - } + if (rescaleSize > 0 && + (img.width() > rescaleSize || img.height() > rescaleSize)) { + img = img.scaled( + rescaleSize, + rescaleSize, + Qt::KeepAspectRatio, + Qt::FastTransformation); + } - if (promise.isCanceled()) { - return; - } + if (promise.isCanceled()) { + return; + } - if (img.format() != QImage::Format_ARGB32) { - img = img.convertToFormat(QImage::Format_ARGB32); - } + if (img.format() != QImage::Format_ARGB32) { + img = img.convertToFormat(QImage::Format_ARGB32); + } - if (promise.isCanceled()) { - return; - } + if (promise.isCanceled()) { + return; + } - const uchar* data = img.bits(); - const int width = img.width(); - const int height = img.height(); - const qsizetype bytesPerLine = img.bytesPerLine(); + const uchar* data = img.bits(); + const int width = img.width(); + const int height = img.height(); + const qsizetype bytesPerLine = img.bytesPerLine(); - std::unordered_map colours; - qreal totalLuminance = 0.0; - int count = 0; + std::unordered_map colours; + qreal totalLuminance = 0.0; + int count = 0; - for (int y = 0; y < height; ++y) { - const uchar* line = data + y * bytesPerLine; - for (int x = 0; x < width; ++x) { - if (promise.isCanceled()) { - return; - } + for (int y = 0; y < height; ++y) { + const uchar* line = data + y * bytesPerLine; + for (int x = 0; x < width; ++x) { + if (promise.isCanceled()) { + return; + } - const uchar* pixel = line + x * 4; + const uchar* pixel = line + x * 4; - if (pixel[3] == 0) { - continue; - } + if (pixel[3] == 0) { + continue; + } - const quint32 mr = static_cast(pixel[0] & 0xF8); - const quint32 mg = static_cast(pixel[1] & 0xF8); - const quint32 mb = static_cast(pixel[2] & 0xF8); - ++colours[(mr << 16) | (mg << 8) | mb]; + const quint32 mr = static_cast(pixel[0] & 0xF8); + const quint32 mg = static_cast(pixel[1] & 0xF8); + const quint32 mb = static_cast(pixel[2] & 0xF8); + ++colours[(mr << 16) | (mg << 8) | mb]; - const qreal r = pixel[0] / 255.0; - const qreal g = pixel[1] / 255.0; - const qreal b = pixel[2] / 255.0; - totalLuminance += std::sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b); - ++count; - } - } + const qreal r = pixel[0] / 255.0; + const qreal g = pixel[1] / 255.0; + const qreal b = pixel[2] / 255.0; + totalLuminance += + std::sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b); + ++count; + } + } - quint32 dominantColour = 0; - int maxCount = 0; - for (const auto& [colour, colourCount] : colours) { - if (promise.isCanceled()) { - return; - } + quint32 dominantColour = 0; + int maxCount = 0; + for (const auto& [colour, colourCount] : colours) { + if (promise.isCanceled()) { + return; + } - if (colourCount > maxCount) { - dominantColour = colour; - maxCount = colourCount; - } - } + if (colourCount > maxCount) { + dominantColour = colour; + maxCount = colourCount; + } + } - promise.addResult(qMakePair(QColor((0xFFu << 24) | dominantColour), count == 0 ? 0.0 : totalLuminance / count)); + promise.addResult(qMakePair( + QColor((0xFFu << 24) | dominantColour), + count == 0 ? 0.0 : totalLuminance / count)); } } // namespace ZShell diff --git a/Plugins/ZShell/imageanalyser.hpp b/Plugins/ZShell/imageanalyser.hpp index 8871617..1c7a893 100644 --- a/Plugins/ZShell/imageanalyser.hpp +++ b/Plugins/ZShell/imageanalyser.hpp @@ -9,53 +9,59 @@ namespace ZShell { class ImageAnalyser : public QObject { -Q_OBJECT -QML_ELEMENT + Q_OBJECT + QML_ELEMENT -Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged) -Q_PROPERTY(QQuickItem* sourceItem READ sourceItem WRITE setSourceItem NOTIFY sourceItemChanged) -Q_PROPERTY(int rescaleSize READ rescaleSize WRITE setRescaleSize NOTIFY rescaleSizeChanged) -Q_PROPERTY(QColor dominantColour READ dominantColour NOTIFY dominantColourChanged) -Q_PROPERTY(qreal luminance READ luminance NOTIFY luminanceChanged) + Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY( + QQuickItem* sourceItem READ sourceItem WRITE setSourceItem NOTIFY + sourceItemChanged) + Q_PROPERTY( + int rescaleSize READ rescaleSize WRITE setRescaleSize NOTIFY + rescaleSizeChanged) + Q_PROPERTY( + QColor dominantColour READ dominantColour NOTIFY dominantColourChanged) + Q_PROPERTY(qreal luminance READ luminance NOTIFY luminanceChanged) -public: -explicit ImageAnalyser(QObject* parent = nullptr); + public: + explicit ImageAnalyser(QObject* parent = nullptr); -[[nodiscard]] QString source() const; -void setSource(const QString& source); + [[nodiscard]] QString source() const; + void setSource(const QString& source); -[[nodiscard]] QQuickItem* sourceItem() const; -void setSourceItem(QQuickItem* sourceItem); + [[nodiscard]] QQuickItem* sourceItem() const; + void setSourceItem(QQuickItem* sourceItem); -[[nodiscard]] int rescaleSize() const; -void setRescaleSize(int rescaleSize); + [[nodiscard]] int rescaleSize() const; + void setRescaleSize(int rescaleSize); -[[nodiscard]] QColor dominantColour() const; -[[nodiscard]] qreal luminance() const; + [[nodiscard]] QColor dominantColour() const; + [[nodiscard]] qreal luminance() const; -Q_INVOKABLE void requestUpdate(); + Q_INVOKABLE void requestUpdate(); -signals: -void sourceChanged(); -void sourceItemChanged(); -void rescaleSizeChanged(); -void dominantColourChanged(); -void luminanceChanged(); + signals: + void sourceChanged(); + void sourceItemChanged(); + void rescaleSizeChanged(); + void dominantColourChanged(); + void luminanceChanged(); -private: -using AnalyseResult = QPair; + private: + using AnalyseResult = QPair; -QFutureWatcher* const m_futureWatcher; + QFutureWatcher* const m_futureWatcher; -QString m_source; -QQuickItem* m_sourceItem; -int m_rescaleSize; + QString m_source; + QQuickItem* m_sourceItem; + int m_rescaleSize; -QColor m_dominantColour; -qreal m_luminance; + QColor m_dominantColour; + qreal m_luminance; -void update(); -static void analyse(QPromise& promise, const QImage& image, int rescaleSize); + void update(); + static void analyse( + QPromise& promise, const QImage& image, int rescaleSize); }; } // namespace ZShell diff --git a/Plugins/ZShell/qalculator.cpp b/Plugins/ZShell/qalculator.cpp index c58962f..944449e 100644 --- a/Plugins/ZShell/qalculator.cpp +++ b/Plugins/ZShell/qalculator.cpp @@ -4,8 +4,7 @@ namespace ZShell { -Qalculator::Qalculator(QObject* parent) - : QObject(parent) { +Qalculator::Qalculator(QObject* parent) : QObject(parent) { if (!CALCULATOR) { new Calculator(); CALCULATOR->loadExchangeRates(); @@ -24,7 +23,11 @@ QString Qalculator::eval(const QString& expr, bool printExpr) const { std::string parsed; std::string result = CALCULATOR->calculateAndPrint( - CALCULATOR->unlocalizeExpression(expr.toStdString(), eo.parse_options), 100, eo, po, &parsed); + CALCULATOR->unlocalizeExpression(expr.toStdString(), eo.parse_options), + 100, + eo, + po, + &parsed); std::string error; while (CALCULATOR->message()) { diff --git a/Plugins/ZShell/qalculator.hpp b/Plugins/ZShell/qalculator.hpp index 67051a6..e3380ed 100644 --- a/Plugins/ZShell/qalculator.hpp +++ b/Plugins/ZShell/qalculator.hpp @@ -6,14 +6,15 @@ namespace ZShell { class Qalculator : public QObject { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -public: -explicit Qalculator(QObject* parent = nullptr); + public: + explicit Qalculator(QObject* parent = nullptr); -Q_INVOKABLE [[nodiscard]] QString eval(const QString& expr, bool printExpr = true) const; + Q_INVOKABLE [[nodiscard]] QString eval( + const QString& expr, bool printExpr = true) const; }; } // namespace ZShell diff --git a/Plugins/ZShell/requests.cpp b/Plugins/ZShell/requests.cpp index 3b8130c..f6e7e7e 100644 --- a/Plugins/ZShell/requests.cpp +++ b/Plugins/ZShell/requests.cpp @@ -7,9 +7,7 @@ namespace ZShell { Requests::Requests(QObject* parent) - : QObject(parent) - , m_manager(new QNetworkAccessManager(this)) { -} + : QObject(parent), m_manager(new QNetworkAccessManager(this)) {} void Requests::get(const QUrl& url, QJSValue onSuccess, QJSValue onError) const { if (!onSuccess.isCallable()) { @@ -20,13 +18,15 @@ void Requests::get(const QUrl& url, QJSValue onSuccess, QJSValue onError) const QNetworkRequest request(url); auto reply = m_manager->get(request); - QObject::connect(reply, &QNetworkReply::finished, [reply, onSuccess, onError]() { + QObject::connect( + reply, &QNetworkReply::finished, [reply, onSuccess, onError]() { if (reply->error() == QNetworkReply::NoError) { - onSuccess.call({ QString(reply->readAll()) }); + onSuccess.call({QString(reply->readAll())}); } else if (onError.isCallable()) { - onError.call({ reply->errorString() }); + onError.call({reply->errorString()}); } else { - qWarning() << "Requests::get: request failed with error" << reply->errorString(); + qWarning() << "Requests::get: request failed with error" + << reply->errorString(); } reply->deleteLater(); diff --git a/Plugins/ZShell/requests.hpp b/Plugins/ZShell/requests.hpp index 40e751b..6e340d4 100644 --- a/Plugins/ZShell/requests.hpp +++ b/Plugins/ZShell/requests.hpp @@ -7,17 +7,20 @@ namespace ZShell { class Requests : public QObject { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -public: -explicit Requests(QObject* parent = nullptr); + public: + explicit Requests(QObject* parent = nullptr); -Q_INVOKABLE void get(const QUrl& url, QJSValue callback, QJSValue onError = QJSValue()) const; + Q_INVOKABLE void get( + const QUrl& url, + QJSValue callback, + QJSValue onError = QJSValue()) const; -private: -QNetworkAccessManager* m_manager; + private: + QNetworkAccessManager* m_manager; }; } // namespace ZShell diff --git a/Plugins/ZShell/toaster.cpp b/Plugins/ZShell/toaster.cpp index cc6088c..a8aa59f 100644 --- a/Plugins/ZShell/toaster.cpp +++ b/Plugins/ZShell/toaster.cpp @@ -6,7 +6,13 @@ namespace ZShell { -Toast::Toast(const QString& title, const QString& message, const QString& icon, Type type, int timeout, QObject* parent) +Toast::Toast( + const QString& title, + const QString& message, + const QString& icon, + Type type, + int timeout, + QObject* parent) : QObject(parent) , m_closed(false) , m_title(title) @@ -94,22 +100,25 @@ void Toast::unlock(QObject* sender) { } } -Toaster::Toaster(QObject* parent) - : QObject(parent) { -} +Toaster::Toaster(QObject* parent) : QObject(parent) {} QQmlListProperty Toaster::toasts() { return QQmlListProperty(this, &m_toasts); } -void Toaster::toast(const QString& title, const QString& message, const QString& icon, Toast::Type type, int timeout) { +void Toaster::toast( + const QString& title, + const QString& message, + const QString& icon, + Toast::Type type, + int timeout) { auto* toast = new Toast(title, message, icon, type, timeout, this); QObject::connect(toast, &Toast::finishedClose, this, [toast, this]() { - if (m_toasts.removeOne(toast)) { - emit toastsChanged(); - toast->deleteLater(); - } - }); + if (m_toasts.removeOne(toast)) { + emit toastsChanged(); + toast->deleteLater(); + } + }); m_toasts.push_front(toast); emit toastsChanged(); } diff --git a/Plugins/ZShell/toaster.hpp b/Plugins/ZShell/toaster.hpp index 0fb0d53..c2e546a 100644 --- a/Plugins/ZShell/toaster.hpp +++ b/Plugins/ZShell/toaster.hpp @@ -8,75 +8,80 @@ namespace ZShell { class Toast : public QObject { -Q_OBJECT -QML_ELEMENT -QML_UNCREATABLE("Toast instances can only be retrieved from a Toaster") + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("Toast instances can only be retrieved from a Toaster") -Q_PROPERTY(bool closed READ closed NOTIFY closedChanged) -Q_PROPERTY(QString title READ title CONSTANT) -Q_PROPERTY(QString message READ message CONSTANT) -Q_PROPERTY(QString icon READ icon CONSTANT) -Q_PROPERTY(int timeout READ timeout CONSTANT) -Q_PROPERTY(Type type READ type CONSTANT) + Q_PROPERTY(bool closed READ closed NOTIFY closedChanged) + Q_PROPERTY(QString title READ title CONSTANT) + Q_PROPERTY(QString message READ message CONSTANT) + Q_PROPERTY(QString icon READ icon CONSTANT) + Q_PROPERTY(int timeout READ timeout CONSTANT) + Q_PROPERTY(Type type READ type CONSTANT) -public: -enum class Type { - Info = 0, - Success, - Warning, - Error -}; -Q_ENUM(Type) + public: + enum class Type { Info = 0, Success, Warning, Error }; + Q_ENUM(Type) -explicit Toast(const QString& title, const QString& message, const QString& icon, Type type, int timeout, - QObject* parent = nullptr); + explicit Toast( + const QString& title, + const QString& message, + const QString& icon, + Type type, + int timeout, + QObject* parent = nullptr); -[[nodiscard]] bool closed() const; -[[nodiscard]] QString title() const; -[[nodiscard]] QString message() const; -[[nodiscard]] QString icon() const; -[[nodiscard]] int timeout() const; -[[nodiscard]] Type type() const; + [[nodiscard]] bool closed() const; + [[nodiscard]] QString title() const; + [[nodiscard]] QString message() const; + [[nodiscard]] QString icon() const; + [[nodiscard]] int timeout() const; + [[nodiscard]] Type type() const; -Q_INVOKABLE void close(); -Q_INVOKABLE void lock(QObject* sender); -Q_INVOKABLE void unlock(QObject* sender); + Q_INVOKABLE void close(); + Q_INVOKABLE void lock(QObject* sender); + Q_INVOKABLE void unlock(QObject* sender); -signals: -void closedChanged(); -void finishedClose(); + signals: + void closedChanged(); + void finishedClose(); -private: -QSet m_locks; + private: + QSet m_locks; -bool m_closed; -QString m_title; -QString m_message; -QString m_icon; -Type m_type; -int m_timeout; + bool m_closed; + QString m_title; + QString m_message; + QString m_icon; + Type m_type; + int m_timeout; }; class Toaster : public QObject { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -Q_PROPERTY(QQmlListProperty toasts READ toasts NOTIFY toastsChanged) + Q_PROPERTY( + QQmlListProperty toasts READ toasts NOTIFY toastsChanged) -public: -explicit Toaster(QObject* parent = nullptr); + public: + explicit Toaster(QObject* parent = nullptr); -[[nodiscard]] QQmlListProperty toasts(); + [[nodiscard]] QQmlListProperty toasts(); -Q_INVOKABLE void toast(const QString& title, const QString& message, const QString& icon = QString(), - ZShell::Toast::Type type = Toast::Type::Info, int timeout = 5000); + Q_INVOKABLE void toast( + const QString& title, + const QString& message, + const QString& icon = QString(), + ZShell::Toast::Type type = Toast::Type::Info, + int timeout = 5000); -signals: -void toastsChanged(); + signals: + void toastsChanged(); -private: -QList m_toasts; + private: + QList m_toasts; }; } // namespace ZShell diff --git a/Plugins/ZShell/writefile.cpp b/Plugins/ZShell/writefile.cpp index 504ba86..8b29efc 100644 --- a/Plugins/ZShell/writefile.cpp +++ b/Plugins/ZShell/writefile.cpp @@ -20,15 +20,12 @@ namespace ZShell { -// ============================================================ -// saveItem -// ============================================================ - void ZShellIo::saveItem(QQuickItem* target, const QUrl& path) { this->saveItem(target, path, QRect(), QJSValue(), QJSValue()); } -void ZShellIo::saveItem(QQuickItem* target, const QUrl& path, const QRect& rect) { +void ZShellIo::saveItem( + QQuickItem* target, const QUrl& path, const QRect& rect) { this->saveItem(target, path, rect, QJSValue(), QJSValue()); } @@ -36,11 +33,13 @@ void ZShellIo::saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved) this->saveItem(target, path, QRect(), onSaved, QJSValue()); } -void ZShellIo::saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed) { +void ZShellIo::saveItem( + QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed) { this->saveItem(target, path, QRect(), onSaved, onFailed); } -void ZShellIo::saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved) { +void ZShellIo::saveItem( + QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved) { this->saveItem(target, path, rect, onSaved, QJSValue()); } @@ -49,8 +48,7 @@ void ZShellIo::saveItem( const QUrl& path, const QRect& rect, QJSValue onSaved, - QJSValue onFailed - ) { + QJSValue onFailed) { if (!target) { qWarning() << "ZShellIo::saveItem: a target is required"; return; @@ -62,9 +60,8 @@ void ZShellIo::saveItem( } if (!target->window()) { - qWarning() << "ZShellIo::saveItem: unable to save target" - << target - << "without a window"; + qWarning() << "ZShellIo::saveItem: unable to save target" << target + << "without a window"; return; } @@ -74,11 +71,11 @@ void ZShellIo::saveItem( if (rect.isValid() && !qFuzzyCompare(scale + 1.0, 2.0)) { scaledRect = QRectF( - rect.left() * scale, - rect.top() * scale, - rect.width() * scale, - rect.height() * scale - ).toRect(); + rect.left() * scale, + rect.top() * scale, + rect.width() * scale, + rect.height() * scale) + .toRect(); } const QSharedPointer grabResult = @@ -89,66 +86,62 @@ void ZShellIo::saveItem( &QQuickItemGrabResult::ready, this, [grabResult, scaledRect, path, onSaved, onFailed, this]() { - const auto future = QtConcurrent::run([grabResult, scaledRect, path]() { - QImage image = grabResult->image(); + const auto future = + QtConcurrent::run([grabResult, scaledRect, path]() { + QImage image = grabResult->image(); - if (scaledRect.isValid()) { - image = image.copy(scaledRect); - } + if (scaledRect.isValid()) { + image = image.copy(scaledRect); + } - const QString file = path.toLocalFile(); - const QString parent = QFileInfo(file).absolutePath(); + const QString file = path.toLocalFile(); + const QString parent = QFileInfo(file).absolutePath(); - QDir().mkpath(parent); + QDir().mkpath(parent); - QSaveFile out(file); - if (!out.open(QIODevice::WriteOnly)) { - return false; - } + QSaveFile out(file); + if (!out.open(QIODevice::WriteOnly)) { + return false; + } - if (!image.save(&out, "PNG")) { - return false; - } + if (!image.save(&out, "PNG")) { + return false; + } - return out.commit(); - }); + return out.commit(); + }); auto* watcher = new QFutureWatcher(this); auto* engine = qmlEngine(this); - QObject::connect(watcher, &QFutureWatcher::finished, this, [=]() { - if (watcher->result()) { - if (onSaved.isCallable() && engine) { - onSaved.call({ - engine->toScriptValue(path.toLocalFile()), - engine->toScriptValue(path) - }); + QObject::connect( + watcher, &QFutureWatcher::finished, this, [=]() { + if (watcher->result()) { + if (onSaved.isCallable() && engine) { + onSaved.call( + {engine->toScriptValue(path.toLocalFile()), + engine->toScriptValue(path)}); + } + } else { + qWarning() + << "ZShellIo::saveItem: failed to save" << path; + if (onFailed.isCallable() && engine) { + onFailed.call({engine->toScriptValue(path)}); + } } - } else { - qWarning() << "ZShellIo::saveItem: failed to save" << path; - if (onFailed.isCallable() && engine) { - onFailed.call({ - engine->toScriptValue(path) - }); - } - } - watcher->deleteLater(); - }); + watcher->deleteLater(); + }); watcher->setFuture(future); - } - ); + }); } -// ============================================================ -// cacheImage -// ============================================================ - void ZShellIo::cacheImage(const QUrl& source, const QString& cacheDir) { this->cacheImage(source, cacheDir, QJSValue(), QJSValue()); } -void ZShellIo::cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved) { +void ZShellIo::cacheImage( + const QUrl& source, const QString& cacheDir, QJSValue onSaved) { this->cacheImage(source, cacheDir, onSaved, QJSValue()); } @@ -156,8 +149,7 @@ void ZShellIo::cacheImage( const QUrl& source, const QString& cacheDir, QJSValue onSaved, - QJSValue onFailed - ) { + QJSValue onFailed) { if (cacheDir.isEmpty()) { qWarning() << "ZShellIo::cacheImage: cacheDir is empty"; return; @@ -165,92 +157,87 @@ void ZShellIo::cacheImage( QImage image; if (!loadSourceImage(source, image)) { - qWarning() << "ZShellIo::cacheImage: failed to load source image" << source; + qWarning() << "ZShellIo::cacheImage: failed to load source image" + << source; auto* engine = qmlEngine(this); if (onFailed.isCallable() && engine) { - onFailed.call({ - engine->toScriptValue(source), - engine->toScriptValue(cacheDir) - }); + onFailed.call( + {engine->toScriptValue(source), + engine->toScriptValue(cacheDir)}); } return; } const auto future = QtConcurrent::run([image, cacheDir]() -> QString { - if (image.isNull()) { - return QString(); - } + if (image.isNull()) { + return QString(); + } - const QImage normalized = image.convertToFormat(QImage::Format_RGBA8888); + const QImage normalized = + image.convertToFormat(QImage::Format_RGBA8888); - const QByteArray bytes( - reinterpret_cast(normalized.constBits()), - qsizetype(normalized.sizeInBytes()) - ); + const QByteArray bytes( + reinterpret_cast(normalized.constBits()), + normalized.sizeInBytes()); - const QByteArray digest = - QCryptographicHash::hash(bytes, QCryptographicHash::Sha256).toHex(); + const QByteArray digest = + QCryptographicHash::hash(bytes, QCryptographicHash::Sha256).toHex(); - QDir dir(cacheDir); - if (!dir.exists() && !QDir().mkpath(cacheDir)) { - return QString(); - } + QDir dir(cacheDir); + if (!dir.exists() && !QDir().mkpath(cacheDir)) { + return QString(); + } - const QString finalPath = dir.filePath(QString::fromLatin1(digest) + ".png"); - - if (QFile::exists(finalPath)) { - return finalPath; - } - - QSaveFile out(finalPath); - if (!out.open(QIODevice::WriteOnly)) { - return QString(); - } - - if (!normalized.save(&out, "PNG")) { - return QString(); - } - - if (!out.commit()) { - return QString(); - } + const QString finalPath = + dir.filePath(QString::fromLatin1(digest) + ".png"); + if (QFile::exists(finalPath)) { return finalPath; - }); + } + + QSaveFile out(finalPath); + if (!out.open(QIODevice::WriteOnly)) { + return QString(); + } + + if (!normalized.save(&out, "PNG")) { + return QString(); + } + + if (!out.commit()) { + return QString(); + } + + return finalPath; + }); auto* watcher = new QFutureWatcher(this); auto* engine = qmlEngine(this); QObject::connect(watcher, &QFutureWatcher::finished, this, [=]() { - const QString finalPath = watcher->result(); + const QString finalPath = watcher->result(); - if (!finalPath.isEmpty()) { - if (onSaved.isCallable() && engine) { - onSaved.call({ - engine->toScriptValue(finalPath), - engine->toScriptValue(QUrl::fromLocalFile(finalPath)) - }); - } - } else { - qWarning() << "ZShellIo::cacheImage: failed to cache" << source; - if (onFailed.isCallable() && engine) { - onFailed.call({ - engine->toScriptValue(source), - engine->toScriptValue(cacheDir) - }); - } + if (!finalPath.isEmpty()) { + if (onSaved.isCallable() && engine) { + onSaved.call( + {engine->toScriptValue(finalPath), + engine->toScriptValue(QUrl::fromLocalFile(finalPath))}); } + } else { + qWarning() << "ZShellIo::cacheImage: failed to cache" << source; + if (onFailed.isCallable() && engine) { + onFailed.call( + {engine->toScriptValue(source), + engine->toScriptValue(cacheDir)}); + } + } - watcher->deleteLater(); - }); + watcher->deleteLater(); + }); watcher->setFuture(future); } -// ============================================================ -// loadSourceImage -// ============================================================ - bool ZShellIo::loadSourceImage(const QUrl& source, QImage& image) const { image = QImage(); @@ -270,22 +257,22 @@ bool ZShellIo::loadSourceImage(const QUrl& source, QImage& image) const { const QString providerId = source.host(); - const QString imageId = - source.path().startsWith('/') - ? source.path().mid(1) - : source.path(); + const QString imageId = source.path().startsWith('/') + ? source.path().mid(1) + : source.path(); auto* providerBase = engine->imageProvider(providerId); if (!providerBase) { qWarning() << "ZShellIo::loadSourceImage: provider not found" - << providerId; + << providerId; return false; } auto* provider = dynamic_cast(providerBase); if (!provider) { - qWarning() << "ZShellIo::loadSourceImage: provider is not a QQuickImageProvider" - << providerId; + qWarning() << "ZShellIo::loadSourceImage: provider is not a " + "QQuickImageProvider" + << providerId; return false; } @@ -302,7 +289,7 @@ bool ZShellIo::loadSourceImage(const QUrl& source, QImage& image) const { default: qWarning() << "ZShellIo::loadSourceImage: unsupported provider type" - << providerId; + << providerId; return false; } @@ -313,17 +300,16 @@ bool ZShellIo::loadSourceImage(const QUrl& source, QImage& image) const { return false; } -// ============================================================ -// File ops -// ============================================================ - -bool ZShellIo::copyFile(const QUrl& source, const QUrl& target, bool overwrite) const { +bool ZShellIo::copyFile( + const QUrl& source, const QUrl& target, bool overwrite) const { if (!source.isLocalFile()) { - qWarning() << "ZShellIo::copyFile: source" << source << "is not a local file"; + qWarning() << "ZShellIo::copyFile: source" << source + << "is not a local file"; return false; } if (!target.isLocalFile()) { - qWarning() << "ZShellIo::copyFile: target" << target << "is not a local file"; + qWarning() << "ZShellIo::copyFile: target" << target + << "is not a local file"; return false; } @@ -336,7 +322,8 @@ bool ZShellIo::copyFile(const QUrl& source, const QUrl& target, bool overwrite) bool ZShellIo::deleteFile(const QUrl& path) const { if (!path.isLocalFile()) { - qWarning() << "ZShellIo::deleteFile: path" << path << "is not a local file"; + qWarning() << "ZShellIo::deleteFile: path" << path + << "is not a local file"; return false; } @@ -345,7 +332,8 @@ bool ZShellIo::deleteFile(const QUrl& path) const { QString ZShellIo::toLocalFile(const QUrl& url) const { if (!url.isLocalFile()) { - qWarning() << "ZShellIo::toLocalFile: given url is not a local file" << url; + qWarning() << "ZShellIo::toLocalFile: given url is not a local file" + << url; return QString(); } diff --git a/Plugins/ZShell/writefile.hpp b/Plugins/ZShell/writefile.hpp index 458d4d9..799cb98 100644 --- a/Plugins/ZShell/writefile.hpp +++ b/Plugins/ZShell/writefile.hpp @@ -10,31 +10,31 @@ namespace ZShell { class ZShellIo : public QObject { + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + public: + // clang-format off + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed); -public: -// clang-format off -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed); + Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir); + Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved); + Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved, QJSValue onFailed); + // clang-format on -Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir); -Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved); -Q_INVOKABLE void cacheImage(const QUrl& source, const QString& cacheDir, QJSValue onSaved, QJSValue onFailed); -// clang-format on + Q_INVOKABLE [[nodiscard]] bool copyFile( + const QUrl& source, const QUrl& target, bool overwrite = true) const; + Q_INVOKABLE [[nodiscard]] bool deleteFile(const QUrl& path) const; + Q_INVOKABLE [[nodiscard]] QString toLocalFile(const QUrl& url) const; -Q_INVOKABLE [[nodiscard]] bool copyFile(const QUrl& source, const QUrl& target, bool overwrite = true) const; -Q_INVOKABLE [[nodiscard]] bool deleteFile(const QUrl& path) const; -Q_INVOKABLE [[nodiscard]] QString toLocalFile(const QUrl& url) const; - -private: -bool loadSourceImage(const QUrl& source, QImage& image) const; + private: + bool loadSourceImage(const QUrl& source, QImage& image) const; }; } // namespace ZShell diff --git a/Plugins/ZShell/zutils.cpp b/Plugins/ZShell/zutils.cpp index ec0449f..8265485 100644 --- a/Plugins/ZShell/zutils.cpp +++ b/Plugins/ZShell/zutils.cpp @@ -27,15 +27,22 @@ void ZUtils::saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved) { this->saveItem(target, path, QRect(), onSaved, QJSValue()); } -void ZUtils::saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed) { +void ZUtils::saveItem( + QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed) { this->saveItem(target, path, QRect(), onSaved, onFailed); } -void ZUtils::saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved) { +void ZUtils::saveItem( + QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved) { this->saveItem(target, path, rect, onSaved, QJSValue()); } -void ZUtils::saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed) { +void ZUtils::saveItem( + QQuickItem* target, + const QUrl& path, + const QRect& rect, + QJSValue onSaved, + QJSValue onFailed) { if (!target) { qCWarning(lcZUtils) << "saveItem: a target is required"; return; @@ -47,21 +54,30 @@ void ZUtils::saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, Q } if (!target->window()) { - qCWarning(lcZUtils) << "saveItem: unable to save target" << target << "without a window"; + qCWarning(lcZUtils) << "saveItem: unable to save target" << target + << "without a window"; return; } auto scaledRect = rect; const qreal scale = target->window()->devicePixelRatio(); if (rect.isValid() && !qFuzzyCompare(scale + 1.0, 2.0)) { - scaledRect = - QRectF(rect.left() * scale, rect.top() * scale, rect.width() * scale, rect.height() * scale).toRect(); + scaledRect = QRectF( + rect.left() * scale, + rect.top() * scale, + rect.width() * scale, + rect.height() * scale) + .toRect(); } - const QSharedPointer grabResult = target->grabToImage(); + const QSharedPointer grabResult = + target->grabToImage(); - QObject::connect(grabResult.data(), &QQuickItemGrabResult::ready, this, - [grabResult, scaledRect, path, onSaved, onFailed, this]() { + QObject::connect( + grabResult.data(), + &QQuickItemGrabResult::ready, + this, + [grabResult, scaledRect, path, onSaved, onFailed, this]() { const auto future = QtConcurrent::run([=]() { QImage image = grabResult->image(); @@ -77,44 +93,52 @@ void ZUtils::saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, Q auto* watcher = new QFutureWatcher(this); auto* engine = qmlEngine(this); - QObject::connect(watcher, &QFutureWatcher::finished, this, [=]() { - if (watcher->result()) { - if (onSaved.isCallable()) { - QJSValueList args = { QJSValue(path.toLocalFile()) }; - if (engine) { - args << engine->toScriptValue(QVariant::fromValue(path)); + QObject::connect( + watcher, &QFutureWatcher::finished, this, [=]() { + if (watcher->result()) { + if (onSaved.isCallable()) { + QJSValueList args = {QJSValue(path.toLocalFile())}; + if (engine) { + args << engine->toScriptValue( + QVariant::fromValue(path)); + } + onSaved.call(args); } - onSaved.call(args); - } - } else { - qCWarning(lcZUtils) << "saveItem: failed to save" << path; - if (onFailed.isCallable()) { - if (engine) { - onFailed.call({ engine->toScriptValue(QVariant::fromValue(path)) }); - } else { - onFailed.call(); + } else { + qCWarning(lcZUtils) + << "saveItem: failed to save" << path; + if (onFailed.isCallable()) { + if (engine) { + onFailed.call({engine->toScriptValue( + QVariant::fromValue(path))}); + } else { + onFailed.call(); + } } } - } - watcher->deleteLater(); - }); + watcher->deleteLater(); + }); watcher->setFuture(future); }); } bool ZUtils::copyFile(const QUrl& source, const QUrl& target, bool overwrite) { if (!source.isLocalFile()) { - qCWarning(lcZUtils) << "copyFile: source" << source << "is not a local file"; + qCWarning(lcZUtils) + << "copyFile: source" << source << "is not a local file"; return false; } if (!target.isLocalFile()) { - qCWarning(lcZUtils) << "copyFile: target" << target << "is not a local file"; + qCWarning(lcZUtils) + << "copyFile: target" << target << "is not a local file"; return false; } if (overwrite && QFile::exists(target.toLocalFile())) { if (!QFile::remove(target.toLocalFile())) { - qCWarning(lcZUtils) << "copyFile: overwrite was specified but failed to remove" << target.toLocalFile(); + qCWarning(lcZUtils) + << "copyFile: overwrite was specified but failed to remove" + << target.toLocalFile(); return false; } } @@ -124,7 +148,8 @@ bool ZUtils::copyFile(const QUrl& source, const QUrl& target, bool overwrite) { bool ZUtils::deleteFile(const QUrl& path) { if (!path.isLocalFile()) { - qCWarning(lcZUtils) << "deleteFile: path" << path << "is not a local file"; + qCWarning(lcZUtils) + << "deleteFile: path" << path << "is not a local file"; return false; } @@ -133,7 +158,8 @@ bool ZUtils::deleteFile(const QUrl& path) { QString ZUtils::toLocalFile(const QUrl& url) { if (!url.isLocalFile()) { - qCWarning(lcZUtils) << "toLocalFile: given url is not a local file" << url; + qCWarning(lcZUtils) + << "toLocalFile: given url is not a local file" << url; return QString(); } diff --git a/Plugins/ZShell/zutils.hpp b/Plugins/ZShell/zutils.hpp index 54cfb5f..4acbaa4 100644 --- a/Plugins/ZShell/zutils.hpp +++ b/Plugins/ZShell/zutils.hpp @@ -8,28 +8,29 @@ namespace ZShell { class ZUtils : public QObject { -Q_OBJECT -QML_ELEMENT -QML_SINGLETON + Q_OBJECT + QML_ELEMENT + QML_SINGLETON -public: -// clang-format off -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved); -Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed); -// clang-format on + public: + // clang-format off + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, QJSValue onSaved, QJSValue onFailed); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved); + Q_INVOKABLE void saveItem(QQuickItem* target, const QUrl& path, const QRect& rect, QJSValue onSaved, QJSValue onFailed); + // clang-format on -Q_INVOKABLE static bool copyFile(const QUrl& source, const QUrl& target, bool overwrite = true); -Q_INVOKABLE static bool deleteFile(const QUrl& path); -Q_INVOKABLE static QString toLocalFile(const QUrl& url); + Q_INVOKABLE static bool copyFile( + const QUrl& source, const QUrl& target, bool overwrite = true); + Q_INVOKABLE static bool deleteFile(const QUrl& path); + Q_INVOKABLE static QString toLocalFile(const QUrl& url); -Q_INVOKABLE static qreal clamp(qreal value, qreal min, qreal max); + Q_INVOKABLE static qreal clamp(qreal value, qreal min, qreal max); -[[nodiscard]] QString version() const; -[[nodiscard]] QString qtVersion() const; + [[nodiscard]] QString version() const; + [[nodiscard]] QString qtVersion() const; }; } // namespace ZShell