mirror of https://github.com/procxx/kepka.git
				
				
				
			Added floating button in dialog list to jump to top.
This commit is contained in:
		
							parent
							
								
									6021923bf1
								
							
						
					
					
						commit
						41b2e7c9c7
					
				| 
						 | 
					@ -20,10 +20,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "lang/lang_keys.h"
 | 
					#include "lang/lang_keys.h"
 | 
				
			||||||
#include "mainwindow.h"
 | 
					#include "mainwindow.h"
 | 
				
			||||||
#include "mainwidget.h"
 | 
					#include "mainwidget.h"
 | 
				
			||||||
#include "core/update_checker.h"
 | 
					 | 
				
			||||||
#include "auth_session.h"
 | 
					#include "auth_session.h"
 | 
				
			||||||
#include "apiwrap.h"
 | 
					#include "apiwrap.h"
 | 
				
			||||||
#include "core/application.h"
 | 
					#include "core/application.h"
 | 
				
			||||||
 | 
					#include "core/event_filter.h"
 | 
				
			||||||
 | 
					#include "core/update_checker.h"
 | 
				
			||||||
#include "boxes/peer_list_box.h"
 | 
					#include "boxes/peer_list_box.h"
 | 
				
			||||||
#include "boxes/peers/edit_participants_box.h"
 | 
					#include "boxes/peers/edit_participants_box.h"
 | 
				
			||||||
#include "window/window_controller.h"
 | 
					#include "window/window_controller.h"
 | 
				
			||||||
| 
						 | 
					@ -36,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "data/data_chat.h"
 | 
					#include "data/data_chat.h"
 | 
				
			||||||
#include "data/data_user.h"
 | 
					#include "data/data_user.h"
 | 
				
			||||||
#include "styles/style_dialogs.h"
 | 
					#include "styles/style_dialogs.h"
 | 
				
			||||||
 | 
					#include "styles/style_history.h"
 | 
				
			||||||
#include "styles/style_window.h"
 | 
					#include "styles/style_window.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
| 
						 | 
					@ -158,7 +160,8 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
 | 
				
			||||||
	object_ptr<Ui::IconButton>(this, st::dialogsCalendar))
 | 
						object_ptr<Ui::IconButton>(this, st::dialogsCalendar))
 | 
				
			||||||
, _cancelSearch(this, st::dialogsCancelSearch)
 | 
					, _cancelSearch(this, st::dialogsCancelSearch)
 | 
				
			||||||
, _lockUnlock(this, st::dialogsLock)
 | 
					, _lockUnlock(this, st::dialogsLock)
 | 
				
			||||||
, _scroll(this, st::dialogsScroll) {
 | 
					, _scroll(this, st::dialogsScroll)
 | 
				
			||||||
 | 
					, _scrollToTop(_scroll, st::dialogsToUp) {
 | 
				
			||||||
	_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, controller, parent));
 | 
						_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, controller, parent));
 | 
				
			||||||
	connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
 | 
						connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
 | 
				
			||||||
	connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
 | 
						connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
 | 
				
			||||||
