跳转至

ui/widget/material/widget/button/button.h

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

Detailed Description

Material Design 3 Button widget.

Author: N/A

Version: N/A

Since: N/A

Date: N/A

Implements Material Design 3 button with support for filled, tonal, outlined, text, and elevated variants. Includes ripple effects, state layers, elevation shadows, and focus indicators.

Source code

#pragma once

#include <QMarginsF>

#include "base/color.h"
#include "base/include/base/weak_ptr/weak_ptr.h"
#include "cfmaterial_animation_factory.h"
#include "export.h"
#include <QIcon>
#include <QPushButton>
#include <QWidget>

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

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

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

class CF_UI_EXPORT Button : public QPushButton {
    Q_OBJECT
    Q_PROPERTY(ButtonVariant variant READ variant WRITE setVariant)
    Q_PROPERTY(int elevation READ elevation WRITE setElevation)
    Q_PROPERTY(bool pressEffectEnabled READ pressEffectEnabled WRITE setPressEffectEnabled)

  public:
    enum class ButtonVariant { Filled, Tonal, Outlined, Text, Elevated };
    Q_ENUM(ButtonVariant);

    explicit Button(ButtonVariant variant = ButtonVariant::Filled, QWidget* parent = nullptr);

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

    ~Button() override;

    int elevation() const;

    void setElevation(int level);

    void setLightSourceAngle(float degrees);

    float lightSourceAngle() const;

    void setLeadingIcon(const QIcon& icon);

    void setIcon(const QIcon& icon) { setLeadingIcon(icon); }

    QIcon icon() const { return leadingIcon_; }

    bool pressEffectEnabled() const;

    void setPressEffectEnabled(bool enabled);

    ButtonVariant variant() const;

    void setVariant(ButtonVariant variant);

    QSize sizeHint() const override;

    QSize minimumSizeHint() const override;

  protected:
    void paintEvent(QPaintEvent* event) override;

    void enterEvent(QEnterEvent* event) override;

    void leaveEvent(QEvent* 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;

  private:
    // Drawing helpers - 7-step paint pipeline
    QMarginsF shadowMargin() const;
    void drawShadow(QPainter& p, const QRectF& contentRect, const QPainterPath& shape);
    void drawBackground(QPainter& p, const QPainterPath& shape);
    void drawStateLayer(QPainter& p, const QPainterPath& shape);
    void drawRipple(QPainter& p, const QPainterPath& shape);
    void drawOutline(QPainter& p, const QPainterPath& shape);
    void drawContent(QPainter& p, const QRectF& contentRect);
    void drawFocusIndicator(QPainter& p, const QPainterPath& shape);

    // Color access methods
    CFColor containerColor() const;
    CFColor labelColor() const;
    CFColor stateLayerColor() const;
    CFColor outlineColor() const;
    float cornerRadius() const;
    QFont labelFont() const;

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

    ButtonVariant variant_;
    QIcon leadingIcon_;
    bool m_pressEffectEnabled = true;
};

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

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