Improve lock/unlock icon behavior.

This commit is contained in:
John Preston 2023-07-13 20:49:08 +04:00
parent 5d234d3103
commit 5368507259
5 changed files with 111 additions and 33 deletions

View File

@ -221,19 +221,20 @@ dialogsMenuToggleUnreadMuted: icon {
dialogsLock: IconButton(dialogsMenuToggle) {
icon: icon {{ "dialogs/dialogs_lock", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_lock", dialogsMenuIconFgOver }};
ripple: emptyRippleAnimation;
}
dialogsUnlockIcon: icon {{ "dialogs/dialogs_unlock", dialogsMenuIconFg }};
dialogsUnlockIconOver: icon {{ "dialogs/dialogs_unlock", dialogsMenuIconFgOver }};
dialogsCalendar: IconButton {
width: 29px;
height: 32px;
width: 32px;
height: 35px;
icon: icon {{ "dialogs/dialogs_calendar", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_calendar", dialogsMenuIconFgOver }};
iconPosition: point(0px, 5px);
iconPosition: point(1px, 6px);
}
dialogsSearchFrom: IconButton(dialogsCalendar) {
width: 26px;
width: 29px;
icon: icon {{ "dialogs/dialogs_search_from", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs/dialogs_search_from", dialogsMenuIconFgOver }};
}
@ -276,12 +277,12 @@ dialogsCancelSearchInPeer: IconButton(dialogsMenuToggle) {
rippleAreaSize: 34px;
}
dialogsCancelSearch: CrossButton {
width: 32px;
height: 32px;
width: 35px;
height: 35px;
cross: CrossAnimation {
size: 32px;
skip: 10px;
size: 35px;
skip: 12px;
stroke: 1.5;
minScale: 0.3;
}

View File

@ -814,14 +814,20 @@ void Widget::setupStories() {
using Phase = Ui::ElasticScrollMovement;
_stories->setExpandedHeight(
_aboveScrollAdded,
(movement == Phase::Momentum || movement == Phase::Returning)
&& (explicitlyExpanded < above));
((movement == Phase::Momentum || movement == Phase::Returning)
&& (explicitlyExpanded < above)));
if (position.overscroll > 0
|| (position.value
> (_storiesExplicitExpandScrollTop
+ st::dialogsRowHeight))) {
storiesToggleExplicitExpand(false);
}
updateLockUnlockPosition();
}, lifetime());
_stories->collapsedGeometryChanged(
) | rpl::start_with_next([=] {
updateLockUnlockPosition();
}, lifetime());
_stories->clicks(
@ -857,6 +863,10 @@ void Widget::setupStories() {
_stories->emptyValue() | rpl::skip(1) | rpl::start_with_next([=] {
updateStoriesVisibility();
}, lifetime());
_stories->widthValue() | rpl::start_with_next([=] {
updateLockUnlockPosition();
}, lifetime());
}
void Widget::storiesToggleExplicitExpand(bool expand) {
@ -977,6 +987,23 @@ void Widget::updateControlsVisibility(bool fast) {
if (_childList && _filter->hasFocus()) {
setInnerFocus();
}
updateLockUnlockPosition();
}
void Widget::updateLockUnlockPosition() {
if (_lockUnlock->isHidden()) {
return;
}
const auto stories = (_stories && !_stories->isHidden())
? _stories->collapsedGeometryCurrent()
: Stories::List::CollapsedGeometry();
const auto simple = _filter->x() + _filter->width();
const auto right = stories.geometry.isEmpty()
? simple
: anim::interpolate(stories.geometry.x(), simple, stories.expanded);
_lockUnlock->move(
right - _lockUnlock->width(),
st::dialogsFilterPadding.y());
}
void Widget::changeOpenedSubsection(
@ -1388,6 +1415,8 @@ void Widget::updateStoriesVisibility() {
if (_aboveScrollAdded > 0 && _updateScrollGeometryCached) {
_updateScrollGeometryCached();
}
updateLockUnlockVisibility();
updateLockUnlockPosition();
}
}
@ -2253,6 +2282,7 @@ void Widget::applyFilterUpdate(bool force) {
_cancelSearch->toggle(!filterText.isEmpty(), anim::type::normal);
updateLoadMoreChatsVisibility();
updateJumpToDateVisibility();
updateLockUnlockPosition();
if (filterText.isEmpty()) {
_peerSearchCache.clear();
@ -2458,6 +2488,7 @@ bool Widget::setSearchInChat(Key chat, PeerData *from) {
updateSearchFromVisibility();
clearSearchCache();
}
updateLockUnlockPosition();
if (_searchInChat && _layout == Layout::Main) {
controller()->closeFolder();
}
@ -2580,9 +2611,18 @@ void Widget::updateLockUnlockVisibility() {
if (_showAnimation) {
return;
}
const auto hidden = !session().domain().local().hasLocalPasscode();
const auto hidden = !session().domain().local().hasLocalPasscode()
|| (_showAnimation != nullptr)
|| _openedForum
|| !_widthAnimationCache.isNull()
|| _childList
|| !_filter->getLastText().isEmpty()
|| _searchInChat;
if (_lockUnlock->isHidden() != hidden) {
_lockUnlock->setVisible(!hidden);
if (!hidden) {
updateLockUnlockPosition();
}
updateControlsGeometry();
}
}
@ -2685,7 +2725,6 @@ void Widget::updateControlsGeometry() {
_searchForNarrowFilters->moveToLeft(searchLeft, st::dialogsFilterPadding.y());
auto right = filterLeft + filterWidth;
_lockUnlock->moveToLeft(right + st::dialogsFilterPadding.x(), st::dialogsFilterPadding.y());
_cancelSearch->moveToLeft(right - _cancelSearch->width(), _filter->y());
right -= _jumpToDate->width(); _jumpToDate->moveToLeft(right, _filter->y());
right -= _chooseFromUser->width(); _chooseFromUser->moveToLeft(right, _filter->y());
@ -2709,6 +2748,8 @@ void Widget::updateControlsGeometry() {
st::lineWidth);
}
updateLockUnlockPosition();
auto bottomSkip = 0;
const auto putBottomButton = [&](auto &button) {
if (button && !button->isHidden()) {

View File

@ -224,6 +224,7 @@ private:
void updateScrollUpVisibility();
void startScrollUpButtonAnimation(bool shown);
void updateScrollUpPosition();
void updateLockUnlockPosition();
MTP::Sender _api;

View File

@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtWidgets/QApplication>
#include "base/debug_log.h"
namespace Dialogs::Stories {
namespace {
@ -36,6 +38,7 @@ constexpr auto kExpandCatchUpDuration = crl::time(200);
struct List::Layout {
int itemsCount = 0;
QPointF geometryShift;
float64 expandedRatio = 0.;
float64 ratio = 0.;
float64 thumbnailLeft = 0.;
@ -147,12 +150,13 @@ rpl::producer<> List::loadMoreRequests() const {
void List::requestExpanded(bool expanded) {
if (_expanded != expanded) {
_expanded = expanded;
_expandedAnimation.start(
[=] { checkForFullState(); update(); },
_expanded ? 0. : 1.,
_expanded ? 1. : 0.,
st::slideWrapDuration,
anim::sineInOut);
const auto from = _expanded ? 0. : 1.;
const auto till = _expanded ? 1. : 0.;
_expandedAnimation.start([=] {
checkForFullState();
update();
_collapsedGeometryChanged.fire({});
}, from, till, st::slideWrapDuration, anim::sineInOut);
}
_toggleExpandedRequests.fire_copy(_expanded);
}
@ -185,13 +189,15 @@ void List::updateExpanding(int expandingHeight, int expandedHeight) {
}
List::Layout List::computeLayout() {
updateExpanding(
_lastExpandedHeight * _expandCatchUpAnimation.value(1.),
_st.full.height);
return computeLayout(_expandedAnimation.value(_expanded ? 1. : 0.));
}
List::Layout List::computeLayout(float64 expanded) const {
const auto &st = _st.small;
const auto &full = _st.full;
const auto use = _lastExpandedHeight
* _expandCatchUpAnimation.value(1.);
updateExpanding(use, full.height);
const auto expanded = _expandedAnimation.value(_expanded ? 1. : 0.);
const auto expandedRatio = _lastRatio;
const auto collapsedRatio = expandedRatio * kFrictionRatio;
const auto ratio = expandedRatio * expanded
@ -234,6 +240,13 @@ List::Layout List::computeLayout() {
const auto photoLeft = lerp(st.photoLeft, full.photoLeft);
return Layout{
.itemsCount = itemsCount,
.geometryShift = QPointF(
(_state == State::Changing
? (lerp(_changingGeometryFrom.x(), _geometryFull.x()) - x())
: 0.),
(_state == State::Changing
? (lerp(_changingGeometryFrom.y(), _geometryFull.y()) - y())
: 0.)),
.expandedRatio = expandedRatio,
.ratio = ratio,
.thumbnailLeft = thumbnailLeft,
@ -287,15 +300,7 @@ void List::paintEvent(QPaintEvent *e) {
auto p = QPainter(this);
if (_state == State::Changing) {
const auto left = anim::interpolate(
_changingGeometryFrom.x(),
_geometryFull.x(),
layout.ratio);
const auto top = anim::interpolate(
_changingGeometryFrom.y(),
_geometryFull.y(),
layout.ratio);
p.translate(QPoint(left, top) - pos());
p.translate(layout.geometryShift);
}
const auto drawSmall = (expandRatio < 1.);
@ -672,6 +677,28 @@ void List::setLayoutConstraints(
update();
}
List::CollapsedGeometry List::collapsedGeometryCurrent() const {
const auto expanded = _expandedAnimation.value(_expanded ? 1. : 0.);
if (expanded == 1.) {
return { QRect(), 1. };
}
const auto layout = computeLayout(0.);
const auto small = countSmallGeometry();
const auto index = layout.smallSkip - layout.startIndexSmall;
const auto shift = x() + layout.geometryShift.x();
const auto left = int(base::SafeRound(
shift + layout.left + layout.single * index));
const auto width = small.x() + small.width() - left;
return {
QRect(left, small.y(), width, small.height()),
expanded,
};
}
rpl::producer<> List::collapsedGeometryChanged() const {
return _collapsedGeometryChanged.events();
}
void List::updateGeometry() {
switch (_state) {
case State::Small: setGeometry(countSmallGeometry()); break;
@ -686,7 +713,7 @@ void List::updateGeometry() {
QRect List::countSmallGeometry() const {
const auto &st = _st.small;
const auto layout = const_cast<List*>(this)->computeLayout();
const auto layout = computeLayout(0.);
const auto count = layout.endIndexSmall
- std::max(layout.startIndexSmall, layout.smallSkip);
const auto width = st.left

View File

@ -70,6 +70,12 @@ public:
QPoint positionSmall,
style::align alignSmall,
QRect geometryFull = QRect());
struct CollapsedGeometry {
QRect geometry;
float64 expanded = 0.;
};
[[nodiscard]] CollapsedGeometry collapsedGeometryCurrent() const;
[[nodiscard]] rpl::producer<> collapsedGeometryChanged() const;
[[nodiscard]] bool empty() const {
return _empty.current();
@ -130,6 +136,7 @@ private:
void updateExpanding(int expandingHeight, int expandedHeight);
[[nodiscard]] Layout computeLayout();
[[nodiscard]] Layout computeLayout(float64 expanded) const;
const style::DialogsStoriesList &_st;
Content _content;
@ -139,6 +146,7 @@ private:
rpl::event_stream<bool> _toggleExpandedRequests;
rpl::event_stream<> _entered;
rpl::event_stream<> _loadMoreRequests;
rpl::event_stream<> _collapsedGeometryChanged;
QPoint _positionSmall;
style::align _alignSmall = {};