/** * RobloxChatWidget.h * Copyright (c) 2015 ROBLOX Corp. All Rights Reserved. */ #pragma once //this will make sure that we can use qt with boost (else moc compiler errors) #ifndef QT_NO_KEYWORDS #define QT_NO_KEYWORDS #endif #include #include #include #include #include #include "rbx/signal.h" #include "Util/HttpAsync.h" namespace RBX { class DataModel; namespace Network { class ChatMessage; } } class RobloxChatWidget; class PlayersDataManager; namespace StudioChat { enum ChatType { All, Whisper, Game }; struct ChatMessageData { ChatType chatType; QString message; QString playerName; int playerId; bool isLocalPlayer; ChatMessageData() {;} ChatMessageData(ChatType chatType_, QString message_) : chatType(chatType_), message(message_), playerId(-1), isLocalPlayer(false) {;} }; } class ChatMessageItem: public QObject, public QListWidgetItem { Q_OBJECT public: ChatMessageItem(QObject* parent); QSize sizeHint(const QStyleOptionViewItem& option, const QSize& viewportSize) const; void paint(QPainter* painter, const QStyleOptionViewItem& option); private Q_SLOTS: void updatePlayerAvatar(const QImage& image); private: static QPolygon getMessageBoxPolygon(QRect& boundingRect, bool pointingRight); }; class ChatMessageDelegate: public QItemDelegate { public: ChatMessageDelegate(QObject* parent); enum Role { SubLabelRole = Qt::UserRole, SubLabelDecorationPath, SubLabelDecorationRole }; private: /*override*/ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; /*override*/ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; }; class ChatMessageListWidget: public QListWidget { public: ChatMessageListWidget(QWidget* parent, boost::shared_ptr playerDataManager); QListWidgetItem* addMessageItem(StudioChat::ChatMessageData messageData); QListWidgetItem* addMessageStatusItem(const QString& statusMessage); QListWidgetItem* addBroadcastItem(const QString& message, bool hasError = false); using QListWidget::itemFromIndex; private: void insertAndScrollToItem(QListWidgetItem* pItem); boost::shared_ptr m_pPlayersDataManager; }; class ChatMessageLineEdit: public QLineEdit { Q_OBJECT public: ChatMessageLineEdit(QWidget* parent, boost::shared_ptr playersDataManager); QString getText(); StudioChat::ChatType getChatType() { return m_chatType; } Q_SIGNALS: void returnPressed(int chatType, const QString& message, const QString& targetPlayerName); private Q_SLOTS: void onTextEdited(const QString& message); void onReturnPressed(); private: boost::shared_ptr m_pPlayersDataManager; StudioChat::ChatType m_chatType; QString m_prefixString; }; class RobloxChatWidget: public QFrame { Q_OBJECT public: RobloxChatWidget(QWidget* parent, boost::shared_ptr dataModel, boost::shared_ptr playerDataManager); private Q_SLOTS: void onReturnPressed(int chatMode, const QString& message, const QString& targetPlayerName); private: Q_INVOKABLE void addMessage(StudioChat::ChatMessageData messageData); void onPlayerChatMessage(const RBX::Network::ChatMessage& chatMessage); void sendMessage(const StudioChat::ChatMessageData& messageData, QString& errorMessage); void updateSentMessageStatus(const QString& message); void showEvent(QShowEvent* evt); void setToggleChatActionPixmap(const QPixmap& pixmap); void updateToggleChatActionPixmap(); QQueue > m_sentMessages; ChatMessageListWidget* m_pChatListWidget; ChatMessageLineEdit* m_pMessageBox; boost::shared_ptr m_pDataModel; boost::shared_ptr m_pPlayersDataManager; rbx::signals::scoped_connection m_cPlayerChatMessage; QPixmap m_OriginalChatActionPixmap; };