#pragma once #include #include #include #include #include #include namespace ZShell { class ZUtils : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON Q_PROPERTY(QString version READ version CONSTANT) Q_PROPERTY(QString qtVersion READ qtVersion CONSTANT) 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 qreal clamp(qreal value, qreal min, qreal max); Q_INVOKABLE static QString enumToString( QObject* target, const QString& property, const QVariant& value = QVariant()); Q_INVOKABLE static QString gitRevision(); Q_INVOKABLE static QString readTextFile(const QString& path); Q_INVOKABLE static bool writeTextFile( const QString& path, const QString& text); Q_INVOKABLE static QStringList listFiles( const QString& dir, const QString& suffix); Q_INVOKABLE static QQuickItem* findChild( QQuickItem* root, const QString& name); Q_INVOKABLE static QList findChildren( QQuickItem* root, const QString& name); Q_INVOKABLE static QList findChildrenMatching( QQuickItem* root, const QString& pattern); // Device pixel ratio of the window the item lives in (falls back to the primary screen, then 1.0) Q_INVOKABLE static qreal dprFor(QQuickItem* item); // Snap a logical value to the device pixel grid of the item's window. // Centering is detected from the item: anchors.centerIn, // anchors.horizontalCenter / verticalCenter, and Layout alignment. A size // along a centered axis is snapped so the centered edges land on whole // device pixels — using Qt's own rounding rule for that anchor style // (exact halves when `alignWhenCentered` is true, the rounded half of the // anchor target when it is false). Q_INVOKABLE static qreal snap(qreal value, QQuickItem* item); Q_INVOKABLE static qreal snapCeil(qreal value, QQuickItem* item); // text-derived sizes Q_INVOKABLE static qreal snapFloor(qreal value, QQuickItem* item); // Logs where an item sits in device pixels and whether it is aligned. // Returns true if aligned. `tag` is an optional label for the log line. // Items centered on a target are judged by the centering rule above // (whole device size, plus the offset the anchor produces), which is // detected from the item's anchors and Layout alignment. Q_INVOKABLE static bool logPlacement( QQuickItem* item, const QString& tag = QString()); // Walks a stroked curve path (flat x,y pairs in the item's logical coords, // every point along the curve, not just its defined points) and checks // whether both stroke edges land on device pixel boundaries at `lineWidth`. // Returns true if every sample is aligned. Q_INVOKABLE static bool logCurvePlacement( QQuickItem* item, const QList& samples, qreal lineWidth, const QString& tag = QString()); // Distributes `total` (logical px) across items with the given preferred widths. // Every result is a whole number of device pixels and the results sum exactly to // the snapped total. If the preferred widths don't fit, they shrink proportionally. Q_INVOKABLE static QList distribute( qreal total, const QList& preferred, QQuickItem* item); [[nodiscard]] QString version() const; [[nodiscard]] QString qtVersion() const; }; } // namespace ZShell