跳转至

ui/widget/material/widget/textarea/textarea.h

Material Design 3 TextArea 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::TextArea
Material Design 3 TextArea widget.

Detailed Description

Material Design 3 TextArea widget.

Author: CFDesktop Team

Version: 0.1

Since: 0.1

Date: 2026-03-01

Implements Material Design 3 text area with support for filled and outlined variants. Includes floating labels, character counter, helper/error text, and multi-line text input.

Source code

#pragma once

#include <QKeyEvent>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QTextEdit>
#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 TextArea : public QTextEdit {
    Q_OBJECT
    Q_PROPERTY(TextAreaVariant 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(int minLines READ minLines WRITE setMinLines)
    Q_PROPERTY(int maxLines READ maxLines WRITE setMaxLines)

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

    explicit TextArea(TextAreaVariant variant = TextAreaVariant::Filled,
                      QWidget* parent = nullptr);

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

    ~TextArea() override;

    TextAreaVariant variant() const;

    void setVariant(TextAreaVariant 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;

    bool showCharacterCounter() const;

    void setShowCharacterCounter(bool show);

    int maxLength() const;

    void setMaxLength(int length);

    int minLines() const;

    void setMinLines(int lines);

    int maxLines() const;

    void setMaxLines(int lines);

    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 keyPressEvent(QKeyEvent* event) override;

    void textChanged();

  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 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;

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

    // 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
    TextAreaVariant m_variant;
    QString m_label;
    QString m_helperText;
    QString m_errorText;
    bool m_showCharacterCounter;
    int m_maxLength;
    int m_minLines;
    int m_maxLines;

    // Internal state
    bool m_isFloating;
    bool m_hasError;
    float m_floatingProgress; // 0.0 = resting, 1.0 = floating
    bool m_updatingGeometry;
};

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

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