#pragma once #include "Document/EditorSession.h" #include "UI/ToolHeaderStyle.h" #include #include #include #include #include #include #include #include #include class NumericScrub; // A labelled number, typed at once, stepped by arrows. class TransformValueField : public QWidget { Q_OBJECT public: // The label scrubs within low and high, in whole steps. TransformValueField(const QString &label, const QString &suffix, double low, double high, EditorSession &session, std::function finish, std::function change, QWidget *parent = nullptr); // Shown when the field is not being edited. void sync(double value); // Swift's `.id` drops a scrub under way with its layer. void endScrub(); // No idle zeros on a whole number, two decimals otherwise. static QString formatted(double value); QLineEdit *const field; protected: bool eventFilter(QObject *watched, QEvent *event) override; private: EditorSession &m_session; // Done with its value: a scrub let go, or left. const std::function m_finish; const std::function m_change; NumericScrub *m_scrub = nullptr; double m_value = 0; // A menu or popup borrows the focus: the typing stays. bool m_borrowed = false; }; // The Move tool's bar: numbers, settings, Apply and Cancel. class TransformInspector : public ToolHeaderBar { Q_OBJECT public: explicit TransformInspector(EditorSession &session, QWidget *parent = nullptr); protected: // Return applies and Escape cancels outside the fields. void keyPressEvent(QKeyEvent *event) override; void changeEvent(QEvent *event) override; private: void applyLockIcon(); LayerTransform value() const; QSizeF pixelSize() const; void change(const std::function &update); // What the fields changed applies, one step. void finish(); // Swift's `resize`; the name would hide QWidget's. void resizeBox(double number, bool width); void synchronize(); EditorSession &m_session; // The layer the fields were built for, as Swift's `.id`. std::optional m_layerID; QCheckBox *const m_autoSelect; QCheckBox *const m_showControls; QScrollArea *const m_fields; TransformValueField *const m_x; TransformValueField *const m_y; TransformValueField *const m_width; TransformValueField *const m_height; QToolButton *const m_lock; TransformValueField *const m_scale; TransformValueField *const m_rotation; QComboBox *const m_sampling; QPushButton *const m_cancel; QPushButton *const m_apply; // Cancel and Apply, seen only while an edit waits. QWidget *const m_pendingButtons; QGraphicsOpacityEffect *const m_fade; QPropertyAnimation *const m_fadeIn; bool m_pending = false; };