diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 214b19fff0..4763f84efd 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -2513,7 +2513,7 @@ bool DialogsInner::chooseRow() { if (IsServerMsgId(chosen.message.fullId.msg)) { Local::saveRecentSearchHashtags(_filter); } - const auto openSearchResult = !App::main()->selectingPeer(true) + const auto openSearchResult = !App::main()->selectingPeer() && (_state == State::Filtered) && base::in_range(_filteredSelected, 0, _filterResults.size()); if (const auto history = chosen.key.history()) { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 524c0fb32c..2ffeabd0f6 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -169,252 +169,6 @@ void ReportSpamPanel::setReported(bool reported, PeerData *onPeer) { update(); } -HistoryHider::HistoryHider( - MainWidget *parent, - MessageIdsList &&items) -: RpWidget(parent) -, _forwardItems(std::move(items)) -, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) -, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { - init(); -} - -HistoryHider::HistoryHider(MainWidget *parent) : RpWidget(parent) -, _sendPath(true) -, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) -, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { - init(); -} - -HistoryHider::HistoryHider(MainWidget *parent, const QString &botAndQuery) : RpWidget(parent) -, _botAndQuery(botAndQuery) -, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) -, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { - init(); -} - -HistoryHider::HistoryHider(MainWidget *parent, const QString &url, const QString &text) : RpWidget(parent) -, _shareUrl(url) -, _shareText(text) -, _send(this, langFactory(lng_forward_send), st::defaultBoxButton) -, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) { - init(); -} - -void HistoryHider::init() { - subscribe(Lang::Current().updated(), [this] { refreshLang(); }); - connect(_send, SIGNAL(clicked()), this, SLOT(forward())); - connect(_cancel, SIGNAL(clicked()), this, SLOT(startHide())); - subscribe(Global::RefPeerChooseCancel(), [this] { startHide(); }); - - _chooseWidth = st::historyForwardChooseFont->width(lang(_botAndQuery.isEmpty() ? lng_forward_choose : lng_inline_switch_choose)); - - resizeEvent(0); - _a_opacity.start([this] { update(); }, 0., 1., st::boxDuration); -} - -void HistoryHider::refreshLang() { - InvokeQueued(this, [this] { updateControlsGeometry(); }); -} - -bool HistoryHider::withConfirm() const { - return _sendPath; -} - -void HistoryHider::paintEvent(QPaintEvent *e) { - Painter p(this); - auto opacity = _a_opacity.current(getms(), _hiding ? 0. : 1.); - if (opacity == 0.) { - if (_hiding) { - QTimer::singleShot(0, this, SLOT(deleteLater())); - } - return; - } - - p.setOpacity(opacity); - if (!_hiding || !_cacheForAnim.isNull() || !_offered) { - p.fillRect(rect(), st::layerBg); - } - if (_cacheForAnim.isNull() || !_offered) { - p.setFont(st::historyForwardChooseFont); - if (_offered) { - Ui::Shadow::paint(p, _box, width(), st::boxRoundShadow); - App::roundRect(p, _box, st::boxBg, BoxCorners); - - p.setPen(st::boxTextFg); - _toText.drawLeftElided(p, _box.left() + st::boxPadding.left(), _box.y() + st::boxTopMargin + st::boxPadding.top(), _toTextWidth + 2, width(), 1, style::al_left); - } else { - auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right(); - auto h = st::historyForwardChooseMargins.top() + st::historyForwardChooseFont->height + st::historyForwardChooseMargins.bottom(); - App::roundRect(p, (width() - w) / 2, (height() - h) / 2, w, h, st::historyForwardChooseBg, ForwardCorners); - - p.setPen(st::historyForwardChooseFg); - p.drawText(_box, lang(_botAndQuery.isEmpty() ? lng_forward_choose : lng_inline_switch_choose), QTextOption(style::al_center)); - } - } else { - p.drawPixmap(_box.left(), _box.top(), _cacheForAnim); - } -} - -void HistoryHider::keyPressEvent(QKeyEvent *e) { - if (e->key() == Qt::Key_Escape) { - if (_offered) { - _offered = nullptr; - resizeEvent(nullptr); - update(); - App::main()->dialogsActivate(); - } else { - startHide(); - } - } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { - if (_offered) { - forward(); - } - } -} - -void HistoryHider::mousePressEvent(QMouseEvent *e) { - if (e->button() == Qt::LeftButton) { - if (!_box.contains(e->pos())) { - startHide(); - } - } -} - -void HistoryHider::startHide() { - if (_hiding) return; - _hiding = true; - if (Adaptive::OneColumn()) { - QTimer::singleShot(0, this, SLOT(deleteLater())); - } else { - if (_offered) _cacheForAnim = Ui::GrabWidget(this, _box); - if (_forwardRequest) MTP::cancel(_forwardRequest); - _send->hide(); - _cancel->hide(); - _a_opacity.start([this] { animationCallback(); }, 1., 0., st::boxDuration); - } -} - -void HistoryHider::animationCallback() { - update(); - if (!_a_opacity.animating() && _hiding) { - QTimer::singleShot(0, this, SLOT(deleteLater())); - } -} - -void HistoryHider::forward() { - if (!_hiding && _offered) { - if (_sendPath) { - parent()->onSendPaths(_offered->id); - } else if (!_shareUrl.isEmpty()) { - parent()->shareUrl(_offered, _shareUrl, _shareText); - } else if (!_botAndQuery.isEmpty()) { - parent()->onInlineSwitchChosen(_offered->id, _botAndQuery); - } else { - parent()->setForwardDraft(_offered->id, std::move(_forwardItems)); - } - } - emit forwarded(); -} - -void HistoryHider::forwardDone() { - _forwardRequest = 0; - startHide(); -} - -MainWidget *HistoryHider::parent() { - return static_cast(parentWidget()); -} - -void HistoryHider::resizeEvent(QResizeEvent *e) { - updateControlsGeometry(); -} - -void HistoryHider::updateControlsGeometry() { - auto w = st::boxWidth; - auto h = st::boxPadding.top() + st::boxPadding.bottom(); - if (_offered) { - if (!_hiding) { - _send->show(); - _cancel->show(); - } - h += st::boxTopMargin + qMax(st::boxTextFont->height, st::boxLabelStyle.lineHeight) + st::boxButtonPadding.top() + _send->height() + st::boxButtonPadding.bottom(); - } else { - h += st::historyForwardChooseFont->height; - _send->hide(); - _cancel->hide(); - } - _box = QRect((width() - w) / 2, (height() - h) / 2, w, h); - _send->moveToRight(width() - (_box.x() + _box.width()) + st::boxButtonPadding.right(), _box.y() + _box.height() - st::boxButtonPadding.bottom() - _send->height()); - _cancel->moveToRight(width() - (_box.x() + _box.width()) + st::boxButtonPadding.right() + _send->width() + st::boxButtonPadding.left(), _send->y()); -} - -bool HistoryHider::offerPeer(PeerId peer) { - if (!peer) { - _offered = nullptr; - _toText.setText(st::boxLabelStyle, QString()); - _toTextWidth = 0; - resizeEvent(nullptr); - return false; - } - _offered = App::peer(peer); - auto phrase = QString(); - auto recipient = _offered->isUser() ? _offered->name : '\xAB' + _offered->name + '\xBB'; - if (_sendPath) { - auto toId = _offered->id; - _offered = nullptr; - if (parent()->onSendPaths(toId)) { - startHide(); - } - return false; - } else if (!_shareUrl.isEmpty()) { - auto offered = base::take(_offered); - if (parent()->shareUrl(offered, _shareUrl, _shareText)) { - startHide(); - } - return false; - } else if (!_botAndQuery.isEmpty()) { - auto toId = _offered->id; - _offered = nullptr; - if (parent()->onInlineSwitchChosen(toId, _botAndQuery)) { - startHide(); - } - return false; - } else { - auto toId = _offered->id; - _offered = nullptr; - if (parent()->setForwardDraft(toId, std::move(_forwardItems))) { - startHide(); - } - return false; - } - - _toText.setText(st::boxLabelStyle, phrase, Ui::NameTextOptions()); - _toTextWidth = _toText.maxWidth(); - if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) { - _toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right(); - } - - resizeEvent(nullptr); - update(); - setFocus(); - - return true; -} - -QString HistoryHider::offeredText() const { - return _toText.originalText(); -} - -bool HistoryHider::wasOffered() const { - return _offered != nullptr; -} - -HistoryHider::~HistoryHider() { - if (_sendPath) cSetSendPaths(QStringList()); - parent()->noHider(this); -} - HistoryWidget::HistoryWidget( QWidget *parent, not_null controller) diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index ec498f9213..15edfd7b6e 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -110,74 +110,6 @@ private: }; -class HistoryHider : public Ui::RpWidget, private base::Subscriber { - Q_OBJECT - -public: - HistoryHider(MainWidget *parent, MessageIdsList &&items); // forward messages - HistoryHider(MainWidget *parent); // send path from command line argument - HistoryHider(MainWidget *parent, const QString &url, const QString &text); // share url - HistoryHider(MainWidget *parent, const QString &botAndQuery); // inline switch button handler - - bool withConfirm() const; - - bool offerPeer(PeerId peer); - QString offeredText() const; - QString botAndQuery() const { - return _botAndQuery; - } - - bool wasOffered() const; - - void forwardDone(); - - ~HistoryHider(); - -protected: - void paintEvent(QPaintEvent *e) override; - void keyPressEvent(QKeyEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void resizeEvent(QResizeEvent *e) override; - -public slots: - void startHide(); - void forward(); - -signals: - void forwarded(); - -private: - void refreshLang(); - void updateControlsGeometry(); - void animationCallback(); - void init(); - MainWidget *parent(); - - MessageIdsList _forwardItems; - bool _sendPath = false; - - QString _shareUrl, _shareText; - QString _botAndQuery; - - object_ptr _send; - object_ptr _cancel; - PeerData *_offered = nullptr; - - Animation _a_opacity; - - QRect _box; - bool _hiding = false; - - mtpRequestId _forwardRequest = 0; - - int _chooseWidth = 0; - - Text _toText; - int32 _toTextWidth = 0; - QPixmap _cacheForAnim; - -}; - class HistoryWidget final : public Window::AbstractSectionWidget, public RPCSender { Q_OBJECT diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index a94d0384d8..27abc7d182 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -75,6 +75,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_slide_animation.h" #include "window/window_controller.h" #include "window/themes/window_theme.h" +#include "window/window_history_hider.h" #include "mtproto/dc_options.h" #include "core/file_utilities.h" #include "core/update_checker.h" @@ -475,9 +476,12 @@ bool MainWidget::setForwardDraft(PeerId peerId, MessageIdsList &&items) { } bool MainWidget::shareUrl( - not_null peer, + PeerId peerId, const QString &url, const QString &text) { + Expects(peerId != 0); + + const auto peer = App::peer(peerId); if (!peer->canWrite()) { Ui::show(Box(lang(lng_share_cant))); return false; @@ -510,9 +514,11 @@ void MainWidget::replyToItem(not_null item) { } } -bool MainWidget::onInlineSwitchChosen(const PeerId &peer, const QString &botAndQuery) { - PeerData *p = App::peer(peer); - if (!peer || !p->canWrite()) { +bool MainWidget::inlineSwitchChosen(PeerId peerId, const QString &botAndQuery) { + Expects(peerId != 0); + + const auto peer = App::peer(peerId); + if (!peer->canWrite()) { Ui::show(Box(lang(lng_inline_switch_cant))); return false; } @@ -521,7 +527,7 @@ bool MainWidget::onInlineSwitchChosen(const PeerId &peer, const QString &botAndQ MessageCursor cursor = { botAndQuery.size(), botAndQuery.size(), QFIXED_MAX }; h->setLocalDraft(std::make_unique(textWithTags, 0, cursor, false)); h->clearEditDraft(); - bool opened = _history->peer() && (_history->peer()->id == peer); + const auto opened = _history->peer() && (_history->peer() == peer); if (opened) { _history->applyDraft(); } else { @@ -548,7 +554,7 @@ void MainWidget::finishForwarding(not_null history) { dialogsToUp(); } -bool MainWidget::onSendPaths(const PeerId &peerId) { +bool MainWidget::sendPaths(PeerId peerId) { Expects(peerId != 0); auto peer = App::peer(peerId); @@ -575,7 +581,7 @@ void MainWidget::onFilesOrForwardDrop( // We've already released the mouse button, so the forwarding is cancelled. if (_hider) { _hider->startHide(); - noHider(_hider); + clearHider(_hider); } } } else { @@ -621,45 +627,49 @@ void MainWidget::notify_historyMuteUpdated(History *history) { _dialogs->notify_historyMuteUpdated(history); } -void MainWidget::noHider(HistoryHider *destroyed) { - if (_hider == destroyed) { - _hider = nullptr; - if (Adaptive::OneColumn()) { - if (_forwardConfirm) { - _forwardConfirm->closeBox(); - _forwardConfirm = nullptr; - } - if (_mainSection || (_history->peer() && _history->peer()->id)) { - auto animationParams = ([this] { - if (_mainSection) { - return prepareMainSectionAnimation(_mainSection); - } - return prepareHistoryAnimation(_history->peer() ? _history->peer()->id : 0); - })(); - _dialogs->hide(); +void MainWidget::clearHider(not_null instance) { + if (_hider != instance) { + return; + } + _hider.release(); + if (Adaptive::OneColumn()) { + if (_mainSection || (_history->peer() && _history->peer()->id)) { + auto animationParams = ([=] { if (_mainSection) { - _mainSection->showAnimated(Window::SlideDirection::FromRight, animationParams); - } else { - _history->showAnimated(Window::SlideDirection::FromRight, animationParams); + return prepareMainSectionAnimation(_mainSection); } - floatPlayerCheckVisibility(); - } - } else { - if (_forwardConfirm) { - _forwardConfirm->deleteLater(); - _forwardConfirm = nullptr; + return prepareHistoryAnimation(_history->peer() ? _history->peer()->id : 0); + })(); + _dialogs->hide(); + if (_mainSection) { + _mainSection->showAnimated(Window::SlideDirection::FromRight, animationParams); + } else { + _history->showAnimated(Window::SlideDirection::FromRight, animationParams); } + floatPlayerCheckVisibility(); } } } -void MainWidget::hiderLayer(object_ptr h) { +void MainWidget::hiderLayer(base::unique_qptr hider) { if (Messenger::Instance().locked()) { return; } - _hider = std::move(h); - connect(_hider, SIGNAL(forwarded()), _dialogs, SLOT(onCancelSearch())); + _hider = std::move(hider); + _hider->setParent(this); + + _hider->hidden( + ) | rpl::start_with_next([=, instance = _hider.get()] { + clearHider(instance); + instance->deleteLater(); + }, _hider->lifetime()); + + _hider->confirmed( + ) | rpl::start_with_next([=] { + _dialogs->onCancelSearch(); + }, _hider->lifetime()); + if (Adaptive::OneColumn()) { dialogsToUp(); @@ -685,11 +695,25 @@ void MainWidget::hiderLayer(object_ptr h) { } void MainWidget::showForwardLayer(MessageIdsList &&items) { - hiderLayer(object_ptr(this, std::move(items))); + auto callback = [=, items = std::move(items)](PeerId peer) mutable { + return setForwardDraft(peer, std::move(items)); + }; + hiderLayer(base::make_unique_q( + this, + lang(lng_forward_choose), + std::move(callback))); } void MainWidget::showSendPathsLayer() { - hiderLayer(object_ptr(this)); + hiderLayer(base::make_unique_q( + this, + lang(lng_forward_choose), + [=](PeerId peer) { return sendPaths(peer); })); + if (_hider) { + connect(_hider, &QObject::destroyed, [] { + cSetSendPaths(QStringList()); + }); + } } void MainWidget::deleteLayer(FullMsgId itemId) { @@ -738,32 +762,27 @@ void MainWidget::shareUrlLayer(const QString &url, const QString &text) { if (url.trimmed().startsWith('@')) { return; } - hiderLayer(object_ptr(this, url, text)); + auto callback = [=](PeerId peer) { + return shareUrl(peer, url, text); + }; + hiderLayer(base::make_unique_q( + this, + lang(lng_forward_choose), + std::move(callback))); } void MainWidget::inlineSwitchLayer(const QString &botAndQuery) { - hiderLayer(object_ptr(this, botAndQuery)); + auto callback = [=](PeerId peer) { + return inlineSwitchChosen(peer, botAndQuery); + }; + hiderLayer(base::make_unique_q( + this, + lang(lng_inline_switch_choose), + std::move(callback))); } -bool MainWidget::selectingPeer(bool withConfirm) const { - return _hider ? (withConfirm ? _hider->withConfirm() : true) : false; -} - -bool MainWidget::selectingPeerForInlineSwitch() { - return selectingPeer() ? !_hider->botAndQuery().isEmpty() : false; -} - -void MainWidget::offerPeer(PeerId peer) { - Ui::hideLayer(); - if (_hider->offerPeer(peer) && Adaptive::OneColumn()) { - _forwardConfirm = Ui::show(Box(_hider->offeredText(), lang(lng_forward_send), crl::guard(this, [this] { - _hider->forward(); - if (_forwardConfirm) _forwardConfirm->closeBox(); - if (_hider) _hider->offerPeer(0); - }), crl::guard(this, [this] { - if (_hider && _forwardConfirm) _hider->offerPeer(0); - }))); - } +bool MainWidget::selectingPeer() const { + return _hider ? true : false; } void MainWidget::dialogsActivate() { @@ -1453,7 +1472,7 @@ bool MainWidget::onSendSticker(DocumentData *document) { void MainWidget::dialogsCancelled() { if (_hider) { _hider->startHide(); - noHider(_hider); + clearHider(_hider); } _history->activate(); } @@ -1538,9 +1557,7 @@ void MainWidget::pushReplyReturn(not_null item) { void MainWidget::setInnerFocus() { if (_hider || !_history->peer()) { - if (_hider && _hider->wasOffered()) { - _hider->setFocus(); - } else if (!_hider && _mainSection) { + if (!_hider && _mainSection) { _mainSection->setInnerFocus(); } else if (!_hider && _thirdSection) { _thirdSection->setInnerFocus(); @@ -1634,7 +1651,7 @@ void MainWidget::createDialog(Dialogs::Key key) { void MainWidget::choosePeer(PeerId peerId, MsgId showAtMsgId) { if (selectingPeer()) { - offerPeer(peerId); + _hider->offerPeer(peerId); } else { Ui::showPeerHistory(peerId, showAtMsgId); } @@ -1711,7 +1728,7 @@ void MainWidget::ui_showPeerHistory( } if (_hider) { _hider->startHide(); - _hider = nullptr; + _hider.release(); } auto animatedShow = [&] { @@ -2415,15 +2432,6 @@ void MainWidget::showAll() { _sideShadow->hide(); if (_hider) { _hider->hide(); - if (!_forwardConfirm && _hider->wasOffered()) { - _forwardConfirm = Ui::show(Box(_hider->offeredText(), lang(lng_forward_send), crl::guard(this, [this] { - _hider->forward(); - if (_forwardConfirm) _forwardConfirm->closeBox(); - if (_hider) _hider->offerPeer(0); - }), crl::guard(this, [this] { - if (_hider && _forwardConfirm) _hider->offerPeer(0); - })), LayerOption::CloseOther, anim::type::instant); - } } if (selectingPeer()) { _dialogs->showFast(); @@ -2449,13 +2457,6 @@ void MainWidget::showAll() { _sideShadow->show(); if (_hider) { _hider->show(); - if (_forwardConfirm) { - _forwardConfirm = nullptr; - Ui::hideLayer(anim::type::instant); - if (_hider->wasOffered()) { - _hider->setFocus(); - } - } } _dialogs->showFast(); if (_mainSection) { @@ -3598,11 +3599,7 @@ void MainWidget::activate() { if (_a_show.animating()) return; if (!_mainSection) { if (_hider) { - if (_hider->wasOffered()) { - _hider->setFocus(); - } else { - _dialogs->activate(); - } + _dialogs->activate(); } else if (App::wnd() && !Ui::isLayerShown()) { if (!cSendPaths().isEmpty()) { showSendPathsLayer(); @@ -3651,10 +3648,6 @@ int32 MainWidget::dlgsWidth() const { MainWidget::~MainWidget() { if (App::main() == this) _history->showHistory(0, 0); - if (HistoryHider *hider = _hider) { - _hider = nullptr; - delete hider; - } Messenger::Instance().mtp()->clearGlobalHandlers(); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 6df0923c64..8ca27c4d64 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -17,7 +17,6 @@ class MainWindow; class ConfirmBox; class DialogsWidget; class HistoryWidget; -class HistoryHider; class StackItem; struct FileLoadResult; @@ -67,6 +66,7 @@ class ConnectingWidget; struct SectionSlideParams; struct SectionShow; enum class Column; +class HistoryHider; } // namespace Window namespace Calls { @@ -174,20 +174,17 @@ public: void cancelUploadLayer(not_null item); void shareUrlLayer(const QString &url, const QString &text); void inlineSwitchLayer(const QString &botAndQuery); - void hiderLayer(object_ptr h); - void noHider(HistoryHider *destroyed); + void hiderLayer(base::unique_qptr h); bool setForwardDraft(PeerId peer, MessageIdsList &&items); bool shareUrl( - not_null peer, + PeerId peerId, const QString &url, const QString &text); void replyToItem(not_null item); - bool onInlineSwitchChosen(const PeerId &peer, const QString &botAndQuery); - bool onSendPaths(const PeerId &peer); + bool inlineSwitchChosen(PeerId peerId, const QString &botAndQuery); + bool sendPaths(PeerId peerId); void onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data); - bool selectingPeer(bool withConfirm = false) const; - bool selectingPeerForInlineSwitch(); - void offerPeer(PeerId peer); + bool selectingPeer() const; void dialogsActivate(); void deletePhotoLayer(PhotoData *photo); @@ -203,7 +200,6 @@ public: not_null peer, bool deleteHistory = true); void deleteAndExit(ChatData *chat); - void deleteAllFromUser(ChannelData *channel, UserData *from); void addParticipants( not_null chatOrChannel, @@ -441,6 +437,7 @@ private: void hideAll(); void showAll(); + void clearHider(not_null instance); void clearCachedBackground(); @@ -505,8 +502,7 @@ private: object_ptr _playerPanel; bool _playerUsingPanel = false; - QPointer _forwardConfirm; // for single column layout - object_ptr _hider = { nullptr }; + base::unique_qptr _hider; std::vector> _stack; int _playerHeight = 0; diff --git a/Telegram/SourceFiles/window/window_history_hider.cpp b/Telegram/SourceFiles/window/window_history_hider.cpp new file mode 100644 index 0000000000..9ef0be42b6 --- /dev/null +++ b/Telegram/SourceFiles/window/window_history_hider.cpp @@ -0,0 +1,124 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "window/window_history_hider.h" + +#include "lang/lang_keys.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/shadow.h" +#include "mainwidget.h" +#include "styles/style_boxes.h" +#include "styles/style_history.h" + +namespace Window { + +HistoryHider::HistoryHider( + QWidget *parent, + const QString &text, + Fn confirm) +: RpWidget(parent) +, _text(text) +, _confirm(std::move(confirm)) { + subscribe(Lang::Current().updated(), [=] { refreshLang(); }); + subscribe(Global::RefPeerChooseCancel(), [=] { startHide(); }); + + _chooseWidth = st::historyForwardChooseFont->width(_text); + + resizeEvent(0); + _a_opacity.start([this] { update(); }, 0., 1., st::boxDuration); +} + +void HistoryHider::refreshLang() { + InvokeQueued(this, [this] { updateControlsGeometry(); }); +} + +void HistoryHider::paintEvent(QPaintEvent *e) { + Painter p(this); + auto opacity = _a_opacity.current(getms(), _hiding ? 0. : 1.); + if (opacity == 0.) { + if (_hiding) { + _hidden.fire({}); + } + return; + } + + p.setOpacity(opacity); + p.fillRect(rect(), st::layerBg); + p.setFont(st::historyForwardChooseFont); + auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right(); + auto h = st::historyForwardChooseMargins.top() + st::historyForwardChooseFont->height + st::historyForwardChooseMargins.bottom(); + App::roundRect(p, (width() - w) / 2, (height() - h) / 2, w, h, st::historyForwardChooseBg, ForwardCorners); + + p.setPen(st::historyForwardChooseFg); + p.drawText(_box, _text, QTextOption(style::al_center)); +} + +void HistoryHider::keyPressEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_Escape) { + startHide(); + } +} + +void HistoryHider::mousePressEvent(QMouseEvent *e) { + if (e->button() == Qt::LeftButton) { + if (!_box.contains(e->pos())) { + startHide(); + } + } +} + +void HistoryHider::startHide() { + if (_hiding) return; + + _hiding = true; + if (Adaptive::OneColumn()) { + crl::on_main(this, [=] { _hidden.fire({}); }); + } else { + _a_opacity.start([=] { animationCallback(); }, 1., 0., st::boxDuration); + } +} + +void HistoryHider::animationCallback() { + update(); + if (!_a_opacity.animating() && _hiding) { + crl::on_main(this, [=] { _hidden.fire({}); }); + } +} + +void HistoryHider::confirm() { + _confirmed.fire({}); +} + +rpl::producer<> HistoryHider::confirmed() const { + return _confirmed.events(); +} + +rpl::producer<> HistoryHider::hidden() const { + return _hidden.events(); +} + +void HistoryHider::resizeEvent(QResizeEvent *e) { + updateControlsGeometry(); +} + +void HistoryHider::updateControlsGeometry() { + auto w = st::boxWidth; + auto h = st::boxPadding.top() + st::boxPadding.bottom(); + h += st::historyForwardChooseFont->height; + _box = QRect((width() - w) / 2, (height() - h) / 2, w, h); +} + +void HistoryHider::offerPeer(PeerId peer) { + if (_confirm(peer)) { + startHide(); + } +} + +HistoryHider::~HistoryHider() { +} + +} // namespace Window diff --git a/Telegram/SourceFiles/window/window_history_hider.h b/Telegram/SourceFiles/window/window_history_hider.h new file mode 100644 index 0000000000..9e843905b3 --- /dev/null +++ b/Telegram/SourceFiles/window/window_history_hider.h @@ -0,0 +1,71 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "ui/rp_widget.h" + +namespace Ui { +class RoundButton; +} // namespace Ui + +namespace Window { + +class HistoryHider : public Ui::RpWidget, private base::Subscriber { +public: + // Forward messages (via drag-n-drop) + HistoryHider(QWidget *parent, MessageIdsList &&items); + + // Send path from command line argument. + HistoryHider(QWidget *parent); + + // Share url. + HistoryHider(QWidget *parent, const QString &url, const QString &text); + + // Inline switch button handler. + HistoryHider(QWidget *parent, const QString &botAndQuery); + + HistoryHider( + QWidget *parent, + const QString &text, + Fn confirm); + + void offerPeer(PeerId peer); + + void startHide(); + void confirm(); + rpl::producer<> confirmed() const; + rpl::producer<> hidden() const; + + ~HistoryHider(); + +protected: + void paintEvent(QPaintEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + +private: + void refreshLang(); + void updateControlsGeometry(); + void animationCallback(); + + QString _text; + Fn _confirm; + Animation _a_opacity; + + QRect _box; + bool _hiding = false; + + int _chooseWidth = 0; + + rpl::event_stream<> _confirmed; + rpl::event_stream<> _hidden; + +}; + +} // namespace Window diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index 3f8fe05b73..03c8a1335d 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -720,6 +720,8 @@ <(src_loc)/window/window_connecting_widget.h <(src_loc)/window/window_controller.cpp <(src_loc)/window/window_controller.h +<(src_loc)/window/window_history_hider.cpp +<(src_loc)/window/window_history_hider.h <(src_loc)/window/window_lock_widgets.cpp <(src_loc)/window/window_lock_widgets.h <(src_loc)/window/window_main_menu.cpp