跳转至

ui/widget/material/widget/textfield/textfield.h

Material Design 3 TextField widget. More...

Namespaces

Name
cf
cf::ui
cf::ui::widget
cf::ui::widget::material
cf::ui::widget::material::base

Classes

Name
class cf::ui::widget::material::TextField
Material Design 3 TextField widget.

Detailed Description

Material Design 3 TextField widget.

Author: CFDesktop Team

Version: 0.1

Since: 0.1

Date: 2026-03-01

Implements Material Design 3 text field with support for filled and outlined variants. Includes floating labels, prefix/suffix icons, character counter, helper/error text, and password mode.

Source code

#pragma once

#include <QIcon>
#include <QLineEdit>
#include <QWidget>

#include "base/color.h"
#include "base/include/base/weak_ptr/weak_ptr.h"
#include "cfmaterial_animation_factory.h"
#include "export.h"

namespace cf::ui::widget::material {

// Forward declarations
namespace base {
class StateMachine;
class RippleHelper;
class MdFocusIndicator;
} // namespace base

using CFColor = cf::ui::base::CFColor;

class CF_UI_EXPORT TextField : public QLineEdit {
    Q_OBJECT
    Q_PROPERTY(TextFieldVariant variant READ variant WRITE setVariant)
    Q_PROPERTY(QString label READ label WRITE setLabel)
    Q_PROPERTY(QString helperText READ helperText WRITE setHelperText)
    Q_PROPERTY(QString errorText READ errorText WRITE setErrorText)
    Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
    Q_PROPERTY(bool showCharacterCounter READ showCharacterCounter WRITE
                setShowCharacterCounter)
    Q_PROPERTY(bool isFloating READ isFloating NOTIFY floatingChanged)
    Q_PROPERTY(QIcon prefixIcon READ prefixIcon WRITE setPrefixIcon)
    Q_PROPERTY(QIcon suffixIcon READ suffixIcon WRITE setSuffixIcon)

  public:
    enum class TextFieldVariant { Filled, Outlined };
    Q_ENUM(TextFieldVariant);

    explicit TextField(TextFieldVariant variant = TextFieldVariant::Filled,
                       QWidget* parent = nullptr);

    explicit TextField(const QString& text, TextFieldVariant variant = TextFieldVariant::Filled,
                       QWidget* parent = nullptr);

    ~TextField() override;

    TextFieldVariant variant() const;

    void setVariant(TextFieldVariant variant);

    QString label() const;

    void setLabel(const QString& label);

    QString helperText() const;

    void setHelperText(const QString& text);

    QString errorText() const;

    void setErrorText(const QString& text);

    bool isFloating() const;

    QIcon prefixIcon() const;

    void setPrefixIcon(const QIcon& icon);

    QIcon suffixIcon() const;

    void setSuffixIcon(const QIcon& icon);

    bool showCharacterCounter() const;

    void setShowCharacterCounter(bool show);

    int maxLength() const;

    void setMaxLength(int length);

    QSize sizeHint() const override;

    QSize minimumSizeHint() const override;

  signals:
    void floatingChanged(bool floating);

  protected:
    void paintEvent(QPaintEvent* event) override;

    void resizeEvent(QResizeEvent* event) override;

    void mousePressEvent(QMouseEvent* event) override;

    void mouseReleaseEvent(QMouseEvent* event) override;

    void focusInEvent(QFocusEvent* event) override;

    void focusOutEvent(QFocusEvent* event) override;

    void changeEvent(QEvent* event) override;

    void textChanged(const QString& text);

  private:
    // Drawing helpers - Material Design paint pipeline
    void drawBackground(QPainter& p, const QRectF& fieldRect);
    void drawOutline(QPainter& p, const QRectF& fieldRect);
    void drawLabel(QPainter& p, const QRectF& fieldRect);
    void drawText(QPainter& p, const QRectF& textRect);
    void drawPrefixIcon(QPainter& p, const QRectF& textRect);
    void drawSuffixIcon(QPainter& p, const QRectF& textRect);
    void drawClearButton(QPainter& p, const QRectF& textRect);
    void drawHelperText(QPainter& p, const QRectF& helperRect);
    void drawCharacterCounter(QPainter& p, const QRectF& helperRect);
    void drawFocusIndicator(QPainter& p, const QRectF& fieldRect);
    void drawRipple(QPainter& p, const QRectF& fieldRect);

    // Layout helpers
    QRectF fieldRect() const;
    QRectF textRect() const;
    QRectF helperTextRect() const;
    QRectF prefixIconRect() const;
    QRectF suffixIconRect() const;
    QRectF clearButtonRect() const;

    // Animation helpers
    void updateFloatingState(bool shouldFloat);
    void animateFloatingTo(bool floating);

    // Color access methods
    CFColor containerColor() const;
    CFColor onContainerColor() const;
    CFColor labelColor() const;
    CFColor inputTextColor() const;
    CFColor outlineColor() const;
    CFColor focusOutlineColor() const;
    CFColor errorColor() const;
    CFColor helperTextColor() const;
    float cornerRadius() const;
    QFont inputFont() const;
    QFont labelFont() const;
    QFont helperFont() const;

    // Behavior components
    cf::WeakPtr<components::material::CFMaterialAnimationFactory> m_animationFactory;
    base::StateMachine* m_stateMachine;
    base::RippleHelper* m_ripple;
    base::MdFocusIndicator* m_focusIndicator;

    // Properties
    TextFieldVariant m_variant;
    QString m_label;
    QString m_helperText;
    QString m_errorText;
    QIcon m_prefixIcon;
    QIcon m_suffixIcon;
    bool m_showCharacterCounter;
    int m_maxLength;

    // Internal state
    bool m_isFloating;
    bool m_hasError;
    float m_floatingProgress; // 0.0 = resting, 1.0 = floating
    float m_outlineWidth;     // For animating outline width
    bool m_hoveringClearButton;
    bool m_pressingClearButton;
};

} // namespace cf::ui::widget::material

Updated on 2026-03-09 at 10:14:01 +0000