diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp index 59f3e033d..2b1e9e8c2 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp @@ -214,7 +214,6 @@ DlgCreateGame::DlgCreateGame(const ServerInfo_Game &gameInfo, const QMapsetChecked(gameInfo.spectators_need_password()); spectatorsCanTalkCheckBox->setChecked(gameInfo.spectators_can_chat()); spectatorsSeeEverythingCheckBox->setChecked(gameInfo.spectators_omniscient()); - shareDecklistsOnLoadCheckBox->setChecked(gameInfo.share_decklists_on_load()); QSet types; for (int i = 0; i < gameInfo.game_types_size(); ++i) { diff --git a/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp b/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp index 112f107d4..edb95f2df 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp @@ -527,21 +527,6 @@ void UserInfoPopup::onGamesContextMenu(const QPoint &pos) // ── showForUser ─────────────────────────────────────────────────────────────── -void UserInfoPopup::refreshHeader() -{ - if (m_currentUser.isEmpty()) { - return; - } - - const QPixmap avatar = m_avatarCache ? m_avatarCache->value(m_currentUser) : QPixmap{}; - const CardArtParams params = (m_cardArtParamsMap && m_cardArtParamsMap->contains(m_currentUser)) - ? m_cardArtParamsMap->value(m_currentUser) - : CardArtParams{}; - const QString artKey = m_currentUser + u'|' + params.cardName + u'|' + params.cardProviderId; - const QPixmap cardArt = (m_cardArtCache && !params.cardName.isEmpty()) ? m_cardArtCache->value(artKey) : QPixmap{}; - m_header->setUserData(m_currentUserInfo, m_currentOnline, avatar, cardArt, params); -} - void UserInfoPopup::showForUser(const QString &userName, const ServerInfo_User &userInfo, bool online, @@ -553,7 +538,13 @@ void UserInfoPopup::showForUser(const QString &userName, m_currentOnline = online; // Header - refreshHeader(); + const QPixmap avatar = m_avatarCache ? m_avatarCache->value(userName) : QPixmap{}; + const CardArtParams params = (m_cardArtParamsMap && m_cardArtParamsMap->contains(userName)) + ? m_cardArtParamsMap->value(userName) + : CardArtParams{}; + const QString artKey = userName + u'|' + params.cardName + u'|' + params.cardProviderId; + const QPixmap cardArt = (m_cardArtCache && !params.cardName.isEmpty()) ? m_cardArtCache->value(artKey) : QPixmap{}; + m_header->setUserData(userInfo, online, avatar, cardArt, params); // Actions rebuildActionButtons(userInfo, online, isBuddy, isIgnored); diff --git a/cockatrice/src/interface/widgets/server/user/user_info_popup.h b/cockatrice/src/interface/widgets/server/user/user_info_popup.h index c634511e1..69517093f 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_popup.h +++ b/cockatrice/src/interface/widgets/server/user/user_info_popup.h @@ -116,9 +116,6 @@ public: /** Called when buddy/ignore status changes externally while popup is open. */ void updateActionButtons(const ServerInfo_User &userInfo, bool online, bool isBuddy, bool isIgnored); - /** Re-pulls the avatar/card art for the currently shown user (e.g. after it loads). */ - void refreshHeader(); - signals: void mouseEnteredPopup(); void mouseLeftPopup(); diff --git a/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp b/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp index 3ad357dd7..64cbb7b7d 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -496,6 +495,8 @@ UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor, m_userInfoPopup->setWindowOpacity(0.0); m_userInfoPopup->installEventFilter(this); + connectPopupSignals(); + m_showPopupTimer = new QTimer(this); m_showPopupTimer->setSingleShot(true); m_showPopupTimer->setInterval(280); @@ -514,8 +515,6 @@ UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor, } }); - connectPopupSignals(); - userTree->setMouseTracking(true); userTree->viewport()->setMouseTracking(true); userTree->viewport()->installEventFilter(this); @@ -544,14 +543,15 @@ UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor, connect(userTree->verticalScrollBar(), &QScrollBar::valueChanged, this, [this] { m_showPopupTimer->stop(); hidePopup(true); - requestAvatarsForVisibleItems(); }); // Forward join requests from popup upward connect(m_userInfoPopup, &UserInfoPopup::joinGameRequested, this, &UserListWidget::joinGameRequested); - connect(avatarProvider, &UserAvatarProvider::avatarUpdated, this, &UserListWidget::refreshVisibleUserHeader); - connect(cardArtProvider, &UserCardArtProvider::cardArtUpdated, this, &UserListWidget::refreshVisibleUserHeader); + connect(avatarProvider, &UserAvatarProvider::avatarUpdated, this, + [this](const QString &) { userTree->viewport()->update(); }); + connect(cardArtProvider, &UserCardArtProvider::cardArtUpdated, this, + [this](const QString &) { userTree->viewport()->update(); }); connect(&SettingsCache::instance().appearance(), &AppearanceSettings::styleUserListChanged, this, &UserListWidget::applyDisplayMode); @@ -633,14 +633,6 @@ void UserListWidget::bind(UserListManager *mgr) rebuild(); } -void UserListWidget::refreshVisibleUserHeader(const QString &name) -{ - userTree->viewport()->update(); - if (m_userInfoPopup->isVisible() && m_userInfoPopup->currentUser() == name) { - m_userInfoPopup->refreshHeader(); - } -} - void UserListWidget::refreshPopupButtons(const QString &userName) { UserListTWI *item = users.value(userName); @@ -665,12 +657,6 @@ void UserListWidget::hideEvent(QHideEvent *e) hidePopup(true); } -void UserListWidget::showEvent(QShowEvent *e) -{ - QGroupBox::showEvent(e); - requestAvatarsForVisibleItems(); -} - void UserListWidget::applyDisplayMode() { const bool styled = SettingsCache::instance().appearance().getStyleUserList(); @@ -772,8 +758,6 @@ void UserListWidget::showPopupForUser(const QString &userName) return; } - avatarProvider->requestAvatar(userName); // ensure the hovered user's avatar is fetched promptly - const ServerInfo_User &info = item->getUserInfo(); const bool online = item->data(0, UserListRoles::Online).toBool(); const bool isBuddy = userContextMenu->getUserListProxy()->isUserBuddy(userName); @@ -817,12 +801,7 @@ void UserListWidget::positionPopup(const QString &userName) const int popH = m_userInfoPopup->height(); const int margin = 12; - QScreen *activeScreen = QGuiApplication::screenAt(itemTL); - if (!activeScreen) { - activeScreen = window()->screen(); - } - const QRect screen = - activeScreen ? activeScreen->availableGeometry() : QGuiApplication::primaryScreen()->availableGeometry(); + const QRect screen = QGuiApplication::primaryScreen()->availableGeometry(); // ── X: prefer the side with more space ─────────────────────────────────── const int spaceLeft = vpTL.x() - screen.left() - margin; @@ -896,38 +875,6 @@ void UserListWidget::retranslateUi() updateCount(); } -void UserListWidget::beginBulkLoad() -{ - m_bulkLoading = true; -} - -void UserListWidget::endBulkLoad() -{ - m_bulkLoading = false; - sortItems(); - requestAvatarsForVisibleItems(); - userTree->viewport()->update(); -} - -bool UserListWidget::isItemNearViewport(const UserListTWI *item) const -{ - // Prefetch a full viewport of rows above and below so scrolling never shows - // an unloaded row. - const QRect nearView = - userTree->viewport()->rect().adjusted(0, -userTree->viewport()->height(), 0, userTree->viewport()->height()); - return userTree->visualItemRect(item).intersects(nearView); -} - -void UserListWidget::requestAvatarsForVisibleItems() -{ - for (int i = 0; i < userTree->topLevelItemCount(); ++i) { - auto *twi = static_cast(userTree->topLevelItem(i)); - if (isItemNearViewport(twi)) { - avatarProvider->requestAvatar(QString::fromStdString(twi->getUserInfo().name())); - } - } -} - void UserListWidget::rebuild() { userTree->clear(); @@ -954,11 +901,11 @@ void UserListWidget::rebuild() break; } - beginBulkLoad(); for (auto it = source->cbegin(); it != source->cend(); ++it) { processUserInfo(it.value(), manager->getOnlineUser(it.key()) != nullptr); } - endBulkLoad(); + + sortItems(); } void UserListWidget::processUserInfo(const ServerInfo_User &user, bool online) @@ -993,15 +940,11 @@ void UserListWidget::processUserInfo(const ServerInfo_User &user, bool online) ++onlineCount; } updateCount(); - if (!m_bulkLoading && isItemNearViewport(item)) { - avatarProvider->requestAvatar(userName); - } + avatarProvider->requestAvatar(userName); } item->setOnline(online); - if (!m_bulkLoading) { - sortItems(); - userTree->viewport()->update(); - } + sortItems(); + userTree->viewport()->update(); } bool UserListWidget::deleteUser(const QString &userName) diff --git a/cockatrice/src/interface/widgets/server/user/user_list_widget.h b/cockatrice/src/interface/widgets/server/user/user_list_widget.h index c98ebebdf..d70cdfbbd 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_widget.h +++ b/cockatrice/src/interface/widgets/server/user/user_list_widget.h @@ -36,7 +36,6 @@ class QPlainTextEdit; class Response; class CommandContainer; class UserContextMenu; -class QShowEvent; class BanDialog : public QDialog { @@ -159,14 +158,11 @@ private: QTimer *m_hidePopupTimer = nullptr; QString m_hoveredUser; bool m_popupPinned = false; - bool m_bulkLoading = false; void showPopupForUser(const QString &userName); void hidePopup(bool immediate = false); void positionPopup(const QString &userName); void connectPopupSignals(); - bool isItemNearViewport(const UserListTWI *item) const; - void requestAvatarsForVisibleItems(); QMap users; TabSupervisor *tabSupervisor; @@ -181,7 +177,6 @@ private: void refreshPopupButtons(const QString &userName); private slots: void userClicked(QTreeWidgetItem *item, int column); - void refreshVisibleUserHeader(const QString &name); signals: void openMessageDialog(const QString &userName, bool focus); void addBuddy(const QString &userName); @@ -197,8 +192,6 @@ public: QWidget *parent = nullptr); void bind(UserListManager *mgr); void applyDisplayMode(); - void beginBulkLoad(); - void endBulkLoad(); bool eventFilter(QObject *obj, QEvent *event) override; void retranslateUi(); void rebuild(); @@ -214,7 +207,6 @@ public: protected: void hideEvent(QHideEvent *e) override; - void showEvent(QShowEvent *e) override; }; #endif diff --git a/cockatrice/src/interface/widgets/tabs/tab_account.cpp b/cockatrice/src/interface/widgets/tabs/tab_account.cpp index 2c30178f3..2cc8165e8 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_account.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_account.cpp @@ -135,7 +135,6 @@ void TabAccount::retranslateUi() void TabAccount::processListUsersResponse(const Response &response) { const Response_ListUsers &resp = response.GetExtension(Response_ListUsers::ext); - allUsersList->beginBulkLoad(); for (int i = 0; i < resp.user_list_size(); ++i) { const ServerInfo_User &info = resp.user_list(i); const QString &userName = QString::fromStdString(info.name()); @@ -143,8 +142,8 @@ void TabAccount::processListUsersResponse(const Response &response) ignoreList->setUserOnline(userName, true); buddyList->setUserOnline(userName, true); } - allUsersList->endBulkLoad(); + allUsersList->sortItems(); ignoreList->sortItems(); buddyList->sortItems(); } @@ -189,20 +188,18 @@ void TabAccount::processUserLeftEvent(const Event_UserLeft &event) void TabAccount::buddyListReceived(const QList &_buddyList) { - buddyList->beginBulkLoad(); for (const auto &user : _buddyList) { buddyList->processUserInfo(user, false); } - buddyList->endBulkLoad(); + buddyList->sortItems(); } void TabAccount::ignoreListReceived(const QList &_ignoreList) { - ignoreList->beginBulkLoad(); for (const auto &user : _ignoreList) { ignoreList->processUserInfo(user, false); } - ignoreList->endBulkLoad(); + ignoreList->sortItems(); } void TabAccount::processAddToListEvent(const Event_AddToList &event)