mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-01 03:50:43 +00:00
Invite link block in the new profile implementation done.
Fixed ClickHandler state when host is destroyed and after drag-n-drop.
This commit is contained in:
parent
66a8aa86e1
commit
15d6a1aacf
@ -596,7 +596,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
"lng_group_invite_create" = "Create an invite link";
|
||||
"lng_group_invite_about" = "Telegram users will be able to join\nyour group by following this link.";
|
||||
"lng_group_invite_create_new" = "Revoke invite link";
|
||||
"lng_group_invite_about_new" = "Your previous link will be deactivated\nand we'll generate a new invite link for you.";
|
||||
"lng_group_invite_about_new" = "Your previous link will be deactivated and we'll generate a new invite link for you.";
|
||||
"lng_group_invite_copied" = "Invite link copied to clipboard.";
|
||||
"lng_group_invite_no_room" = "Unable to join this group because there are too many members in it already.";
|
||||
|
||||
|
@ -145,9 +145,11 @@ public:
|
||||
}
|
||||
static void hostDestroyed(ClickHandlerHost *host) {
|
||||
if (_activeHost == host) {
|
||||
if (_active) (*_active).clear();
|
||||
_activeHost = nullptr;
|
||||
}
|
||||
if (_pressedHost == host) {
|
||||
if (_pressed) (*_pressed).clear();
|
||||
_pressedHost = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -772,6 +772,9 @@ void HistoryInner::onDragExec() {
|
||||
mimeData->setData(qsl("application/x-td-forward-selected"), "1");
|
||||
}
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
// We don't receive mouseReleaseEvent when drag is finished.
|
||||
ClickHandler::unpressed();
|
||||
drag->exec(Qt::CopyAction);
|
||||
if (App::main()) App::main()->updateAfterDrag();
|
||||
return;
|
||||
@ -806,6 +809,9 @@ void HistoryInner::onDragExec() {
|
||||
}
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
// We don't receive mouseReleaseEvent when drag is finished.
|
||||
ClickHandler::unpressed();
|
||||
drag->exec(Qt::CopyAction);
|
||||
if (App::main()) App::main()->updateAfterDrag();
|
||||
return;
|
||||
|
@ -615,6 +615,9 @@ void OverviewInner::onDragExec() {
|
||||
mimeData->setData(qsl("application/x-td-forward-selected"), "1");
|
||||
}
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
// We don't receive mouseReleaseEvent when drag is finished.
|
||||
ClickHandler::unpressed();
|
||||
drag->exec(Qt::CopyAction);
|
||||
if (App::main()) App::main()->updateAfterDrag();
|
||||
return;
|
||||
@ -643,6 +646,9 @@ void OverviewInner::onDragExec() {
|
||||
}
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
// We don't receive mouseReleaseEvent when drag is finished.
|
||||
ClickHandler::unpressed();
|
||||
drag->exec(Qt::CopyAction);
|
||||
if (App::main()) App::main()->updateAfterDrag();
|
||||
return;
|
||||
|
@ -133,3 +133,7 @@ profileBlockOneLineTextPart: flatLabel(profileBlockTextPart) {
|
||||
}
|
||||
profileBlockOneLineSkip: 9px;
|
||||
profileBlockOneLineWidthMax: 240px;
|
||||
|
||||
profileInviteLinkText: flatLabel(profileBlockTextPart) {
|
||||
width: 1px; // Required for BreakEverywhere
|
||||
}
|
||||
|
@ -22,19 +22,92 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "profile/profile_invite_link_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/flatlabel.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "observer_peer.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
InviteLinkWidget::InviteLinkWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_invite_link_section))
|
||||
{
|
||||
show();
|
||||
InviteLinkWidget::InviteLinkWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_invite_link_section)) {
|
||||
auto observeEvents = Notify::PeerUpdateFlag::InviteLinkChanged;
|
||||
Notify::registerPeerObserver(observeEvents, this, &InviteLinkWidget::notifyPeerUpdated);
|
||||
|
||||
refreshLink();
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void InviteLinkWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.peer != peer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.flags & Notify::PeerUpdateFlag::InviteLinkChanged) {
|
||||
refreshLink();
|
||||
refreshVisibility();
|
||||
|
||||
contentSizeUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
int InviteLinkWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
int marginLeft = st::profileBlockTextPart.margin.left();
|
||||
int marginRight = st::profileBlockTextPart.margin.right();
|
||||
int left = st::profileBlockTitlePosition.x();
|
||||
if (_link) {
|
||||
int textWidth = _link->naturalWidth();
|
||||
int availableWidth = newWidth - left - st::profileBlockMarginRight;
|
||||
int maxWidth = st::msgMaxWidth;
|
||||
accumulate_min(textWidth, availableWidth);
|
||||
accumulate_min(textWidth, st::msgMaxWidth);
|
||||
_link->resizeToWidth(textWidth + marginLeft + marginRight);
|
||||
_link->moveToLeft(left - marginLeft, newHeight - st::profileBlockTextPart.margin.top());
|
||||
newHeight += _link->height();
|
||||
}
|
||||
|
||||
newHeight += st::profileBlockMarginBottom;
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
void InviteLinkWidget::refreshVisibility() {
|
||||
setVisible(_link != nullptr);
|
||||
}
|
||||
|
||||
QString InviteLinkWidget::getInviteLink() const {
|
||||
if (auto chat = peer()->asChat()) {
|
||||
return chat->inviteLink();
|
||||
} else if (auto channel = peer()->asChannel()) {
|
||||
return channel->inviteLink();
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
|
||||
void InviteLinkWidget::refreshLink() {
|
||||
_link.destroy();
|
||||
TextWithEntities linkData = { getInviteLink(), EntitiesInText() };
|
||||
if (!linkData.text.isEmpty()) {
|
||||
_link = new FlatLabel(this, QString(), FlatLabel::InitType::Simple, st::profileInviteLinkText);
|
||||
_link->show();
|
||||
|
||||
linkData.entities.push_back(EntityInText(EntityInTextUrl, 0, linkData.text.size()));
|
||||
_link->setMarkedText(linkData);
|
||||
_link->setSelectable(true);
|
||||
_link->setContextCopyText(QString());
|
||||
_link->setClickHandlerHook(func(this, &InviteLinkWidget::clickHandlerHook));
|
||||
}
|
||||
}
|
||||
|
||||
bool InviteLinkWidget::clickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
||||
auto link = getInviteLink();
|
||||
if (link.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QApplication::clipboard()->setText(link);
|
||||
Ui::showLayer(new InformBox(lang(lng_group_invite_copied)));
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Profile
|
||||
|
@ -21,10 +21,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
#include "core/observer.h"
|
||||
|
||||
class FlatLabel;
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class InviteLinkWidget : public BlockWidget {
|
||||
class InviteLinkWidget : public BlockWidget, public Notify::Observer {
|
||||
public:
|
||||
InviteLinkWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
@ -32,6 +39,18 @@ protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
QString getInviteLink() const;
|
||||
void refreshLink();
|
||||
void refreshVisibility();
|
||||
|
||||
bool clickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button);
|
||||
|
||||
ChildWidget<FlatLabel> _link = { nullptr };
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
||||
|
@ -108,6 +108,10 @@ void FlatLabel::setExpandLinksMode(ExpandLinksMode mode) {
|
||||
_contextExpandLinksMode = mode;
|
||||
}
|
||||
|
||||
void FlatLabel::setBreakEverywhere(bool breakEverywhere) {
|
||||
_breakEverywhere = breakEverywhere;
|
||||
}
|
||||
|
||||
void FlatLabel::resizeToWidth(int32 width) {
|
||||
textstyleSet(&_tst);
|
||||
_allowedWidth = width;
|
||||
@ -465,6 +469,9 @@ void FlatLabel::onExecuteDrag() {
|
||||
mimeData->setText(selectedText);
|
||||
auto drag = new QDrag(App::wnd());
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
// We don't receive mouseReleaseEvent when drag is finished.
|
||||
ClickHandler::unpressed();
|
||||
drag->exec(Qt::CopyAction);
|
||||
}
|
||||
}
|
||||
@ -563,9 +570,15 @@ Text::StateResult FlatLabel::getTextState(const QPoint &m) const {
|
||||
|
||||
textstyleSet(&_tst);
|
||||
Text::StateResult state;
|
||||
if (_st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth())) {
|
||||
bool heightExceeded = _st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth());
|
||||
bool renderElided = _breakEverywhere || heightExceeded;
|
||||
if (renderElided) {
|
||||
auto lineHeight = qMax(_tst.lineHeight, _st.font->height);
|
||||
request.lines = qMax(_st.maxHeight / lineHeight, 1);
|
||||
auto lines = _st.maxHeight ? qMax(_st.maxHeight / lineHeight, 1) : ((height() / lineHeight) + 2);
|
||||
request.lines = lines;
|
||||
if (_breakEverywhere) {
|
||||
request.flags |= Text::StateRequest::Flag::BreakEverywhere;
|
||||
}
|
||||
state = _text.getStateElided(m.x() - _st.margin.left(), m.y() - _st.margin.top(), textWidth, request);
|
||||
} else {
|
||||
state = _text.getState(m.x() - _st.margin.left(), m.y() - _st.margin.top(), textWidth, request);
|
||||
@ -587,10 +600,12 @@ void FlatLabel::paintEvent(QPaintEvent *e) {
|
||||
textstyleSet(&_tst);
|
||||
int textWidth = width() - _st.margin.left() - _st.margin.right();
|
||||
auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
|
||||
if (_st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth())) {
|
||||
bool heightExceeded = _st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth());
|
||||
bool renderElided = _breakEverywhere || heightExceeded;
|
||||
if (renderElided) {
|
||||
auto lineHeight = qMax(_tst.lineHeight, _st.font->height);
|
||||
auto lines = qMax(_st.maxHeight / lineHeight, 1);
|
||||
_text.drawElided(p, _st.margin.left(), _st.margin.top(), textWidth, lines, _st.align, e->rect().y(), e->rect().bottom(), 0, false, selection);
|
||||
auto lines = _st.maxHeight ? qMax(_st.maxHeight / lineHeight, 1) : ((height() / lineHeight) + 2);
|
||||
_text.drawElided(p, _st.margin.left(), _st.margin.top(), textWidth, lines, _st.align, e->rect().y(), e->rect().bottom(), 0, _breakEverywhere, selection);
|
||||
} else {
|
||||
_text.draw(p, _st.margin.left(), _st.margin.top(), textWidth, _st.align, e->rect().y(), e->rect().bottom(), selection);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
void setDoubleClickSelectsParagraph(bool doubleClickSelectsParagraph);
|
||||
void setContextCopyText(const QString ©Text);
|
||||
void setExpandLinksMode(ExpandLinksMode mode);
|
||||
void setBreakEverywhere(bool breakEverywhere);
|
||||
|
||||
void resizeToWidth(int32 width);
|
||||
int naturalWidth() const;
|
||||
@ -106,6 +107,7 @@ private:
|
||||
|
||||
int _allowedWidth = 0;
|
||||
int _fullTextHeight = 0;
|
||||
bool _breakEverywhere = false;
|
||||
|
||||
style::cursor _cursor = style::cur_default;
|
||||
bool _selectable = false;
|
||||
|
Loading…
Reference in New Issue
Block a user