#pragma once #include #include #include #include struct ChatTextSelection { QPersistentModelIndex index; QPoint clickPos; QPoint dragPos; int startChar = -1; int endChar = -1; bool active = false; }; class ChatView : public QListView { Q_OBJECT public: explicit ChatView(QWidget *parent = nullptr); void setBackgroundImage(const QString &path); bool hasSelection() const { return m_selStart.isValid(); } QModelIndex selStart() const { return QModelIndex(m_selStart); } QModelIndex selEnd() const { return QModelIndex(m_selEnd); } bool isSelecting() const { return m_selecting; } const ChatTextSelection &textSelection() const { return m_textSel; } bool isRowSelected(const QModelIndex &idx) const; void setTextSelChars(int start, int end) { m_textSel.startChar = start; m_textSel.endChar = end; } signals: void hoveredIndexChanged(const QModelIndex &idx); protected: void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; void scrollContentsBy(int dx, int dy) override; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void keyPressEvent(QKeyEvent *event) override; private: void copySelection(); void updateScrollDownBtn(); QPixmap m_background; QPersistentModelIndex m_selStart; QPersistentModelIndex m_selEnd; ChatTextSelection m_textSel; QPersistentModelIndex m_lastHovered; QPersistentModelIndex m_pressIndex; QPoint m_pressPos; bool m_selecting = false; QPushButton *m_scrollDownBtn = nullptr; };