Improve history -> profile top bar navigation.

This commit is contained in:
John Preston 2017-11-16 19:24:01 +04:00
parent 903aa46e5c
commit cf977cb41a
11 changed files with 124 additions and 102 deletions

View File

@ -493,10 +493,6 @@ object_ptr<TabbedSelector::InnerFooter> StickersListWidget::createFooter() {
void StickersListWidget::visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) {
if (!_columnCount) {
return;
}
auto top = getVisibleTop();
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
if (_section == Section::Featured) {

View File

@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "styles/style_window.h"
#include "styles/style_dialogs.h"
#include "styles/style_history.h"
#include "styles/style_info.h"
#include "boxes/add_contact_box.h"
#include "boxes/confirm_box.h"
#include "info/info_memento.h"
@ -51,12 +52,14 @@ HistoryTopBarWidget::HistoryTopBarWidget(
, _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton)
, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton)
, _delete(this, langFactory(lng_selected_delete), st::defaultActiveButton)
, _back(this, st::historyTopBarBack)
, _call(this, st::topBarCall)
, _search(this, st::topBarSearch)
, _infoToggle(this, st::topBarInfo)
, _menuToggle(this, st::topBarMenuToggle)
, _onlineUpdater([this] { updateOnlineDisplay(); }) {
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
setAttribute(Qt::WA_OpaquePaintEvent);
_forward->setClickedCallback([this] { onForwardSelection(); });
_forward->setWidthChangedCallback([this] { updateControlsGeometry(); });
@ -67,6 +70,7 @@ HistoryTopBarWidget::HistoryTopBarWidget(
_search->setClickedCallback([this] { onSearch(); });
_menuToggle->setClickedCallback([this] { showMenu(); });
_infoToggle->setClickedCallback([this] { toggleInfoSection(); });
_back->addClickHandler([this] { backClicked(); });
rpl::combine(
_controller->historyPeer.value(),
@ -116,7 +120,8 @@ HistoryTopBarWidget::HistoryTopBarWidget(
}
}));
subscribe(Global::RefPhoneCallsEnabledChanged(), [this] {
updateControlsVisibility(); });
updateControlsVisibility();
});
rpl::combine(
Auth().data().thirdSectionInfoEnabledValue(),
@ -145,12 +150,6 @@ void HistoryTopBarWidget::onClearSelection() {
if (App::main()) App::main()->clearSelectedItems();
}
void HistoryTopBarWidget::onInfoClicked() {
if (_historyPeer) {
_controller->showPeerInfo(_historyPeer);
}
}
void HistoryTopBarWidget::onSearch() {
if (_historyPeer) {
App::main()->searchInPeer(_historyPeer);
@ -240,6 +239,9 @@ bool HistoryTopBarWidget::eventFilter(QObject *obj, QEvent *e) {
}
void HistoryTopBarWidget::paintEvent(QPaintEvent *e) {
if (_animationMode) {
return;
}
Painter p(this);
auto ms = getms();
@ -253,43 +255,21 @@ void HistoryTopBarWidget::paintEvent(QPaintEvent *e) {
p.translate(0, selectedButtonsTop + st::topBarHeight);
p.save();
auto decreaseWidth = 0;
if (_info && !_info->isHidden()) {
decreaseWidth += _info->width();
}
if (!_menuToggle->isHidden()) {
decreaseWidth += _menuToggle->width();
}
if (!_infoToggle->isHidden()) {
decreaseWidth += _infoToggle->width() + st::topBarSkip;
}
if (!_search->isHidden()) {
decreaseWidth += _search->width();
}
if (!_call->isHidden()) {
decreaseWidth += st::topBarCallSkip + _call->width();
}
paintTopBar(p, decreaseWidth, ms);
paintTopBar(p, ms);
p.restore();
paintUnreadCounter(p, width(), _historyPeer);
}
}
void HistoryTopBarWidget::paintTopBar(
Painter &p,
int decreaseWidth,
TimeMs ms) {
void HistoryTopBarWidget::paintTopBar(Painter &p, TimeMs ms) {
auto history = App::historyLoaded(_historyPeer);
if (!history) return;
auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty())
? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right())
: 0;
auto nameleft = st::topBarArrowPadding.right() + increaseLeft;
auto nameleft = _leftTaken;
auto nametop = st::topBarArrowPadding.top();
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
auto namewidth = width() - decreaseWidth - nameleft - st::topBarArrowPadding.right();
auto namewidth = width() - _rightTaken - nameleft;
p.setFont(st::dialogsTextFont);
if (!history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) {
p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg);
@ -298,21 +278,10 @@ void HistoryTopBarWidget::paintTopBar(
p.setPen(st::dialogsNameFg);
_historyPeer->dialogName().drawElided(p, nameleft, nametop, namewidth);
if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
st::topBarBackward.paint(
p,
(st::topBarArrowPadding.left() - st::topBarBackward.width()) / 2,
(st::topBarHeight - st::topBarBackward.height()) / 2,
width());
}
}
QRect HistoryTopBarWidget::getMembersShowAreaGeometry() const {
int increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty())
? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right())
: 0;
int membersTextLeft = st::topBarArrowPadding.right() + increaseLeft;
int membersTextLeft = _leftTaken;
int membersTextTop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
int membersTextWidth = _titlePeerTextWidth;
int membersTextHeight = st::topBarHeight - membersTextTop;
@ -353,19 +322,24 @@ void HistoryTopBarWidget::paintUnreadCounter(
}
void HistoryTopBarWidget::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton
&& e->pos().y() < st::topBarHeight
&& !_selectedCount) {
clicked();
auto handleClick = (e->button() == Qt::LeftButton)
&& (e->pos().y() < st::topBarHeight)
&& (!_selectedCount);
if (handleClick) {
if (_animationMode && _back->rect().contains(e->pos())) {
backClicked();
} else if (_historyPeer) {
infoClicked();
}
}
}
void HistoryTopBarWidget::clicked() {
if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
_controller->showBackFromStack();
} else if (_historyPeer) {
_controller->showPeerInfo(_historyPeer);
}
void HistoryTopBarWidget::infoClicked() {
_controller->showPeerInfo(_historyPeer);
}
void HistoryTopBarWidget::backClicked() {
_controller->showBackFromStack();
}
void HistoryTopBarWidget::setHistoryPeer(
@ -377,8 +351,9 @@ void HistoryTopBarWidget::setHistoryPeer(
this,
_controller,
_historyPeer,
Ui::UserpicButton::Role::OpenProfile,
Ui::UserpicButton::Role::Custom,
st::topBarInfoButton);
_info->setAttribute(Qt::WA_TransparentForMouseEvents);
} else {
_info.destroy();
}
@ -417,49 +392,58 @@ void HistoryTopBarWidget::updateControlsGeometry() {
_delete->moveToLeft(buttonsLeft, selectedButtonsTop);
_clearSelection->moveToRight(st::topBarActionSkip, selectedButtonsTop);
auto right = 0;
if (_info) {
_info->moveToRight(right, otherButtonsTop);
}
_menuToggle->moveToRight(right, otherButtonsTop);
if (!_info || _info->isHidden()) {
right += _menuToggle->width() + st::topBarSkip;
if (_back->isHidden()) {
_leftTaken = st::topBarArrowPadding.right();
} else {
right += _info->width();
_leftTaken = 0;
_back->moveToLeft(_leftTaken, otherButtonsTop);
_leftTaken += _back->width();
if (_info) {
_info->moveToLeft(_leftTaken, otherButtonsTop);
_leftTaken += _info->width();
}
}
_infoToggle->moveToRight(right, otherButtonsTop);
_rightTaken = 0;
_menuToggle->moveToRight(_rightTaken, otherButtonsTop);
_rightTaken += _menuToggle->width() + st::topBarSkip;
_infoToggle->moveToRight(_rightTaken, otherButtonsTop);
if (!_infoToggle->isHidden()) {
right += _infoToggle->width() + st::topBarSkip;
_rightTaken += _infoToggle->width() + st::topBarSkip;
}
_search->moveToRight(right, otherButtonsTop);
right += _search->width() + st::topBarCallSkip;
_call->moveToRight(right, otherButtonsTop);
_search->moveToRight(_rightTaken, otherButtonsTop);
_rightTaken += _search->width() + st::topBarCallSkip;
_call->moveToRight(_rightTaken, otherButtonsTop);
_rightTaken += _call->width();
}
void HistoryTopBarWidget::animationFinished() {
updateMembersShowArea();
updateControlsVisibility();
void HistoryTopBarWidget::setAnimationMode(bool enabled) {
if (_animationMode != enabled) {
_animationMode = enabled;
setAttribute(Qt::WA_OpaquePaintEvent, !_animationMode);
_selectedShown.finish();
updateMembersShowArea();
updateControlsVisibility();
}
}
void HistoryTopBarWidget::updateControlsVisibility() {
if (_animationMode) {
hideChildren();
return;
}
_clearSelection->show();
_delete->setVisible(_canDelete);
_forward->setVisible(_canForward);
if (Adaptive::OneColumn()
|| (App::main() && !App::main()->stackIsEmpty())) {
if (_info) {
_info->show();
}
_menuToggle->hide();
_menu.destroy();
} else {
if (_info) {
_info->hide();
}
_menuToggle->show();
auto backVisible = Adaptive::OneColumn()
|| (App::main() && !App::main()->stackIsEmpty());
_back->setVisible(backVisible);
if (_info) {
_info->setVisible(backVisible);
}
_search->show();
_menuToggle->show();
_infoToggle->setVisible(!Adaptive::OneColumn()
&& _controller->canShowThirdSection());
auto callsEnabled = false;

View File

@ -49,14 +49,13 @@ public:
void updateControlsVisibility();
void showSelected(SelectedState state);
void animationFinished();
rpl::producer<bool> membersShowAreaActive() const {
return _membersShowAreaActive.events();
}
void setAnimationMode(bool enabled);
void setHistoryPeer(not_null<PeerData*> historyPeer);
void clicked();
static void paintUnreadCounter(
Painter &p,
int outerWidth,
@ -77,7 +76,6 @@ private:
void onForwardSelection();
void onDeleteSelection();
void onClearSelection();
void onInfoClicked();
void onCall();
void onSearch();
void showMenu();
@ -86,13 +84,16 @@ private:
void updateAdaptiveLayout();
int countSelectedButtonsTop(float64 selectedShown);
void paintTopBar(Painter &p, int decreaseWidth, TimeMs ms);
void paintTopBar(Painter &p, TimeMs ms);
QRect getMembersShowAreaGeometry() const;
void updateMembersShowArea();
void updateOnlineDisplay();
void updateOnlineDisplayTimer();
void updateOnlineDisplayIn(TimeMs timeout);
void infoClicked();
void backClicked();
not_null<Window::Controller*> _controller;
PeerData *_historyPeer = nullptr;
@ -105,6 +106,7 @@ private:
object_ptr<Ui::RoundButton> _clearSelection;
object_ptr<Ui::RoundButton> _forward, _delete;
object_ptr<Ui::IconButton> _back;
object_ptr<Ui::UserpicButton> _info = { nullptr };
object_ptr<Ui::IconButton> _call;
@ -119,6 +121,9 @@ private:
QString _titlePeerText;
bool _titlePeerTextOnline = false;
int _titlePeerTextWidth = 0;
int _leftTaken = 0;
int _rightTaken = 0;
bool _animationMode = false;
int _unreadCounterSubscription = 0;
base::Timer _onlineUpdater;

View File

@ -2998,10 +2998,8 @@ void HistoryWidget::showAnimated(
}
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
if (_history) {
_backAnimationButton.create(this);
_backAnimationButton->setClickedCallback([this] { _topBar->clicked(); });
_backAnimationButton->setGeometry(_topBar->geometry());
_backAnimationButton->show();
_topBar->show();
_topBar->setAnimationMode(true);
}
activate();
@ -3018,8 +3016,7 @@ void HistoryWidget::animationCallback() {
}
void HistoryWidget::doneShow() {
_topBar->animationFinished();
_backAnimationButton.destroy();
_topBar->setAnimationMode(false);
updateReportSpamStatus();
updateBotKeyboard();
updateControlsVisibility();

View File

@ -728,7 +728,6 @@ private:
MsgId _delayedShowAtMsgId = -1; // wtf?
mtpRequestId _delayedShowAtRequest = 0;
object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
object_ptr<HistoryTopBarWidget> _topBar;
object_ptr<Ui::ScrollArea> _scroll;
QPointer<HistoryInner> _list;

View File

@ -385,6 +385,7 @@ infoNotificationsButton: InfoProfileButton(infoProfileButton) {
infoMainButton: InfoProfileButton(infoProfileButton) {
textFg: lightButtonFg;
textFgOver: lightButtonFgOver;
font: semiboldFont;
}
infoSharedMediaCoverHeight: 62px;
infoSharedMediaButton: infoProfileButton;
@ -610,3 +611,7 @@ editPeerSignaturesMargins: margins(23px, 16px, 23px, 8px);
editPeerInvitesMargins: margins(23px, 18px, 23px, 16px);
editPeerInvitesTopSkip: 10px;
editPeerInvitesSkip: 10px;
historyTopBarBack: IconButton(infoTopBarBack) {
width: 52px;
}

View File

@ -74,9 +74,15 @@ void SectionWidget::doSetInnerFocus() {
}
void SectionWidget::showFinishedHook() {
_topBarSurrogate.destroy();
_content->showFast();
}
void SectionWidget::showAnimatedHook(
const Window::SectionSlideParams &params) {
_topBarSurrogate = _content->createTopBarSurrogate(this);
}
bool SectionWidget::showInternal(
not_null<Window::SectionMemento*> memento,
const Window::SectionShow &params) {

View File

@ -70,10 +70,14 @@ protected:
void doSetInnerFocus() override;
void showFinishedHook() override;
void showAnimatedHook(
const Window::SectionSlideParams &params) override;
private:
void init();
object_ptr<WrapWidget> _content;
object_ptr<Ui::RpWidget> _topBarSurrogate = { nullptr };
};

View File

@ -620,6 +620,7 @@ void WrapWidget::showAnimatedHook(
if (params.withTopBarShadow) {
_topShadow->setVisible(true);
}
_topBarSurrogate = createTopBarSurrogate(this);
}
void WrapWidget::doSetInnerFocus() {
@ -629,6 +630,7 @@ void WrapWidget::doSetInnerFocus() {
void WrapWidget::showFinishedHook() {
// Restore shadow visibility after showChildren() call.
_topShadow->toggle(_topShadow->toggled(), anim::type::instant);
_topBarSurrogate.destroy();
}
bool WrapWidget::showInternal(
@ -807,6 +809,24 @@ QRect WrapWidget::rectForFloatPlayer() const {
return _content->rectForFloatPlayer();
}
object_ptr<Ui::RpWidget> WrapWidget::createTopBarSurrogate(
QWidget *parent) {
if (hasStackHistory() || wrap() == Wrap::Narrow) {
Assert(_topBar != nullptr);
auto result = object_ptr<Ui::AbstractButton>(parent);
result->addClickHandler([wrap = weak(this)]{
if (wrap) {
wrap->showBackFromStack();
}
});
result->setGeometry(_topBar->geometry());
result->show();
return std::move(result);
}
return nullptr;
}
WrapWidget::~WrapWidget() = default;
} // namespace Info

View File

@ -109,8 +109,7 @@ public:
bool hasTopBarShadow() const override;
QPixmap grabForShowAnimation(
const Window::SectionSlideParams &params) override;
void showAnimatedHook(
const Window::SectionSlideParams &params) override;
void forceContentRepaint();
bool showInternal(
@ -126,6 +125,8 @@ public:
bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer() const override;
object_ptr<Ui::RpWidget> createTopBarSurrogate(QWidget *parent);
~WrapWidget();
protected:
@ -134,6 +135,9 @@ protected:
void doSetInnerFocus() override;
void showFinishedHook() override;
void showAnimatedHook(
const Window::SectionSlideParams &params) override;
private:
using SlideDirection = Window::SlideDirection;
using SectionSlideParams = Window::SectionSlideParams;
@ -194,6 +198,7 @@ private:
//object_ptr<Ui::PlainShadow> _topTabsBackground = { nullptr };
//object_ptr<Ui::SettingsSlider> _topTabs = { nullptr };
object_ptr<TopBar> _topBar = { nullptr };
object_ptr<Ui::RpWidget> _topBarSurrogate = { nullptr };
object_ptr<TopBarOverride> _topBarOverride = { nullptr };
Animation _topBarOverrideAnimation;
object_ptr<Ui::FadeShadow> _topShadow;

View File

@ -300,8 +300,9 @@ topBarMenuToggle: IconButton(topBarSearch) {
topBarActionSkip: 10px;
topBarInfoButton: UserpicButton(defaultUserpicButton) {
size: size(topBarHeight, topBarHeight);
size: size(52px, topBarHeight);
photoSize: 42px;
photoPosition: point(2px, -1px);
}
topBarSlideDuration: 200;