mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[Room][UserList] Introduce style delegate (#6981)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
* [Room] Additionally show a tab for friends and ignored users instead of just all online users.
Took 21 minutes
Took 12 minutes
* [Room][UserList] Introduce style delegate for user list
- Allow users to set a card name and parameters as their background banner
- Allow mods to white/blacklist cards
- Allow toggling back to the old display style
Took 7 minutes
Took 28 seconds
Took 2 minutes
Took 2 minutes
* Right checkstate.
Took 14 minutes
Took 2 minutes
* Utility for test.
Took 9 minutes
Took 8 seconds
Took 2 seconds
* Lint.
Took 10 minutes
* Algorithm for sql schema migration
Took 13 minutes
* Use {prefix}, bound card name, return errors.
Took 27 seconds
* Convert queue to while loop.
Took 19 seconds
* Hover popup.
Took 36 minutes
Took 1 minute
* More granular signals, popup for user info.
Took 25 minutes
Took 8 seconds
Took 16 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
c9ebdb451f
commit
2914874720
45 changed files with 3387 additions and 83 deletions
181
cockatrice/src/interface/widgets/server/user/user_info_popup.h
Normal file
181
cockatrice/src/interface/widgets/server/user/user_info_popup.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#ifndef COCKATRICE_USER_INFO_POPUP_H
|
||||
#define COCKATRICE_USER_INFO_POPUP_H
|
||||
|
||||
#include "../../interface/widgets/server/game_type_map.h"
|
||||
#include "user_list_painter.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QListView>
|
||||
#include <QMap>
|
||||
#include <QPixmap>
|
||||
#include <QStandardItemModel>
|
||||
#include <libcockatrice/network/server/remote/user_level.h>
|
||||
#include <libcockatrice/protocol/pb/response.pb.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_game.pb.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
|
||||
class AbstractClient;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class TabSupervisor;
|
||||
|
||||
// ── Roles ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
namespace PopupRoles
|
||||
{
|
||||
constexpr int GameData = Qt::UserRole + 10;
|
||||
}
|
||||
|
||||
// ── Header widget ─────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @class UserInfoHeaderWidget
|
||||
* @brief Paints the enlarged banner card art + circular avatar section at the
|
||||
* top of the UserInfoPopup.
|
||||
*
|
||||
* Layout mirrors UserListPainter but at a larger scale: the card art fills the
|
||||
* full width as a semi-transparent background, a bottom gradient ensures the
|
||||
* avatar and username text remain legible, and the status ring colour matches
|
||||
* the UserListPainter convention.
|
||||
*/
|
||||
class UserInfoHeaderWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
static constexpr int HeaderHeight = 130;
|
||||
static constexpr int AvatarSize = 68;
|
||||
static constexpr int AvatarPawnSize = 46;
|
||||
static constexpr int LeftPad = 14;
|
||||
static constexpr int AvatarToTextGap = 10;
|
||||
|
||||
public:
|
||||
explicit UserInfoHeaderWidget(QWidget *parent = nullptr);
|
||||
|
||||
void setUserData(const ServerInfo_User &user,
|
||||
bool online,
|
||||
const QPixmap &avatar,
|
||||
const QPixmap &cardArt,
|
||||
const CardArtParams ¶ms);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
ServerInfo_User m_user;
|
||||
bool m_online = false;
|
||||
QPixmap m_avatar;
|
||||
QPixmap m_cardArt;
|
||||
CardArtParams m_params;
|
||||
};
|
||||
|
||||
// ── Main popup ────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @class UserInfoPopup
|
||||
* @brief Floating panel showing an enlarged user card, quick action buttons,
|
||||
* and a live scrollable games list.
|
||||
*
|
||||
* Lifecycle (mirrors DeckEditorDeckDockWidget):
|
||||
* - showForUser() — populate, position externally, call show()
|
||||
* - mouseEnteredPopup / mouseLeftPopup — caller manages hide timer
|
||||
* - closeRequested() — emitted by the internal close button
|
||||
*
|
||||
* The popup is a Qt::Tool frameless child so windowOpacity animations and
|
||||
* move() in screen coordinates work identically to CardInfoPictureEnlargedWidget.
|
||||
*
|
||||
* Action signals map 1-to-1 to UserContextMenu::exec*() methods so all action
|
||||
* logic stays in one place.
|
||||
*/
|
||||
class UserInfoPopup : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
static constexpr int PopupWidth = 316;
|
||||
|
||||
public:
|
||||
explicit UserInfoPopup(TabSupervisor *tabSupervisor,
|
||||
AbstractClient *client,
|
||||
const QMap<QString, QPixmap> *avatarCache,
|
||||
const QMap<QString, QPixmap> *cardArtCache,
|
||||
const QMap<QString, CardArtParams> *cardArtParamsMap,
|
||||
QWidget *parent);
|
||||
|
||||
/**
|
||||
* Populate the popup for @p userName and kick off a game list fetch.
|
||||
* Call show() / move() externally after this.
|
||||
*/
|
||||
void
|
||||
showForUser(const QString &userName, const ServerInfo_User &userInfo, bool online, bool isBuddy, bool isIgnored);
|
||||
void fetchGames();
|
||||
|
||||
[[nodiscard]] QString currentUser() const
|
||||
{
|
||||
return m_currentUser;
|
||||
}
|
||||
|
||||
/** Called when buddy/ignore status changes externally while popup is open. */
|
||||
void updateActionButtons(const ServerInfo_User &userInfo, bool online, bool isBuddy, bool isIgnored);
|
||||
|
||||
signals:
|
||||
void mouseEnteredPopup();
|
||||
void mouseLeftPopup();
|
||||
void closeRequested();
|
||||
|
||||
/** Emitted when the user requests joining or spectating a game in the list. */
|
||||
void joinGameRequested(int gameId, int roomId, bool asSpectator);
|
||||
|
||||
// ── Action signals — connect to UserContextMenu::exec*() ──────────────────
|
||||
void chatRequested(const QString &userName);
|
||||
void detailsRequested(const QString &userName);
|
||||
void showGamesRequested(const QString &userName);
|
||||
void addBuddyRequested(const QString &userName);
|
||||
void removeBuddyRequested(const QString &userName);
|
||||
void addIgnoreRequested(const QString &userName);
|
||||
void removeIgnoreRequested(const QString &userName);
|
||||
void banRequested(const QString &userName);
|
||||
void warnRequested(const QString &userName);
|
||||
void banHistoryRequested(const QString &userName);
|
||||
void warnHistoryRequested(const QString &userName);
|
||||
void adminNotesRequested(const QString &userName);
|
||||
void promoteToModRequested(const QString &userName);
|
||||
void demoteFromModRequested(const QString &userName);
|
||||
void promoteToJudgeRequested(const QString &userName);
|
||||
void demoteFromJudgeRequested(const QString &userName);
|
||||
|
||||
protected:
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
void enterEvent(QEnterEvent *e) override;
|
||||
#else
|
||||
void enterEvent(QEvent *e) override;
|
||||
#endif
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
private slots:
|
||||
void refreshGames();
|
||||
void onGamesReceived(const Response &r, const QString &forUser);
|
||||
void onGamesContextMenu(const QPoint &pos);
|
||||
|
||||
private:
|
||||
void buildUi();
|
||||
void rebuildActionButtons(const ServerInfo_User &userInfo, bool online, bool isBuddy, bool isIgnored);
|
||||
|
||||
TabSupervisor *m_ts;
|
||||
AbstractClient *m_client;
|
||||
const QMap<QString, QPixmap> *m_avatarCache;
|
||||
const QMap<QString, QPixmap> *m_cardArtCache;
|
||||
const QMap<QString, CardArtParams> *m_cardArtParamsMap;
|
||||
|
||||
QString m_currentUser;
|
||||
ServerInfo_User m_currentUserInfo;
|
||||
bool m_currentOnline = false;
|
||||
|
||||
UserInfoHeaderWidget *m_header;
|
||||
QWidget *m_actionArea; ///< rebuilt per user
|
||||
QListView *m_gamesView;
|
||||
QStandardItemModel *m_gamesModel;
|
||||
QLabel *m_gamesStatus;
|
||||
QPushButton *m_closeBtn;
|
||||
QPushButton *m_refreshBtn;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_USER_INFO_POPUP_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue