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 "window/notifications_manager.h"
#include "ui/effects/widget_fade_wrap.h"
#include "window/window_controller.h"
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)
, _filter(this, st::dialogsFilter, lang(lng_dlg_filter))
, _jumpToDate(this, object_ptr<Ui::IconButton>(this, st::dialogsCalendar))
@ -2984,7 +2986,7 @@ void DialogsWidget::setSearchInPeer(PeerData *peer) {
_searchInMigrated = newSearchInPeer ? newSearchInPeer->migrateFrom() : nullptr;
if (newSearchInPeer != _searchInPeer) {
_searchInPeer = newSearchInPeer;
App::main()->searchInPeerChanged().notify(_searchInPeer, true);
_controller->searchInPeerChanged().notify(_searchInPeer, true);
updateJumpToDateVisibility();
}
_inner->searchInPeer(_searchInPeer);

View File

@ -41,6 +41,10 @@ template <typename Widget>
class WidgetScaledFadeWrap;
} // namespace Ui
namespace Window {
class Controller;
} // namespace Window
enum DialogsSearchRequestType {
DialogsSearchFromStart,
DialogsSearchFromOffset,
@ -303,7 +307,7 @@ class DialogsWidget : public TWidget, public RPCSender, private base::Subscriber
Q_OBJECT
public:
DialogsWidget(QWidget *parent);
DialogsWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
void updateDragInScroll(bool inScroll);
@ -402,16 +406,18 @@ private:
void updateControlsGeometry();
void updateForwardBar();
bool _dragInScroll = false;
bool _dragForward = false;
QTimer _chooseByDragTimer;
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
bool dialogsFailed(const RPCError &error, mtpRequestId req);
bool contactsFailed(const RPCError &error);
bool searchFailed(DialogsSearchRequestType type, 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;
int32 _dialogsOffsetDate = 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 "auth_session.h"
#include "window/notifications_manager.h"
#include "window/window_controller.h"
namespace {
@ -3191,8 +3192,10 @@ TextWithTags::Tags textTagsFromEntities(const EntitiesInText &entities) {
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)
, _topBar(this, _controller)
, _scroll(this, st::historyScroll, false)
, _historyDown(_scroll, st::historyToDown)
, _fieldAutocomplete(this)
@ -3220,6 +3223,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
setAcceptDrops(true);
subscribe(AuthSession::CurrentDownloaderTaskFinished(), [this] { update(); });
connect(_topBar, &Window::TopBarWidget::clicked, this, [this] { topBarClick(); });
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
connect(_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked()));
connect(_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide()));
@ -3280,6 +3284,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
_fieldBarCancel->hide();
_topBar->hide();
_scroll->hide();
_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);
emit historyShown(_history, _showAtMsgId);
App::main()->topBar()->update();
_topBar->update();
update();
if (startBot && _peer->isUser() && _peer->asUser()->botInfo) {
@ -4423,7 +4428,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
noSelectingScroll();
_selCount = 0;
App::main()->topBar()->showSelected(0);
_topBar->showSelected(0);
App::hoveredItem(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);
emit historyShown(_history, _showAtMsgId);
App::main()->historyPeerChanged().notify(_peer, true);
_controller->historyPeerChanged().notify(_peer, true);
update();
}
@ -4663,7 +4668,8 @@ bool HistoryWidget::canWriteMessage() const {
void HistoryWidget::updateControlsVisibility() {
if (!_a_show.animating()) {
_topShadow->setVisible(_peer ? true : false);
_topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
}
updateHistoryDownVisibility();
if (!_history || _a_show.animating()) {
@ -5584,12 +5590,13 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
_cacheUnder = params.oldContentCache;
show();
_topShadow->setVisible(params.withTopBarShadow ? false : true);
_topBar->showAll();
historyDownAnimationFinish();
_topShadow->setVisible(params.withTopBarShadow ? false : true);
_cacheOver = App::main()->grabForShowAnimation(params);
App::main()->topBar()->startAnim();
_topShadow->setVisible(params.withTopBarShadow ? true : false);
_topBar->hide();
_scroll->hide();
_kbScroll->hide();
_reportSpamPanel->hide();
@ -5617,26 +5624,30 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
std::swap(_cacheUnder, _cacheOver);
}
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
App::main()->topBar()->update();
if (_history) {
_backAnimationButton.create(this);
_backAnimationButton->setClickedCallback([this] { topBarClick(); });
_backAnimationButton->setGeometry(_topBar->geometry());
_backAnimationButton->show();
}
activate();
}
void HistoryWidget::animationCallback() {
update();
App::main()->topBar()->update();
if (!_a_show.animating()) {
_topShadow->setVisible(_peer ? true : false);
_topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
historyDownAnimationFinish();
_cacheUnder = _cacheOver = QPixmap();
App::main()->topBar()->stopAnim();
doneShow();
}
}
void HistoryWidget::doneShow() {
_topBar->animationFinished();
_backAnimationButton.destroy();
updateReportSpamStatus();
updateBotKeyboard();
updateControlsVisibility();
@ -5655,7 +5666,8 @@ void HistoryWidget::doneShow() {
void HistoryWidget::finishAnimation() {
if (!_a_show.animating()) return;
_a_show.finish();
_topShadow->setVisible(_peer ? true : false);
_topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
historyDownAnimationFinish();
}
@ -5751,7 +5763,7 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
void HistoryWidget::updateOverStates(QPoint pos) {
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 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;
if (inField != _inField && _recording) {
_inField = inField;
@ -6318,25 +6330,6 @@ void HistoryWidget::selectMessage() {
}
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;
auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0;
@ -6466,8 +6459,8 @@ void HistoryWidget::updateOnlineDisplay() {
_titlePeerTextOnline = titlePeerTextOnline;
_titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
if (App::main()) {
App::main()->topBar()->updateMembersShowArea();
App::main()->topBar()->update();
_topBar->updateMembersShowArea();
_topBar->update();
}
}
updateOnlineDisplayTimer();
@ -7182,21 +7175,20 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
}
void HistoryWidget::updateControlsGeometry() {
_topBar->setGeometryToLeft(0, 0, width(), st::topBarHeight);
_reportSpamPanel->resize(width(), _reportSpamPanel->height());
moveFieldControls();
auto scrollAreaTop = _topBar->bottomNoMargins();
if (_pinnedBar) {
if (_scroll->y() != st::historyReplyHeight) {
_scroll->move(0, st::historyReplyHeight);
_reportSpamPanel->move(0, st::historyReplyHeight);
_fieldAutocomplete->setBoundings(_scroll->geometry());
}
_pinnedBar->cancel->move(width() - _pinnedBar->cancel->width(), 0);
_pinnedBar->shadow->setGeometry(0, st::historyReplyHeight, width(), st::lineWidth);
} else if (_scroll->y() != 0) {
_scroll->move(0, 0);
_reportSpamPanel->move(0, 0);
_pinnedBar->cancel->move(width() - _pinnedBar->cancel->width(), scrollAreaTop);
scrollAreaTop += st::historyReplyHeight;
_pinnedBar->shadow->setGeometry(0, scrollAreaTop, width(), st::lineWidth);
}
if (_scroll->y() != scrollAreaTop) {
_scroll->move(0, scrollAreaTop);
_reportSpamPanel->move(0, scrollAreaTop);
_fieldAutocomplete->setBoundings(_scroll->geometry());
}
@ -7230,7 +7222,7 @@ void HistoryWidget::updateControlsGeometry() {
}
_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) {
@ -7276,7 +7268,7 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
return; // scrollTopMax etc are not working after recountHeight()
}
int newScrollHeight = height();
int newScrollHeight = height() - _topBar->height();
if (isBlocked() || isBotStart() || isJoinChannel() || isMuteUnmute()) {
newScrollHeight -= _unblock->height();
} else {
@ -8597,14 +8589,14 @@ void HistoryWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
void HistoryWidget::updateTopBarSelection() {
if (!_list) {
App::main()->topBar()->showSelected(0);
_topBar->showSelected(0);
return;
}
int32 selectedForForward, selectedForDelete;
_list->getSelectionState(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();
updateListSize();
if (!Ui::isLayerShown() && !App::passcoded()) {
@ -8614,7 +8606,7 @@ void HistoryWidget::updateTopBarSelection() {
_field->setFocus();
}
}
App::main()->topBar()->update();
_topBar->update();
update();
}
@ -8843,14 +8835,16 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
}
void HistoryWidget::drawPinnedBar(Painter &p) {
t_assert(_pinnedBar != nullptr);
Expects(_pinnedBar != nullptr);
auto top = _topBar->bottomNoMargins();
Text *from = 0, *text = 0;
bool serviceColor = false, hasForward = readyToForward();
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);
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
@ -8858,21 +8852,21 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
if (_pinnedBar->msg->getMedia() && _pinnedBar->msg->getMedia()->hasReplyPreview()) {
ImagePtr replyPreview = _pinnedBar->msg->getMedia()->replyPreview();
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));
}
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}
p.setPen(st::historyReplyNameFg);
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);
_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 {
p.setFont(st::msgDateFont);
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()) {
p.setClipRect(r);
}
bool hasTopBar = !App::main()->topBar()->isHidden();
auto ms = getms();
_historyDownShown.step(ms);
auto progress = _a_show.current(ms, 1.);
if (_a_show.animating()) {
auto retina = cIntRetinaFactor();
auto inCacheTop = hasTopBar ? st::topBarHeight : 0;
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, 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.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
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);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
return;
}
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);
if (cached.isNull()) {
if (Window::Theme::Background()->tile()) {

View File

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

View File

@ -65,6 +65,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/calendarbox.h"
#include "auth_session.h"
#include "window/notifications_manager.h"
#include "window/window_controller.h"
StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr)
, _memento(std::move(memento)) {
@ -73,16 +74,15 @@ StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&mem
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)
, _sideShadow(this, st::shadowFg)
, _sideResizeArea(this)
, _dialogs(this)
, _history(this)
, _topBar(this)
, _dialogs(this, _controller.get())
, _history(this, _controller.get())
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
, _playerPanel(this, Media::Player::Panel::Layout::Full)
, _mediaType(this, st::defaultDropdownMenu)
, _api(new ApiWrap(this)) {
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
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(_api.get(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(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(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings()));
subscribe(Media::Player::Updated(), [this](const AudioMsgId &audioId) {
@ -174,13 +173,9 @@ MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
} else {
_history->show();
}
_topBar->hide();
orderWidgets();
_mediaType->hide();
_mediaType->setOrigin(Ui::PanelAnimation::Origin::TopRight);
_topBar->mediaTypeButton()->installEventFilter(_mediaType);
_sideResizeArea->installEventFilter(this);
_api->init();
@ -1407,37 +1402,6 @@ void MainWidget::mediaOverviewUpdated(const Notify::PeerUpdate &update) {
auto peer = update.peer;
if (_overview && (_overview->peer() == peer || _overview->peer()->migrateFrom() == peer)) {
_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) {
_topBar->hide();
_history->hide();
if (!_a_show.animating()) {
if (animationParams) {
@ -2310,7 +2273,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
}
} else {
if (noPeer) {
_topBar->hide();
updateControlsGeometry();
} else if (wasActivePeer != activePeer()) {
if (activePeer()->isChannel()) {
@ -2340,7 +2302,6 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
}
_dialogs->update();
}
topBar()->showAll();
}
PeerData *MainWidget::ui_getPeerForMouseAction() {
@ -2385,15 +2346,8 @@ PeerData *MainWidget::overviewPeer() {
return _overview ? _overview->peer() : 0;
}
bool MainWidget::mediaTypeSwitch() {
if (!_overview) return false;
for (int32 i = 0; i < OverviewCount; ++i) {
if (!(_mediaTypeMask & ~(1 << i))) {
return false;
}
}
return true;
bool MainWidget::showMediaTypeSwitch() const {
return _overview ? _overview->showMediaTypeSwitch() : false;
}
void MainWidget::saveSectionInStack() {
@ -2452,9 +2406,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
_wideSection->deleteLater();
_wideSection = nullptr;
}
_overview.create(this, peer, type);
_mediaTypeMask = 0;
_topBar->show();
_overview.create(this, _controller.get(), peer, type);
updateControlsGeometry();
// Send a fake update.
@ -2609,7 +2561,6 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool
_wideSection = nullptr;
}
_wideSection = std::move(newWideSection);
_topBar->hide();
updateControlsGeometry();
_history->finishAnimation();
_history->showHistory(0, 0);
@ -2672,7 +2623,6 @@ void MainWidget::showBackFromStack() {
}
void MainWidget::orderWidgets() {
_topBar->raise();
_dialogs->raise();
if (_player) {
_player->raise();
@ -2680,7 +2630,6 @@ void MainWidget::orderWidgets() {
if (_playerVolume) {
_playerVolume->raise();
}
_mediaType->raise();
_sideShadow->raise();
_sideResizeArea->raise();
_playerPlaylist->raise();
@ -2696,7 +2645,6 @@ QRect MainWidget::historyRect() const {
}
QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &params) {
_topBar->stopAnim();
QPixmap result;
if (_player) {
_player->hideShadow();
@ -2954,8 +2902,6 @@ void MainWidget::hideAll() {
_overview->hide();
}
_sideShadow->hide();
_topBar->hide();
_mediaType->hide();
if (_player) {
_player->hide();
_playerHeight = 0;
@ -2986,7 +2932,6 @@ void MainWidget::showAll() {
_history->hide();
if (_overview) _overview->hide();
if (_wideSection) _wideSection->hide();
_topBar->hide();
} else if (_overview) {
_overview->show();
} else if (_wideSection) {
@ -3000,10 +2945,8 @@ void MainWidget::showAll() {
}
if (!selectingPeer()) {
if (_wideSection) {
_topBar->hide();
_dialogs->hide();
} else if (isSectionShown()) {
_topBar->show();
_dialogs->hide();
}
}
@ -3028,11 +2971,6 @@ void MainWidget::showAll() {
_history->show();
_history->updateControlsGeometry();
}
if (_wideSection) {
_topBar->hide();
} else if (isSectionShown()) {
_topBar->show();
}
}
if (_player) {
_player->show();
@ -3049,7 +2987,6 @@ void MainWidget::resizeEvent(QResizeEvent *e) {
void MainWidget::updateControlsGeometry() {
updateWindowAdaptiveLayout();
auto topBarHeight = _topBar->isHidden() ? 0 : st::topBarHeight;
if (!Adaptive::SmallColumn()) {
_a_dialogsWidth.finish();
}
@ -3063,8 +3000,7 @@ void MainWidget::updateControlsGeometry() {
_player->moveToLeft(0, 0);
}
_dialogs->setGeometry(0, _playerHeight, dialogsWidth, height() - _playerHeight);
_topBar->setGeometry(0, _playerHeight, dialogsWidth, st::topBarHeight);
_history->setGeometry(0, _playerHeight + topBarHeight, dialogsWidth, height() - _playerHeight - topBarHeight);
_history->setGeometry(0, _playerHeight, dialogsWidth, height() - _playerHeight);
if (_hider) _hider->setGeometry(0, 0, dialogsWidth, height());
} else {
accumulate_min(dialogsWidth, width() - st::windowMinWidth);
@ -3076,8 +3012,7 @@ void MainWidget::updateControlsGeometry() {
_player->resizeToWidth(sectionWidth);
_player->moveToLeft(dialogsWidth, 0);
}
_topBar->setGeometryToLeft(dialogsWidth, _playerHeight, sectionWidth, st::topBarHeight);
_history->setGeometryToLeft(dialogsWidth, _playerHeight + topBarHeight, sectionWidth, height() - _playerHeight - topBarHeight);
_history->setGeometryToLeft(dialogsWidth, _playerHeight, sectionWidth, height() - _playerHeight);
if (_hider) {
_hider->setGeometryToLeft(dialogsWidth, 0, sectionWidth, height());
}
@ -3093,9 +3028,8 @@ void MainWidget::updateControlsGeometry() {
return true;
};
_sideResizeArea->setVisible(isSideResizeAreaVisible());
_mediaType->moveToLeft(width() - _mediaType->width(), _playerHeight + st::topBarHeight);
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);
}
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 {
return (_topBar->isHidden() ? 0 : (-st::topBarHeight)) - _playerHeight;
}
void MainWidget::onTopBarClick() {
if (_overview) {
_overview->topBarClick();
} else if (!_wideSection) {
_history->topBarClick();
}
return -_playerHeight;
}
void MainWidget::onHistoryShown(History *history, MsgId atMsgId) {
if ((!Adaptive::OneColumn() || !selectingPeer()) && (_overview || history)) {
_topBar->show();
} else {
_topBar->hide();
}
updateControlsGeometry();
if (_a_show.animating()) {
_topBar->hide();
}
dlgUpdated(history ? history->peer : nullptr, atMsgId);
}
@ -3988,11 +3871,11 @@ void MainWidget::onSelfParticipantUpdated(ChannelData *channel) {
}
bool MainWidget::contentOverlapped(const QRect &globalRect) {
return (_history->contentOverlapped(globalRect) ||
_playerPanel->overlaps(globalRect) ||
_playerPlaylist->overlaps(globalRect) ||
(_playerVolume && _playerVolume->overlaps(globalRect)) ||
_mediaType->overlaps(globalRect));
return (_history->contentOverlapped(globalRect)
|| (_overview && _overview->contentOverlapped(globalRect))
|| _playerPanel->overlaps(globalRect)
|| _playerPlaylist->overlaps(globalRect)
|| (_playerVolume && _playerVolume->overlaps(globalRect)));
}
void MainWidget::usernameResolveDone(QPair<MsgId, QString> msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result) {

View File

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

View File

@ -44,6 +44,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "observer_peer.h"
#include "auth_session.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
@ -1895,13 +1896,23 @@ OverviewInner::~OverviewInner() {
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)
, _mediaType(this, st::defaultDropdownMenu)
, _topShadow(this, st::shadowFg) {
_inner = _scroll->setOwnedWidget(object_ptr<OverviewInner>(this, _scroll, peer, type));
_scroll->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();
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
@ -1934,11 +1945,14 @@ void OverviewWidget::onScroll() {
}
void OverviewWidget::resizeEvent(QResizeEvent *e) {
_topBar->setGeometryToLeft(0, 0, width(), st::topBarHeight);
auto scrollAreaTop = _topBar->bottomNoMargins();
_noDropResizeIndex = true;
int32 st = _scroll->scrollTop();
_scroll->resize(size());
int32 newScrollTop = _inner->resizeToWidth(width(), st, height());
if (int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0) {
auto st = _scroll->scrollTop();
_scroll->setGeometryToLeft(0, scrollAreaTop, width(), height() - scrollAreaTop);
auto newScrollTop = _inner->resizeToWidth(width(), st, height() - _topBar->height());
if (auto addToY = App::main() ? App::main()->contentScrollAddToY() : 0) {
newScrollTop += addToY;
}
if (newScrollTop != _scroll->scrollTop()) {
@ -1947,7 +1961,9 @@ void OverviewWidget::resizeEvent(QResizeEvent *e) {
_noDropResizeIndex = false;
_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) {
@ -1957,18 +1973,17 @@ void OverviewWidget::paintEvent(QPaintEvent *e) {
auto progress = _a_show.current(getms(), 1.);
if (_a_show.animating()) {
auto retina = cIntRetinaFactor();
auto inCacheTop = st::topBarHeight;
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, 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.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
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);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
return;
@ -1994,24 +2009,6 @@ void OverviewWidget::scrollReset() {
}
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());
p.setFont(st::defaultLightButton.font);
p.setPen(st::defaultLightButton.textFg);
@ -2053,7 +2050,7 @@ void OverviewWidget::switchType(MediaOverviewType type) {
_header = _header.toUpper();
noSelectingScroll();
App::main()->topBar()->showSelected(0);
_topBar->showSelected(0);
updateTopBarSelection();
scrollReset();
@ -2063,14 +2060,27 @@ void OverviewWidget::switchType(MediaOverviewType type) {
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() {
int32 selectedForForward, selectedForDelete;
_inner->getSelectionState(selectedForForward, selectedForDelete);
_selCount = selectedForForward ? selectedForForward : selectedForDelete;
_inner->setSelectMode(_selCount > 0);
if (App::main()) {
App::main()->topBar()->showSelected(_selCount > 0 ? _selCount : 0, (selectedForDelete == selectedForForward));
App::main()->topBar()->update();
_topBar->showSelected(_selCount > 0 ? _selCount : 0, (selectedForDelete == selectedForForward));
_topBar->update();
}
if (App::wnd() && !Ui::isLayerShown()) {
_inner->activate();
@ -2122,11 +2132,12 @@ void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window
_cacheUnder = params.oldContentCache;
show();
_topBar->showAll();
_topShadow->setVisible(params.withTopBarShadow ? false : true);
_cacheOver = App::main()->grabForShowAnimation(params);
_topShadow->setVisible(params.withTopBarShadow ? true : false);
App::main()->topBar()->startAnim();
_topBar->hide();
_scrollSetAfterShow = _scroll->scrollTop();
_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());
App::main()->topBar()->update();
_backAnimationButton.create(this);
_backAnimationButton->setClickedCallback([this] { topBarClick(); });
_backAnimationButton->setGeometry(_topBar->geometry());
_backAnimationButton->show();
activate();
}
void OverviewWidget::animationCallback() {
update();
App::main()->topBar()->update();
if (!_a_show.animating()) {
_topShadow->show();
_cacheUnder = _cacheOver = QPixmap();
App::main()->topBar()->stopAnim();
doneShow();
}
}
void OverviewWidget::doneShow() {
_topBar->animationFinished();
_backAnimationButton.destroy();
_topBar->show();
_scroll->show();
_scroll->scrollToY(_scrollSetAfterShow);
activate();
@ -2166,6 +2179,47 @@ void OverviewWidget::mediaOverviewUpdated(const Notify::PeerUpdate &update) {
onScroll();
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) {

View File

@ -33,17 +33,24 @@ class Date;
} // namespace Overview
namespace Ui {
class AbstractButton;
class PlainShadow;
class PopupMenu;
class IconButton;
class FlatInput;
class CrossButton;
class DropdownMenu;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Window {
class Controller;
class TopBarWidget;
} // namespace Window
class OverviewWidget;
class OverviewInner : public TWidget, public Ui::AbstractTooltipShower, public RPCSender, private base::Subscriber {
Q_OBJECT
@ -280,7 +287,7 @@ class OverviewWidget : public TWidget, public RPCSender {
Q_OBJECT
public:
OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type);
OverviewWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller, PeerData *peer, MediaOverviewType type);
void clear();
@ -288,13 +295,14 @@ public:
void scrollReset();
bool paintTopBar(Painter &p, int decreaseWidth);
void topBarClick();
PeerData *peer() const;
PeerData *migratePeer() const;
MediaOverviewType type() const;
void switchType(MediaOverviewType type);
bool showMediaTypeSwitch() const;
void updateTopBarSelection();
bool contentOverlapped(const QRect &globalRect);
int32 lastWidth() const;
int32 lastScrollTop() const;
@ -361,12 +369,20 @@ public slots:
void onClearSelected();
private:
void topBarClick();
void animationCallback();
gsl::not_null<Window::Controller*> _controller;
object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
object_ptr<Window::TopBarWidget> _topBar;
object_ptr<Ui::ScrollArea> _scroll;
QPointer<OverviewInner> _inner;
bool _noDropResizeIndex = false;
object_ptr<Ui::DropdownMenu> _mediaType;
int32 _mediaTypeMask = 0;
QString _header;
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/dropdown_menu.h"
#include "dialogs/dialogs_layout.h"
#include "window/window_controller.h"
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)
, _forward(this, lang(lng_selected_forward), st::defaultActiveButton)
, _delete(this, lang(lng_selected_delete), st::defaultActiveButton)
@ -51,12 +53,12 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
_search->setClickedCallback([this] { onSearch(); });
_menuToggle->setClickedCallback([this] { showMenu(); });
subscribe(w->searchInPeerChanged(), [this](PeerData *peer) {
subscribe(_controller->searchInPeerChanged(), [this](PeerData *peer) {
_searchInPeer = peer;
auto historyPeer = App::main() ? App::main()->historyPeer() : nullptr;
_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);
update();
});
@ -143,11 +145,11 @@ bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
return true;
case QEvent::Enter:
main()->setMembersShowAreaActive(true);
App::main()->setMembersShowAreaActive(true);
break;
case QEvent::Leave:
main()->setMembersShowAreaActive(false);
App::main()->setMembersShowAreaActive(false);
break;
}
}
@ -178,7 +180,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
if (!_search->isHidden()) {
decreaseWidth += _search->width();
}
auto paintCounter = main()->paintTopBar(p, decreaseWidth, ms);
auto paintCounter = App::main()->paintTopBar(p, decreaseWidth, ms);
p.restore();
if (paintCounter) {
@ -256,33 +258,12 @@ void TopBarWidget::updateControlsGeometry() {
_search->moveToRight(_info->isHidden() ? _menuToggle->width() : _info->width(), otherButtonsTop);
}
void TopBarWidget::startAnim() {
_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;
void TopBarWidget::animationFinished() {
updateMembersShowArea();
showAll();
}
void TopBarWidget::showAll() {
if (_animating) {
updateControlsGeometry();
return;
}
auto historyPeer = App::main() ? App::main()->historyPeer() : nullptr;
auto overviewPeer = App::main() ? App::main()->overviewPeer() : nullptr;
@ -290,7 +271,7 @@ void TopBarWidget::showAll() {
_delete->setVisible(_canDelete);
_forward->show();
_mediaType->setVisible(App::main() ? App::main()->mediaTypeSwitch() : false);
_mediaType->setVisible(App::main() ? App::main()->showMediaTypeSwitch() : false);
if (historyPeer && !overviewPeer) {
if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
_info->setPeer(historyPeer);
@ -330,7 +311,7 @@ void TopBarWidget::updateMembersShowArea() {
};
if (!membersShowAreaNeeded()) {
if (_membersShowArea) {
main()->setMembersShowAreaActive(false);
App::main()->setMembersShowAreaActive(false);
_membersShowArea.destroy();
}
return;
@ -397,8 +378,4 @@ Ui::RoundButton *TopBarWidget::mediaTypeButton() {
return _mediaType;
}
MainWidget *TopBarWidget::main() {
return static_cast<MainWidget*>(parentWidget());
}
} // namespace Window

View File

@ -31,17 +31,17 @@ class DropdownMenu;
namespace Window {
class Controller;
class TopBarWidget : public TWidget, private base::Subscriber {
Q_OBJECT
public:
TopBarWidget(MainWidget *w);
TopBarWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller);
void startAnim();
void stopAnim();
void showAll();
void showSelected(int selectedCount, bool canDelete = false);
void animationFinished();
void updateMembersShowArea();
Ui::RoundButton *mediaTypeButton();
@ -71,14 +71,12 @@ private:
void updateAdaptiveLayout();
int countSelectedButtonsTop(float64 selectedShown);
MainWidget *main();
gsl::not_null<Window::Controller*> _controller;
PeerData *_searchInPeer = nullptr;
int _selectedCount = 0;
bool _canDelete = false;
bool _animating = false;
Animation _selectedShown;
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/twidget.cpp
<(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.h
<(src_loc)/window/notifications_manager.cpp
@ -439,12 +441,13 @@
<(src_loc)/window/section_memento.h
<(src_loc)/window/section_widget.cpp
<(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.h
<(src_loc)/window/window_main_menu.cpp
<(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.h
<(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_warning.cpp
<(src_loc)/window/themes/window_theme_warning.h
<(src_loc)/window/window_title.h
<(src_loc)/apiwrap.cpp
<(src_loc)/apiwrap.h
<(src_loc)/app.cpp