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:
John Preston 2016-06-01 19:40:51 +03:00
parent 66a8aa86e1
commit 15d6a1aacf
9 changed files with 137 additions and 10 deletions

View File

@ -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.";

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -133,3 +133,7 @@ profileBlockOneLineTextPart: flatLabel(profileBlockTextPart) {
}
profileBlockOneLineSkip: 9px;
profileBlockOneLineWidthMax: 240px;
profileInviteLinkText: flatLabel(profileBlockTextPart) {
width: 1px; // Required for BreakEverywhere
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -41,6 +41,7 @@ public:
void setDoubleClickSelectsParagraph(bool doubleClickSelectsParagraph);
void setContextCopyText(const QString &copyText);
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;