| 
						 | 
					@ -243,6 +246,60 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
 | 
				
			||||||
	updateSearchFromVisibility(true);
 | 
						updateSearchFromVisibility(true);
 | 
				
			||||||
	setupConnectingWidget();
 | 
						setupConnectingWidget();
 | 
				
			||||||
	setupSupportMode();
 | 
						setupSupportMode();
 | 
				
			||||||
 | 
						setupScrollUpButton();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DialogsWidget::setupScrollUpButton() {
 | 
				
			||||||
 | 
						_scrollToTop->setClickedCallback([=] {
 | 
				
			||||||
 | 
							if (_scrollToAnimation.animating()) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							scrollToTop();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						Core::InstallEventFilter(_scrollToTop, [=](not_null<QEvent*> event) {
 | 
				
			||||||
 | 
							if (event->type() == QEvent::Wheel) {
 | 
				
			||||||
 | 
								return _scroll->viewportEvent(event);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						updateScrollUpVisibility();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DialogsWidget::updateScrollUpVisibility() {
 | 
				
			||||||
 | 
						if (_scrollToAnimation.animating()) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						startScrollUpButtonAnimation(
 | 
				
			||||||
 | 
							_scroll->scrollTop() > st::historyToDownShownAfter);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DialogsWidget::startScrollUpButtonAnimation(bool shown) {
 | 
				
			||||||
 | 
						if (_scrollToTopIsShown == shown) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_scrollToTopIsShown = shown;
 | 
				
			||||||
 | 
						_scrollToTopShown.start(
 | 
				
			||||||
 | 
							[=] { updateScrollUpPosition(); },
 | 
				
			||||||
 | 
							_scrollToTopIsShown ? 0. : 1.,
 | 
				
			||||||
 | 
							_scrollToTopIsShown ? 1. : 0.,
 | 
				
			||||||
 | 
							st::historyToDownDuration);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DialogsWidget::updateScrollUpPosition() {
 | 
				
			||||||
 | 
						// _scrollToTop is a child widget of _scroll, not me.
 | 
				
			||||||
 | 
						auto top = anim::interpolate(
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							_scrollToTop->height() + st::historyToDownPosition.y(),
 | 
				
			||||||
 | 
							_scrollToTopShown.value(_scrollToTopIsShown ? 1. : 0.));
 | 
				
			||||||
 | 
						_scrollToTop->moveToRight(
 | 
				
			||||||
 | 
							st::historyToDownPosition.x(),
 | 
				
			||||||
 | 
							_scroll->height() - top);
 | 
				
			||||||
 | 
						const auto shouldBeHidden =
 | 
				
			||||||
 | 
							!_scrollToTopIsShown && !_scrollToTopShown.animating();
 | 
				
			||||||
 | 
						if (shouldBeHidden != _scrollToTop->isHidden()) {
 | 
				
			||||||
 | 
							_scrollToTop->setVisible(!shouldBeHidden);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DialogsWidget::setupConnectingWidget() {
 | 
					void DialogsWidget::setupConnectingWidget() {
 | 
				
			||||||
| 
						 | 
					@ -328,33 +385,39 @@ void DialogsWidget::repaintDialogRow(Dialogs::RowDescriptor row) {
 | 
				
			||||||
	_inner->repaintDialogRow(row);
 | 
						_inner->repaintDialogRow(row);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DialogsWidget::dialogsToUp() {
 | 
					void DialogsWidget::jumpToTop() {
 | 
				
			||||||
	if (Auth().supportMode()) {
 | 
						if (Auth().supportMode()) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (_filter->getLastText().trimmed().isEmpty() && !_searchInChat) {
 | 
						if ((_filter->getLastText().trimmed().isEmpty() && !_searchInChat)) {
 | 
				
			||||||
		_scrollToAnimation.stop();
 | 
							scrollToTop();
 | 
				
			||||||
		auto scrollTop = _scroll->scrollTop();
 | 
					 | 
				
			||||||
		const auto scrollTo = 0;
 | 
					 | 
				
			||||||
		const auto maxAnimatedDelta = _scroll->height();
 | 
					 | 
				
			||||||
		if (scrollTo + maxAnimatedDelta < scrollTop) {
 | 
					 | 
				
			||||||
			scrollTop = scrollTo + maxAnimatedDelta;
 | 
					 | 
				
			||||||
			_scroll->scrollToY(scrollTop);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const auto scroll = [=] {
 | 
					 | 
				
			||||||
			_scroll->scrollToY(qRound(_scrollToAnimation.value(scrollTo)));
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		_scrollToAnimation.start(
 | 
					 | 
				
			||||||
			scroll,
 | 
					 | 
				
			||||||
			scrollTop,
 | 
					 | 
				
			||||||
			scrollTo,
 | 
					 | 
				
			||||||
			st::slideDuration,
 | 
					 | 
				
			||||||
			anim::sineInOut);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DialogsWidget::scrollToTop() {
 | 
				
			||||||
 | 
						_scrollToAnimation.stop();
 | 
				
			||||||
 | 
						auto scrollTop = _scroll->scrollTop();
 | 
				
			||||||
 | 
						const auto scrollTo = 0;
 | 
				
			||||||
 | 
						const auto maxAnimatedDelta = _scroll->height();
 | 
				
			||||||
 | 
						if (scrollTo + maxAnimatedDelta < scrollTop) {
 | 
				
			||||||
 | 
							scrollTop = scrollTo + maxAnimatedDelta;
 | 
				
			||||||
 | 
							_scroll->scrollToY(scrollTop);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						startScrollUpButtonAnimation(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto scroll = [=] {
 | 
				
			||||||
 | 
							_scroll->scrollToY(qRound(_scrollToAnimation.value(scrollTo)));
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_scrollToAnimation.start(
 | 
				
			||||||
 | 
							scroll,
 | 
				
			||||||
 | 
							scrollTop,
 | 
				
			||||||
 | 
							scrollTo,
 | 
				
			||||||
 | 
							st::slideDuration,
 | 
				
			||||||
 | 
							anim::sineInOut);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DialogsWidget::startWidthAnimation() {
 | 
					void DialogsWidget::startWidthAnimation() {
 | 
				
			||||||
	if (!_widthAnimationCache.isNull()) {
 | 
						if (!_widthAnimationCache.isNull()) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -1157,6 +1220,7 @@ void DialogsWidget::dropEvent(QDropEvent *e) {
 | 
				
			||||||
void DialogsWidget::onListScroll() {
 | 
					void DialogsWidget::onListScroll() {
 | 
				
			||||||
	auto scrollTop = _scroll->scrollTop();
 | 
						auto scrollTop = _scroll->scrollTop();
 | 
				
			||||||
	_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
 | 
						_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
 | 
				
			||||||
 | 
						updateScrollUpVisibility();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DialogsWidget::applyFilterUpdate(bool force) {
 | 
					void DialogsWidget::applyFilterUpdate(bool force) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "ui/effects/animations.h"
 | 
					#include "ui/effects/animations.h"
 | 
				
			||||||
#include "ui/widgets/scroll_area.h"
 | 
					#include "ui/widgets/scroll_area.h"
 | 
				
			||||||
#include "dialogs/dialogs_key.h"
 | 
					#include "dialogs/dialogs_key.h"
 | 
				
			||||||
 | 
					#include "ui/special_buttons.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DialogsInner;
 | 
					class DialogsInner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,7 +65,7 @@ public:
 | 
				
			||||||
	void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row);
 | 
						void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row);
 | 
				
			||||||
	void repaintDialogRow(Dialogs::RowDescriptor row);
 | 
						void repaintDialogRow(Dialogs::RowDescriptor row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void dialogsToUp();
 | 
						void jumpToTop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void startWidthAnimation();
 | 
						void startWidthAnimation();
 | 
				
			||||||
	void stopWidthAnimation();
 | 
						void stopWidthAnimation();
 | 
				
			||||||
| 
						 | 
					@ -205,6 +206,16 @@ private:
 | 
				
			||||||
	Window::SlideDirection _showDirection;
 | 
						Window::SlideDirection _showDirection;
 | 
				
			||||||
	QPixmap _cacheUnder, _cacheOver;
 | 
						QPixmap _cacheUnder, _cacheOver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Ui::Animations::Simple _scrollToTopShown;
 | 
				
			||||||
 | 
						bool _scrollToTopIsShown = false;
 | 
				
			||||||
 | 
						object_ptr<Ui::HistoryDownButton> _scrollToTop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void scrollToTop();
 | 
				
			||||||
 | 
						void setupScrollUpButton();
 | 
				
			||||||
 | 
						void updateScrollUpVisibility();
 | 
				
			||||||
 | 
						void startScrollUpButtonAnimation(bool shown);
 | 
				
			||||||
 | 
						void updateScrollUpPosition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Dialogs::Key _searchInChat;
 | 
						Dialogs::Key _searchInChat;
 | 
				
			||||||
	History *_searchInMigrated = nullptr;
 | 
						History *_searchInMigrated = nullptr;
 | 
				
			||||||
	UserData *_searchFromUser = nullptr;
 | 
						UserData *_searchFromUser = nullptr;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,14 @@ historyToDownBadgeSize: 22px;
 | 
				
			||||||
historyToDownShownAfter: 480px;
 | 
					historyToDownShownAfter: 480px;
 | 
				
			||||||
historyToDownDuration: 150;
 | 
					historyToDownDuration: 150;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dialogsToUpAbove: icon {{ "history_down_arrow-flip_vertical", historyToDownFg, point(17px, 20px) }};
 | 
				
			||||||
 | 
					dialogsToUpAboveOver: icon {{ "history_down_arrow-flip_vertical", historyToDownFgOver, point(17px, 20px) }};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dialogsToUp: TwoIconButton(historyToDown) {
 | 
				
			||||||
 | 
						iconAbove: dialogsToUpAbove;
 | 
				
			||||||
 | 
						iconAboveOver: dialogsToUpAboveOver;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
historyUnreadMentions: TwoIconButton(historyToDown) {
 | 
					historyUnreadMentions: TwoIconButton(historyToDown) {
 | 
				
			||||||
	iconAbove: icon {{ "history_unread_mention", historyToDownFg, point(16px, 16px) }};
 | 
						iconAbove: icon {{ "history_unread_mention", historyToDownFg, point(16px, 16px) }};
 | 
				
			||||||
	iconAboveOver: icon {{ "history_unread_mention", historyToDownFgOver, point(16px, 16px) }};
 | 
						iconAboveOver: icon {{ "history_unread_mention", historyToDownFgOver, point(16px, 16px) }};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2217,7 +2217,7 @@ void MainWidget::historyToDown(History *history) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::dialogsToUp() {
 | 
					void MainWidget::dialogsToUp() {
 | 
				
			||||||
	_dialogs->dialogsToUp();
 | 
						_dialogs->jumpToTop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::newUnreadMsg(
 | 
					void MainWidget::newUnreadMsg(
 | 
				
			||||||
| 
						 | 
					@ -2803,7 +2803,6 @@ int MainWidget::backgroundFromY() const {
 | 
				
			||||||
void MainWidget::searchInChat(Dialogs::Key chat) {
 | 
					void MainWidget::searchInChat(Dialogs::Key chat) {
 | 
				
			||||||
	_dialogs->searchInChat(chat);
 | 
						_dialogs->searchInChat(chat);
 | 
				
			||||||
	if (Adaptive::OneColumn()) {
 | 
						if (Adaptive::OneColumn()) {
 | 
				
			||||||
		dialogsToUp();
 | 
					 | 
				
			||||||
		Ui::showChatsList();
 | 
							Ui::showChatsList();
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_dialogs->activate();
 | 
							_dialogs->activate();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue