Use separate TopBar for History and Overview.

Move TopBar widget to History and Overview from MainWidget.
This commit is contained in:
John Preston 2017-03-27 15:24:38 +03:00
parent cdca00368f
commit 8d4be19952
14 changed files with 309 additions and 315 deletions

View File

@ -47,6 +47,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "auth_session.h" #include "auth_session.h"
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "ui/effects/widget_fade_wrap.h" #include "ui/effects/widget_fade_wrap.h"
#include "window/window_controller.h"
namespace { namespace {
@ -2265,7 +2266,8 @@ void DialogsWidget::UpdateButton::paintEvent(QPaintEvent *e) {
} }
} }
DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent) DialogsWidget::DialogsWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller) : TWidget(parent)
, _controller(controller)
, _mainMenuToggle(this, st::dialogsMenuToggle) , _mainMenuToggle(this, st::dialogsMenuToggle)
, _filter(this, st::dialogsFilter, lang(lng_dlg_filter)) , _filter(this, st::dialogsFilter, lang(lng_dlg_filter))
, _jumpToDate(this, object_ptr<Ui::IconButton>(this, st::dialogsCalendar)) , _jumpToDate(this, object_ptr<Ui::IconButton>(this, st::dialogsCalendar))
@ -2984,7 +2986,7 @@ void DialogsWidget::setSearchInPeer(PeerData *peer) {
_searchInMigrated = newSearchInPeer ? newSearchInPeer->migrateFrom() : nullptr; _searchInMigrated = newSearchInPeer ? newSearchInPeer->migrateFrom() : nullptr;
if (newSearchInPeer != _searchInPeer) { if (newSearchInPeer != _searchInPeer) {
_searchInPeer = newSearchInPeer; _searchInPeer = newSearchInPeer;
App::main()->searchInPeerChanged().notify(_searchInPeer, true); _controller->searchInPeerChanged().notify(_searchInPeer, true);
updateJumpToDateVisibility(); updateJumpToDateVisibility();
} }
_inner->searchInPeer(_searchInPeer); _inner->searchInPeer(_searchInPeer);

View File

@ -41,6 +41,10 @@ template <typename Widget>
class WidgetScaledFadeWrap; class WidgetScaledFadeWrap;
} // namespace Ui } // namespace Ui
namespace Window {
class Controller;
} // namespace Window
enum DialogsSearchRequestType { enum DialogsSearchRequestType {
DialogsSearchFromStart, DialogsSearchFromStart,
DialogsSearchFromOffset, DialogsSearchFromOffset,
@ -303,7 +307,7 @@ class DialogsWidget : public TWidget, public RPCSender, private base::Subscriber
Q_OBJECT Q_OBJECT
public: public:
DialogsWidget(QWidget *parent); DialogsWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
void updateDragInScroll(bool inScroll); void updateDragInScroll(bool inScroll);
@ -402,16 +406,18 @@ private:
void updateControlsGeometry(); void updateControlsGeometry();
void updateForwardBar(); void updateForwardBar();
bool _dragInScroll = false;
bool _dragForward = false;
QTimer _chooseByDragTimer;
void unreadCountsReceived(const QVector<MTPDialog> &dialogs); void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
bool dialogsFailed(const RPCError &error, mtpRequestId req); bool dialogsFailed(const RPCError &error, mtpRequestId req);
bool contactsFailed(const RPCError &error); bool contactsFailed(const RPCError &error);
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req); bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
bool peopleFailed(const RPCError &error, mtpRequestId req); bool peopleFailed(const RPCError &error, mtpRequestId req);
gsl::not_null<Window::Controller*> _controller;
bool _dragInScroll = false;
bool _dragForward = false;
QTimer _chooseByDragTimer;
bool _dialogsFull = false; bool _dialogsFull = false;
int32 _dialogsOffsetDate = 0; int32 _dialogsOffsetDate = 0;
MsgId _dialogsOffsetId = 0; MsgId _dialogsOffsetId = 0;

View File

@ -62,6 +62,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "platform/platform_file_utilities.h" #include "platform/platform_file_utilities.h"
#include "auth_session.h" #include "auth_session.h"
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "window/window_controller.h"
namespace { namespace {
@ -3191,8 +3192,10 @@ TextWithTags::Tags textTagsFromEntities(const EntitiesInText &entities) {
return result; return result;
} }
HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) HistoryWidget::HistoryWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller) : TWidget(parent)
, _controller(controller)
, _fieldBarCancel(this, st::historyReplyCancel) , _fieldBarCancel(this, st::historyReplyCancel)
, _topBar(this, _controller)
, _scroll(this, st::historyScroll, false) , _scroll(this, st::historyScroll, false)
, _historyDown(_scroll, st::historyToDown) , _historyDown(_scroll, st::historyToDown)
, _fieldAutocomplete(this) , _fieldAutocomplete(this)
@ -3220,6 +3223,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
setAcceptDrops(true); setAcceptDrops(true);
subscribe(AuthSession::CurrentDownloaderTaskFinished(), [this] { update(); }); subscribe(AuthSession::CurrentDownloaderTaskFinished(), [this] { update(); });
connect(_topBar, &Window::TopBarWidget::clicked, this, [this] { topBarClick(); });
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
connect(_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked())); connect(_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked()));
connect(_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide())); connect(_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide()));
@ -3280,6 +3284,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
_fieldBarCancel->hide(); _fieldBarCancel->hide();
_topBar->hide();
_scroll->hide(); _scroll->hide();
_keyboard = _kbScroll->setOwnedWidget(object_ptr<BotKeyboard>(this)); _keyboard = _kbScroll->setOwnedWidget(object_ptr<BotKeyboard>(this));
@ -4341,7 +4346,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId); App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId);
emit historyShown(_history, _showAtMsgId); emit historyShown(_history, _showAtMsgId);
App::main()->topBar()->update(); _topBar->update();
update(); update();
if (startBot && _peer->isUser() && _peer->asUser()->botInfo) { if (startBot && _peer->isUser() && _peer->asUser()->botInfo) {
@ -4423,7 +4428,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
noSelectingScroll(); noSelectingScroll();
_selCount = 0; _selCount = 0;
App::main()->topBar()->showSelected(0); _topBar->showSelected(0);
App::hoveredItem(nullptr); App::hoveredItem(nullptr);
App::pressedItem(nullptr); App::pressedItem(nullptr);
@ -4505,7 +4510,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId); App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId);
emit historyShown(_history, _showAtMsgId); emit historyShown(_history, _showAtMsgId);
App::main()->historyPeerChanged().notify(_peer, true); _controller->historyPeerChanged().notify(_peer, true);
update(); update();
} }
@ -4663,7 +4668,8 @@ bool HistoryWidget::canWriteMessage() const {
void HistoryWidget::updateControlsVisibility() { void HistoryWidget::updateControlsVisibility() {
if (!_a_show.animating()) { if (!_a_show.animating()) {
_topShadow->setVisible(_peer ? true : false); _topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
} }
updateHistoryDownVisibility(); updateHistoryDownVisibility();
if (!_history || _a_show.animating()) { if (!_history || _a_show.animating()) {
@ -5584,12 +5590,13 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
_cacheUnder = params.oldContentCache; _cacheUnder = params.oldContentCache;
show(); show();
_topShadow->setVisible(params.withTopBarShadow ? false : true); _topBar->showAll();
historyDownAnimationFinish(); historyDownAnimationFinish();
_topShadow->setVisible(params.withTopBarShadow ? false : true);
_cacheOver = App::main()->grabForShowAnimation(params); _cacheOver = App::main()->grabForShowAnimation(params);
App::main()->topBar()->startAnim();
_topShadow->setVisible(params.withTopBarShadow ? true : false); _topShadow->setVisible(params.withTopBarShadow ? true : false);
_topBar->hide();
_scroll->hide(); _scroll->hide();
_kbScroll->hide(); _kbScroll->hide();
_reportSpamPanel->hide(); _reportSpamPanel->hide();
@ -5617,26 +5624,30 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
std::swap(_cacheUnder, _cacheOver); std::swap(_cacheUnder, _cacheOver);
} }
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition()); _a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
if (_history) {
App::main()->topBar()->update(); _backAnimationButton.create(this);
_backAnimationButton->setClickedCallback([this] { topBarClick(); });
_backAnimationButton->setGeometry(_topBar->geometry());
_backAnimationButton->show();
}
activate(); activate();
} }
void HistoryWidget::animationCallback() { void HistoryWidget::animationCallback() {
update(); update();
App::main()->topBar()->update();
if (!_a_show.animating()) { if (!_a_show.animating()) {
_topShadow->setVisible(_peer ? true : false); _topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
historyDownAnimationFinish(); historyDownAnimationFinish();
_cacheUnder = _cacheOver = QPixmap(); _cacheUnder = _cacheOver = QPixmap();
App::main()->topBar()->stopAnim();
doneShow(); doneShow();
} }
} }
void HistoryWidget::doneShow() { void HistoryWidget::doneShow() {
_topBar->animationFinished();
_backAnimationButton.destroy();
updateReportSpamStatus(); updateReportSpamStatus();
updateBotKeyboard(); updateBotKeyboard();
updateControlsVisibility(); updateControlsVisibility();
@ -5655,7 +5666,8 @@ void HistoryWidget::doneShow() {
void HistoryWidget::finishAnimation() { void HistoryWidget::finishAnimation() {
if (!_a_show.animating()) return; if (!_a_show.animating()) return;
_a_show.finish(); _a_show.finish();
_topShadow->setVisible(_peer ? true : false); _topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
historyDownAnimationFinish(); historyDownAnimationFinish();
} }
@ -5751,7 +5763,7 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
void HistoryWidget::updateOverStates(QPoint pos) { void HistoryWidget::updateOverStates(QPoint pos) {
auto inField = pos.y() >= (_scroll->y() + _scroll->height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width(); auto inField = pos.y() >= (_scroll->y() + _scroll->height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
auto inReplyEdit = QRect(st::historyReplySkip, _field->y() - st::historySendPadding - st::historyReplyHeight, width() - st::historyReplySkip - _fieldBarCancel->width(), st::historyReplyHeight).contains(pos) && (_editMsgId || replyToId()); auto inReplyEdit = QRect(st::historyReplySkip, _field->y() - st::historySendPadding - st::historyReplyHeight, width() - st::historyReplySkip - _fieldBarCancel->width(), st::historyReplyHeight).contains(pos) && (_editMsgId || replyToId());
auto inPinnedMsg = QRect(0, 0, width(), st::historyReplyHeight).contains(pos) && _pinnedBar; auto inPinnedMsg = QRect(0, _topBar->bottomNoMargins(), width(), st::historyReplyHeight).contains(pos) && _pinnedBar;
auto inClickable = inReplyEdit || inPinnedMsg; auto inClickable = inReplyEdit || inPinnedMsg;
if (inField != _inField && _recording) { if (inField != _inField && _recording) {
_inField = inField; _inField = inField;
@ -6318,25 +6330,6 @@ void HistoryWidget::selectMessage() {
} }
bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) { bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
if (_a_show.animating()) {
auto progress = _a_show.current(1.);
auto retina = cIntRetinaFactor();
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = fromLeft ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, st::topBarHeight), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, st::topBarHeight * retina));
p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, st::topBarHeight, st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, st::topBarHeight), _cacheOver, QRect(0, 0, _cacheOver.width(), st::topBarHeight * retina));
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), st::topBarHeight));
return false;
}
if (!_history) return false; if (!_history) return false;
auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0; auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0;
@ -6466,8 +6459,8 @@ void HistoryWidget::updateOnlineDisplay() {
_titlePeerTextOnline = titlePeerTextOnline; _titlePeerTextOnline = titlePeerTextOnline;
_titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText); _titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
if (App::main()) { if (App::main()) {
App::main()->topBar()->updateMembersShowArea(); _topBar->updateMembersShowArea();
App::main()->topBar()->update(); _topBar->update();
} }
} }
updateOnlineDisplayTimer(); updateOnlineDisplayTimer();
@ -7182,21 +7175,20 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
} }
void HistoryWidget::updateControlsGeometry() { void HistoryWidget::updateControlsGeometry() {
_topBar->setGeometryToLeft(0, 0, width(), st::topBarHeight);
_reportSpamPanel->resize(width(), _reportSpamPanel->height()); _reportSpamPanel->resize(width(), _reportSpamPanel->height());
moveFieldControls(); moveFieldControls();
auto scrollAreaTop = _topBar->bottomNoMargins();
if (_pinnedBar) { if (_pinnedBar) {
if (_scroll->y() != st::historyReplyHeight) { _pinnedBar->cancel->move(width() - _pinnedBar->cancel->width(), scrollAreaTop);
_scroll->move(0, st::historyReplyHeight); scrollAreaTop += st::historyReplyHeight;
_reportSpamPanel->move(0, st::historyReplyHeight); _pinnedBar->shadow->setGeometry(0, scrollAreaTop, width(), st::lineWidth);
_fieldAutocomplete->setBoundings(_scroll->geometry()); }
} if (_scroll->y() != scrollAreaTop) {
_pinnedBar->cancel->move(width() - _pinnedBar->cancel->width(), 0); _scroll->move(0, scrollAreaTop);
_pinnedBar->shadow->setGeometry(0, st::historyReplyHeight, width(), st::lineWidth); _reportSpamPanel->move(0, scrollAreaTop);
} else if (_scroll->y() != 0) {
_scroll->move(0, 0);
_reportSpamPanel->move(0, 0);
_fieldAutocomplete->setBoundings(_scroll->geometry()); _fieldAutocomplete->setBoundings(_scroll->geometry());
} }
@ -7230,7 +7222,7 @@ void HistoryWidget::updateControlsGeometry() {
} }
_topShadow->resize(width() - ((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0), st::lineWidth); _topShadow->resize(width() - ((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
_topShadow->moveToLeft((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0, 0); _topShadow->moveToLeft((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0, _topBar->bottomNoMargins());
} }
void HistoryWidget::itemRemoved(HistoryItem *item) { void HistoryWidget::itemRemoved(HistoryItem *item) {
@ -7276,7 +7268,7 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
return; // scrollTopMax etc are not working after recountHeight() return; // scrollTopMax etc are not working after recountHeight()
} }
int newScrollHeight = height(); int newScrollHeight = height() - _topBar->height();
if (isBlocked() || isBotStart() || isJoinChannel() || isMuteUnmute()) { if (isBlocked() || isBotStart() || isJoinChannel() || isMuteUnmute()) {
newScrollHeight -= _unblock->height(); newScrollHeight -= _unblock->height();
} else { } else {
@ -8597,14 +8589,14 @@ void HistoryWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
void HistoryWidget::updateTopBarSelection() { void HistoryWidget::updateTopBarSelection() {
if (!_list) { if (!_list) {
App::main()->topBar()->showSelected(0); _topBar->showSelected(0);
return; return;
} }
int32 selectedForForward, selectedForDelete; int32 selectedForForward, selectedForDelete;
_list->getSelectionState(selectedForForward, selectedForDelete); _list->getSelectionState(selectedForForward, selectedForDelete);
_selCount = selectedForForward ? selectedForForward : selectedForDelete; _selCount = selectedForForward ? selectedForForward : selectedForDelete;
App::main()->topBar()->showSelected(_selCount > 0 ? _selCount : 0, (selectedForDelete == selectedForForward)); _topBar->showSelected(_selCount > 0 ? _selCount : 0, (selectedForDelete == selectedForForward));
updateControlsVisibility(); updateControlsVisibility();
updateListSize(); updateListSize();
if (!Ui::isLayerShown() && !App::passcoded()) { if (!Ui::isLayerShown() && !App::passcoded()) {
@ -8614,7 +8606,7 @@ void HistoryWidget::updateTopBarSelection() {
_field->setFocus(); _field->setFocus();
} }
} }
App::main()->topBar()->update(); _topBar->update();
update(); update();
} }
@ -8843,14 +8835,16 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
} }
void HistoryWidget::drawPinnedBar(Painter &p) { void HistoryWidget::drawPinnedBar(Painter &p) {
t_assert(_pinnedBar != nullptr); Expects(_pinnedBar != nullptr);
auto top = _topBar->bottomNoMargins();
Text *from = 0, *text = 0; Text *from = 0, *text = 0;
bool serviceColor = false, hasForward = readyToForward(); bool serviceColor = false, hasForward = readyToForward();
ImagePtr preview; ImagePtr preview;
p.fillRect(0, 0, width(), st::historyReplyHeight, st::historyPinnedBg); p.fillRect(0, top, width(), st::historyReplyHeight, st::historyPinnedBg);
QRect rbar(rtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), width())); top += st::msgReplyPadding.top();
QRect rbar(rtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), width()));
p.fillRect(rbar, st::msgInReplyBarColor); p.fillRect(rbar, st::msgInReplyBarColor);
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip; int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
@ -8858,21 +8852,21 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
if (_pinnedBar->msg->getMedia() && _pinnedBar->msg->getMedia()->hasReplyPreview()) { if (_pinnedBar->msg->getMedia() && _pinnedBar->msg->getMedia()->hasReplyPreview()) {
ImagePtr replyPreview = _pinnedBar->msg->getMedia()->replyPreview(); ImagePtr replyPreview = _pinnedBar->msg->getMedia()->replyPreview();
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
QRect to(left, st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
} }
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
p.setPen(st::historyReplyNameFg); p.setPen(st::historyReplyNameFg);
p.setFont(st::msgServiceNameFont); p.setFont(st::msgServiceNameFont);
p.drawText(left, st::msgReplyPadding.top() + st::msgServiceNameFont->ascent, lang(lng_pinned_message)); p.drawText(left, top + st::msgServiceNameFont->ascent, lang(lng_pinned_message));
p.setPen(((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg); p.setPen(((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
_pinnedBar->text.drawElided(p, left, st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()); _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
} else { } else {
p.setFont(st::msgDateFont); p.setFont(st::msgDateFont);
p.setPen(st::historyComposeAreaFgService); p.setPen(st::historyComposeAreaFgService);
p.drawText(left, st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right())); p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()));
} }
} }
@ -8889,32 +8883,31 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
if (r != rect()) { if (r != rect()) {
p.setClipRect(r); p.setClipRect(r);
} }
bool hasTopBar = !App::main()->topBar()->isHidden();
auto ms = getms(); auto ms = getms();
_historyDownShown.step(ms); _historyDownShown.step(ms);
auto progress = _a_show.current(ms, 1.); auto progress = _a_show.current(ms, 1.);
if (_a_show.animating()) { if (_a_show.animating()) {
auto retina = cIntRetinaFactor(); auto retina = cIntRetinaFactor();
auto inCacheTop = hasTopBar ? st::topBarHeight : 0;
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft); auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress); auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress); auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = fromLeft ? (1. - progress) : progress; auto shadow = fromLeft ? (1. - progress) : progress;
if (coordOver > 0) { if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, inCacheTop * retina, coordOver * retina, height() * retina)); p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, height() * retina));
p.setOpacity(shadow); p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg); p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
p.setOpacity(1); p.setOpacity(1);
} }
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, inCacheTop * retina, _cacheOver.width(), height() * retina)); p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, 0, _cacheOver.width(), height() * retina));
p.setOpacity(shadow); p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height())); st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
return; return;
} }
QRect fill(0, 0, width(), App::main()->height()); QRect fill(0, 0, width(), App::main()->height());
int fromy = App::main()->backgroundFromY(), x = 0, y = 0; auto fromy = App::main()->backgroundFromY();
auto x = 0, y = 0;
QPixmap cached = App::main()->cachedBackground(fill, x, y); QPixmap cached = App::main()->cachedBackground(fill, x, y);
if (cached.isNull()) { if (cached.isNull()) {
if (Window::Theme::Background()->tile()) { if (Window::Theme::Background()->tile()) {

View File

@ -37,6 +37,7 @@ class Result;
} // namespace InlineBots } // namespace InlineBots
namespace Ui { namespace Ui {
class AbstractButton;
class InnerDropdown; class InnerDropdown;
class DropdownMenu; class DropdownMenu;
class PlainShadow; class PlainShadow;
@ -50,6 +51,11 @@ class LinkButton;
class RoundButton; class RoundButton;
} // namespace Ui } // namespace Ui
namespace Window {
class Controller;
class TopBarWidget;
} // namespace Window
class DragArea; class DragArea;
class EmojiPan; class EmojiPan;
class SilentToggle; class SilentToggle;
@ -534,7 +540,7 @@ class HistoryWidget : public TWidget, public RPCSender, private base::Subscriber
Q_OBJECT Q_OBJECT
public: public:
HistoryWidget(QWidget *parent); HistoryWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
void start(); void start();
@ -554,7 +560,6 @@ public:
bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms); bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms);
QRect getMembersShowAreaGeometry() const; QRect getMembersShowAreaGeometry() const;
void setMembersShowAreaActive(bool active); void setMembersShowAreaActive(bool active);
void topBarClick();
void loadMessages(); void loadMessages();
void loadMessagesDown(); void loadMessagesDown();
@ -843,6 +848,8 @@ private slots:
void updateField(); void updateField();
private: private:
void topBarClick();
void animationCallback(); void animationCallback();
void updateOverStates(QPoint pos); void updateOverStates(QPoint pos);
void recordStartCallback(); void recordStartCallback();
@ -895,6 +902,8 @@ private:
void hideSelectorControlsAnimated(); void hideSelectorControlsAnimated();
int countMembersDropdownHeightMax() const; int countMembersDropdownHeightMax() const;
gsl::not_null<Window::Controller*> _controller;
MsgId _replyToId = 0; MsgId _replyToId = 0;
Text _replyToName; Text _replyToName;
int _replyToNameVersion = 0; int _replyToNameVersion = 0;
@ -1075,6 +1084,8 @@ private:
MsgId _activeAnimMsgId = 0; MsgId _activeAnimMsgId = 0;
object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
object_ptr<Window::TopBarWidget> _topBar;
object_ptr<Ui::ScrollArea> _scroll; object_ptr<Ui::ScrollArea> _scroll;
QPointer<HistoryInner> _list; QPointer<HistoryInner> _list;
History *_migrated = nullptr; History *_migrated = nullptr;

View File

@ -65,6 +65,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/calendarbox.h" #include "boxes/calendarbox.h"
#include "auth_session.h" #include "auth_session.h"
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "window/window_controller.h"
StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr) StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr)
, _memento(std::move(memento)) { , _memento(std::move(memento)) {
@ -73,16 +74,15 @@ StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&mem
StackItemSection::~StackItemSection() { StackItemSection::~StackItemSection() {
} }
MainWidget::MainWidget(QWidget *parent) : TWidget(parent) MainWidget::MainWidget(QWidget *parent, std::unique_ptr<Window::Controller> controller) : TWidget(parent)
, _controller(std::move(controller))
, _dialogsWidth(st::dialogsWidthMin) , _dialogsWidth(st::dialogsWidthMin)
, _sideShadow(this, st::shadowFg) , _sideShadow(this, st::shadowFg)
, _sideResizeArea(this) , _sideResizeArea(this)
, _dialogs(this) , _dialogs(this, _controller.get())
, _history(this) , _history(this, _controller.get())
, _topBar(this)
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist) , _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
, _playerPanel(this, Media::Player::Panel::Layout::Full) , _playerPanel(this, Media::Player::Panel::Layout::Full)
, _mediaType(this, st::defaultDropdownMenu)
, _api(new ApiWrap(this)) { , _api(new ApiWrap(this)) {
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived)); Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail)); Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
@ -104,7 +104,6 @@ MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeAfterFail())); connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeAfterFail()));
connect(_api.get(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*))); connect(_api.get(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
connect(this, SIGNAL(peerUpdated(PeerData*)), _history, SLOT(peerUpdated(PeerData*))); connect(this, SIGNAL(peerUpdated(PeerData*)), _history, SLOT(peerUpdated(PeerData*)));
connect(_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
connect(_history, SIGNAL(historyShown(History*,MsgId)), this, SLOT(onHistoryShown(History*,MsgId))); connect(_history, SIGNAL(historyShown(History*,MsgId)), this, SLOT(onHistoryShown(History*,MsgId)));
connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings())); connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings()));
subscribe(Media::Player::Updated(), [this](const AudioMsgId &audioId) { subscribe(Media::Player::Updated(), [this](const AudioMsgId &audioId) {
@ -174,13 +173,9 @@ MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
} else { } else {
_history->show(); _history->show();
} }
_topBar->hide();
orderWidgets(); orderWidgets();
_mediaType->hide();
_mediaType->setOrigin(Ui::PanelAnimation::Origin::TopRight);
_topBar->mediaTypeButton()->installEventFilter(_mediaType);
_sideResizeArea->installEventFilter(this); _sideResizeArea->installEventFilter(this);
_api->init(); _api->init();
@ -1407,37 +1402,6 @@ void MainWidget::mediaOverviewUpdated(const Notify::PeerUpdate &update) {
auto peer = update.peer; auto peer = update.peer;
if (_overview && (_overview->peer() == peer || _overview->peer()->migrateFrom() == peer)) { if (_overview && (_overview->peer() == peer || _overview->peer()->migrateFrom() == peer)) {
_overview->mediaOverviewUpdated(update); _overview->mediaOverviewUpdated(update);
int32 mask = 0;
History *h = peer ? App::historyLoaded((peer->migrateTo() ? peer->migrateTo() : peer)->id) : 0;
History *m = (peer && peer->migrateFrom()) ? App::historyLoaded(peer->migrateFrom()->id) : 0;
if (h) {
for (int32 i = 0; i < OverviewCount; ++i) {
if (!h->overview[i].isEmpty() || h->overviewCount(i) > 0 || i == _overview->type()) {
mask |= (1 << i);
} else if (m && (!m->overview[i].isEmpty() || m->overviewCount(i) > 0)) {
mask |= (1 << i);
}
}
}
if (mask != _mediaTypeMask) {
_mediaType->clearActions();
for (int32 i = 0; i < OverviewCount; ++i) {
if (mask & (1 << i)) {
switch (i) {
case OverviewPhotos: _mediaType->addAction(lang(lng_media_type_photos), this, SLOT(onPhotosSelect())); break;
case OverviewVideos: _mediaType->addAction(lang(lng_media_type_videos), this, SLOT(onVideosSelect())); break;
case OverviewMusicFiles: _mediaType->addAction(lang(lng_media_type_songs), this, SLOT(onSongsSelect())); break;
case OverviewFiles: _mediaType->addAction(lang(lng_media_type_files), this, SLOT(onDocumentsSelect())); break;
case OverviewVoiceFiles: _mediaType->addAction(lang(lng_media_type_audios), this, SLOT(onAudiosSelect())); break;
case OverviewLinks: _mediaType->addAction(lang(lng_media_type_links), this, SLOT(onLinksSelect())); break;
}
}
}
_mediaTypeMask = mask;
_mediaType->move(width() - _mediaType->width(), st::topBarHeight);
_overview->updateTopBarSelection();
}
} }
} }
@ -2298,7 +2262,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
} }
} }
if (onlyDialogs) { if (onlyDialogs) {
_topBar->hide();
_history->hide(); _history->hide();
if (!_a_show.animating()) { if (!_a_show.animating()) {
if (animationParams) { if (animationParams) {
@ -2310,7 +2273,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
} }
} else { } else {
if (noPeer) { if (noPeer) {
_topBar->hide();
updateControlsGeometry(); updateControlsGeometry();
} else if (wasActivePeer != activePeer()) { } else if (wasActivePeer != activePeer()) {
if (activePeer()->isChannel()) { if (activePeer()->isChannel()) {
@ -2340,7 +2302,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
} }
_dialogs->update(); _dialogs->update();
} }
topBar()->showAll();
} }
PeerData *MainWidget::ui_getPeerForMouseAction() { PeerData *MainWidget::ui_getPeerForMouseAction() {
@ -2385,15 +2346,8 @@ PeerData *MainWidget::overviewPeer() {
return _overview ? _overview->peer() : 0; return _overview ? _overview->peer() : 0;
} }
bool MainWidget::mediaTypeSwitch() { bool MainWidget::showMediaTypeSwitch() const {
if (!_overview) return false; return _overview ? _overview->showMediaTypeSwitch() : false;
for (int32 i = 0; i < OverviewCount; ++i) {
if (!(_mediaTypeMask & ~(1 << i))) {
return false;
}
}
return true;
} }
void MainWidget::saveSectionInStack() { void MainWidget::saveSectionInStack() {
@ -2452,9 +2406,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
_wideSection->deleteLater(); _wideSection->deleteLater();
_wideSection = nullptr; _wideSection = nullptr;
} }
_overview.create(this, peer, type); _overview.create(this, _controller.get(), peer, type);
_mediaTypeMask = 0;
_topBar->show();
updateControlsGeometry(); updateControlsGeometry();
// Send a fake update. // Send a fake update.
@ -2609,7 +2561,6 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool
_wideSection = nullptr; _wideSection = nullptr;
} }
_wideSection = std::move(newWideSection); _wideSection = std::move(newWideSection);
_topBar->hide();
updateControlsGeometry(); updateControlsGeometry();
_history->finishAnimation(); _history->finishAnimation();
_history->showHistory(0, 0); _history->showHistory(0, 0);
@ -2672,7 +2623,6 @@ void MainWidget::showBackFromStack() {
} }
void MainWidget::orderWidgets() { void MainWidget::orderWidgets() {
_topBar->raise();
_dialogs->raise(); _dialogs->raise();
if (_player) { if (_player) {
_player->raise(); _player->raise();
@ -2680,7 +2630,6 @@ void MainWidget::orderWidgets() {
if (_playerVolume) { if (_playerVolume) {
_playerVolume->raise(); _playerVolume->raise();
} }
_mediaType->raise();
_sideShadow->raise(); _sideShadow->raise();
_sideResizeArea->raise(); _sideResizeArea->raise();
_playerPlaylist->raise(); _playerPlaylist->raise();
@ -2696,7 +2645,6 @@ QRect MainWidget::historyRect() const {
} }
QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &params) { QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &params) {
_topBar->stopAnim();
QPixmap result; QPixmap result;
if (_player) { if (_player) {
_player->hideShadow(); _player->hideShadow();
@ -2954,8 +2902,6 @@ void MainWidget::hideAll() {
_overview->hide(); _overview->hide();
} }
_sideShadow->hide(); _sideShadow->hide();
_topBar->hide();
_mediaType->hide();
if (_player) { if (_player) {
_player->hide(); _player->hide();
_playerHeight = 0; _playerHeight = 0;
@ -2986,7 +2932,6 @@ void MainWidget::showAll() {
_history->hide(); _history->hide();
if (_overview) _overview->hide(); if (_overview) _overview->hide();
if (_wideSection) _wideSection->hide(); if (_wideSection) _wideSection->hide();
_topBar->hide();
} else if (_overview) { } else if (_overview) {
_overview->show(); _overview->show();
} else if (_wideSection) { } else if (_wideSection) {
@ -3000,10 +2945,8 @@ void MainWidget::showAll() {
} }
if (!selectingPeer()) { if (!selectingPeer()) {
if (_wideSection) { if (_wideSection) {
_topBar->hide();
_dialogs->hide(); _dialogs->hide();
} else if (isSectionShown()) { } else if (isSectionShown()) {
_topBar->show();
_dialogs->hide(); _dialogs->hide();
} }
} }
@ -3028,11 +2971,6 @@ void MainWidget::showAll() {
_history->show(); _history->show();
_history->updateControlsGeometry(); _history->updateControlsGeometry();
} }
if (_wideSection) {
_topBar->hide();
} else if (isSectionShown()) {
_topBar->show();
}
} }
if (_player) { if (_player) {
_player->show(); _player->show();
@ -3049,7 +2987,6 @@ void MainWidget::resizeEvent(QResizeEvent *e) {
void MainWidget::updateControlsGeometry() { void MainWidget::updateControlsGeometry() {
updateWindowAdaptiveLayout(); updateWindowAdaptiveLayout();
auto topBarHeight = _topBar->isHidden() ? 0 : st::topBarHeight;
if (!Adaptive::SmallColumn()) { if (!Adaptive::SmallColumn()) {
_a_dialogsWidth.finish(); _a_dialogsWidth.finish();
} }
@ -3063,8 +3000,7 @@ void MainWidget::updateControlsGeometry() {
_player->moveToLeft(0, 0); _player->moveToLeft(0, 0);
} }
_dialogs->setGeometry(0, _playerHeight, dialogsWidth, height() - _playerHeight); _dialogs->setGeometry(0, _playerHeight, dialogsWidth, height() - _playerHeight);
_topBar->setGeometry(0, _playerHeight, dialogsWidth, st::topBarHeight); _history->setGeometry(0, _playerHeight, dialogsWidth, height() - _playerHeight);
_history->setGeometry(0, _playerHeight + topBarHeight, dialogsWidth, height() - _playerHeight - topBarHeight);
if (_hider) _hider->setGeometry(0, 0, dialogsWidth, height()); if (_hider) _hider->setGeometry(0, 0, dialogsWidth, height());
} else { } else {
accumulate_min(dialogsWidth, width() - st::windowMinWidth); accumulate_min(dialogsWidth, width() - st::windowMinWidth);
@ -3076,8 +3012,7 @@ void MainWidget::updateControlsGeometry() {
_player->resizeToWidth(sectionWidth); _player->resizeToWidth(sectionWidth);
_player->moveToLeft(dialogsWidth, 0); _player->moveToLeft(dialogsWidth, 0);
} }
_topBar->setGeometryToLeft(dialogsWidth, _playerHeight, sectionWidth, st::topBarHeight); _history->setGeometryToLeft(dialogsWidth, _playerHeight, sectionWidth, height() - _playerHeight);
_history->setGeometryToLeft(dialogsWidth, _playerHeight + topBarHeight, sectionWidth, height() - _playerHeight - topBarHeight);
if (_hider) { if (_hider) {
_hider->setGeometryToLeft(dialogsWidth, 0, sectionWidth, height()); _hider->setGeometryToLeft(dialogsWidth, 0, sectionWidth, height());
} }
@ -3093,9 +3028,8 @@ void MainWidget::updateControlsGeometry() {
return true; return true;
}; };
_sideResizeArea->setVisible(isSideResizeAreaVisible()); _sideResizeArea->setVisible(isSideResizeAreaVisible());
_mediaType->moveToLeft(width() - _mediaType->width(), _playerHeight + st::topBarHeight);
if (_wideSection) { if (_wideSection) {
QRect wideSectionGeometry(_history->x(), _playerHeight, _history->width(), height() - _playerHeight); auto wideSectionGeometry = QRect(_history->x(), _playerHeight, _history->width(), height() - _playerHeight);
_wideSection->setGeometryWithTopMoved(wideSectionGeometry, _contentScrollAddToY); _wideSection->setGeometryWithTopMoved(wideSectionGeometry, _contentScrollAddToY);
} }
if (_overview) _overview->setGeometry(_history->geometry()); if (_overview) _overview->setGeometry(_history->geometry());
@ -3273,63 +3207,12 @@ void MainWidget::setMembersShowAreaActive(bool active) {
} }
} }
void MainWidget::onPhotosSelect() {
if (_overview) _overview->switchType(OverviewPhotos);
_mediaType->hideAnimated();
}
void MainWidget::onVideosSelect() {
if (_overview) _overview->switchType(OverviewVideos);
_mediaType->hideAnimated();
}
void MainWidget::onSongsSelect() {
if (_overview) _overview->switchType(OverviewMusicFiles);
_mediaType->hideAnimated();
}
void MainWidget::onDocumentsSelect() {
if (_overview) _overview->switchType(OverviewFiles);
_mediaType->hideAnimated();
}
void MainWidget::onAudiosSelect() {
if (_overview) _overview->switchType(OverviewVoiceFiles);
_mediaType->hideAnimated();
}
void MainWidget::onLinksSelect() {
if (_overview) _overview->switchType(OverviewLinks);
_mediaType->hideAnimated();
}
Window::TopBarWidget *MainWidget::topBar() {
return _topBar;
}
int MainWidget::backgroundFromY() const { int MainWidget::backgroundFromY() const {
return (_topBar->isHidden() ? 0 : (-st::topBarHeight)) - _playerHeight; return -_playerHeight;
}
void MainWidget::onTopBarClick() {
if (_overview) {
_overview->topBarClick();
} else if (!_wideSection) {
_history->topBarClick();
}
} }
void MainWidget::onHistoryShown(History *history, MsgId atMsgId) { void MainWidget::onHistoryShown(History *history, MsgId atMsgId) {
if ((!Adaptive::OneColumn() || !selectingPeer()) && (_overview || history)) {
_topBar->show();
} else {
_topBar->hide();
}
updateControlsGeometry(); updateControlsGeometry();
if (_a_show.animating()) {
_topBar->hide();
}
dlgUpdated(history ? history->peer : nullptr, atMsgId); dlgUpdated(history ? history->peer : nullptr, atMsgId);
} }
@ -3988,11 +3871,11 @@ void MainWidget::onSelfParticipantUpdated(ChannelData *channel) {
} }
bool MainWidget::contentOverlapped(const QRect &globalRect) { bool MainWidget::contentOverlapped(const QRect &globalRect) {
return (_history->contentOverlapped(globalRect) || return (_history->contentOverlapped(globalRect)
_playerPanel->overlaps(globalRect) || || (_overview && _overview->contentOverlapped(globalRect))
_playerPlaylist->overlaps(globalRect) || || _playerPanel->overlaps(globalRect)
(_playerVolume && _playerVolume->overlaps(globalRect)) || || _playerPlaylist->overlaps(globalRect)
_mediaType->overlaps(globalRect)); || (_playerVolume && _playerVolume->overlaps(globalRect)));
} }
void MainWidget::usernameResolveDone(QPair<MsgId, QString> msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result) { void MainWidget::usernameResolveDone(QPair<MsgId, QString> msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result) {

View File

@ -46,6 +46,7 @@ class DropdownMenu;
} // namespace Ui } // namespace Ui
namespace Window { namespace Window {
class Controller;
class PlayerWrapWidget; class PlayerWrapWidget;
class TopBarWidget; class TopBarWidget;
class SectionMemento; class SectionMemento;
@ -142,7 +143,7 @@ class MainWidget : public TWidget, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
MainWidget(QWidget *parent); MainWidget(QWidget *parent, std::unique_ptr<Window::Controller> controller);
bool needBackButton(); bool needBackButton();
@ -150,8 +151,6 @@ public:
bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms); bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms);
QRect getMembersShowAreaGeometry() const; QRect getMembersShowAreaGeometry() const;
void setMembersShowAreaActive(bool active); void setMembersShowAreaActive(bool active);
Window::TopBarWidget *topBar();
int backgroundFromY() const;
int contentScrollAddToY() const; int contentScrollAddToY() const;
@ -204,8 +203,9 @@ public:
PeerData *activePeer(); PeerData *activePeer();
MsgId activeMsgId(); MsgId activeMsgId();
int backgroundFromY() const;
PeerData *overviewPeer(); PeerData *overviewPeer();
bool mediaTypeSwitch(); bool showMediaTypeSwitch() const;
void showWideSection(const Window::SectionMemento &memento); void showWideSection(const Window::SectionMemento &memento);
void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1); void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1);
bool stackIsEmpty() const; bool stackIsEmpty() const;
@ -374,13 +374,6 @@ public:
bool contentOverlapped(const QRect &globalRect); bool contentOverlapped(const QRect &globalRect);
base::Observable<PeerData*> &searchInPeerChanged() {
return _searchInPeerChanged;
}
base::Observable<PeerData*> &historyPeerChanged() {
return _historyPeerChanged;
}
void rpcClear() override; void rpcClear() override;
bool isItemVisible(HistoryItem *item); bool isItemVisible(HistoryItem *item);
@ -444,20 +437,12 @@ public slots:
void checkIdleFinish(); void checkIdleFinish();
void updateOnlineDisplay(); void updateOnlineDisplay();
void onTopBarClick();
void onHistoryShown(History *history, MsgId atMsgId); void onHistoryShown(History *history, MsgId atMsgId);
void searchInPeer(PeerData *peer); void searchInPeer(PeerData *peer);
void onUpdateNotifySettings(); void onUpdateNotifySettings();
void onPhotosSelect();
void onVideosSelect();
void onSongsSelect();
void onDocumentsSelect();
void onAudiosSelect();
void onLinksSelect();
void onCacheBackground(); void onCacheBackground();
void onInviteImport(); void onInviteImport();
@ -522,6 +507,7 @@ private:
void saveSectionInStack(); void saveSectionInStack();
std::unique_ptr<Window::Controller> _controller;
bool _started = false; bool _started = false;
SelectedItemSet _toForward; SelectedItemSet _toForward;
@ -584,9 +570,6 @@ private:
void clearCachedBackground(); void clearCachedBackground();
base::Observable<PeerData*> _searchInPeerChanged;
base::Observable<PeerData*> _historyPeerChanged;
Animation _a_show; Animation _a_show;
bool _showBack = false; bool _showBack = false;
QPixmap _cacheUnder, _cacheOver; QPixmap _cacheUnder, _cacheOver;
@ -600,7 +583,6 @@ private:
object_ptr<HistoryWidget> _history; object_ptr<HistoryWidget> _history;
object_ptr<Window::SectionWidget> _wideSection = { nullptr }; object_ptr<Window::SectionWidget> _wideSection = { nullptr };
object_ptr<OverviewWidget> _overview = { nullptr }; object_ptr<OverviewWidget> _overview = { nullptr };
object_ptr<Window::TopBarWidget> _topBar;
object_ptr<Window::PlayerWrapWidget> _player = { nullptr }; object_ptr<Window::PlayerWrapWidget> _player = { nullptr };
object_ptr<Media::Player::VolumeWidget> _playerVolume = { nullptr }; object_ptr<Media::Player::VolumeWidget> _playerVolume = { nullptr };
@ -617,9 +599,6 @@ private:
int _playerHeight = 0; int _playerHeight = 0;
int _contentScrollAddToY = 0; int _contentScrollAddToY = 0;
object_ptr<Ui::DropdownMenu> _mediaType;
int32 _mediaTypeMask = 0;
int32 updDate = 0; int32 updDate = 0;
int32 updQts = -1; int32 updQts = -1;
int32 updSeq = 0; int32 updSeq = 0;

View File

@ -52,6 +52,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "window/window_main_menu.h" #include "window/window_main_menu.h"
#include "core/task_queue.h" #include "core/task_queue.h"
#include "auth_session.h" #include "auth_session.h"
#include "window/window_controller.h"
ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : TWidget(parent) ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : TWidget(parent)
, _reconnect(this, QString()) { , _reconnect(this, QString()) {
@ -350,7 +351,7 @@ void MainWindow::setupMain(const MTPUser *self) {
t_assert(AuthSession::Exists()); t_assert(AuthSession::Exists());
_main.create(bodyWidget()); _main.create(bodyWidget(), std::make_unique<Window::Controller>(this));
_main->show(); _main->show();
updateControlsGeometry(); updateControlsGeometry();

View File

@ -44,6 +44,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "observer_peer.h" #include "observer_peer.h"
#include "auth_session.h" #include "auth_session.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "ui/widgets/dropdown_menu.h"
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html // flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
@ -1895,13 +1896,23 @@ OverviewInner::~OverviewInner() {
clear(); clear();
} }
OverviewWidget::OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type) : TWidget(parent) OverviewWidget::OverviewWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller, PeerData *peer, MediaOverviewType type) : TWidget(parent)
, _controller(controller)
, _topBar(this, _controller)
, _scroll(this, st::settingsScroll, false) , _scroll(this, st::settingsScroll, false)
, _mediaType(this, st::defaultDropdownMenu)
, _topShadow(this, st::shadowFg) { , _topShadow(this, st::shadowFg) {
_inner = _scroll->setOwnedWidget(object_ptr<OverviewInner>(this, _scroll, peer, type)); _inner = _scroll->setOwnedWidget(object_ptr<OverviewInner>(this, _scroll, peer, type));
_scroll->move(0, 0); _scroll->move(0, 0);
_inner->move(0, 0); _inner->move(0, 0);
connect(_topBar, &Window::TopBarWidget::clicked, this, [this] { topBarClick(); });
_mediaType->hide();
_mediaType->setOrigin(Ui::PanelAnimation::Origin::TopRight);
_topBar->mediaTypeButton()->installEventFilter(_mediaType);
_topBar->show();
_scroll->show(); _scroll->show();
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
@ -1934,11 +1945,14 @@ void OverviewWidget::onScroll() {
} }
void OverviewWidget::resizeEvent(QResizeEvent *e) { void OverviewWidget::resizeEvent(QResizeEvent *e) {
_topBar->setGeometryToLeft(0, 0, width(), st::topBarHeight);
auto scrollAreaTop = _topBar->bottomNoMargins();
_noDropResizeIndex = true; _noDropResizeIndex = true;
int32 st = _scroll->scrollTop(); auto st = _scroll->scrollTop();
_scroll->resize(size()); _scroll->setGeometryToLeft(0, scrollAreaTop, width(), height() - scrollAreaTop);
int32 newScrollTop = _inner->resizeToWidth(width(), st, height()); auto newScrollTop = _inner->resizeToWidth(width(), st, height() - _topBar->height());
if (int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0) { if (auto addToY = App::main() ? App::main()->contentScrollAddToY() : 0) {
newScrollTop += addToY; newScrollTop += addToY;
} }
if (newScrollTop != _scroll->scrollTop()) { if (newScrollTop != _scroll->scrollTop()) {
@ -1947,7 +1961,9 @@ void OverviewWidget::resizeEvent(QResizeEvent *e) {
_noDropResizeIndex = false; _noDropResizeIndex = false;
_topShadow->resize(width() - ((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0), st::lineWidth); _topShadow->resize(width() - ((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
_topShadow->moveToLeft((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0, 0); _topShadow->moveToLeft((!Adaptive::OneColumn() && !_inGrab) ? st::lineWidth : 0, _topBar->bottomNoMargins());
_mediaType->moveToRight(0, scrollAreaTop);
} }
void OverviewWidget::paintEvent(QPaintEvent *e) { void OverviewWidget::paintEvent(QPaintEvent *e) {
@ -1957,18 +1973,17 @@ void OverviewWidget::paintEvent(QPaintEvent *e) {
auto progress = _a_show.current(getms(), 1.); auto progress = _a_show.current(getms(), 1.);
if (_a_show.animating()) { if (_a_show.animating()) {
auto retina = cIntRetinaFactor(); auto retina = cIntRetinaFactor();
auto inCacheTop = st::topBarHeight;
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft); auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress); auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress); auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = fromLeft ? (1. - progress) : progress; auto shadow = fromLeft ? (1. - progress) : progress;
if (coordOver > 0) { if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, inCacheTop * retina, coordOver * retina, height() * retina)); p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, height() * retina));
p.setOpacity(shadow); p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg); p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
p.setOpacity(1); p.setOpacity(1);
} }
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, inCacheTop * retina, _cacheOver.width(), height() * retina)); p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, 0, _cacheOver.width(), height() * retina));
p.setOpacity(shadow); p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height())); st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
return; return;
@ -1994,24 +2009,6 @@ void OverviewWidget::scrollReset() {
} }
bool OverviewWidget::paintTopBar(Painter &p, int decreaseWidth) { bool OverviewWidget::paintTopBar(Painter &p, int decreaseWidth) {
if (_a_show.animating()) {
auto progress = _a_show.current(1.);
auto retina = cIntRetinaFactor();
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = fromLeft ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, st::topBarHeight), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, st::topBarHeight * retina));
p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, st::topBarHeight, st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, st::topBarHeight), _cacheOver, QRect(0, 0, _cacheOver.width(), st::topBarHeight * retina));
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), st::topBarHeight));
return false;
}
st::topBarBack.paint(p, (st::topBarArrowPadding.left() - st::topBarBack.width()) / 2, (st::topBarHeight - st::topBarBack.height()) / 2, width()); st::topBarBack.paint(p, (st::topBarArrowPadding.left() - st::topBarBack.width()) / 2, (st::topBarHeight - st::topBarBack.height()) / 2, width());
p.setFont(st::defaultLightButton.font); p.setFont(st::defaultLightButton.font);
p.setPen(st::defaultLightButton.textFg); p.setPen(st::defaultLightButton.textFg);
@ -2053,7 +2050,7 @@ void OverviewWidget::switchType(MediaOverviewType type) {
_header = _header.toUpper(); _header = _header.toUpper();
noSelectingScroll(); noSelectingScroll();
App::main()->topBar()->showSelected(0); _topBar->showSelected(0);
updateTopBarSelection(); updateTopBarSelection();
scrollReset(); scrollReset();
@ -2063,14 +2060,27 @@ void OverviewWidget::switchType(MediaOverviewType type) {
activate(); activate();
} }
bool OverviewWidget::showMediaTypeSwitch() const {
for (int32 i = 0; i < OverviewCount; ++i) {
if (!(_mediaTypeMask & ~(1 << i))) {
return false;
}
}
return true;
}
bool OverviewWidget::contentOverlapped(const QRect &globalRect) {
return _mediaType->overlaps(globalRect);
}
void OverviewWidget::updateTopBarSelection() { void OverviewWidget::updateTopBarSelection() {
int32 selectedForForward, selectedForDelete; int32 selectedForForward, selectedForDelete;
_inner->getSelectionState(selectedForForward, selectedForDelete); _inner->getSelectionState(selectedForForward, selectedForDelete);
_selCount = selectedForForward ? selectedForForward : selectedForDelete; _selCount = selectedForForward ? selectedForForward : selectedForDelete;
_inner->setSelectMode(_selCount > 0); _inner->setSelectMode(_selCount > 0);
if (App::main()) { if (App::main()) {
App::main()->topBar()->showSelected(_selCount > 0 ? _selCount : 0, (selectedForDelete == selectedForForward)); _topBar->showSelected(_selCount > 0 ? _selCount : 0, (selectedForDelete == selectedForForward));
App::main()->topBar()->update(); _topBar->update();
} }
if (App::wnd() && !Ui::isLayerShown()) { if (App::wnd() && !Ui::isLayerShown()) {
_inner->activate(); _inner->activate();
@ -2122,11 +2132,12 @@ void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window
_cacheUnder = params.oldContentCache; _cacheUnder = params.oldContentCache;
show(); show();
_topBar->showAll();
_topShadow->setVisible(params.withTopBarShadow ? false : true); _topShadow->setVisible(params.withTopBarShadow ? false : true);
_cacheOver = App::main()->grabForShowAnimation(params); _cacheOver = App::main()->grabForShowAnimation(params);
_topShadow->setVisible(params.withTopBarShadow ? true : false); _topShadow->setVisible(params.withTopBarShadow ? true : false);
App::main()->topBar()->startAnim();
_topBar->hide();
_scrollSetAfterShow = _scroll->scrollTop(); _scrollSetAfterShow = _scroll->scrollTop();
_scroll->hide(); _scroll->hide();
@ -2135,25 +2146,27 @@ void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window
} }
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition()); _a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
App::main()->topBar()->update(); _backAnimationButton.create(this);
_backAnimationButton->setClickedCallback([this] { topBarClick(); });
_backAnimationButton->setGeometry(_topBar->geometry());
_backAnimationButton->show();
activate(); activate();
} }
void OverviewWidget::animationCallback() { void OverviewWidget::animationCallback() {
update(); update();
App::main()->topBar()->update();
if (!_a_show.animating()) { if (!_a_show.animating()) {
_topShadow->show(); _topShadow->show();
_cacheUnder = _cacheOver = QPixmap(); _cacheUnder = _cacheOver = QPixmap();
App::main()->topBar()->stopAnim();
doneShow(); doneShow();
} }
} }
void OverviewWidget::doneShow() { void OverviewWidget::doneShow() {
_topBar->animationFinished();
_backAnimationButton.destroy();
_topBar->show();
_scroll->show(); _scroll->show();
_scroll->scrollToY(_scrollSetAfterShow); _scroll->scrollToY(_scrollSetAfterShow);
activate(); activate();
@ -2166,6 +2179,47 @@ void OverviewWidget::mediaOverviewUpdated(const Notify::PeerUpdate &update) {
onScroll(); onScroll();
updateTopBarSelection(); updateTopBarSelection();
} }
int32 mask = 0;
History *h = update.peer ? App::historyLoaded(update.peer->migrateTo() ? update.peer->migrateTo() : update.peer) : nullptr;
History *m = (update.peer && update.peer->migrateFrom()) ? App::historyLoaded(update.peer->migrateFrom()->id) : 0;
if (h) {
for (int32 i = 0; i < OverviewCount; ++i) {
if (!h->overview[i].isEmpty() || h->overviewCount(i) > 0 || i == type()) {
mask |= (1 << i);
} else if (m && (!m->overview[i].isEmpty() || m->overviewCount(i) > 0)) {
mask |= (1 << i);
}
}
}
if (mask != _mediaTypeMask) {
auto typeLabel = [](MediaOverviewType type) -> QString {
switch (type) {
case OverviewPhotos: return lang(lng_media_type_photos);
case OverviewVideos: return lang(lng_media_type_videos);
case OverviewMusicFiles: return lang(lng_media_type_songs);
case OverviewFiles: return lang(lng_media_type_files);
case OverviewVoiceFiles: return lang(lng_media_type_audios);
case OverviewLinks: return lang(lng_media_type_links);
}
return QString();
};
_mediaType->clearActions();
for (auto i = 0; i != OverviewCount; ++i) {
if (mask & (1 << i)) {
auto type = static_cast<MediaOverviewType>(i);
auto label = typeLabel(type);
if (!label.isEmpty()) {
_mediaType->addAction(label, [this, type] {
switchType(type);
_mediaType->hideAnimated();
});
}
}
}
_mediaTypeMask = mask;
_mediaType->move(width() - _mediaType->width(), st::topBarHeight);
updateTopBarSelection();
}
} }
void OverviewWidget::changingMsgId(HistoryItem *row, MsgId newId) { void OverviewWidget::changingMsgId(HistoryItem *row, MsgId newId) {

View File

@ -33,17 +33,24 @@ class Date;
} // namespace Overview } // namespace Overview
namespace Ui { namespace Ui {
class AbstractButton;
class PlainShadow; class PlainShadow;
class PopupMenu; class PopupMenu;
class IconButton; class IconButton;
class FlatInput; class FlatInput;
class CrossButton; class CrossButton;
class DropdownMenu;
} // namespace Ui } // namespace Ui
namespace Notify { namespace Notify {
struct PeerUpdate; struct PeerUpdate;
} // namespace Notify } // namespace Notify
namespace Window {
class Controller;
class TopBarWidget;
} // namespace Window
class OverviewWidget; class OverviewWidget;
class OverviewInner : public TWidget, public Ui::AbstractTooltipShower, public RPCSender, private base::Subscriber { class OverviewInner : public TWidget, public Ui::AbstractTooltipShower, public RPCSender, private base::Subscriber {
Q_OBJECT Q_OBJECT
@ -280,7 +287,7 @@ class OverviewWidget : public TWidget, public RPCSender {
Q_OBJECT Q_OBJECT
public: public:
OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type); OverviewWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller, PeerData *peer, MediaOverviewType type);
void clear(); void clear();
@ -288,13 +295,14 @@ public:
void scrollReset(); void scrollReset();
bool paintTopBar(Painter &p, int decreaseWidth); bool paintTopBar(Painter &p, int decreaseWidth);
void topBarClick();
PeerData *peer() const; PeerData *peer() const;
PeerData *migratePeer() const; PeerData *migratePeer() const;
MediaOverviewType type() const; MediaOverviewType type() const;
void switchType(MediaOverviewType type); void switchType(MediaOverviewType type);
bool showMediaTypeSwitch() const;
void updateTopBarSelection(); void updateTopBarSelection();
bool contentOverlapped(const QRect &globalRect);
int32 lastWidth() const; int32 lastWidth() const;
int32 lastScrollTop() const; int32 lastScrollTop() const;
@ -361,12 +369,20 @@ public slots:
void onClearSelected(); void onClearSelected();
private: private:
void topBarClick();
void animationCallback(); void animationCallback();
gsl::not_null<Window::Controller*> _controller;
object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
object_ptr<Window::TopBarWidget> _topBar;
object_ptr<Ui::ScrollArea> _scroll; object_ptr<Ui::ScrollArea> _scroll;
QPointer<OverviewInner> _inner; QPointer<OverviewInner> _inner;
bool _noDropResizeIndex = false; bool _noDropResizeIndex = false;
object_ptr<Ui::DropdownMenu> _mediaType;
int32 _mediaTypeMask = 0;
QString _header; QString _header;
Animation _a_show; Animation _a_show;

View File

@ -31,10 +31,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/dropdown_menu.h" #include "ui/widgets/dropdown_menu.h"
#include "dialogs/dialogs_layout.h" #include "dialogs/dialogs_layout.h"
#include "window/window_controller.h"
namespace Window { namespace Window {
TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w) TopBarWidget::TopBarWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller) : TWidget(parent)
, _controller(controller)
, _clearSelection(this, lang(lng_selected_clear), st::topBarClearButton) , _clearSelection(this, lang(lng_selected_clear), st::topBarClearButton)
, _forward(this, lang(lng_selected_forward), st::defaultActiveButton) , _forward(this, lang(lng_selected_forward), st::defaultActiveButton)
, _delete(this, lang(lng_selected_delete), st::defaultActiveButton) , _delete(this, lang(lng_selected_delete), st::defaultActiveButton)
@ -51,12 +53,12 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
_search->setClickedCallback([this] { onSearch(); }); _search->setClickedCallback([this] { onSearch(); });
_menuToggle->setClickedCallback([this] { showMenu(); }); _menuToggle->setClickedCallback([this] { showMenu(); });
subscribe(w->searchInPeerChanged(), [this](PeerData *peer) { subscribe(_controller->searchInPeerChanged(), [this](PeerData *peer) {
_searchInPeer = peer; _searchInPeer = peer;
auto historyPeer = App::main() ? App::main()->historyPeer() : nullptr; auto historyPeer = App::main() ? App::main()->historyPeer() : nullptr;
_search->setForceRippled(historyPeer && historyPeer == _searchInPeer); _search->setForceRippled(historyPeer && historyPeer == _searchInPeer);
}); });
subscribe(w->historyPeerChanged(), [this](PeerData *peer) { subscribe(_controller->historyPeerChanged(), [this](PeerData *peer) {
_search->setForceRippled(peer && peer == _searchInPeer, Ui::IconButton::SetForceRippledWay::SkipAnimation); _search->setForceRippled(peer && peer == _searchInPeer, Ui::IconButton::SetForceRippledWay::SkipAnimation);
update(); update();
}); });
@ -143,11 +145,11 @@ bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
return true; return true;
case QEvent::Enter: case QEvent::Enter:
main()->setMembersShowAreaActive(true); App::main()->setMembersShowAreaActive(true);
break; break;
case QEvent::Leave: case QEvent::Leave:
main()->setMembersShowAreaActive(false); App::main()->setMembersShowAreaActive(false);
break; break;
} }
} }
@ -178,7 +180,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
if (!_search->isHidden()) { if (!_search->isHidden()) {
decreaseWidth += _search->width(); decreaseWidth += _search->width();
} }
auto paintCounter = main()->paintTopBar(p, decreaseWidth, ms); auto paintCounter = App::main()->paintTopBar(p, decreaseWidth, ms);
p.restore(); p.restore();
if (paintCounter) { if (paintCounter) {
@ -256,33 +258,12 @@ void TopBarWidget::updateControlsGeometry() {
_search->moveToRight(_info->isHidden() ? _menuToggle->width() : _info->width(), otherButtonsTop); _search->moveToRight(_info->isHidden() ? _menuToggle->width() : _info->width(), otherButtonsTop);
} }
void TopBarWidget::startAnim() { void TopBarWidget::animationFinished() {
_info->hide();
_clearSelection->hide();
_delete->hide();
_forward->hide();
_mediaType->hide();
_search->hide();
_menuToggle->hide();
_menu.destroy();
if (_membersShowArea) {
_membersShowArea->hide();
}
_animating = true;
}
void TopBarWidget::stopAnim() {
_animating = false;
updateMembersShowArea(); updateMembersShowArea();
showAll(); showAll();
} }
void TopBarWidget::showAll() { void TopBarWidget::showAll() {
if (_animating) {
updateControlsGeometry();
return;
}
auto historyPeer = App::main() ? App::main()->historyPeer() : nullptr; auto historyPeer = App::main() ? App::main()->historyPeer() : nullptr;
auto overviewPeer = App::main() ? App::main()->overviewPeer() : nullptr; auto overviewPeer = App::main() ? App::main()->overviewPeer() : nullptr;
@ -290,7 +271,7 @@ void TopBarWidget::showAll() {
_delete->setVisible(_canDelete); _delete->setVisible(_canDelete);
_forward->show(); _forward->show();
_mediaType->setVisible(App::main() ? App::main()->mediaTypeSwitch() : false); _mediaType->setVisible(App::main() ? App::main()->showMediaTypeSwitch() : false);
if (historyPeer && !overviewPeer) { if (historyPeer && !overviewPeer) {
if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
_info->setPeer(historyPeer); _info->setPeer(historyPeer);
@ -330,7 +311,7 @@ void TopBarWidget::updateMembersShowArea() {
}; };
if (!membersShowAreaNeeded()) { if (!membersShowAreaNeeded()) {
if (_membersShowArea) { if (_membersShowArea) {
main()->setMembersShowAreaActive(false); App::main()->setMembersShowAreaActive(false);
_membersShowArea.destroy(); _membersShowArea.destroy();
} }
return; return;
@ -397,8 +378,4 @@ Ui::RoundButton *TopBarWidget::mediaTypeButton() {
return _mediaType; return _mediaType;
} }
MainWidget *TopBarWidget::main() {
return static_cast<MainWidget*>(parentWidget());
}
} // namespace Window } // namespace Window

View File

@ -31,17 +31,17 @@ class DropdownMenu;
namespace Window { namespace Window {
class Controller;
class TopBarWidget : public TWidget, private base::Subscriber { class TopBarWidget : public TWidget, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
TopBarWidget(MainWidget *w); TopBarWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
void startAnim();
void stopAnim();
void showAll(); void showAll();
void showSelected(int selectedCount, bool canDelete = false); void showSelected(int selectedCount, bool canDelete = false);
void animationFinished();
void updateMembersShowArea(); void updateMembersShowArea();
Ui::RoundButton *mediaTypeButton(); Ui::RoundButton *mediaTypeButton();
@ -71,14 +71,12 @@ private:
void updateAdaptiveLayout(); void updateAdaptiveLayout();
int countSelectedButtonsTop(float64 selectedShown); int countSelectedButtonsTop(float64 selectedShown);
MainWidget *main(); gsl::not_null<Window::Controller*> _controller;
PeerData *_searchInPeer = nullptr; PeerData *_searchInPeer = nullptr;
int _selectedCount = 0; int _selectedCount = 0;
bool _canDelete = false; bool _canDelete = false;
bool _animating = false;
Animation _selectedShown; Animation _selectedShown;
object_ptr<Ui::RoundButton> _clearSelection; object_ptr<Ui::RoundButton> _clearSelection;

View File

@ -0,0 +1,22 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "window/window_controller.h"

View File

@ -0,0 +1,50 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
namespace Window {
class Controller {
public:
Controller(MainWindow *window) : _window(window) {
}
// This is needed for History TopBar updating when searchInPeer
// is changed in the DialogsWidget of the current window.
base::Observable<PeerData*> &searchInPeerChanged() {
return _searchInPeerChanged;
}
// This is needed while we have one HistoryWidget and one TopBarWidget
// for all histories we show in a window. Once each history is shown
// in its own HistoryWidget with its own TopBarWidget this can be removed.
base::Observable<PeerData*> &historyPeerChanged() {
return _historyPeerChanged;
}
private:
gsl::not_null<MainWindow*> _window;
base::Observable<PeerData*> _searchInPeerChanged;
base::Observable<PeerData*> _historyPeerChanged;
};
} // namespace Window

View File

@ -426,6 +426,8 @@
<(src_loc)/ui/special_buttons.h <(src_loc)/ui/special_buttons.h
<(src_loc)/ui/twidget.cpp <(src_loc)/ui/twidget.cpp
<(src_loc)/ui/twidget.h <(src_loc)/ui/twidget.h
<(src_loc)/window/window_controller.cpp
<(src_loc)/window/window_controller.h
<(src_loc)/window/main_window.cpp <(src_loc)/window/main_window.cpp
<(src_loc)/window/main_window.h <(src_loc)/window/main_window.h
<(src_loc)/window/notifications_manager.cpp <(src_loc)/window/notifications_manager.cpp
@ -439,12 +441,13 @@
<(src_loc)/window/section_memento.h <(src_loc)/window/section_memento.h
<(src_loc)/window/section_widget.cpp <(src_loc)/window/section_widget.cpp
<(src_loc)/window/section_widget.h <(src_loc)/window/section_widget.h
<(src_loc)/window/window_slide_animation.cpp
<(src_loc)/window/window_slide_animation.h
<(src_loc)/window/top_bar_widget.cpp <(src_loc)/window/top_bar_widget.cpp
<(src_loc)/window/top_bar_widget.h <(src_loc)/window/top_bar_widget.h
<(src_loc)/window/window_main_menu.cpp <(src_loc)/window/window_main_menu.cpp
<(src_loc)/window/window_main_menu.h <(src_loc)/window/window_main_menu.h
<(src_loc)/window/window_slide_animation.cpp
<(src_loc)/window/window_slide_animation.h
<(src_loc)/window/window_title.h
<(src_loc)/window/themes/window_theme.cpp <(src_loc)/window/themes/window_theme.cpp
<(src_loc)/window/themes/window_theme.h <(src_loc)/window/themes/window_theme.h
<(src_loc)/window/themes/window_theme_editor.cpp <(src_loc)/window/themes/window_theme_editor.cpp
@ -455,7 +458,6 @@
<(src_loc)/window/themes/window_theme_preview.h <(src_loc)/window/themes/window_theme_preview.h
<(src_loc)/window/themes/window_theme_warning.cpp <(src_loc)/window/themes/window_theme_warning.cpp
<(src_loc)/window/themes/window_theme_warning.h <(src_loc)/window/themes/window_theme_warning.h
<(src_loc)/window/window_title.h
<(src_loc)/apiwrap.cpp <(src_loc)/apiwrap.cpp
<(src_loc)/apiwrap.h <(src_loc)/apiwrap.h
<(src_loc)/app.cpp <(src_loc)/app.cpp