diff --git a/src/session-widgets/lockcontent.cpp b/src/session-widgets/lockcontent.cpp index 88c86789..50cc2038 100644 --- a/src/session-widgets/lockcontent.cpp +++ b/src/session-widgets/lockcontent.cpp @@ -383,7 +383,8 @@ void LockContent::resizeEvent(QResizeEvent *event) changeCenterSpaceSize(0, m_authWidget->getTopSpacing()); } - return SessionBaseWindow::resizeEvent(event); + SessionBaseWindow::resizeEvent(event); + m_userListWidget->setMaximumSize(getCenterContentSize()); } void LockContent::restoreMode() diff --git a/src/session-widgets/user_widget.cpp b/src/session-widgets/user_widget.cpp index 68d265c6..edfb3eeb 100644 --- a/src/session-widgets/user_widget.cpp +++ b/src/session-widgets/user_widget.cpp @@ -6,7 +6,7 @@ #include "useravatar.h" #include -#include +#include const int BlurRadius = 15; const int BlurTransparency = 70; @@ -45,7 +45,7 @@ void UserWidget::initUI() nameLayout->setContentsMargins(0, 0, 0, 0); nameLayout->setSpacing(5); - QPixmap pixmap = DHiDPIHelper::loadNxPixmap(":/misc/images/select.svg"); + QPixmap pixmap = DIcon::loadNxPixmap(":/misc/images/select.svg"); pixmap.setDevicePixelRatio(devicePixelRatioF()); m_loginState->setAccessibleName("LoginState"); m_loginState->setPixmap(pixmap); diff --git a/src/session-widgets/userframelist.cpp b/src/session-widgets/userframelist.cpp index a0d273cc..624c4593 100644 --- a/src/session-widgets/userframelist.cpp +++ b/src/session-widgets/userframelist.cpp @@ -18,7 +18,18 @@ #include -const int UserFrameSpaceing = 40; +static constexpr int UserWidgetSpacing = 40; +static constexpr int ContentsMargin = 10; + +static inline int listWidth(int col) +{ + return qMax(0, (UserFrameWidth + UserWidgetSpacing) * col - UserWidgetSpacing); +} + +static inline int listHeight(int row) +{ + return qMax(0, (UserFrameHeight + UserWidgetSpacing) * row - UserWidgetSpacing); +} UserFrameList::UserFrameList(QWidget *parent) : QWidget(parent) @@ -46,6 +57,7 @@ UserFrameList::UserFrameList(QWidget *parent) connect(this, &UserFrameList::destroyed, this, [this, index] { m_frameDataBind->unRegisterFunction("UserFrameList", index); }); + connect(this, &UserFrameList::gridBoundChanged, this, &UserFrameList::updateLayout); } void UserFrameList::initUI() @@ -55,10 +67,11 @@ void UserFrameList::initUI() m_flowLayout = new DFlowLayout(m_centerWidget); m_flowLayout->setFlow(QListView::LeftToRight); - m_flowLayout->setContentsMargins(10, 10, 10, 10); - m_flowLayout->setSpacing(40); + m_flowLayout->setContentsMargins(0, 0, 0, 0); + m_flowLayout->setSpacing(UserWidgetSpacing); m_scrollArea->setAccessibleName("UserFrameListCenterWidget"); + m_scrollArea->setContentsMargins(0, 0, 0, 0); m_scrollArea->setWidget(m_centerWidget); m_scrollArea->setWidgetResizable(true); m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); @@ -68,6 +81,7 @@ void UserFrameList::initUI() m_centerWidget->setAutoFillBackground(false); m_scrollArea->viewport()->setAutoFillBackground(false); QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(ContentsMargin, ContentsMargin, ContentsMargin, ContentsMargin); mainLayout->addWidget(m_scrollArea, 0, Qt::AlignCenter); } @@ -79,17 +93,28 @@ void UserFrameList::setModel(SessionBaseModel *model) connect(model, &SessionBaseModel::userAdded, this, &UserFrameList::handlerBeforeAddUser); connect(model, &SessionBaseModel::userRemoved, this, &UserFrameList::removeUser); - QList> userList = m_model->userList(); - for (auto user : userList) { + for (auto user : m_model->userList()) { handlerBeforeAddUser(user); } + onCurrentUserChanged(m_model->currentUser()); + connect(m_model, &SessionBaseModel::currentUserChanged, this, &UserFrameList::onCurrentUserChanged); } -void UserFrameList::setFixedSize(const QSize &size) +void UserFrameList::setFixedSize(int w, int h) { - QWidget::setFixedSize(size); - //先确定界面大小,再根据界面大小计算用户列表区域大小 - updateLayout(); + QWidget::setFixedSize(w, h); + onMaximumSizeChanged(w, h); +} + +void UserFrameList::setMaximumSize(int maxw, int maxh) +{ + QWidget::setMaximumSize(maxw, maxh); + onMaximumSizeChanged(maxw, maxh); +} + +void UserFrameList::setMaximumSize(const QSize &maximumSize) +{ + setMaximumSize(maximumSize.width(), maximumSize.height()); } void UserFrameList::handlerBeforeAddUser(std::shared_ptr user) @@ -184,7 +209,7 @@ void UserFrameList::switchNextUser() //处理m_scrollArea翻页显示 int selectedRight = m_loginWidgets[i]->geometry().right(); int scrollRight = m_scrollArea->widget()->geometry().right(); - if (selectedRight + UserFrameSpaceing == scrollRight) { + if (selectedRight + UserWidgetSpacing == scrollRight) { QPoint topLeft; if (m_rowCount == 1) { topLeft = m_loginWidgets[i + 1]->geometry().topLeft(); @@ -233,6 +258,14 @@ void UserFrameList::switchPreviousUser() } } +void UserFrameList::setGridBound(QPair bound) +{ + if (m_gridBound != bound) { + m_gridBound = bound; + Q_EMIT this->gridBoundChanged(bound); + } +} + void UserFrameList::onOtherPageChanged(const QVariant &value) { foreach (auto w, m_loginWidgets) { @@ -240,24 +273,27 @@ void UserFrameList::onOtherPageChanged(const QVariant &value) } } -void UserFrameList::updateLayout() +void UserFrameList::onMaximumSizeChanged(int maxw, int maxh) { - //处理窗体数量小于5个时的居中显示,取 窗体数量*窗体宽度 和 最大宽度 的较小值,设置为m_centerWidget的宽度 - int count = m_flowLayout->count(); - if (count < 5 && count > 0) { - m_scrollArea->setFixedSize((UserFrameWidth + UserFrameSpaceing) * count, UserFrameHeight + 20); + static constexpr qreal DisplayRatio = 0.8; + static constexpr QMargins margin{ContentsMargin, ContentsMargin, ContentsMargin, ContentsMargin}; + QSize bound = QSize(maxw, maxh).shrunkBy(margin) * DisplayRatio; + int candidateCol = qCeil(static_cast(bound.width()) / (UserFrameWidth + UserWidgetSpacing)); + int candidateRow = qCeil(static_cast(bound.height()) / (UserFrameHeight + UserWidgetSpacing)); + if (listWidth(candidateCol) > bound.width()) { + --candidateCol; } - if (count >= 5) { - m_scrollArea->setFixedSize((UserFrameWidth + UserFrameSpaceing) * 5, (UserFrameHeight + UserFrameSpaceing) * 2); + if (listHeight(candidateRow) > bound.height()) { + --candidateRow; } - m_centerWidget->setFixedWidth(m_scrollArea->width() - 10); - - std::shared_ptr user = m_model->currentUser(); - if (user.get() == nullptr) return; - for (auto it = m_loginWidgets.constBegin(); it != m_loginWidgets.constEnd(); ++it) { - auto login_widget = *it; + setGridBound({candidateCol, candidateRow}); +} - if (login_widget->uid() == user->uid()) { +void UserFrameList::onCurrentUserChanged(std::shared_ptr currentUser) +{ + if (!currentUser) return; + for (const auto login_widget : m_loginWidgets) { + if (login_widget->uid() == currentUser->uid()) { currentSelectedUser = login_widget; currentSelectedUser->setSelected(true); } else { @@ -266,6 +302,19 @@ void UserFrameList::updateLayout() } } +void UserFrameList::updateLayout() +{ + // 用户控件分行显示,超过最大显示行数时显示滚动条 + const int MaxDisplayCol = colBound(); + const int MaxDisplayRow = rowBound(); + int count = m_flowLayout->count(); + int row = qCeil(static_cast(count) / MaxDisplayCol); + int areaWidth = listWidth(qMin(count, MaxDisplayCol)); + int areaHeight = listHeight(qMin(row, MaxDisplayRow)); + m_scrollArea->setFixedSize(areaWidth, areaHeight); + m_centerWidget->setFixedSize(areaWidth, listHeight(row)); +} + void UserFrameList::hideEvent(QHideEvent *event) { return QWidget::hideEvent(event); diff --git a/src/session-widgets/userframelist.h b/src/session-widgets/userframelist.h index a6de21ce..1fa06008 100644 --- a/src/session-widgets/userframelist.h +++ b/src/session-widgets/userframelist.h @@ -24,15 +24,29 @@ DWIDGET_USE_NAMESPACE class UserFrameList : public QWidget { Q_OBJECT + Q_PROPERTY(QPair gridBound READ gridBound WRITE setGridBound NOTIFY gridBoundChanged) + Q_PROPERTY(int rowBound READ rowBound) + Q_PROPERTY(int colBound READ colBound) + public: explicit UserFrameList(QWidget *parent = nullptr); void setModel(SessionBaseModel *model); - void setFixedSize(const QSize &size); + + void setFixedSize(int w, int h); + void setMaximumSize(int maxw, int maxh); + void setMaximumSize(const QSize &maximumSize); + void updateLayout(); -signals: + inline QPair gridBound() const { return m_gridBound; } + inline int colBound() const { return m_gridBound.first; } + inline int rowBound() const { return m_gridBound.second; } + + +Q_SIGNALS: void requestSwitchUser(std::shared_ptr user); void clicked(); + void gridBoundChanged(QPair bound); protected: void hideEvent(QHideEvent *event) override; @@ -41,15 +55,20 @@ class UserFrameList : public QWidget void focusOutEvent(QFocusEvent *event) override; void resizeEvent(QResizeEvent *event) override; +private Q_SLOTS: + void onUserClicked(); + void onOtherPageChanged(const QVariant &value); + void onMaximumSizeChanged(int maxw, int maxh); + void onCurrentUserChanged(std::shared_ptr currentUser); + private: void initUI(); void handlerBeforeAddUser(std::shared_ptr user); void addUser(const std::shared_ptr user); void removeUser(const std::shared_ptr user); - void onUserClicked(); void switchNextUser(); void switchPreviousUser(); - void onOtherPageChanged(const QVariant &value); + void setGridBound(QPair bound); private: QScrollArea *m_scrollArea; @@ -62,6 +81,7 @@ class UserFrameList : public QWidget QWidget *m_centerWidget; int m_colCount; int m_rowCount; + QPair m_gridBound; }; #endif // USERFRAMELIST_H