mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 12:38:48 +03:00
Fix UI inconsistencies between room list & communities
fixes #204 fixes #255
This commit is contained in:
parent
bee9278a1a
commit
7621dc0cb0
17 changed files with 261 additions and 321 deletions
|
@ -260,7 +260,6 @@ qt5_wrap_cpp(MOC_HEADERS
|
||||||
include/ChatPage.h
|
include/ChatPage.h
|
||||||
include/CommunitiesListItem.h
|
include/CommunitiesListItem.h
|
||||||
include/CommunitiesList.h
|
include/CommunitiesList.h
|
||||||
include/Community.h
|
|
||||||
include/LoginPage.h
|
include/LoginPage.h
|
||||||
include/MainWindow.h
|
include/MainWindow.h
|
||||||
include/InviteeItem.h
|
include/InviteeItem.h
|
||||||
|
|
|
@ -143,8 +143,6 @@ private:
|
||||||
Splitter *splitter;
|
Splitter *splitter;
|
||||||
|
|
||||||
QWidget *sideBar_;
|
QWidget *sideBar_;
|
||||||
QWidget *communitiesSideBar_;
|
|
||||||
QVBoxLayout *communitiesSideBarLayout_;
|
|
||||||
QVBoxLayout *sideBarLayout_;
|
QVBoxLayout *sideBarLayout_;
|
||||||
QWidget *sideBarTopWidget_;
|
QWidget *sideBarTopWidget_;
|
||||||
QVBoxLayout *sideBarTopWidgetLayout_;
|
QVBoxLayout *sideBarTopWidgetLayout_;
|
||||||
|
|
|
@ -30,6 +30,8 @@ public slots:
|
||||||
void highlightSelectedCommunity(const QString &id);
|
void highlightSelectedCommunity(const QString &id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void addGlobalItem() { addCommunity(QSharedPointer<Community>(new Community), "world"); }
|
||||||
|
|
||||||
//! Check whether or not a community id is currently managed.
|
//! Check whether or not a community id is currently managed.
|
||||||
bool communityExists(const QString &id)
|
bool communityExists(const QString &id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "Community.h"
|
#include "Community.h"
|
||||||
#include "Menu.h"
|
#include "Config.h"
|
||||||
#include "ui/Theme.h"
|
#include "ui/Theme.h"
|
||||||
|
|
||||||
|
class RippleOverlay;
|
||||||
|
|
||||||
class CommunitiesListItem : public QWidget
|
class CommunitiesListItem : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -19,27 +21,37 @@ class CommunitiesListItem : public QWidget
|
||||||
QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor)
|
QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor)
|
||||||
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
|
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:
|
public:
|
||||||
CommunitiesListItem(QSharedPointer<Community> community,
|
CommunitiesListItem(QSharedPointer<Community> community,
|
||||||
QString community_id,
|
QString community_id,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
void setCommunity(QSharedPointer<Community> community);
|
void setCommunity(QSharedPointer<Community> community) { community_ = community; };
|
||||||
|
|
||||||
inline bool isPressed() const;
|
bool isPressed() const { return isPressed_; }
|
||||||
inline void setAvatar(const QImage &avatar_image);
|
void setAvatar(const QImage &img);
|
||||||
|
|
||||||
QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; }
|
QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; }
|
||||||
QColor hoverBackgroundColor() const { return hoverBackgroundColor_; }
|
QColor hoverBackgroundColor() const { return hoverBackgroundColor_; }
|
||||||
QColor backgroundColor() const { return backgroundColor_; }
|
QColor backgroundColor() const { return backgroundColor_; }
|
||||||
|
|
||||||
|
QColor avatarFgColor() const { return avatarFgColor_; }
|
||||||
|
QColor avatarBgColor() const { return avatarBgColor_; }
|
||||||
|
|
||||||
void setHighlightedBackgroundColor(QColor &color) { highlightedBackgroundColor_ = color; }
|
void setHighlightedBackgroundColor(QColor &color) { highlightedBackgroundColor_ = color; }
|
||||||
void setHoverBackgroundColor(QColor &color) { hoverBackgroundColor_ = color; }
|
void setHoverBackgroundColor(QColor &color) { hoverBackgroundColor_ = color; }
|
||||||
void setBackgroundColor(QColor &color) { backgroundColor_ = color; }
|
void setBackgroundColor(QColor &color) { backgroundColor_ = color; }
|
||||||
|
|
||||||
QColor highlightedBackgroundColor_;
|
void setAvatarFgColor(QColor &color) { avatarFgColor_ = color; }
|
||||||
QColor hoverBackgroundColor_;
|
void setAvatarBgColor(QColor &color) { avatarBgColor_ = color; }
|
||||||
QColor backgroundColor_;
|
|
||||||
|
QSize sizeHint() const override
|
||||||
|
{
|
||||||
|
return QSize(IconSize + IconSize / 3, IconSize + IconSize / 3);
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void clicked(const QString &community_id);
|
void clicked(const QString &community_id);
|
||||||
|
@ -50,10 +62,9 @@ public slots:
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int IconSize = 55;
|
const int IconSize = 36;
|
||||||
|
|
||||||
QSharedPointer<Community> community_;
|
QSharedPointer<Community> community_;
|
||||||
QString communityId_;
|
QString communityId_;
|
||||||
|
@ -62,34 +73,22 @@ private:
|
||||||
|
|
||||||
QPixmap communityAvatar_;
|
QPixmap communityAvatar_;
|
||||||
|
|
||||||
Menu *menu_;
|
QColor highlightedBackgroundColor_;
|
||||||
bool isPressed_ = false;
|
QColor hoverBackgroundColor_;
|
||||||
};
|
QColor backgroundColor_;
|
||||||
|
|
||||||
inline bool
|
QColor avatarFgColor_;
|
||||||
CommunitiesListItem::isPressed() const
|
QColor avatarBgColor_;
|
||||||
{
|
|
||||||
return isPressed_;
|
bool isPressed_ = false;
|
||||||
}
|
|
||||||
|
RippleOverlay *rippleOverlay_;
|
||||||
|
};
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
CommunitiesListItem::setAvatar(const QImage &avatar_image)
|
CommunitiesListItem::setAvatar(const QImage &img)
|
||||||
{
|
{
|
||||||
communityAvatar_ = QPixmap::fromImage(
|
communityAvatar_ = QPixmap::fromImage(
|
||||||
avatar_image.scaled(IconSize, IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
img.scaled(IconSize, IconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
update();
|
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;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Community : public QObject
|
struct Community
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
void parseProfile(const QJsonObject &profile);
|
void parseProfile(const QJsonObject &profile);
|
||||||
void parseRooms(const QJsonObject &rooms);
|
void parseRooms(const QJsonObject &rooms);
|
||||||
|
|
||||||
|
@ -19,7 +16,6 @@ public:
|
||||||
QString getLongDescription() const { return long_description_; }
|
QString getLongDescription() const { return long_description_; }
|
||||||
std::vector<QString> getRoomList() const { return rooms_; }
|
std::vector<QString> getRoomList() const { return rooms_; }
|
||||||
|
|
||||||
private:
|
|
||||||
QUrl avatar_;
|
QUrl avatar_;
|
||||||
QString name_;
|
QString name_;
|
||||||
QString short_description_;
|
QString short_description_;
|
||||||
|
|
|
@ -61,10 +61,11 @@ static constexpr int cornerRadius = 3;
|
||||||
// RoomList specific.
|
// RoomList specific.
|
||||||
namespace roomlist {
|
namespace roomlist {
|
||||||
namespace fonts {
|
namespace fonts {
|
||||||
static constexpr int heading = 13;
|
static constexpr int heading = 13;
|
||||||
static constexpr int timestamp = heading;
|
static constexpr int timestamp = heading;
|
||||||
static constexpr int badge = 10;
|
static constexpr int badge = 10;
|
||||||
static constexpr int bubble = 20;
|
static constexpr int bubble = 20;
|
||||||
|
static constexpr int communityBubble = bubble - 4;
|
||||||
} // namespace fonts
|
} // namespace fonts
|
||||||
} // namespace roomlist
|
} // namespace roomlist
|
||||||
|
|
||||||
|
|
161
include/ui/Painter.h
Normal file
161
include/ui/Painter.h
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QPaintDevice>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
|
@ -15,7 +15,7 @@ enum class AvatarType
|
||||||
namespace sidebar {
|
namespace sidebar {
|
||||||
static const int SmallSize = 60;
|
static const int SmallSize = 60;
|
||||||
static const int NormalSize = 260;
|
static const int NormalSize = 260;
|
||||||
static const int CommunitiesSidebarSize = 64;
|
static const int CommunitiesSidebarSize = 48;
|
||||||
}
|
}
|
||||||
// Default font size.
|
// Default font size.
|
||||||
const int FontSize = 16;
|
const int FontSize = 16;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB |
|
@ -1,98 +1 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"/></svg>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="48px"
|
|
||||||
height="48px"
|
|
||||||
id="svg3304"
|
|
||||||
sodipodi:version="0.32"
|
|
||||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
|
|
||||||
sodipodi:docname="world.svg"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:export-filename="/home/max/Program/nheko/resources/icons/world.png"
|
|
||||||
inkscape:export-xdpi="256"
|
|
||||||
inkscape:export-ydpi="256">
|
|
||||||
<defs
|
|
||||||
id="defs3306" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="7.9375"
|
|
||||||
inkscape:cx="11.531663"
|
|
||||||
inkscape:cy="15.491127"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
inkscape:grid-bbox="true"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:grid-points="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:guide-bbox="true"
|
|
||||||
inkscape:window-width="1280"
|
|
||||||
inkscape:window-height="704"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="0" />
|
|
||||||
<metadata
|
|
||||||
id="metadata3309">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
id="layer1"
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer">
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 12.998425,32.054724 c 6.286614,-2.35748 15.716536,-2.35748 22.00315,0"
|
|
||||||
id="path5512"
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="M 11.402021,24 H 36.597979"
|
|
||||||
id="path5516"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 20.856693,11.074078 c -3.929134,8.210961 -3.929134,18.426709 0,26.284977"
|
|
||||||
id="path5520"
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
id="path6250"
|
|
||||||
d="m 12.998425,15.945276 c 6.286614,2.35748 15.716536,2.35748 22.00315,0"
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
id="path9156"
|
|
||||||
d="m 27.143307,11.074078 c 3.929134,8.210961 3.929134,18.426709 0,26.284977"
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<circle
|
|
||||||
style="fill:none;fill-opacity:0.67634858;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
id="path1767"
|
|
||||||
cx="24"
|
|
||||||
cy="24"
|
|
||||||
r="13.609846" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 818 B |
|
@ -22,7 +22,7 @@
|
||||||
<file>icons/ui/paper-clip-outline@2x.png</file>
|
<file>icons/ui/paper-clip-outline@2x.png</file>
|
||||||
<file>icons/ui/angle-pointing-to-left.png</file>
|
<file>icons/ui/angle-pointing-to-left.png</file>
|
||||||
<file>icons/ui/angle-pointing-to-left@2x.png</file>
|
<file>icons/ui/angle-pointing-to-left@2x.png</file>
|
||||||
<file>icons/ui/world.png</file>
|
<file>icons/ui/world.svg</file>
|
||||||
<file>icons/ui/angle-arrow-down.png</file>
|
<file>icons/ui/angle-arrow-down.png</file>
|
||||||
<file>icons/ui/angle-arrow-down@2x.png</file>
|
<file>icons/ui/angle-arrow-down@2x.png</file>
|
||||||
<file>icons/ui/arrow-pointing-down.png</file>
|
<file>icons/ui/arrow-pointing-down.png</file>
|
||||||
|
|
|
@ -93,9 +93,12 @@ RoomInfoListItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommunitiesListItem {
|
CommunitiesListItem {
|
||||||
qproperty-highlightedBackgroundColor: #5294e2;
|
qproperty-highlightedBackgroundColor: #4d84c7;
|
||||||
qproperty-hoverBackgroundColor: #39679e;
|
qproperty-hoverBackgroundColor: rgba(57,103,158, 100);
|
||||||
qproperty-backgroundColor: #2d3139;
|
qproperty-backgroundColor: #2d3139;
|
||||||
|
|
||||||
|
qproperty-avatarBgColor: #202228;
|
||||||
|
qproperty-avatarFgColor: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingIndicator {
|
LoadingIndicator {
|
||||||
|
|
|
@ -92,8 +92,11 @@ RoomInfoListItem {
|
||||||
|
|
||||||
CommunitiesListItem {
|
CommunitiesListItem {
|
||||||
qproperty-highlightedBackgroundColor: #38A3D8;
|
qproperty-highlightedBackgroundColor: #38A3D8;
|
||||||
qproperty-hoverBackgroundColor: rgba(200, 200, 200, 128);
|
qproperty-hoverBackgroundColor: rgba(200, 200, 200, 100);
|
||||||
qproperty-backgroundColor: white;
|
qproperty-backgroundColor: white;
|
||||||
|
|
||||||
|
qproperty-avatarBgColor: #eee;
|
||||||
|
qproperty-avatarFgColor: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ChatPageLoadSpinner {
|
#ChatPageLoadSpinner {
|
||||||
|
|
|
@ -95,8 +95,11 @@ RoomInfoListItem {
|
||||||
|
|
||||||
CommunitiesListItem {
|
CommunitiesListItem {
|
||||||
qproperty-highlightedBackgroundColor: palette(highlight);
|
qproperty-highlightedBackgroundColor: palette(highlight);
|
||||||
qproperty-hoverBackgroundColor: palette(mid);
|
qproperty-hoverBackgroundColor: palette(light);
|
||||||
qproperty-backgroundColor: palette(window);
|
qproperty-backgroundColor: palette(window);
|
||||||
|
|
||||||
|
qproperty-avatarBgColor: palette(mid);
|
||||||
|
qproperty-avatarFgColor: palette(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingIndicator {
|
LoadingIndicator {
|
||||||
|
|
|
@ -58,16 +58,8 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client,
|
||||||
topLayout_->setSpacing(0);
|
topLayout_->setSpacing(0);
|
||||||
topLayout_->setMargin(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);
|
communitiesList_ = new CommunitiesList(client, this);
|
||||||
communitiesSideBarLayout_->addWidget(communitiesList_);
|
topLayout_->addWidget(communitiesList_);
|
||||||
// communitiesSideBarLayout_->addStretch(1);
|
|
||||||
topLayout_->addWidget(communitiesSideBar_);
|
|
||||||
|
|
||||||
auto splitter = new Splitter(this);
|
auto splitter = new Splitter(this);
|
||||||
splitter->setHandleWidth(0);
|
splitter->setHandleWidth(0);
|
||||||
|
@ -806,12 +798,12 @@ ChatPage::setGroupViewState(bool isEnabled)
|
||||||
{
|
{
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
communitiesList_->communityChanged("world");
|
communitiesList_->communityChanged("world");
|
||||||
communitiesSideBar_->hide();
|
communitiesList_->hide();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
communitiesSideBar_->show();
|
communitiesList_->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -32,13 +32,7 @@ CommunitiesList::CommunitiesList(QSharedPointer<MatrixClient> client, QWidget *p
|
||||||
contentsLayout_->setSpacing(0);
|
contentsLayout_->setSpacing(0);
|
||||||
contentsLayout_->setMargin(0);
|
contentsLayout_->setMargin(0);
|
||||||
|
|
||||||
WorldCommunityListItem *world_list_item = new WorldCommunityListItem();
|
addGlobalItem();
|
||||||
contentsLayout_->addWidget(world_list_item);
|
|
||||||
communities_.emplace("world", QSharedPointer<CommunitiesListItem>(world_list_item));
|
|
||||||
connect(world_list_item,
|
|
||||||
&WorldCommunityListItem::clicked,
|
|
||||||
this,
|
|
||||||
&CommunitiesList::highlightSelectedCommunity);
|
|
||||||
contentsLayout_->addStretch(1);
|
contentsLayout_->addStretch(1);
|
||||||
|
|
||||||
scrollArea_->setWidget(scrollAreaContents_);
|
scrollArea_->setWidget(scrollAreaContents_);
|
||||||
|
@ -62,14 +56,7 @@ CommunitiesList::setCommunities(const std::map<QString, QSharedPointer<Community
|
||||||
{
|
{
|
||||||
communities_.clear();
|
communities_.clear();
|
||||||
|
|
||||||
// TODO: still not sure how to handle the "world" special-case
|
addGlobalItem();
|
||||||
WorldCommunityListItem *world_list_item = new WorldCommunityListItem();
|
|
||||||
communities_.emplace("world", QSharedPointer<CommunitiesListItem>(world_list_item));
|
|
||||||
connect(world_list_item,
|
|
||||||
&WorldCommunityListItem::clicked,
|
|
||||||
this,
|
|
||||||
&CommunitiesList::highlightSelectedCommunity);
|
|
||||||
contentsLayout_->insertWidget(0, world_list_item);
|
|
||||||
|
|
||||||
for (const auto &community : communities) {
|
for (const auto &community : communities) {
|
||||||
addCommunity(community.second, community.first);
|
addCommunity(community.second, community.first);
|
||||||
|
@ -78,7 +65,7 @@ CommunitiesList::setCommunities(const std::map<QString, QSharedPointer<Community
|
||||||
client_->fetchCommunityRooms(community.first);
|
client_->fetchCommunityRooms(community.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
world_list_item->setPressedState(true);
|
communities_["world"]->setPressedState(true);
|
||||||
emit communityChanged("world");
|
emit communityChanged("world");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#include "CommunitiesListItem.h"
|
#include "CommunitiesListItem.h"
|
||||||
|
#include "Painter.h"
|
||||||
|
#include "Ripple.h"
|
||||||
|
#include "RippleOverlay.h"
|
||||||
|
|
||||||
CommunitiesListItem::CommunitiesListItem(QSharedPointer<Community> community,
|
CommunitiesListItem::CommunitiesListItem(QSharedPointer<Community> community,
|
||||||
QString community_id,
|
QString community_id,
|
||||||
|
@ -7,16 +10,17 @@ CommunitiesListItem::CommunitiesListItem(QSharedPointer<Community> community,
|
||||||
, community_(community)
|
, community_(community)
|
||||||
, communityId_(community_id)
|
, communityId_(community_id)
|
||||||
{
|
{
|
||||||
// menu_ = new Menu(this);
|
setMouseTracking(true);
|
||||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
setAttribute(Qt::WA_Hover);
|
||||||
setFixedHeight(ui::sidebar::CommunitiesSidebarSize);
|
|
||||||
setFixedWidth(ui::sidebar::CommunitiesSidebarSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
QPainterPath path;
|
||||||
CommunitiesListItem::setCommunity(QSharedPointer<Community> community)
|
path.addRect(0, 0, parent->width(), height());
|
||||||
{
|
rippleOverlay_ = new RippleOverlay(this);
|
||||||
community_ = community;
|
rippleOverlay_->setClipPath(path);
|
||||||
|
rippleOverlay_->setClipping(true);
|
||||||
|
|
||||||
|
if (communityId_ == "world")
|
||||||
|
communityAvatar_ = QPixmap(":/icons/icons/ui/world.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -39,17 +43,24 @@ CommunitiesListItem::mousePressEvent(QMouseEvent *event)
|
||||||
emit clicked(communityId_);
|
emit clicked(communityId_);
|
||||||
|
|
||||||
setPressedState(true);
|
setPressedState(true);
|
||||||
|
|
||||||
|
QPoint pos = event->pos();
|
||||||
|
qreal radiusEndValue = static_cast<qreal>(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
|
void
|
||||||
CommunitiesListItem::paintEvent(QPaintEvent *event)
|
CommunitiesListItem::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Painter p(this);
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
QPainter p(this);
|
|
||||||
p.setRenderHint(QPainter::TextAntialiasing);
|
|
||||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
if (isPressed_)
|
if (isPressed_)
|
||||||
p.fillRect(rect(), highlightedBackgroundColor_);
|
p.fillRect(rect(), highlightedBackgroundColor_);
|
||||||
|
@ -58,139 +69,21 @@ CommunitiesListItem::paintEvent(QPaintEvent *event)
|
||||||
else
|
else
|
||||||
p.fillRect(rect(), backgroundColor_);
|
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()) {
|
if (communityAvatar_.isNull()) {
|
||||||
QBrush brush;
|
QFont font;
|
||||||
brush.setStyle(Qt::SolidPattern);
|
font.setPixelSize(conf::roomlist::fonts::communityBubble);
|
||||||
brush.setColor("#eee");
|
|
||||||
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(brush);
|
|
||||||
|
|
||||||
p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2);
|
|
||||||
|
|
||||||
font.setPixelSize(conf::roomlist::fonts::bubble);
|
|
||||||
p.setFont(font);
|
p.setFont(font);
|
||||||
p.setPen(QColor("#000"));
|
|
||||||
p.setBrush(Qt::NoBrush);
|
p.drawLetterAvatar(community_->getName()[0],
|
||||||
p.drawText(
|
avatarFgColor_,
|
||||||
avatarRegion.translated(0, -1), Qt::AlignCenter, QChar(community_->getName()[0]));
|
avatarBgColor_,
|
||||||
|
width(),
|
||||||
|
height(),
|
||||||
|
IconSize);
|
||||||
} else {
|
} else {
|
||||||
p.save();
|
p.save();
|
||||||
|
|
||||||
QPainterPath path;
|
p.drawAvatar(communityAvatar_, width(), height(), IconSize);
|
||||||
path.addEllipse(
|
|
||||||
(width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize);
|
|
||||||
p.setClipPath(path);
|
|
||||||
|
|
||||||
p.drawPixmap(avatarRegion, communityAvatar_);
|
|
||||||
p.restore();
|
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<Community>(), "", 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);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue