From 2cd08b8923f5e5b7f16fa4edff67636915751c79 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 20 Jul 2023 22:50:18 +0400 Subject: [PATCH] Cut off name / date correctly. --- .../stories/media_stories_controller.cpp | 8 +- .../media/stories/media_stories_controller.h | 1 + .../media/stories/media_stories_header.cpp | 133 ++++++++++++------ .../media/stories/media_stories_header.h | 4 +- .../SourceFiles/media/view/media_view.style | 6 +- 5 files changed, 105 insertions(+), 47 deletions(-) diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index b42a0bd740897d..f32aec6c667e4f 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -910,9 +910,11 @@ PauseState Controller::pauseState() const { const auto playing = !inactive && !_paused; return playing ? PauseState::Playing - : inactive - ? PauseState::Inactive - : PauseState::Paused; + : !inactive + ? PauseState::Paused + : _paused + ? PauseState::InactivePaused + : PauseState::Inactive; } float64 Controller::currentVolume() const { diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index 19b2de4d9fe309..d234d540c5570a 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -76,6 +76,7 @@ enum class PauseState { Playing, Paused, Inactive, + InactivePaused, }; struct SiblingLayout { diff --git a/Telegram/SourceFiles/media/stories/media_stories_header.cpp b/Telegram/SourceFiles/media/stories/media_stories_header.cpp index e710cd28829155..7a9e92bfa141ca 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_header.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_header.cpp @@ -235,16 +235,12 @@ void UserpicBadge::updateGeometry() { return { Ui::FormatDateTime(whenFull) }; } -[[nodiscard]] TextWithEntities ComposeName(HeaderData data) { - auto result = Ui::Text::Bold(data.user->isSelf() - ? tr::lng_stories_my_name(tr::now) - : data.user->shortName()); - if (data.fullCount) { - result.append(QString::fromUtf8(" \xE2\x80\xA2 %1/%2" - ).arg(data.fullIndex + 1 - ).arg(data.fullCount)); - } - return result; +[[nodiscard]] QString ComposeCounter(HeaderData data) { + const auto index = data.fullIndex + 1; + const auto count = data.fullCount; + return count + ? QString::fromUtf8(" \xE2\x80\xA2 %1/%2").arg(index).arg(count) + : QString(); } [[nodiscard]] Timestamp ComposeDetails(HeaderData data, TimeId now) { @@ -269,17 +265,23 @@ void Header::show(HeaderData data) { if (_data == data) { return; } - const auto userChanged = !_data - || (_data->user != data.user); - const auto nameDataChanged = userChanged - || !_name - || (_data->fullCount != data.fullCount) - || (data.fullCount && _data->fullIndex != data.fullIndex); + const auto userChanged = !_data || (_data->user != data.user); _data = data; + const auto updateInfoGeometry = [=] { + if (_name && _date) { + const auto namex = st::storiesHeaderNamePosition.x(); + const auto namer = namex + _name->width(); + const auto datex = st::storiesHeaderDatePosition.x(); + const auto dater = datex + _date->width(); + const auto r = std::max(namer, dater); + _info->setGeometry({ 0, 0, r, _widget->height() }); + } + }; if (userChanged) { _volume = nullptr; _date = nullptr; _name = nullptr; + _counter = nullptr; _userpic = nullptr; _info = nullptr; _privacy = nullptr; @@ -288,10 +290,12 @@ void Header::show(HeaderData data) { const auto parent = _controller->wrap(); auto widget = std::make_unique(parent); const auto raw = widget.get(); + _info = std::make_unique(raw); _info->setClickedCallback([=] { _controller->uiShow()->show(PrepareShortInfoBox(_data->user)); }); + _userpic = std::make_unique( raw, data.user, @@ -301,38 +305,30 @@ void Header::show(HeaderData data) { _userpic->move( st::storiesHeaderMargin.left(), st::storiesHeaderMargin.top()); - raw->show(); - _widget = std::move(widget); - _controller->layoutValue( - ) | rpl::start_with_next([=](const Layout &layout) { - raw->setGeometry(layout.header); - }, raw->lifetime()); - } - const auto updateInfoGeometry = [=] { - if (_name && _date) { - const auto namex = st::storiesHeaderNamePosition.x(); - const auto namer = namex + _name->width(); - const auto datex = st::storiesHeaderDatePosition.x(); - const auto dater = datex + _date->width(); - const auto r = std::max(namer, dater); - _info->setGeometry({ 0, 0, r, _widget->height() }); - } - }; - if (nameDataChanged) { _name = std::make_unique( - _widget.get(), - rpl::single(ComposeName(data)), + raw, + rpl::single(data.user->isSelf() + ? tr::lng_stories_my_name(tr::now) + : data.user->shortName()), st::storiesHeaderName); _name->setAttribute(Qt::WA_TransparentForMouseEvents); _name->setOpacity(kNameOpacity); - _name->move(st::storiesHeaderNamePosition); _name->show(); + _name->move(st::storiesHeaderNamePosition); rpl::combine( _name->widthValue(), - _widget->heightValue() + raw->heightValue() ) | rpl::start_with_next(updateInfoGeometry, _name->lifetime()); + + raw->show(); + _widget = std::move(widget); + + _controller->layoutValue( + ) | rpl::start_with_next([=](const Layout &layout) { + raw->setGeometry(layout.header); + }, raw->lifetime()); } auto timestamp = ComposeDetails(data, base::unixtime::now()); _date = std::make_unique( @@ -347,8 +343,21 @@ void Header::show(HeaderData data) { _date->widthValue( ) | rpl::start_with_next(updateInfoGeometry, _date->lifetime()); - _privacy = MakePrivacyBadge(_userpic.get(), data.privacy, [=] { + auto counter = ComposeCounter(data); + if (!counter.isEmpty()) { + _counter = std::make_unique( + _widget.get(), + std::move(counter), + st::storiesHeaderDate); + _counter->resizeToNaturalWidth(_counter->naturalWidth()); + _counter->setAttribute(Qt::WA_TransparentForMouseEvents); + _counter->setOpacity(kNameOpacity); + _counter->show(); + } else { + _counter = nullptr; + } + _privacy = MakePrivacyBadge(_userpic.get(), data.privacy, [=] { }); if (data.video) { @@ -370,6 +379,41 @@ void Header::show(HeaderData data) { _volumeToggle = nullptr; } + rpl::combine( + _widget->widthValue(), + _counter ? _counter->widthValue() : rpl::single(0), + _dateUpdated.events_starting_with_copy(rpl::empty) + ) | rpl::start_with_next([=](int outer, int counter, auto) { + const auto right = _playPause + ? _playPause->x() + : (outer - st::storiesHeaderMargin.right()); + const auto nameLeft = st::storiesHeaderNamePosition.x(); + const auto nameNatural = _name->naturalWidth(); + if (counter) { + counter += st::normalFont->spacew; + } + const auto nameAvailable = right - nameLeft - counter; + auto counterLeft = nameLeft; + if (nameAvailable <= 0) { + _name->hide(); + } else { + _name->show(); + _name->resizeToNaturalWidth(nameAvailable); + counterLeft += _name->width() + st::normalFont->spacew; + } + if (_counter) { + _counter->move(counterLeft, _name->y()); + } + const auto dateLeft = st::storiesHeaderDatePosition.x(); + const auto dateAvailable = right - dateLeft; + if (dateAvailable <= 0) { + _date->hide(); + } else { + _date->show(); + _date->resizeToNaturalWidth(dateAvailable); + } + }, _date->lifetime()); + if (timestamp.changes > 0) { _dateUpdateTimer.callOnce(timestamp.changes * crl::time(1000)); } @@ -403,14 +447,17 @@ void Header::createPlayPause() { } else if (type == QEvent::MouseButtonRelease) { const auto down = base::take(state->down); if (down && state->over) { - _controller->togglePaused(_pauseState != PauseState::Paused); + const auto paused = (_pauseState == PauseState::Paused) + || (_pauseState == PauseState::InactivePaused); + _controller->togglePaused(!paused); } } }, lifetime); _playPause->paintRequest() | rpl::start_with_next([=] { auto p = QPainter(_playPause.get()); - const auto paused = (_pauseState == PauseState::Paused); + const auto paused = (_pauseState == PauseState::Paused) + || (_pauseState == PauseState::InactivePaused); const auto icon = paused ? &st::storiesPlayIcon : &st::storiesPauseIcon; @@ -620,7 +667,8 @@ void Header::updateVolumeIcon() { void Header::applyPauseState() { Expects(_playPause != nullptr); - const auto inactive = (_pauseState == PauseState::Inactive); + const auto inactive = (_pauseState == PauseState::Inactive) + || (_pauseState == PauseState::InactivePaused); _playPause->setAttribute(Qt::WA_TransparentForMouseEvents, inactive); if (inactive) { QEvent e(QEvent::Leave); @@ -646,6 +694,7 @@ void Header::updateDateText() { } auto timestamp = ComposeDetails(*_data, base::unixtime::now()); _date->setText(timestamp.text); + _dateUpdated.fire({}); if (timestamp.changes > 0) { _dateUpdateTimer.callOnce(timestamp.changes * crl::time(1000)); } diff --git a/Telegram/SourceFiles/media/stories/media_stories_header.h b/Telegram/SourceFiles/media/stories/media_stories_header.h index f837494823a819..12a66b1a15753e 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_header.h +++ b/Telegram/SourceFiles/media/stories/media_stories_header.h @@ -62,7 +62,7 @@ class Header final { void createPlayPause(); void createVolumeToggle(); void rebuildVolumeControls( - not_null dropdown, + not_null dropdown, bool horizontal); const not_null _controller; @@ -73,7 +73,9 @@ class Header final { std::unique_ptr _info; std::unique_ptr _userpic; std::unique_ptr _name; + std::unique_ptr _counter; std::unique_ptr _date; + rpl::event_stream<> _dateUpdated; std::unique_ptr _playPause; std::unique_ptr _volumeToggle; std::unique_ptr> _volume; diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 5803475396a321..d463e8adc04702 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -426,11 +426,15 @@ storiesHeaderPhoto: UserpicButton(defaultUserpicButton) { } storiesHeaderName: FlatLabel(defaultFlatLabel) { textFg: mediaviewControlFg; - style: defaultTextStyle; + style: semiboldTextStyle; + minWidth: 10px; + maxHeight: 20px; } storiesHeaderNamePosition: point(50px, 0px); storiesHeaderDate: FlatLabel(defaultFlatLabel) { textFg: mediaviewControlFg; + minWidth: 10px; + maxHeight: 20px; } storiesHeaderDatePosition: point(50px, 17px); storiesShadowTop: icon{{ "mediaview/shadow_bottom-flip_vertical", windowShadowFg }};