Browse Source

move INV button from footer into channel delegate rows (second button left of plus)

topo_upd
evgeny 2 months ago
parent
commit
44c99f603d
  1. 30
      tools/chatgui/src/channeldelegate.cpp
  2. 3
      tools/chatgui/src/channeldelegate.h
  3. 46
      tools/chatgui/src/channellist.cpp

30
tools/chatgui/src/channeldelegate.cpp

@ -12,6 +12,13 @@ QRect ChannelDelegate::inviteButtonRect(const QRect &itemRect) {
InviteBtnSize, InviteBtnSize); InviteBtnSize, InviteBtnSize);
} }
QRect ChannelDelegate::inviteByLinkButtonRect(const QRect &itemRect) {
const int margin = 6;
return QRect(itemRect.right() - margin - InviteBtnSize * 2 - InviteBtnGap,
itemRect.bottom() - margin - InviteBtnSize,
InviteBtnSize, InviteBtnSize);
}
void ChannelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, void ChannelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const { const QModelIndex &index) const {
painter->save(); painter->save();
@ -169,6 +176,29 @@ void ChannelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio
painter->drawLine(plusRect.left() + 5, plusRect.center().y(), painter->drawLine(plusRect.left() + 5, plusRect.center().y(),
plusRect.right() - 5, plusRect.center().y()); plusRect.right() - 5, plusRect.center().y());
/* ── invite-by-link button (left of plus, orange square with arrow) ── */
QRect invRect = inviteByLinkButtonRect(option.rect);
bool invHovered = index.data(ChannelInviteByLinkBtnHoveredRole).toInt() != 0;
painter->setRenderHint(QPainter::Antialiasing);
if (invHovered) {
painter->setBrush(QColor(0xE6, 0x7E, 0x22));
painter->setPen(Qt::NoPen);
painter->drawRoundedRect(invRect, 3, 3);
painter->setPen(QPen(Qt::white, 1.5));
} else {
painter->setBrush(QColor(0xE6, 0x7E, 0x22, 110));
painter->setPen(Qt::NoPen);
painter->drawRoundedRect(invRect, 3, 3);
painter->setPen(QPen(QColor(0xE6, 0x7E, 0x22), 1.5));
}
/* arrow pointing into a box: →| or a simple arrow-left: ← */
int cx = invRect.center().x(), cy = invRect.center().y();
int dx = 3;
painter->drawLine(cx + dx, cy - 3, cx - dx, cy);
painter->drawLine(cx + dx, cy + 3, cx - dx, cy);
painter->drawLine(cx + dx + 1, cy, cx + dx + 1, cy - 3 + 1);
painter->drawLine(cx + dx + 1, cy, cx + dx + 1, cy + 3 - 1);
painter->restore(); painter->restore();
} }

3
tools/chatgui/src/channeldelegate.h

@ -10,6 +10,7 @@ enum ChannelDataRole {
ChannelPeersOnlineRole = Qt::UserRole + 3, /* int: count of online peers */ ChannelPeersOnlineRole = Qt::UserRole + 3, /* int: count of online peers */
ChannelAutoConnectActiveRole = Qt::UserRole + 4, /* bool: 1 if auto-connect in progress */ ChannelAutoConnectActiveRole = Qt::UserRole + 4, /* bool: 1 if auto-connect in progress */
ChannelInviteBtnHoveredRole = Qt::UserRole + 5, /* bool: 1 when mouse hovers invite button */ ChannelInviteBtnHoveredRole = Qt::UserRole + 5, /* bool: 1 when mouse hovers invite button */
ChannelInviteByLinkBtnHoveredRole = Qt::UserRole + 8, /* bool: hover for invite-by-link button */
ChannelUnreadCountRole = Qt::UserRole + 6, /* int: unread message count, 0 if none */ ChannelUnreadCountRole = Qt::UserRole + 6, /* int: unread message count, 0 if none */
ChannelLastMsgAtRole = Qt::UserRole + 7 /* qint64: last message timestamp for sorting */ ChannelLastMsgAtRole = Qt::UserRole + 7 /* qint64: last message timestamp for sorting */
}; };
@ -25,5 +26,7 @@ public:
const QModelIndex &index) const override; const QModelIndex &index) const override;
static constexpr int InviteBtnSize = 18; static constexpr int InviteBtnSize = 18;
static constexpr int InviteBtnGap = 2;
static QRect inviteButtonRect(const QRect &itemRect); static QRect inviteButtonRect(const QRect &itemRect);
static QRect inviteByLinkButtonRect(const QRect &itemRect);
}; };

46
tools/chatgui/src/channellist.cpp

