From 7621dc0cb028ff15ac2375c31a1dd6fd64b4b94b Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Sat, 28 Apr 2018 15:27:12 +0300 Subject: [PATCH] Fix UI inconsistencies between room list & communities fixes #204 fixes #255 --- CMakeLists.txt | 1 - include/ChatPage.h | 2 - include/CommunitiesList.h | 2 + include/CommunitiesListItem.h | 65 ++++++------ include/Community.h | 8 +- include/Config.h | 9 +- include/ui/Painter.h | 161 ++++++++++++++++++++++++++++ include/ui/Theme.h | 2 +- resources/icons/ui/world.png | Bin 2863 -> 0 bytes resources/icons/ui/world.svg | 99 +---------------- resources/res.qrc | 2 +- resources/styles/nheko-dark.qss | 7 +- resources/styles/nheko.qss | 5 +- resources/styles/system.qss | 5 +- src/ChatPage.cc | 14 +-- src/CommunitiesList.cc | 19 +--- src/CommunitiesListItem.cc | 181 +++++++------------------------- 17 files changed, 261 insertions(+), 321 deletions(-) create mode 100644 include/ui/Painter.h delete mode 100644 resources/icons/ui/world.png diff --git a/CMakeLists.txt b/CMakeLists.txt index e01340ff..675525a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,7 +260,6 @@ qt5_wrap_cpp(MOC_HEADERS include/ChatPage.h include/CommunitiesListItem.h include/CommunitiesList.h - include/Community.h include/LoginPage.h include/MainWindow.h include/InviteeItem.h diff --git a/include/ChatPage.h b/include/ChatPage.h index 16c0c322..831f3933 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -143,8 +143,6 @@ private: Splitter *splitter; QWidget *sideBar_; - QWidget *communitiesSideBar_; - QVBoxLayout *communitiesSideBarLayout_; QVBoxLayout *sideBarLayout_; QWidget *sideBarTopWidget_; QVBoxLayout *sideBarTopWidgetLayout_; diff --git a/include/CommunitiesList.h b/include/CommunitiesList.h index d03d32a2..81408f58 100644 --- a/include/CommunitiesList.h +++ b/include/CommunitiesList.h @@ -30,6 +30,8 @@ public slots: void highlightSelectedCommunity(const QString &id); private: + void addGlobalItem() { addCommunity(QSharedPointer(new Community), "world"); } + //! Check whether or not a community id is currently managed. bool communityExists(const QString &id) { diff --git a/include/CommunitiesListItem.h b/include/CommunitiesListItem.h index c9272524..9309d334 100644 --- a/include/CommunitiesListItem.h +++ b/include/CommunitiesListItem.h @@ -7,9 +7,11 @@ #include #include "Community.h" -#include "Menu.h" +#include "Config.h" #include "ui/Theme.h" +class RippleOverlay; + class CommunitiesListItem : public QWidget { Q_OBJECT @@ -19,27 +21,37 @@ class CommunitiesListItem : public QWidget QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor) Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(QColor avatarFgColor READ avatarFgColor WRITE setAvatarFgColor) + Q_PROPERTY(QColor avatarBgColor READ avatarBgColor WRITE setAvatarBgColor) + public: CommunitiesListItem(QSharedPointer community, QString community_id, QWidget *parent = nullptr); - void setCommunity(QSharedPointer community); + void setCommunity(QSharedPointer community) { community_ = community; }; - inline bool isPressed() const; - inline void setAvatar(const QImage &avatar_image); + bool isPressed() const { return isPressed_; } + void setAvatar(const QImage &img); QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; } QColor hoverBackgroundColor() const { return hoverBackgroundColor_; } QColor backgroundColor() const { return backgroundColor_; } + QColor avatarFgColor() const { return avatarFgColor_; } + QColor avatarBgColor() const { return avatarBgColor_; } + void setHighlightedBackgroundColor(QColor &color) { highlightedBackgroundColor_ = color; } void setHoverBackgroundColor(QColor &color) { hoverBackgroundColor_ = color; } void setBackgroundColor(QColor &color) { backgroundColor_ = color; } - QColor highlightedBackgroundColor_; - QColor hoverBackgroundColor_; - QColor backgroundColor_; + void setAvatarFgColor(QColor &color) { avatarFgColor_ = color; } + void setAvatarBgColor(QColor &color) { avatarBgColor_ = color; } + + QSize sizeHint() const override + { + return QSize(IconSize + IconSize / 3, IconSize + IconSize / 3); + } signals: void clicked(const QString &community_id); @@ -50,10 +62,9 @@ public slots: protected: void mousePressEvent(QMouseEvent *event) override; void paintEvent(QPaintEvent *event) override; - void contextMenuEvent(QContextMenuEvent *event) override; private: - const int IconSize = 55; + const int IconSize = 36; QSharedPointer community_; QString communityId_; @@ -62,34 +73,22 @@ private: QPixmap communityAvatar_; - Menu *menu_; - bool isPressed_ = false; -}; + QColor highlightedBackgroundColor_; + QColor hoverBackgroundColor_; + QColor backgroundColor_; -inline bool -CommunitiesListItem::isPressed() const -{ - return isPressed_; -} + QColor avatarFgColor_; + QColor avatarBgColor_; + + bool isPressed_ = false; + + RippleOverlay *rippleOverlay_; +}; inline void -CommunitiesListItem::setAvatar(const QImage &avatar_image) +CommunitiesListItem::setAvatar(const QImage &img) { communityAvatar_ = QPixmap::fromImage( - avatar_image.scaled(IconSize, IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + img.scaled(IconSize, IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); update(); } - -class WorldCommunityListItem : public CommunitiesListItem -{ - Q_OBJECT -public: - WorldCommunityListItem(QWidget *parent = nullptr); - -protected: - void mousePressEvent(QMouseEvent *event) override; - void paintEvent(QPaintEvent *event) override; - -private: - const int IconSize = 55; -}; diff --git a/include/Community.h b/include/Community.h index 5b759e55..6a398099 100644 --- a/include/Community.h +++ b/include/Community.h @@ -1,15 +1,12 @@ #pragma once #include -#include #include #include +#include -class Community : public QObject +struct Community { - Q_OBJECT - -public: void parseProfile(const QJsonObject &profile); void parseRooms(const QJsonObject &rooms); @@ -19,7 +16,6 @@ public: QString getLongDescription() const { return long_description_; } std::vector getRoomList() const { return rooms_; } -private: QUrl avatar_; QString name_; QString short_description_; diff --git a/include/Config.h b/include/Config.h index d7021d92..1d05e82d 100644 --- a/include/Config.h +++ b/include/Config.h @@ -61,10 +61,11 @@ static constexpr int cornerRadius = 3; // RoomList specific. namespace roomlist { namespace fonts { -static constexpr int heading = 13; -static constexpr int timestamp = heading; -static constexpr int badge = 10; -static constexpr int bubble = 20; +static constexpr int heading = 13; +static constexpr int timestamp = heading; +static constexpr int badge = 10; +static constexpr int bubble = 20; +static constexpr int communityBubble = bubble - 4; } // namespace fonts } // namespace roomlist diff --git a/include/ui/Painter.h b/include/ui/Painter.h new file mode 100644 index 00000000..9558b004 --- /dev/null +++ b/include/ui/Painter.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include +#include + +class Painter : public QPainter +{ +public: + explicit Painter(QPaintDevice *device) + : QPainter(device) + {} + + void drawTextLeft(int x, int y, const QString &text) + { + QFontMetrics m(fontMetrics()); + drawText(x, y + m.ascent(), text); + } + + void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) + { + QFontMetrics m(fontMetrics()); + if (textWidth < 0) + textWidth = m.width(text); + drawText((outerw - x - textWidth), y + m.ascent(), text); + } + + void drawPixmapLeft(int x, int y, const QPixmap &pix, const QRect &from) + { + drawPixmap(QPoint(x, y), pix, from); + } + + void drawPixmapLeft(const QPoint &p, const QPixmap &pix, const QRect &from) + { + return drawPixmapLeft(p.x(), p.y(), pix, from); + } + + void drawPixmapLeft(int x, int y, int w, int h, const QPixmap &pix, const QRect &from) + { + drawPixmap(QRect(x, y, w, h), pix, from); + } + + void drawPixmapLeft(const QRect &r, const QPixmap &pix, const QRect &from) + { + return drawPixmapLeft(r.x(), r.y(), r.width(), r.height(), pix, from); + } + + void drawPixmapLeft(int x, int y, int outerw, const QPixmap &pix) + { + Q_UNUSED(outerw); + drawPixmap(QPoint(x, y), pix); + } + + void drawPixmapLeft(const QPoint &p, int outerw, const QPixmap &pix) + { + return drawPixmapLeft(p.x(), p.y(), outerw, pix); + } + + void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix, const QRect &from) + { + drawPixmap( + QPoint((outerw - x - (from.width() / pix.devicePixelRatio())), y), pix, from); + } + + void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix, const QRect &from) + { + return drawPixmapRight(p.x(), p.y(), outerw, pix, from); + } + void drawPixmapRight(int x, + int y, + int w, + int h, + int outerw, + const QPixmap &pix, + const QRect &from) + { + drawPixmap(QRect((outerw - x - w), y, w, h), pix, from); + } + + void drawPixmapRight(const QRect &r, int outerw, const QPixmap &pix, const QRect &from) + { + return drawPixmapRight(r.x(), r.y(), r.width(), r.height(), outerw, pix, from); + } + + void drawPixmapRight(int x, int y, int outerw, const QPixmap &pix) + { + drawPixmap(QPoint((outerw - x - (pix.width() / pix.devicePixelRatio())), y), pix); + } + + void drawPixmapRight(const QPoint &p, int outerw, const QPixmap &pix) + { + return drawPixmapRight(p.x(), p.y(), outerw, pix); + } + + void drawAvatar(const QPixmap &pix, int w, int h, int d) + { + QPainterPath pp; + pp.addEllipse((w - d) / 2, (h - d) / 2, d, d); + + QRect region((w - d) / 2, (h - d) / 2, d, d); + + setClipPath(pp); + drawPixmap(region, pix); + } + + void drawLetterAvatar(const QChar &c, + const QColor &penColor, + const QColor &brushColor, + int w, + int h, + int d) + { + QRect region((w - d) / 2, (h - d) / 2, d, d); + + setPen(Qt::NoPen); + setBrush(brushColor); + + drawEllipse(region.center(), d / 2, d / 2); + + setBrush(Qt::NoBrush); + drawEllipse(region.center(), d / 2, d / 2); + + setPen(penColor); + drawText(region.translated(0, -1), Qt::AlignCenter, c); + } +}; + +class PainterHighQualityEnabler +{ +public: + PainterHighQualityEnabler(Painter &p) + : _painter(p) + { + static constexpr QPainter::RenderHint Hints[] = {QPainter::Antialiasing, + QPainter::SmoothPixmapTransform, + QPainter::TextAntialiasing, + QPainter::HighQualityAntialiasing}; + + auto hints = _painter.renderHints(); + for (const auto &hint : Hints) { + if (!(hints & hint)) + hints_ |= hint; + } + + if (hints_) + _painter.setRenderHints(hints_); + } + + ~PainterHighQualityEnabler() + { + if (hints_) + _painter.setRenderHints(hints_, false); + } + + PainterHighQualityEnabler(const PainterHighQualityEnabler &other) = delete; + PainterHighQualityEnabler &operator=(const PainterHighQualityEnabler &other) = delete; + +private: + Painter &_painter; + QPainter::RenderHints hints_ = 0; +}; diff --git a/include/ui/Theme.h b/include/ui/Theme.h index 54bd4f5f..7a0bdcb7 100644 --- a/include/ui/Theme.h +++ b/include/ui/Theme.h @@ -15,7 +15,7 @@ enum class AvatarType namespace sidebar { static const int SmallSize = 60; static const int NormalSize = 260; -static const int CommunitiesSidebarSize = 64; +static const int CommunitiesSidebarSize = 48; } // Default font size. const int FontSize = 16; diff --git a/resources/icons/ui/world.png b/resources/icons/ui/world.png deleted file mode 100644 index d687d1413cc1c6345e6f8e9831541b90520eed14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2863 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 diff --git a/resources/icons/ui/world.svg b/resources/icons/ui/world.svg index c3acf162..93b61784 100644 --- a/resources/icons/ui/world.svg +++ b/resources/icons/ui/world.svg @@ -1,98 +1 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/resources/res.qrc b/resources/res.qrc index a5461718..77a1ca83 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -22,7 +22,7 @@ icons/ui/paper-clip-outline@2x.png icons/ui/angle-pointing-to-left.png icons/ui/angle-pointing-to-left@2x.png - icons/ui/world.png + icons/ui/world.svg icons/ui/angle-arrow-down.png icons/ui/angle-arrow-down@2x.png icons/ui/arrow-pointing-down.png diff --git a/resources/styles/nheko-dark.qss b/resources/styles/nheko-dark.qss index 69502c01..28850711 100644 --- a/resources/styles/nheko-dark.qss +++ b/resources/styles/nheko-dark.qss @@ -93,9 +93,12 @@ RoomInfoListItem { } CommunitiesListItem { - qproperty-highlightedBackgroundColor: #5294e2; - qproperty-hoverBackgroundColor: #39679e; + qproperty-highlightedBackgroundColor: #4d84c7; + qproperty-hoverBackgroundColor: rgba(57,103,158, 100); qproperty-backgroundColor: #2d3139; + + qproperty-avatarBgColor: #202228; + qproperty-avatarFgColor: white; } LoadingIndicator { diff --git a/resources/styles/nheko.qss b/resources/styles/nheko.qss index e468540c..e1cb839f 100644 --- a/resources/styles/nheko.qss +++ b/resources/styles/nheko.qss @@ -92,8 +92,11 @@ RoomInfoListItem { CommunitiesListItem { qproperty-highlightedBackgroundColor: #38A3D8; - qproperty-hoverBackgroundColor: rgba(200, 200, 200, 128); + qproperty-hoverBackgroundColor: rgba(200, 200, 200, 100); qproperty-backgroundColor: white; + + qproperty-avatarBgColor: #eee; + qproperty-avatarFgColor: black; } #ChatPageLoadSpinner { diff --git a/resources/styles/system.qss b/resources/styles/system.qss index baf736f7..0921a832 100644 --- a/resources/styles/system.qss +++ b/resources/styles/system.qss @@ -95,8 +95,11 @@ RoomInfoListItem { CommunitiesListItem { qproperty-highlightedBackgroundColor: palette(highlight); - qproperty-hoverBackgroundColor: palette(mid); + qproperty-hoverBackgroundColor: palette(light); qproperty-backgroundColor: palette(window); + + qproperty-avatarBgColor: palette(mid); + qproperty-avatarFgColor: palette(text); } LoadingIndicator { diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 8981cb98..ee338c2d 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -58,16 +58,8 @@ ChatPage::ChatPage(QSharedPointer client, topLayout_->setSpacing(0); topLayout_->setMargin(0); - communitiesSideBar_ = new QWidget(this); - communitiesSideBar_->setFixedWidth(ui::sidebar::CommunitiesSidebarSize); - communitiesSideBarLayout_ = new QVBoxLayout(communitiesSideBar_); - communitiesSideBarLayout_->setSpacing(0); - communitiesSideBarLayout_->setMargin(0); - communitiesList_ = new CommunitiesList(client, this); - communitiesSideBarLayout_->addWidget(communitiesList_); - // communitiesSideBarLayout_->addStretch(1); - topLayout_->addWidget(communitiesSideBar_); + topLayout_->addWidget(communitiesList_); auto splitter = new Splitter(this); splitter->setHandleWidth(0); @@ -806,12 +798,12 @@ ChatPage::setGroupViewState(bool isEnabled) { if (!isEnabled) { communitiesList_->communityChanged("world"); - communitiesSideBar_->hide(); + communitiesList_->hide(); return; } - communitiesSideBar_->show(); + communitiesList_->show(); } void diff --git a/src/CommunitiesList.cc b/src/CommunitiesList.cc index 2f547936..25021ba4 100644 --- a/src/CommunitiesList.cc +++ b/src/CommunitiesList.cc @@ -32,13 +32,7 @@ CommunitiesList::CommunitiesList(QSharedPointer client, QWidget *p contentsLayout_->setSpacing(0); contentsLayout_->setMargin(0); - WorldCommunityListItem *world_list_item = new WorldCommunityListItem(); - contentsLayout_->addWidget(world_list_item); - communities_.emplace("world", QSharedPointer(world_list_item)); - connect(world_list_item, - &WorldCommunityListItem::clicked, - this, - &CommunitiesList::highlightSelectedCommunity); + addGlobalItem(); contentsLayout_->addStretch(1); scrollArea_->setWidget(scrollAreaContents_); @@ -62,14 +56,7 @@ CommunitiesList::setCommunities(const std::map(world_list_item)); - connect(world_list_item, - &WorldCommunityListItem::clicked, - this, - &CommunitiesList::highlightSelectedCommunity); - contentsLayout_->insertWidget(0, world_list_item); + addGlobalItem(); for (const auto &community : communities) { addCommunity(community.second, community.first); @@ -78,7 +65,7 @@ CommunitiesList::setCommunities(const std::mapfetchCommunityRooms(community.first); } - world_list_item->setPressedState(true); + communities_["world"]->setPressedState(true); emit communityChanged("world"); } diff --git a/src/CommunitiesListItem.cc b/src/CommunitiesListItem.cc index 5aedfcbc..e86216e8 100644 --- a/src/CommunitiesListItem.cc +++ b/src/CommunitiesListItem.cc @@ -1,4 +1,7 @@ #include "CommunitiesListItem.h" +#include "Painter.h" +#include "Ripple.h" +#include "RippleOverlay.h" CommunitiesListItem::CommunitiesListItem(QSharedPointer community, QString community_id, @@ -7,16 +10,17 @@ CommunitiesListItem::CommunitiesListItem(QSharedPointer community, , community_(community) , communityId_(community_id) { - // menu_ = new Menu(this); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFixedHeight(ui::sidebar::CommunitiesSidebarSize); - setFixedWidth(ui::sidebar::CommunitiesSidebarSize); -} + setMouseTracking(true); + setAttribute(Qt::WA_Hover); -void -CommunitiesListItem::setCommunity(QSharedPointer community) -{ - community_ = community; + QPainterPath path; + path.addRect(0, 0, parent->width(), height()); + rippleOverlay_ = new RippleOverlay(this); + rippleOverlay_->setClipPath(path); + rippleOverlay_->setClipping(true); + + if (communityId_ == "world") + communityAvatar_ = QPixmap(":/icons/icons/ui/world.svg"); } void @@ -39,17 +43,24 @@ CommunitiesListItem::mousePressEvent(QMouseEvent *event) emit clicked(communityId_); setPressedState(true); + + QPoint pos = event->pos(); + qreal radiusEndValue = static_cast(width()) / 3; + + auto ripple = new Ripple(pos); + ripple->setRadiusEndValue(radiusEndValue); + ripple->setOpacityStartValue(0.15); + ripple->setColor("white"); + ripple->radiusAnimation()->setDuration(200); + ripple->opacityAnimation()->setDuration(400); + rippleOverlay_->addRipple(ripple); } void -CommunitiesListItem::paintEvent(QPaintEvent *event) +CommunitiesListItem::paintEvent(QPaintEvent *) { - Q_UNUSED(event); - - QPainter p(this); - p.setRenderHint(QPainter::TextAntialiasing); - p.setRenderHint(QPainter::SmoothPixmapTransform); - p.setRenderHint(QPainter::Antialiasing); + Painter p(this); + PainterHighQualityEnabler hq(p); if (isPressed_) p.fillRect(rect(), highlightedBackgroundColor_); @@ -58,139 +69,21 @@ CommunitiesListItem::paintEvent(QPaintEvent *event) else p.fillRect(rect(), backgroundColor_); - QFont font; - font.setPixelSize(conf::fontSize); - - p.setPen(QColor("#333")); - - QRect avatarRegion((width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); - - font.setBold(false); - p.setPen(Qt::NoPen); - - // We using the first letter of room's name. if (communityAvatar_.isNull()) { - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor("#eee"); - - p.setPen(Qt::NoPen); - p.setBrush(brush); - - p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2); - - font.setPixelSize(conf::roomlist::fonts::bubble); + QFont font; + font.setPixelSize(conf::roomlist::fonts::communityBubble); p.setFont(font); - p.setPen(QColor("#000")); - p.setBrush(Qt::NoBrush); - p.drawText( - avatarRegion.translated(0, -1), Qt::AlignCenter, QChar(community_->getName()[0])); + + p.drawLetterAvatar(community_->getName()[0], + avatarFgColor_, + avatarBgColor_, + width(), + height(), + IconSize); } else { p.save(); - QPainterPath path; - path.addEllipse( - (width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); - p.setClipPath(path); - - p.drawPixmap(avatarRegion, communityAvatar_); + p.drawAvatar(communityAvatar_, width(), height(), IconSize); p.restore(); } - - // TODO: Discord-style community ping counts? - /*if (unreadMsgCount_ > 0) { - QColor textColor("white"); - QColor backgroundColor("#38A3D8"); - - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(backgroundColor); - - if (isPressed_) - brush.setColor(textColor); - - QFont unreadCountFont; - unreadCountFont.setPixelSize(conf::roomlist::fonts::badge); - unreadCountFont.setBold(true); - - p.setBrush(brush); - p.setPen(Qt::NoPen); - p.setFont(unreadCountFont); - - int diameter = 20; - - QRectF r( - width() - diameter - 5, height() - diameter - 5, diameter, diameter); - - p.setPen(Qt::NoPen); - p.drawEllipse(r); - - p.setPen(QPen(textColor)); - - if (isPressed_) - p.setPen(QPen(backgroundColor)); - - p.setBrush(Qt::NoBrush); - p.drawText( - r.translated(0, -0.5), Qt::AlignCenter, QString::number(unreadMsgCount_)); - }*/ -} - -void -CommunitiesListItem::contextMenuEvent(QContextMenuEvent *event) -{ - Q_UNUSED(event); - - // menu_->popup(event->globalPos()); -} - -WorldCommunityListItem::WorldCommunityListItem(QWidget *parent) - : CommunitiesListItem(QSharedPointer(), "", parent) -{} - -void -WorldCommunityListItem::mousePressEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::RightButton) { - QWidget::mousePressEvent(event); - return; - } - - emit CommunitiesListItem::clicked("world"); - - setPressedState(true); -} - -void -WorldCommunityListItem::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - static QPixmap worldIcon(":/icons/icons/ui/world.png"); - - QPainter p(this); - p.setRenderHint(QPainter::SmoothPixmapTransform); - p.setRenderHint(QPainter::Antialiasing); - - if (isPressed()) - p.fillRect(rect(), highlightedBackgroundColor_); - else if (underMouse()) - p.fillRect(rect(), hoverBackgroundColor_); - else - p.fillRect(rect(), backgroundColor_); - - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor("#FFFFFF"); - - p.setPen(Qt::NoPen); - p.setBrush(brush); - - QRect avatarRegion((width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); - p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2); - QPainterPath path; - path.addEllipse((width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); - p.setClipPath(path); - - p.drawPixmap(avatarRegion, worldIcon); }