#ifndef BUBBLEMESSAGEMANAGER_H #define BUBBLEMESSAGEMANAGER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // 基础气泡消息类 class BubbleMessage : public QGraphicsItem { public: // 消息类型枚举 enum MessageType { TimeMessage, TextMessage, SuccessMessage, FailureMessage, FileMessage, RecallMessage, ImageMessage, TextImageMessage }; // 消息方向枚举 enum MessageDirection { Sent, // 发送的消息(右侧) Received // 接收的消息(左侧) }; BubbleMessage(const QString &content, MessageType type, MessageDirection direction, QGraphicsItem *parent = nullptr); virtual ~BubbleMessage(); QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; MessageType messageType() const { return m_type; } MessageDirection messageDirection() const { return m_direction; } QString content() const { return m_content; } QDateTime timestamp() const { return m_timestamp; } virtual void updateSize(); virtual bool isSelectable() const { return true; } void setAvatar(const QPixmap &avatar) { m_avatar = avatar; updateSize(); } QPixmap avatar() const { return m_avatar; } protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; void mousePressEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; MessageType m_type; MessageDirection m_direction; QString m_content; QDateTime m_timestamp; QRectF m_boundingRect; bool m_isHovered; QColor m_bubbleColor; QColor m_textColor; int m_padding; int m_borderRadius; QFont m_font; QPixmap m_avatar; int m_avatarSize; bool m_isSelecting; QPointF m_selectionStart; QPointF m_selectionEnd; }; // 时间消息类 class TimeMessage : public BubbleMessage { public: TimeMessage(const QDateTime &time, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; bool isSelectable() const override { return false; } }; // 文本消息类 class TextMessage : public BubbleMessage { public: TextMessage(const QString &text, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void updateSize() override; virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; int m_selectionStart; int m_selectionEnd; bool m_hasSelection; QString selectedText(); protected: QTextDocument m_textDocument; protected: int positionAt(const QPointF &pos) const; QRectF selectionRect() const; }; // 成功消息类 class SuccessMessage : public TextMessage { public: SuccessMessage(const QString &text, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; }; // 失败消息类 class FailureMessage : public TextMessage { public: FailureMessage(const QString &text, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; }; // 文件消息类 class FileMessage : public BubbleMessage { public: FileMessage(const QString &fileName, const QString &filePath, qint64 fileSize, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void updateSize() override; protected: QString m_fileName; QString m_filePath; qint64 m_fileSize; QPixmap m_fileIcon; }; // 撤回消息类 class RecallMessage : public BubbleMessage { public: RecallMessage(const QString &recalledBy, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; bool isSelectable() const override { return false; } }; // 图片消息类 class ImageMessage : public BubbleMessage { public: ImageMessage(const QPixmap &image, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void updateSize() override; protected: QPixmap m_image; QPixmap m_scaledImage; }; // 文本图片混合消息类 class TextImageMessage : public BubbleMessage { public: TextImageMessage(const QString &text, const QPixmap &image, MessageDirection direction, QGraphicsItem *parent = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void updateSize() override; protected: QTextDocument m_textDocument; QPixmap m_image; QPixmap m_scaledImage; }; // 消息场景类 class MessageScene : public QGraphicsScene { public: MessageScene(QObject *parent = nullptr); void addMessage(BubbleMessage *message); void clear(); void setDefaultAvatars(const QPixmap &sentAvatar, const QPixmap &receivedAvatar); void arrangeMessages(); private: void placeNewMessage(BubbleMessage *message); int m_verticalSpacing; int m_horizontalMargin; QPixmap m_defaultSentAvatar; QPixmap m_defaultReceivedAvatar; }; // 消息视图类 class BubbleMessageView : public QGraphicsView { public: BubbleMessageView(QWidget *parent = nullptr); void addTimeMessage(const QDateTime &time); void addTextMessage(const QString &text, BubbleMessage::MessageDirection direction); void addSuccessMessage(const QString &text, BubbleMessage::MessageDirection direction); void addFailureMessage(const QString &text, BubbleMessage::MessageDirection direction); void addFileMessage(const QString &fileName, const QString &filePath, qint64 fileSize, BubbleMessage::MessageDirection direction); void addRecallMessage(const QString &recalledBy, BubbleMessage::MessageDirection direction); void addImageMessage(const QPixmap &image, BubbleMessage::MessageDirection direction); void addTextImageMessage(const QString &text, const QPixmap &image, BubbleMessage::MessageDirection direction); void clearMessages(); protected: void resizeEvent(QResizeEvent *event) override; void wheelEvent(QWheelEvent *event) override; private: MessageScene *m_scene; bool m_autoScroll; }; #endif // BUBBLEMESSAGEMANAGER_H