@ -19,13 +19,19 @@ class ChannelListView : public QListView {
public: public:
using QListView::QListView; using QListView::QListView;
signals: signals:
void inviteClicked(const QString& channelId); void inviteClicked(const QString& channelId);
void inviteByLinkClicked(const QString& channelId);
protected: protected:
void mousePressEvent(QMouseEvent* e) override { void mousePressEvent(QMouseEvent* e) override {
QModelIndex idx = indexAt(e->pos()); QModelIndex idx = indexAt(e->pos());
if (!idx.isValid()) return; if (!idx.isValid()) return;
QRect invRect = ChannelDelegate::inviteByLinkButtonRect(visualRect(idx));
if (invRect.contains(e->pos())) {
emit inviteByLinkClicked(idx.data(ChannelChannelIdRole).toString());
return;
}
QRect plusRect = ChannelDelegate::inviteButtonRect(visualRect(idx)); QRect plusRect = ChannelDelegate::inviteButtonRect(visualRect(idx));
if (plusRect.contains(e->pos())) { if (plusRect.contains(e->pos())) {
emit inviteClicked(idx.data(ChannelChannelIdRole).toString()); emit inviteClicked(idx.data(ChannelChannelIdRole).toString());
@ -34,19 +40,28 @@ protected:
QListView::mousePressEvent(e); QListView::mousePressEvent(e);
} }
void mouseMoveEvent(QMouseEvent* e) override { void mouseMoveEvent(QMouseEvent* e) override {
int prevRow = m_hoveredInviteRow; int prevInv = m_hoveredInviteRow;
int prevInvBy = m_hoveredInviteByLinkRow;
m_hoveredInviteRow = -1; m_hoveredInviteRow = -1;
m_hoveredInviteByLinkRow = -1;
QModelIndex idx = indexAt(e->pos()); QModelIndex idx = indexAt(e->pos());
if (idx.isValid()) { if (idx.isValid()) {
QRect invRect = ChannelDelegate::inviteByLinkButtonRect(visualRect(idx));
QRect plusRect = ChannelDelegate::inviteButtonRect(visualRect(idx)); QRect plusRect = ChannelDelegate::inviteButtonRect(visualRect(idx));
if (plusRect.contains(e->pos())) if (invRect.contains(e->pos()))
m_hoveredInviteByLinkRow = idx.row();
else if (plusRect.contains(e->pos()))
m_hoveredInviteRow = idx.row(); m_hoveredInviteRow = idx.row();
} }
if (m_hoveredInviteRow != prevRow) { if (m_hoveredInviteRow != prevInv)
model()->setData(model()->index(prevRow, 0), 0, ChannelInviteBtnHoveredRole); model()->setData(model()->index(prevInv, 0), 0, ChannelInviteBtnHoveredRole);
if (m_hoveredInviteRow >= 0)
model()->setData(model()->index(m_hoveredInviteRow, 0), 1, ChannelInviteBtnHoveredRole); model()->setData(model()->index(m_hoveredInviteRow, 0), 1, ChannelInviteBtnHoveredRole);
} if (m_hoveredInviteByLinkRow != prevInvBy)
setCursor(m_hoveredInviteRow >= 0 ? Qt::PointingHandCursor : Qt::ArrowCursor); model()->setData(model()->index(prevInvBy, 0), 0, ChannelInviteByLinkBtnHoveredRole);
if (m_hoveredInviteByLinkRow >= 0)
model()->setData(model()->index(m_hoveredInviteByLinkRow, 0), 1, ChannelInviteByLinkBtnHoveredRole);
setCursor((m_hoveredInviteRow >= 0 || m_hoveredInviteByLinkRow >= 0) ? Qt::PointingHandCursor : Qt::ArrowCursor);
QListView::mouseMoveEvent(e); QListView::mouseMoveEvent(e);
} }
QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex& idx, const QEvent* e) const override { QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex& idx, const QEvent* e) const override {
@ -63,6 +78,7 @@ protected:
private: private:
int m_hoveredInviteRow = -1; int m_hoveredInviteRow = -1;
int m_hoveredInviteByLinkRow = -1;
}; };
static QIcon makeChannelIcon(const QColor &color, const QString &letter) { static QIcon makeChannelIcon(const QColor &color, const QString &letter) {
@ -134,20 +150,6 @@ ChannelList::ChannelList(DbManager* db, QWidget *parent)
connect(createBtn, &QPushButton::clicked, this, [this] { emit createGroupRequested(); }); connect(createBtn, &QPushButton::clicked, this, [this] { emit createGroupRequested(); });
fl->addWidget(createBtn); fl->addWidget(createBtn);
auto *inviteBtn = new QPushButton("INV", footer);
inviteBtn->setFixedSize(36, 28);
inviteBtn->setToolTip(QString::fromUtf8("Пригласить в канал по ссылке"));
inviteBtn->setStyleSheet(
"QPushButton { border: 1.5px solid #E67E22; border-radius: 6px;"
" font-size: 11px; font-weight: bold; color: #E67E22; background: transparent; }"
"QPushButton:hover { background: #E67E22; color: white; }");
connect(inviteBtn, &QPushButton::clicked, this, [this] {
QModelIndex cur = m_listView->currentIndex();
if (cur.isValid())
emit inviteByLinkRequested(cur.data(ChannelChannelIdRole).toString());
});
fl->addWidget(inviteBtn);
auto *plusBtn = new QPushButton("+", footer); auto *plusBtn = new QPushButton("+", footer);
plusBtn->setFixedSize(28, 28); plusBtn->setFixedSize(28, 28);
plusBtn->setToolTip(QString::fromUtf8("Присоединиться")); plusBtn->setToolTip(QString::fromUtf8("Присоединиться"));
@ -169,6 +171,8 @@ ChannelList::ChannelList(DbManager* db, QWidget *parent)
}); });
connect(static_cast<ChannelListView*>(m_listView), &ChannelListView::inviteClicked, connect(static_cast<ChannelListView*>(m_listView), &ChannelListView::inviteClicked,
this, &ChannelList::inviteRequested); this, &ChannelList::inviteRequested);
connect(static_cast<ChannelListView*>(m_listView), &ChannelListView::inviteByLinkClicked,
this, &ChannelList::inviteByLinkRequested);
} }
void ChannelList::loadChannels() { void ChannelList::loadChannels() {

Loading…
Cancel
Save