mirror of https://github.com/procxx/kepka.git
				
				
				
			ShareBox and CountrySelect use Ui::MultiSelect as a search field.
This commit is contained in:
		
							parent
							
								
									48332c0c6b
								
							
						
					
					
						commit
						8bc4e3816b
					
				| 
						 | 
					@ -68,37 +68,6 @@ aboutRevokePublicLabel: flatLabel(labelDefFlat) {
 | 
				
			||||||
	textFg: windowTextFg;
 | 
						textFg: windowTextFg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
boxSearchField: InputField(defaultInputField) {
 | 
					 | 
				
			||||||
	textBg: transparent;
 | 
					 | 
				
			||||||
	textMargins: margins(2px, 7px, 2px, 0px);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	placeholderFg: #999;
 | 
					 | 
				
			||||||
	placeholderFgActive: #aaa;
 | 
					 | 
				
			||||||
	placeholderMargins: margins(2px, 0px, 2px, 0px);
 | 
					 | 
				
			||||||
	duration: 150;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	border: 0px;
 | 
					 | 
				
			||||||
	borderActive: 0px;
 | 
					 | 
				
			||||||
	borderError: 0px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	height: 32px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	font: normalFont;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
boxSearchCancel: IconButton {
 | 
					 | 
				
			||||||
	width: 41px;
 | 
					 | 
				
			||||||
	height: 48px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	opacity: 0.3;
 | 
					 | 
				
			||||||
	overOpacity: 0.4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	icon: icon {{ "box_search_cancel", #000000 }};
 | 
					 | 
				
			||||||
	iconPosition: point(8px, 18px);
 | 
					 | 
				
			||||||
	downIconPosition: point(8px, 19px);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	duration: 150;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
contactsMultiSelect: MultiSelect {
 | 
					contactsMultiSelect: MultiSelect {
 | 
				
			||||||
	padding: margins(8px, 8px, 8px, 8px);
 | 
						padding: margins(8px, 8px, 8px, 8px);
 | 
				
			||||||
	maxHeight: 104px;
 | 
						maxHeight: 104px;
 | 
				
			||||||
| 
						 | 
					@ -128,12 +97,40 @@ contactsMultiSelect: MultiSelect {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	itemSkip: 8px;
 | 
						itemSkip: 8px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	field: boxSearchField;
 | 
						field: InputField(defaultInputField) {
 | 
				
			||||||
 | 
							textBg: transparent;
 | 
				
			||||||
 | 
							textMargins: margins(2px, 7px, 2px, 0px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							placeholderFg: #999;
 | 
				
			||||||
 | 
							placeholderFgActive: #aaa;
 | 
				
			||||||
 | 
							placeholderMargins: margins(2px, 0px, 2px, 0px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							border: 0px;
 | 
				
			||||||
 | 
							borderActive: 0px;
 | 
				
			||||||
 | 
							borderError: 0px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							height: 32px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							font: normalFont;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fieldMinWidth: 42px;
 | 
				
			||||||
	fieldIcon: icon {{ "box_search_icon", #aaaaaa, point(11px, 9px) }};
 | 
						fieldIcon: icon {{ "box_search_icon", #aaaaaa, point(11px, 9px) }};
 | 
				
			||||||
	fieldIconSkip: 36px;
 | 
						fieldIconSkip: 36px;
 | 
				
			||||||
	fieldCancel: boxSearchCancel;
 | 
					
 | 
				
			||||||
 | 
						fieldCancel: IconButton {
 | 
				
			||||||
 | 
							width: 41px;
 | 
				
			||||||
 | 
							height: 48px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							opacity: 0.3;
 | 
				
			||||||
 | 
							overOpacity: 0.4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							icon: icon {{ "box_search_cancel", #000000 }};
 | 
				
			||||||
 | 
							iconPosition: point(8px, 18px);
 | 
				
			||||||
 | 
							downIconPosition: point(8px, 19px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							duration: 150;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	fieldCancelSkip: 34px;
 | 
						fieldCancelSkip: 34px;
 | 
				
			||||||
	fieldMinWidth: 42px;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
contactsPhotoCheckbox: RoundImageCheckbox {
 | 
					contactsPhotoCheckbox: RoundImageCheckbox {
 | 
				
			||||||
	imageRadius: 21px;
 | 
						imageRadius: 21px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "application.h"
 | 
					#include "application.h"
 | 
				
			||||||
#include "ui/filedialog.h"
 | 
					#include "ui/filedialog.h"
 | 
				
			||||||
#include "ui/widgets/multi_select.h"
 | 
					#include "ui/widgets/multi_select.h"
 | 
				
			||||||
 | 
					#include "ui/widgets/widget_slide_wrap.h"
 | 
				
			||||||
#include "boxes/photocropbox.h"
 | 
					#include "boxes/photocropbox.h"
 | 
				
			||||||
#include "boxes/confirmbox.h"
 | 
					#include "boxes/confirmbox.h"
 | 
				
			||||||
#include "observer_peer.h"
 | 
					#include "observer_peer.h"
 | 
				
			||||||
| 
						 | 
					@ -43,7 +44,7 @@ QString cantInviteError() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ContactsBox::ContactsBox() : ItemListBox(st::contactsScroll)
 | 
					ContactsBox::ContactsBox() : ItemListBox(st::contactsScroll)
 | 
				
			||||||
, _inner(this, CreatingGroupNone)
 | 
					, _inner(this, CreatingGroupNone)
 | 
				
			||||||
, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
					, _select(this, new Ui::MultiSelect(this, st::contactsMultiSelect, lang(lng_participant_filter)), QMargins(0, 0, 0, 0), [this] { updateScrollSkips(); })
 | 
				
			||||||
, _next(this, lang(lng_create_group_next), st::defaultBoxButton)
 | 
					, _next(this, lang(lng_create_group_next), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this) {
 | 
					, _topShadow(this) {
 | 
				
			||||||
| 
						 | 
					@ -52,7 +53,7 @@ ContactsBox::ContactsBox() : ItemListBox(st::contactsScroll)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ContactsBox::ContactsBox(const QString &name, const QImage &photo) : ItemListBox(st::boxScroll)
 | 
					ContactsBox::ContactsBox(const QString &name, const QImage &photo) : ItemListBox(st::boxScroll)
 | 
				
			||||||
, _inner(this, CreatingGroupGroup)
 | 
					, _inner(this, CreatingGroupGroup)
 | 
				
			||||||
, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
					, _select(this, new Ui::MultiSelect(this, st::contactsMultiSelect, lang(lng_participant_filter)), QMargins(0, 0, 0, 0), [this] { updateScrollSkips(); })
 | 
				
			||||||
, _next(this, lang(lng_create_group_create), st::defaultBoxButton)
 | 
					, _next(this, lang(lng_create_group_create), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_create_group_back), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_create_group_back), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this)
 | 
					, _topShadow(this)
 | 
				
			||||||
| 
						 | 
					@ -63,7 +64,7 @@ ContactsBox::ContactsBox(const QString &name, const QImage &photo) : ItemListBox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ContactsBox::ContactsBox(ChannelData *channel) : ItemListBox(st::boxScroll)
 | 
					ContactsBox::ContactsBox(ChannelData *channel) : ItemListBox(st::boxScroll)
 | 
				
			||||||
, _inner(this, channel, MembersFilter::Recent, MembersAlreadyIn())
 | 
					, _inner(this, channel, MembersFilter::Recent, MembersAlreadyIn())
 | 
				
			||||||
, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
					, _select(this, new Ui::MultiSelect(this, st::contactsMultiSelect, lang(lng_participant_filter)), QMargins(0, 0, 0, 0), [this] { updateScrollSkips(); })
 | 
				
			||||||
, _next(this, lang(lng_participant_invite), st::defaultBoxButton)
 | 
					, _next(this, lang(lng_participant_invite), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_create_group_skip), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_create_group_skip), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this) {
 | 
					, _topShadow(this) {
 | 
				
			||||||
| 
						 | 
					@ -72,7 +73,7 @@ ContactsBox::ContactsBox(ChannelData *channel) : ItemListBox(st::boxScroll)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ContactsBox::ContactsBox(ChannelData *channel, MembersFilter filter, const MembersAlreadyIn &already) : ItemListBox((filter == MembersFilter::Admins) ? st::contactsScroll : st::boxScroll)
 | 
					ContactsBox::ContactsBox(ChannelData *channel, MembersFilter filter, const MembersAlreadyIn &already) : ItemListBox((filter == MembersFilter::Admins) ? st::contactsScroll : st::boxScroll)
 | 
				
			||||||
, _inner(this, channel, filter, already)
 | 
					, _inner(this, channel, filter, already)
 | 
				
			||||||
, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
					, _select(this, new Ui::MultiSelect(this, st::contactsMultiSelect, lang(lng_participant_filter)), QMargins(0, 0, 0, 0), [this] { updateScrollSkips(); })
 | 
				
			||||||
, _next(this, lang(lng_participant_invite), st::defaultBoxButton)
 | 
					, _next(this, lang(lng_participant_invite), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this) {
 | 
					, _topShadow(this) {
 | 
				
			||||||
| 
						 | 
					@ -81,7 +82,7 @@ ContactsBox::ContactsBox(ChannelData *channel, MembersFilter filter, const Membe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ContactsBox::ContactsBox(ChatData *chat, MembersFilter filter) : ItemListBox(st::boxScroll)
 | 
					ContactsBox::ContactsBox(ChatData *chat, MembersFilter filter) : ItemListBox(st::boxScroll)
 | 
				
			||||||
, _inner(this, chat, filter)
 | 
					, _inner(this, chat, filter)
 | 
				
			||||||
, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
					, _select(this, new Ui::MultiSelect(this, st::contactsMultiSelect, lang(lng_participant_filter)), QMargins(0, 0, 0, 0), [this] { updateScrollSkips(); })
 | 
				
			||||||
, _next(this, lang((filter == MembersFilter::Admins) ? lng_settings_save : lng_participant_invite), st::defaultBoxButton)
 | 
					, _next(this, lang((filter == MembersFilter::Admins) ? lng_settings_save : lng_participant_invite), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this) {
 | 
					, _topShadow(this) {
 | 
				
			||||||
| 
						 | 
					@ -90,7 +91,7 @@ ContactsBox::ContactsBox(ChatData *chat, MembersFilter filter) : ItemListBox(st:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ContactsBox::ContactsBox(UserData *bot) : ItemListBox(st::contactsScroll)
 | 
					ContactsBox::ContactsBox(UserData *bot) : ItemListBox(st::contactsScroll)
 | 
				
			||||||
, _inner(this, bot)
 | 
					, _inner(this, bot)
 | 
				
			||||||
, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
					, _select(this, new Ui::MultiSelect(this, st::contactsMultiSelect, lang(lng_participant_filter)), QMargins(0, 0, 0, 0), [this] { updateScrollSkips(); })
 | 
				
			||||||
, _next(this, lang(lng_create_group_next), st::defaultBoxButton)
 | 
					, _next(this, lang(lng_create_group_next), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this) {
 | 
					, _topShadow(this) {
 | 
				
			||||||
| 
						 | 
					@ -101,7 +102,7 @@ void ContactsBox::init() {
 | 
				
			||||||
	_select->resizeToWidth(st::boxWideWidth);
 | 
						_select->resizeToWidth(st::boxWideWidth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto inviting = (_inner->creating() == CreatingGroupGroup) || (_inner->channel() && _inner->membersFilter() == MembersFilter::Recent) || _inner->chat();
 | 
						auto inviting = (_inner->creating() == CreatingGroupGroup) || (_inner->channel() && _inner->membersFilter() == MembersFilter::Recent) || _inner->chat();
 | 
				
			||||||
	auto topSkip = st::boxTitleHeight + _select->height();
 | 
						auto topSkip = getTopScrollSkip();
 | 
				
			||||||
	auto bottomSkip = inviting ? (st::boxButtonPadding.top() + _next.height() + st::boxButtonPadding.bottom()) : st::boxScrollSkip;
 | 
						auto bottomSkip = inviting ? (st::boxButtonPadding.top() + _next.height() + st::boxButtonPadding.bottom()) : st::boxScrollSkip;
 | 
				
			||||||
	ItemListBox::init(_inner, bottomSkip, topSkip);
 | 
						ItemListBox::init(_inner, bottomSkip, topSkip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,6 +110,20 @@ void ContactsBox::init() {
 | 
				
			||||||
	_inner->setPeerSelectedChangedCallback([this](PeerData *peer, bool checked) {
 | 
						_inner->setPeerSelectedChangedCallback([this](PeerData *peer, bool checked) {
 | 
				
			||||||
		onPeerSelectedChanged(peer, checked);
 | 
							onPeerSelectedChanged(peer, checked);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
						for (auto i : _inner->selected()) {
 | 
				
			||||||
 | 
							addPeerToMultiSelect(i, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_inner->setAllAdminsChangedCallback([this] {
 | 
				
			||||||
 | 
							if (_inner->allAdmins()) {
 | 
				
			||||||
 | 
								_select->entity()->clearQuery();
 | 
				
			||||||
 | 
								_select->slideUp();
 | 
				
			||||||
 | 
								_inner->setFocus();
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								_select->slideDown();
 | 
				
			||||||
 | 
								_select->entity()->setInnerFocus();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							updateScrollSkips();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (_inner->channel() && _inner->membersFilter() == MembersFilter::Admins) {
 | 
						if (_inner->channel() && _inner->membersFilter() == MembersFilter::Admins) {
 | 
				
			||||||
		_next.hide();
 | 
							_next.hide();
 | 
				
			||||||
| 
						 | 
					@ -128,15 +143,14 @@ void ContactsBox::init() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
 | 
						connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
 | 
				
			||||||
	connect(scrollArea(), SIGNAL(scrolled()), this, SLOT(onScroll()));
 | 
						connect(scrollArea(), SIGNAL(scrolled()), this, SLOT(onScroll()));
 | 
				
			||||||
	_select->setQueryChangedCallback([this](const QString &query) { onFilterUpdate(query); });
 | 
						_select->entity()->setQueryChangedCallback([this](const QString &query) { onFilterUpdate(query); });
 | 
				
			||||||
	_select->setItemRemovedCallback([this](uint64 itemId) {
 | 
						_select->entity()->setItemRemovedCallback([this](uint64 itemId) {
 | 
				
			||||||
		if (auto peer = App::peerLoaded(itemId)) {
 | 
							if (auto peer = App::peerLoaded(itemId)) {
 | 
				
			||||||
			_inner->peerUnselected(peer);
 | 
								_inner->peerUnselected(peer);
 | 
				
			||||||
			update();
 | 
								update();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
	_select->setSubmittedCallback([this](bool) { onSubmit(); });
 | 
						_select->entity()->setSubmittedCallback([this](bool) { onSubmit(); });
 | 
				
			||||||
	_select->setResizedCallback([this] { updateScrollSkips(); });
 | 
					 | 
				
			||||||
	connect(_inner, SIGNAL(mustScrollTo(int, int)), scrollArea(), SLOT(scrollToY(int, int)));
 | 
						connect(_inner, SIGNAL(mustScrollTo(int, int)), scrollArea(), SLOT(scrollToY(int, int)));
 | 
				
			||||||
	connect(_inner, SIGNAL(searchByUsername()), this, SLOT(onNeedSearchByUsername()));
 | 
						connect(_inner, SIGNAL(searchByUsername()), this, SLOT(onNeedSearchByUsername()));
 | 
				
			||||||
	connect(_inner, SIGNAL(adminAdded()), this, SIGNAL(adminAdded()));
 | 
						connect(_inner, SIGNAL(adminAdded()), this, SIGNAL(adminAdded()));
 | 
				
			||||||
| 
						 | 
					@ -148,7 +162,7 @@ void ContactsBox::init() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ContactsBox::onSearchByUsername(bool searchCache) {
 | 
					bool ContactsBox::onSearchByUsername(bool searchCache) {
 | 
				
			||||||
	auto q = _select->getQuery();
 | 
						auto q = _select->entity()->getQuery();
 | 
				
			||||||
	if (q.isEmpty()) {
 | 
						if (q.isEmpty()) {
 | 
				
			||||||
		if (_peopleRequest) {
 | 
							if (_peopleRequest) {
 | 
				
			||||||
			_peopleRequest = 0;
 | 
								_peopleRequest = 0;
 | 
				
			||||||
| 
						 | 
					@ -216,7 +230,11 @@ bool ContactsBox::peopleFailed(const RPCError &error, mtpRequestId req) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::showAll() {
 | 
					void ContactsBox::showAll() {
 | 
				
			||||||
	_select->show();
 | 
						if (_inner->chat() && _inner->membersFilter() == MembersFilter::Admins && _inner->allAdmins()) {
 | 
				
			||||||
 | 
							_select->hideFast();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							_select->showFast();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (_inner->channel() && _inner->membersFilter() == MembersFilter::Admins) {
 | 
						if (_inner->channel() && _inner->membersFilter() == MembersFilter::Admins) {
 | 
				
			||||||
		_next.hide();
 | 
							_next.hide();
 | 
				
			||||||
		_cancel.hide();
 | 
							_cancel.hide();
 | 
				
			||||||
| 
						 | 
					@ -236,7 +254,11 @@ void ContactsBox::showAll() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::doSetInnerFocus() {
 | 
					void ContactsBox::doSetInnerFocus() {
 | 
				
			||||||
	_select->setInnerFocus();
 | 
						if (_select->isHidden()) {
 | 
				
			||||||
 | 
							_inner->setFocus();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							_select->entity()->setInnerFocus();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::onSubmit() {
 | 
					void ContactsBox::onSubmit() {
 | 
				
			||||||
| 
						 | 
					@ -282,10 +304,18 @@ void ContactsBox::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ContactsBox::getTopScrollSkip() const {
 | 
				
			||||||
 | 
						auto result = st::boxTitleHeight;
 | 
				
			||||||
 | 
						if (!_select->isHidden()) {
 | 
				
			||||||
 | 
							result += _select->height();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::updateScrollSkips() {
 | 
					void ContactsBox::updateScrollSkips() {
 | 
				
			||||||
	auto oldScrollHeight = scrollArea()->height();
 | 
						auto oldScrollHeight = scrollArea()->height();
 | 
				
			||||||
	auto inviting = (_inner->creating() == CreatingGroupGroup) || (_inner->channel() && _inner->membersFilter() == MembersFilter::Recent) || _inner->chat();
 | 
						auto inviting = (_inner->creating() == CreatingGroupGroup) || (_inner->channel() && _inner->membersFilter() == MembersFilter::Recent) || _inner->chat();
 | 
				
			||||||
	auto topSkip = st::boxTitleHeight + _select->height();
 | 
						auto topSkip = getTopScrollSkip();
 | 
				
			||||||
	auto bottomSkip = inviting ? (st::boxButtonPadding.top() + _next.height() + st::boxButtonPadding.bottom()) : st::boxScrollSkip;
 | 
						auto bottomSkip = inviting ? (st::boxButtonPadding.top() + _next.height() + st::boxButtonPadding.bottom()) : st::boxScrollSkip;
 | 
				
			||||||
	setScrollSkips(bottomSkip, topSkip);
 | 
						setScrollSkips(bottomSkip, topSkip);
 | 
				
			||||||
	auto scrollHeightDelta = scrollArea()->height() - oldScrollHeight;
 | 
						auto scrollHeightDelta = scrollArea()->height() - oldScrollHeight;
 | 
				
			||||||
| 
						 | 
					@ -293,7 +323,7 @@ void ContactsBox::updateScrollSkips() {
 | 
				
			||||||
		scrollArea()->scrollToY(scrollArea()->scrollTop() - scrollHeightDelta);
 | 
							scrollArea()->scrollToY(scrollArea()->scrollTop() - scrollHeightDelta);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_topShadow.setGeometry(0, st::boxTitleHeight + _select->height(), width(), st::lineWidth);
 | 
						_topShadow.setGeometry(0, topSkip, width(), st::lineWidth);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::resizeEvent(QResizeEvent *e) {
 | 
					void ContactsBox::resizeEvent(QResizeEvent *e) {
 | 
				
			||||||
| 
						 | 
					@ -321,24 +351,30 @@ void ContactsBox::onFilterUpdate(const QString &filter) {
 | 
				
			||||||
	_inner->updateFilter(filter);
 | 
						_inner->updateFilter(filter);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ContactsBox::addPeerToMultiSelect(PeerData *peer, bool skipAnimation) {
 | 
				
			||||||
 | 
						auto getColor = [peer]() -> const style::color & {
 | 
				
			||||||
 | 
							switch (peer->colorIndex) {
 | 
				
			||||||
 | 
							case 1: return st::historyPeer2UserpicFg;
 | 
				
			||||||
 | 
							case 2: return st::historyPeer3UserpicFg;
 | 
				
			||||||
 | 
							case 3: return st::historyPeer4UserpicFg;
 | 
				
			||||||
 | 
							case 4: return st::historyPeer5UserpicFg;
 | 
				
			||||||
 | 
							case 5: return st::historyPeer6UserpicFg;
 | 
				
			||||||
 | 
							case 6: return st::historyPeer7UserpicFg;
 | 
				
			||||||
 | 
							case 7: return st::historyPeer8UserpicFg;
 | 
				
			||||||
 | 
							default: return st::historyPeer1UserpicFg;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						using AddItemWay = Ui::MultiSelect::AddItemWay;
 | 
				
			||||||
 | 
						auto addItemWay = skipAnimation ? AddItemWay::SkipAnimation : AddItemWay::Default;
 | 
				
			||||||
 | 
						_select->entity()->addItem(peer->id, peer->shortName(), getColor(), PaintUserpicCallback(peer), addItemWay);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::onPeerSelectedChanged(PeerData *peer, bool checked) {
 | 
					void ContactsBox::onPeerSelectedChanged(PeerData *peer, bool checked) {
 | 
				
			||||||
	if (checked) {
 | 
						if (checked) {
 | 
				
			||||||
		auto getColor = [peer]() -> const style::color &{
 | 
							addPeerToMultiSelect(peer);
 | 
				
			||||||
			switch (peer->colorIndex) {
 | 
							_select->entity()->clearQuery();
 | 
				
			||||||
			case 1: return st::historyPeer2UserpicFg;
 | 
					 | 
				
			||||||
			case 2: return st::historyPeer3UserpicFg;
 | 
					 | 
				
			||||||
			case 3: return st::historyPeer4UserpicFg;
 | 
					 | 
				
			||||||
			case 4: return st::historyPeer5UserpicFg;
 | 
					 | 
				
			||||||
			case 5: return st::historyPeer6UserpicFg;
 | 
					 | 
				
			||||||
			case 6: return st::historyPeer7UserpicFg;
 | 
					 | 
				
			||||||
			case 7: return st::historyPeer8UserpicFg;
 | 
					 | 
				
			||||||
			default: return st::historyPeer1UserpicFg;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		_select->addItem(peer->id, peer->shortName(), getColor(), PaintUserpicCallback(peer));
 | 
					 | 
				
			||||||
		_select->clearQuery();
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_select->removeItem(peer->id);
 | 
							_select->entity()->removeItem(peer->id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	update();
 | 
						update();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -346,7 +382,7 @@ void ContactsBox::onPeerSelectedChanged(PeerData *peer, bool checked) {
 | 
				
			||||||
void ContactsBox::onInvite() {
 | 
					void ContactsBox::onInvite() {
 | 
				
			||||||
	QVector<UserData*> users(_inner->selected());
 | 
						QVector<UserData*> users(_inner->selected());
 | 
				
			||||||
	if (users.isEmpty()) {
 | 
						if (users.isEmpty()) {
 | 
				
			||||||
		_select->setInnerFocus();
 | 
							_select->entity()->setInnerFocus();
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -364,7 +400,7 @@ void ContactsBox::onCreate() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto users = _inner->selectedInputs();
 | 
						auto users = _inner->selectedInputs();
 | 
				
			||||||
	if (users.isEmpty() || (users.size() == 1 && users.at(0).type() == mtpc_inputUserSelf)) {
 | 
						if (users.isEmpty() || (users.size() == 1 && users.at(0).type() == mtpc_inputUserSelf)) {
 | 
				
			||||||
		_select->setInnerFocus();
 | 
							_select->entity()->setInnerFocus();
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_saveRequestId = MTP::send(MTPmessages_CreateChat(MTP_vector<MTPInputUser>(users), MTP_string(_creationName)), rpcDone(&ContactsBox::creationDone), rpcFail(&ContactsBox::creationFail));
 | 
						_saveRequestId = MTP::send(MTPmessages_CreateChat(MTP_vector<MTPInputUser>(users), MTP_string(_creationName)), rpcDone(&ContactsBox::creationDone), rpcFail(&ContactsBox::creationFail));
 | 
				
			||||||
| 
						 | 
					@ -514,7 +550,7 @@ bool ContactsBox::creationFail(const RPCError &error) {
 | 
				
			||||||
		onClose();
 | 
							onClose();
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	} else if (error.type() == "USERS_TOO_FEW") {
 | 
						} else if (error.type() == "USERS_TOO_FEW") {
 | 
				
			||||||
		_select->setInnerFocus();
 | 
							_select->entity()->setInnerFocus();
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	} else if (error.type() == "PEER_FLOOD") {
 | 
						} else if (error.type() == "PEER_FLOOD") {
 | 
				
			||||||
		Ui::showLayer(new InformBox(cantInviteError()), KeepOtherLayers);
 | 
							Ui::showLayer(new InformBox(cantInviteError()), KeepOtherLayers);
 | 
				
			||||||
| 
						 | 
					@ -641,7 +677,7 @@ void ContactsBox::Inner::init() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::Inner::initList() {
 | 
					void ContactsBox::Inner::initList() {
 | 
				
			||||||
	if (!usingMultiSelect()) return;
 | 
						if (!_chat || _membersFilter != MembersFilter::Admins) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QList<UserData*> admins, others;
 | 
						QList<UserData*> admins, others;
 | 
				
			||||||
	admins.reserve(_chat->admins.size() + 1);
 | 
						admins.reserve(_chat->admins.size() + 1);
 | 
				
			||||||
| 
						 | 
					@ -653,7 +689,9 @@ void ContactsBox::Inner::initList() {
 | 
				
			||||||
		if (i.key()->id == peerFromUser(_chat->creator)) continue;
 | 
							if (i.key()->id == peerFromUser(_chat->creator)) continue;
 | 
				
			||||||
		if (!_allAdmins.checked() && _chat->admins.contains(i.key())) {
 | 
							if (!_allAdmins.checked() && _chat->admins.contains(i.key())) {
 | 
				
			||||||
			admins.push_back(i.key());
 | 
								admins.push_back(i.key());
 | 
				
			||||||
			_checkedContacts.insert(i.key());
 | 
								if (!_checkedContacts.contains(i.key())) {
 | 
				
			||||||
 | 
									_checkedContacts.insert(i.key());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			others.push_back(i.key());
 | 
								others.push_back(i.key());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -716,10 +754,10 @@ void ContactsBox::Inner::onNoAddAdminBox(QObject *obj) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ContactsBox::Inner::onAllAdminsChanged() {
 | 
					void ContactsBox::Inner::onAllAdminsChanged() {
 | 
				
			||||||
	if (_saving) {
 | 
						if (_saving && _allAdmins.checked() != _allAdminsChecked) {
 | 
				
			||||||
		if (_allAdmins.checked() != _allAdminsChecked) {
 | 
							_allAdmins.setChecked(_allAdminsChecked);
 | 
				
			||||||
			_allAdmins.setChecked(_allAdminsChecked);
 | 
						} else if (_allAdminsChangedCallback) {
 | 
				
			||||||
		}
 | 
							_allAdminsChangedCallback();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	update();
 | 
						update();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1355,7 +1393,8 @@ void ContactsBox::Inner::changeCheckState(Dialogs::Row *row) {
 | 
				
			||||||
void ContactsBox::Inner::changeCheckState(ContactData *data, PeerData *peer) {
 | 
					void ContactsBox::Inner::changeCheckState(ContactData *data, PeerData *peer) {
 | 
				
			||||||
	t_assert(usingMultiSelect());
 | 
						t_assert(usingMultiSelect());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (data->checkbox->checked()) {
 | 
						if (_chat && _membersFilter == MembersFilter::Admins && _allAdmins.checked()) {
 | 
				
			||||||
 | 
						} else if (data->checkbox->checked()) {
 | 
				
			||||||
		changePeerCheckState(data, peer, false);
 | 
							changePeerCheckState(data, peer, false);
 | 
				
			||||||
	} else if (selectedCount() < ((_channel && _channel->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
 | 
						} else if (selectedCount() < ((_channel && _channel->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
 | 
				
			||||||
		changePeerCheckState(data, peer, true);
 | 
							changePeerCheckState(data, peer, true);
 | 
				
			||||||
| 
						 | 
					@ -1385,7 +1424,7 @@ void ContactsBox::Inner::changePeerCheckState(ContactData *data, PeerData *peer,
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_checkedContacts.remove(peer);
 | 
							_checkedContacts.remove(peer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (useCallback != ChangeStateWay::SkipCallback) {
 | 
						if (useCallback != ChangeStateWay::SkipCallback && _peerSelectedChangedCallback) {
 | 
				
			||||||
		_peerSelectedChangedCallback(peer, checked);
 | 
							_peerSelectedChangedCallback(peer, checked);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1874,12 +1913,12 @@ QVector<UserData*> ContactsBox::Inner::selected() {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result.reserve(_contactsData.size());
 | 
						result.reserve(_contactsData.size());
 | 
				
			||||||
	for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
 | 
						for (auto i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
 | 
				
			||||||
		if (i.value()->checkbox->checked() && i.key()->isUser()) {
 | 
							if (i.value()->checkbox->checked() && i.key()->isUser()) {
 | 
				
			||||||
			result.push_back(i.key()->asUser());
 | 
								result.push_back(i.key()->asUser());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (int32 i = 0, l = _byUsername.size(); i < l; ++i) {
 | 
						for (int i = 0, l = _byUsername.size(); i < l; ++i) {
 | 
				
			||||||
		if (d_byUsername[i]->checkbox->checked() && _byUsername[i]->isUser()) {
 | 
							if (d_byUsername[i]->checkbox->checked() && _byUsername[i]->isUser()) {
 | 
				
			||||||
			result.push_back(_byUsername[i]->asUser());
 | 
								result.push_back(_byUsername[i]->asUser());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1899,12 +1938,12 @@ QVector<MTPInputUser> ContactsBox::Inner::selectedInputs() {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result.reserve(_contactsData.size());
 | 
						result.reserve(_contactsData.size());
 | 
				
			||||||
	for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
 | 
						for (auto i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
 | 
				
			||||||
		if (i.value()->checkbox->checked() && i.key()->isUser()) {
 | 
							if (i.value()->checkbox->checked() && i.key()->isUser()) {
 | 
				
			||||||
			result.push_back(i.key()->asUser()->inputUser);
 | 
								result.push_back(i.key()->asUser()->inputUser);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (int32 i = 0, l = _byUsername.size(); i < l; ++i) {
 | 
						for (int i = 0, l = _byUsername.size(); i < l; ++i) {
 | 
				
			||||||
		if (d_byUsername[i]->checkbox->checked() && _byUsername[i]->isUser()) {
 | 
							if (d_byUsername[i]->checkbox->checked() && _byUsername[i]->isUser()) {
 | 
				
			||||||
			result.push_back(_byUsername[i]->asUser()->inputUser);
 | 
								result.push_back(_byUsername[i]->asUser()->inputUser);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,8 @@ class IndexedList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ui {
 | 
					namespace Ui {
 | 
				
			||||||
class MultiSelect;
 | 
					class MultiSelect;
 | 
				
			||||||
 | 
					template <typename Widget>
 | 
				
			||||||
 | 
					class WidgetSlideWrap;
 | 
				
			||||||
} // namespace Ui
 | 
					} // namespace Ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString cantInviteError();
 | 
					QString cantInviteError();
 | 
				
			||||||
| 
						 | 
					@ -79,13 +81,15 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void init();
 | 
						void init();
 | 
				
			||||||
 | 
						int getTopScrollSkip() const;
 | 
				
			||||||
	void updateScrollSkips();
 | 
						void updateScrollSkips();
 | 
				
			||||||
	void onFilterUpdate(const QString &filter);
 | 
						void onFilterUpdate(const QString &filter);
 | 
				
			||||||
	void onPeerSelectedChanged(PeerData *peer, bool checked);
 | 
						void onPeerSelectedChanged(PeerData *peer, bool checked);
 | 
				
			||||||
 | 
						void addPeerToMultiSelect(PeerData *peer, bool skipAnimation = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class Inner;
 | 
						class Inner;
 | 
				
			||||||
	ChildWidget<Inner> _inner;
 | 
						ChildWidget<Inner> _inner;
 | 
				
			||||||
	ChildWidget<Ui::MultiSelect> _select;
 | 
						ChildWidget<Ui::WidgetSlideWrap<Ui::MultiSelect>> _select;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BoxButton _next, _cancel;
 | 
						BoxButton _next, _cancel;
 | 
				
			||||||
	MembersFilter _membersFilter;
 | 
						MembersFilter _membersFilter;
 | 
				
			||||||
| 
						 | 
					@ -151,6 +155,9 @@ public:
 | 
				
			||||||
	bool allAdmins() const {
 | 
						bool allAdmins() const {
 | 
				
			||||||
		return _allAdmins.checked();
 | 
							return _allAdmins.checked();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						void setAllAdminsChangedCallback(base::lambda_unique<void()> allAdminsChangedCallback) {
 | 
				
			||||||
 | 
							_allAdminsChangedCallback = std_::move(allAdminsChangedCallback);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void loadProfilePhotos(int32 yFrom);
 | 
						void loadProfilePhotos(int32 yFrom);
 | 
				
			||||||
	void chooseParticipant();
 | 
						void chooseParticipant();
 | 
				
			||||||
| 
						 | 
					@ -259,6 +266,7 @@ private:
 | 
				
			||||||
	Checkbox _allAdmins;
 | 
						Checkbox _allAdmins;
 | 
				
			||||||
	int32 _aboutWidth;
 | 
						int32 _aboutWidth;
 | 
				
			||||||
	Text _aboutAllAdmins, _aboutAdmins;
 | 
						Text _aboutAllAdmins, _aboutAdmins;
 | 
				
			||||||
 | 
						base::lambda_unique<void()> _allAdminsChangedCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PeerData *_addToPeer = nullptr;
 | 
						PeerData *_addToPeer = nullptr;
 | 
				
			||||||
	UserData *_addAdmin = nullptr;
 | 
						UserData *_addAdmin = nullptr;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dialogs/dialogs_indexed_list.h"
 | 
					#include "dialogs/dialogs_indexed_list.h"
 | 
				
			||||||
#include "styles/style_boxes.h"
 | 
					#include "styles/style_boxes.h"
 | 
				
			||||||
 | 
					#include "styles/style_history.h"
 | 
				
			||||||
#include "observer_peer.h"
 | 
					#include "observer_peer.h"
 | 
				
			||||||
#include "lang.h"
 | 
					#include "lang.h"
 | 
				
			||||||
#include "mainwindow.h"
 | 
					#include "mainwindow.h"
 | 
				
			||||||
| 
						 | 
					@ -32,7 +33,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "boxes/confirmbox.h"
 | 
					#include "boxes/confirmbox.h"
 | 
				
			||||||
#include "apiwrap.h"
 | 
					#include "apiwrap.h"
 | 
				
			||||||
#include "ui/toast/toast.h"
 | 
					#include "ui/toast/toast.h"
 | 
				
			||||||
#include "ui/buttons/icon_button.h"
 | 
					#include "ui/widgets/multi_select.h"
 | 
				
			||||||
#include "history/history_media_types.h"
 | 
					#include "history/history_media_types.h"
 | 
				
			||||||
#include "boxes/contactsbox.h"
 | 
					#include "boxes/contactsbox.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,30 +41,37 @@ ShareBox::ShareBox(CopyCallback &©Callback, SubmitCallback &&submitCallback,
 | 
				
			||||||
, _copyCallback(std_::move(copyCallback))
 | 
					, _copyCallback(std_::move(copyCallback))
 | 
				
			||||||
, _submitCallback(std_::move(submitCallback))
 | 
					, _submitCallback(std_::move(submitCallback))
 | 
				
			||||||
, _inner(this, std_::move(filterCallback))
 | 
					, _inner(this, std_::move(filterCallback))
 | 
				
			||||||
, _filter(this, st::boxSearchField, lang(lng_participant_filter))
 | 
					, _select(this, st::contactsMultiSelect, lang(lng_participant_filter))
 | 
				
			||||||
, _filterCancel(this, st::boxSearchCancel)
 | 
					 | 
				
			||||||
, _copy(this, lang(lng_share_copy_link), st::defaultBoxButton)
 | 
					, _copy(this, lang(lng_share_copy_link), st::defaultBoxButton)
 | 
				
			||||||
, _share(this, lang(lng_share_confirm), st::defaultBoxButton)
 | 
					, _share(this, lang(lng_share_confirm), st::defaultBoxButton)
 | 
				
			||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
					, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
 | 
				
			||||||
, _topShadow(this)
 | 
					, _topShadow(this)
 | 
				
			||||||
, _bottomShadow(this) {
 | 
					, _bottomShadow(this) {
 | 
				
			||||||
	int topSkip = st::boxTitleHeight + _filter->height();
 | 
						_select->resizeToWidth(st::boxWideWidth);
 | 
				
			||||||
	int bottomSkip = st::boxButtonPadding.top() + _share->height() + st::boxButtonPadding.bottom();
 | 
					
 | 
				
			||||||
 | 
						auto topSkip = getTopScrollSkip();
 | 
				
			||||||
 | 
						auto bottomSkip = st::boxButtonPadding.top() + _share->height() + st::boxButtonPadding.bottom();
 | 
				
			||||||
	init(_inner, bottomSkip, topSkip);
 | 
						init(_inner, bottomSkip, topSkip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	connect(_inner, SIGNAL(selectedChanged()), this, SLOT(onSelectedChanged()));
 | 
					 | 
				
			||||||
	connect(_inner, SIGNAL(mustScrollTo(int,int)), this, SLOT(onMustScrollTo(int,int)));
 | 
						connect(_inner, SIGNAL(mustScrollTo(int,int)), this, SLOT(onMustScrollTo(int,int)));
 | 
				
			||||||
	connect(_copy, SIGNAL(clicked()), this, SLOT(onCopyLink()));
 | 
						connect(_copy, SIGNAL(clicked()), this, SLOT(onCopyLink()));
 | 
				
			||||||
	connect(_share, SIGNAL(clicked()), this, SLOT(onSubmit()));
 | 
						connect(_share, SIGNAL(clicked()), this, SLOT(onSubmit()));
 | 
				
			||||||
	connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
 | 
						connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
 | 
				
			||||||
	connect(scrollArea(), SIGNAL(scrolled()), this, SLOT(onScroll()));
 | 
						connect(scrollArea(), SIGNAL(scrolled()), this, SLOT(onScroll()));
 | 
				
			||||||
	connect(_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
 | 
						_select->setQueryChangedCallback([this](const QString &query) { onFilterUpdate(query); });
 | 
				
			||||||
	connect(_filter, SIGNAL(submitted(bool)), _inner, SLOT(onSelectActive()));
 | 
						_select->setItemRemovedCallback([this](uint64 itemId) {
 | 
				
			||||||
	connect(_filterCancel, SIGNAL(clicked()), this, SLOT(onFilterCancel()));
 | 
							if (auto peer = App::peerLoaded(itemId)) {
 | 
				
			||||||
	connect(_inner, SIGNAL(filterCancel()), this, SLOT(onFilterCancel()));
 | 
								_inner->peerUnselected(peer);
 | 
				
			||||||
 | 
								onSelectedChanged();
 | 
				
			||||||
 | 
								update();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						_select->setResizedCallback([this] { updateScrollSkips(); });
 | 
				
			||||||
 | 
						_select->setSubmittedCallback([this](bool) { _inner->onSelectActive(); });
 | 
				
			||||||
	connect(_inner, SIGNAL(searchByUsername()), this, SLOT(onNeedSearchByUsername()));
 | 
						connect(_inner, SIGNAL(searchByUsername()), this, SLOT(onNeedSearchByUsername()));
 | 
				
			||||||
 | 
						_inner->setPeerSelectedChangedCallback([this](PeerData *peer, bool checked) {
 | 
				
			||||||
	_filterCancel->setAttribute(Qt::WA_OpaquePaintEvent);
 | 
							onPeerSelectedChanged(peer, checked);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_searchTimer.setSingleShot(true);
 | 
						_searchTimer.setSingleShot(true);
 | 
				
			||||||
	connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchByUsername()));
 | 
						connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchByUsername()));
 | 
				
			||||||
| 
						 | 
					@ -73,8 +81,29 @@ ShareBox::ShareBox(CopyCallback &©Callback, SubmitCallback &&submitCallback,
 | 
				
			||||||
	prepare();
 | 
						prepare();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ShareBox::getTopScrollSkip() const {
 | 
				
			||||||
 | 
						auto result = st::boxTitleHeight;
 | 
				
			||||||
 | 
						if (!_select->isHidden()) {
 | 
				
			||||||
 | 
							result += _select->height();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShareBox::updateScrollSkips() {
 | 
				
			||||||
 | 
						auto oldScrollHeight = scrollArea()->height();
 | 
				
			||||||
 | 
						auto topSkip = getTopScrollSkip();
 | 
				
			||||||
 | 
						auto bottomSkip = st::boxButtonPadding.top() + _share->height() + st::boxButtonPadding.bottom();
 | 
				
			||||||
 | 
						setScrollSkips(bottomSkip, topSkip);
 | 
				
			||||||
 | 
						auto scrollHeightDelta = scrollArea()->height() - oldScrollHeight;
 | 
				
			||||||
 | 
						if (scrollHeightDelta) {
 | 
				
			||||||
 | 
							scrollArea()->scrollToY(scrollArea()->scrollTop() - scrollHeightDelta);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_topShadow->setGeometry(0, topSkip, width(), st::lineWidth);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ShareBox::onSearchByUsername(bool searchCache) {
 | 
					bool ShareBox::onSearchByUsername(bool searchCache) {
 | 
				
			||||||
	auto query = _filter->getLastText().trimmed();
 | 
						auto query = _select->getQuery();
 | 
				
			||||||
	if (query.isEmpty()) {
 | 
						if (query.isEmpty()) {
 | 
				
			||||||
		if (_peopleRequest) {
 | 
							if (_peopleRequest) {
 | 
				
			||||||
			_peopleRequest = 0;
 | 
								_peopleRequest = 0;
 | 
				
			||||||
| 
						 | 
					@ -142,7 +171,7 @@ bool ShareBox::peopleFailed(const RPCError &error, mtpRequestId requestId) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::doSetInnerFocus() {
 | 
					void ShareBox::doSetInnerFocus() {
 | 
				
			||||||
	_filter->setFocus();
 | 
						_select->setInnerFocus();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::paintEvent(QPaintEvent *e) {
 | 
					void ShareBox::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
| 
						 | 
					@ -154,17 +183,21 @@ void ShareBox::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::resizeEvent(QResizeEvent *e) {
 | 
					void ShareBox::resizeEvent(QResizeEvent *e) {
 | 
				
			||||||
	ItemListBox::resizeEvent(e);
 | 
						ItemListBox::resizeEvent(e);
 | 
				
			||||||
	_filter->resize(width(), _filter->height());
 | 
					
 | 
				
			||||||
	_filter->moveToLeft(0, st::boxTitleHeight);
 | 
						_select->resizeToWidth(width());
 | 
				
			||||||
	_filterCancel->moveToRight(0, st::boxTitleHeight);
 | 
						_select->moveToLeft(0, st::boxTitleHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						updateScrollSkips();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_inner->resizeToWidth(width());
 | 
						_inner->resizeToWidth(width());
 | 
				
			||||||
	moveButtons();
 | 
						moveButtons();
 | 
				
			||||||
	_topShadow->setGeometry(0, st::boxTitleHeight + _filter->height(), width(), st::lineWidth);
 | 
						_topShadow->setGeometry(0, getTopScrollSkip(), width(), st::lineWidth);
 | 
				
			||||||
	_bottomShadow->setGeometry(0, height() - st::boxButtonPadding.bottom() - _share->height() - st::boxButtonPadding.top() - st::lineWidth, width(), st::lineWidth);
 | 
						_bottomShadow->setGeometry(0, height() - st::boxButtonPadding.bottom() - _share->height() - st::boxButtonPadding.top() - st::lineWidth, width(), st::lineWidth);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::keyPressEvent(QKeyEvent *e) {
 | 
					void ShareBox::keyPressEvent(QKeyEvent *e) {
 | 
				
			||||||
	if (_filter->hasFocus()) {
 | 
						auto focused = focusWidget();
 | 
				
			||||||
 | 
						if (_select == focused || _select->isAncestorOf(focusWidget())) {
 | 
				
			||||||
		if (e->key() == Qt::Key_Up) {
 | 
							if (e->key() == Qt::Key_Up) {
 | 
				
			||||||
			_inner->activateSkipColumn(-1);
 | 
								_inner->activateSkipColumn(-1);
 | 
				
			||||||
		} else if (e->key() == Qt::Key_Down) {
 | 
							} else if (e->key() == Qt::Key_Down) {
 | 
				
			||||||
| 
						 | 
					@ -194,13 +227,38 @@ void ShareBox::updateButtonsVisibility() {
 | 
				
			||||||
	_cancel->setVisible(hasSelected);
 | 
						_cancel->setVisible(hasSelected);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::onFilterCancel() {
 | 
					void ShareBox::onFilterUpdate(const QString &query) {
 | 
				
			||||||
	_filter->setText(QString());
 | 
						scrollArea()->scrollToY(0);
 | 
				
			||||||
 | 
						_inner->updateFilter(query);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::onFilterUpdate() {
 | 
					void ShareBox::addPeerToMultiSelect(PeerData *peer, bool skipAnimation) {
 | 
				
			||||||
	_filterCancel->setVisible(!_filter->getLastText().isEmpty());
 | 
						auto getColor = [peer]() -> const style::color & {
 | 
				
			||||||
	_inner->updateFilter(_filter->getLastText());
 | 
							switch (peer->colorIndex) {
 | 
				
			||||||
 | 
							case 1: return st::historyPeer2UserpicFg;
 | 
				
			||||||
 | 
							case 2: return st::historyPeer3UserpicFg;
 | 
				
			||||||
 | 
							case 3: return st::historyPeer4UserpicFg;
 | 
				
			||||||
 | 
							case 4: return st::historyPeer5UserpicFg;
 | 
				
			||||||
 | 
							case 5: return st::historyPeer6UserpicFg;
 | 
				
			||||||
 | 
							case 6: return st::historyPeer7UserpicFg;
 | 
				
			||||||
 | 
							case 7: return st::historyPeer8UserpicFg;
 | 
				
			||||||
 | 
							default: return st::historyPeer1UserpicFg;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						using AddItemWay = Ui::MultiSelect::AddItemWay;
 | 
				
			||||||
 | 
						auto addItemWay = skipAnimation ? AddItemWay::SkipAnimation : AddItemWay::Default;
 | 
				
			||||||
 | 
						_select->addItem(peer->id, peer->shortName(), getColor(), PaintUserpicCallback(peer), addItemWay);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShareBox::onPeerSelectedChanged(PeerData *peer, bool checked) {
 | 
				
			||||||
 | 
						if (checked) {
 | 
				
			||||||
 | 
							addPeerToMultiSelect(peer);
 | 
				
			||||||
 | 
							_select->clearQuery();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							_select->removeItem(peer->id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						onSelectedChanged();
 | 
				
			||||||
 | 
						update();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShareBox::onSubmit() {
 | 
					void ShareBox::onSubmit() {
 | 
				
			||||||
| 
						 | 
					@ -597,17 +655,34 @@ void ShareBox::Inner::changeCheckState(Chat *chat) {
 | 
				
			||||||
		if (!chat->checkbox.checked()) {
 | 
							if (!chat->checkbox.checked()) {
 | 
				
			||||||
			_chatsIndexed->moveToTop(chat->peer);
 | 
								_chatsIndexed->moveToTop(chat->peer);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		emit filterCancel();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chat->checkbox.setChecked(!chat->checkbox.checked());
 | 
						changePeerCheckState(chat, !chat->checkbox.checked());
 | 
				
			||||||
	if (chat->checkbox.checked()) {
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShareBox::Inner::peerUnselected(PeerData *peer) {
 | 
				
			||||||
 | 
						// If data is nullptr we simply won't do anything.
 | 
				
			||||||
 | 
						auto chat = _dataMap.value(peer, nullptr);
 | 
				
			||||||
 | 
						changePeerCheckState(chat, false, ChangeStateWay::SkipCallback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShareBox::Inner::setPeerSelectedChangedCallback(base::lambda_unique<void(PeerData *peer, bool selected)> callback) {
 | 
				
			||||||
 | 
						_peerSelectedChangedCallback = std_::move(callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShareBox::Inner::changePeerCheckState(Chat *chat, bool checked, ChangeStateWay useCallback) {
 | 
				
			||||||
 | 
						if (chat) {
 | 
				
			||||||
 | 
							chat->checkbox.setChecked(checked);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (checked) {
 | 
				
			||||||
		_selected.insert(chat->peer);
 | 
							_selected.insert(chat->peer);
 | 
				
			||||||
		setActive(chatIndex(chat->peer));
 | 
							setActive(chatIndex(chat->peer));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_selected.remove(chat->peer);
 | 
							_selected.remove(chat->peer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	emit selectedChanged();
 | 
						if (useCallback != ChangeStateWay::SkipCallback && _peerSelectedChangedCallback) {
 | 
				
			||||||
 | 
							_peerSelectedChangedCallback(chat->peer, checked);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ShareBox::Inner::hasSelected() const {
 | 
					bool ShareBox::Inner::hasSelected() const {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ struct PeerUpdate;
 | 
				
			||||||
} // namespace Notify
 | 
					} // namespace Notify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ui {
 | 
					namespace Ui {
 | 
				
			||||||
class IconButton;
 | 
					class MultiSelect;
 | 
				
			||||||
} // namespace Ui
 | 
					} // namespace Ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId);
 | 
					QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId);
 | 
				
			||||||
| 
						 | 
					@ -52,8 +52,6 @@ public:
 | 
				
			||||||
	ShareBox(CopyCallback &©Callback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback);
 | 
						ShareBox(CopyCallback &©Callback, SubmitCallback &&submitCallback, FilterCallback &&filterCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
	void onFilterUpdate();
 | 
					 | 
				
			||||||
	void onFilterCancel();
 | 
					 | 
				
			||||||
	void onScroll();
 | 
						void onScroll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool onSearchByUsername(bool searchCache = false);
 | 
						bool onSearchByUsername(bool searchCache = false);
 | 
				
			||||||
| 
						 | 
					@ -61,7 +59,6 @@ private slots:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onSubmit();
 | 
						void onSubmit();
 | 
				
			||||||
	void onCopyLink();
 | 
						void onCopyLink();
 | 
				
			||||||
	void onSelectedChanged();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onMustScrollTo(int top, int bottom);
 | 
						void onMustScrollTo(int top, int bottom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,8 +70,15 @@ protected:
 | 
				
			||||||
	void doSetInnerFocus() override;
 | 
						void doSetInnerFocus() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
						void onFilterUpdate(const QString &query);
 | 
				
			||||||
 | 
						void onSelectedChanged();
 | 
				
			||||||
	void moveButtons();
 | 
						void moveButtons();
 | 
				
			||||||
	void updateButtonsVisibility();
 | 
						void updateButtonsVisibility();
 | 
				
			||||||
 | 
						int getTopScrollSkip() const;
 | 
				
			||||||
 | 
						void updateScrollSkips();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void addPeerToMultiSelect(PeerData *peer, bool skipAnimation = false);
 | 
				
			||||||
 | 
						void onPeerSelectedChanged(PeerData *peer, bool checked);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void peopleReceived(const MTPcontacts_Found &result, mtpRequestId requestId);
 | 
						void peopleReceived(const MTPcontacts_Found &result, mtpRequestId requestId);
 | 
				
			||||||
	bool peopleFailed(const RPCError &error, mtpRequestId requestId);
 | 
						bool peopleFailed(const RPCError &error, mtpRequestId requestId);
 | 
				
			||||||
| 
						 | 
					@ -84,8 +88,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class Inner;
 | 
						class Inner;
 | 
				
			||||||
	ChildWidget<Inner> _inner;
 | 
						ChildWidget<Inner> _inner;
 | 
				
			||||||
	ChildWidget<InputField> _filter;
 | 
						ChildWidget<Ui::MultiSelect> _select;
 | 
				
			||||||
	ChildWidget<Ui::IconButton> _filterCancel;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ChildWidget<BoxButton> _copy;
 | 
						ChildWidget<BoxButton> _copy;
 | 
				
			||||||
	ChildWidget<BoxButton> _share;
 | 
						ChildWidget<BoxButton> _share;
 | 
				
			||||||
| 
						 | 
					@ -116,6 +119,9 @@ class ShareBox::Inner : public ScrolledWidget, public RPCSender, private base::S
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallback);
 | 
						Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void setPeerSelectedChangedCallback(base::lambda_unique<void(PeerData *peer, bool selected)> callback);
 | 
				
			||||||
 | 
						void peerUnselected(PeerData *peer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QVector<PeerData*> selected() const;
 | 
						QVector<PeerData*> selected() const;
 | 
				
			||||||
	bool hasSelected() const;
 | 
						bool hasSelected() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,9 +140,7 @@ public slots:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void mustScrollTo(int ymin, int ymax);
 | 
						void mustScrollTo(int ymin, int ymax);
 | 
				
			||||||
	void filterCancel();
 | 
					 | 
				
			||||||
	void searchByUsername();
 | 
						void searchByUsername();
 | 
				
			||||||
	void selectedChanged();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	void paintEvent(QPaintEvent *e) override;
 | 
						void paintEvent(QPaintEvent *e) override;
 | 
				
			||||||
| 
						 | 
					@ -170,6 +174,11 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void loadProfilePhotos(int yFrom);
 | 
						void loadProfilePhotos(int yFrom);
 | 
				
			||||||
	void changeCheckState(Chat *chat);
 | 
						void changeCheckState(Chat *chat);
 | 
				
			||||||
 | 
						enum class ChangeStateWay {
 | 
				
			||||||
 | 
							Default,
 | 
				
			||||||
 | 
							SkipCallback,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						void changePeerCheckState(Chat *chat, bool checked, ChangeStateWay useCallback = ChangeStateWay::Default);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Chat *getChat(Dialogs::Row *row);
 | 
						Chat *getChat(Dialogs::Row *row);
 | 
				
			||||||
	void setActive(int active);
 | 
						void setActive(int active);
 | 
				
			||||||
| 
						 | 
					@ -198,6 +207,8 @@ private:
 | 
				
			||||||
	using SelectedChats = OrderedSet<PeerData*>;
 | 
						using SelectedChats = OrderedSet<PeerData*>;
 | 
				
			||||||
	SelectedChats _selected;
 | 
						SelectedChats _selected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						base::lambda_unique<void(PeerData *peer, bool selected)> _peerSelectedChangedCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ChatData *data(Dialogs::Row *row);
 | 
						ChatData *data(Dialogs::Row *row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool _searching = false;
 | 
						bool _searching = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,7 +60,7 @@ struct lambda_wrap_helper_base {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	static void bad_construct_copy(void *lambda, const void *source) {
 | 
						static void bad_construct_copy(void *lambda, const void *source) {
 | 
				
			||||||
		throw std::exception();
 | 
							t_assert(!"base::lambda bad_construct_copy() called!");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -72,7 +72,8 @@ struct lambda_wrap_empty : public lambda_wrap_helper_base<Return, Args...> {
 | 
				
			||||||
	static void construct_move_other_method(void *lambda, void *source) {
 | 
						static void construct_move_other_method(void *lambda, void *source) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	static Return call_method(const void *lambda, Args... args) {
 | 
						static Return call_method(const void *lambda, Args... args) {
 | 
				
			||||||
		throw std::exception();
 | 
							t_assert(!"base::lambda empty call_method() called!");
 | 
				
			||||||
 | 
							return Return();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	static void destruct_method(const void *lambda) {
 | 
						static void destruct_method(const void *lambda) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "lang.h"
 | 
					#include "lang.h"
 | 
				
			||||||
#include "application.h"
 | 
					#include "application.h"
 | 
				
			||||||
#include "ui/scrollarea.h"
 | 
					#include "ui/scrollarea.h"
 | 
				
			||||||
#include "ui/buttons/icon_button.h"
 | 
					#include "ui/widgets/multi_select.h"
 | 
				
			||||||
#include "boxes/contactsbox.h"
 | 
					#include "boxes/contactsbox.h"
 | 
				
			||||||
#include "countries.h"
 | 
					#include "countries.h"
 | 
				
			||||||
#include "styles/style_boxes.h"
 | 
					#include "styles/style_boxes.h"
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,8 @@ namespace {
 | 
				
			||||||
		countriesFiltered.reserve(countriesCount);
 | 
							countriesFiltered.reserve(countriesCount);
 | 
				
			||||||
		countriesNames.resize(countriesCount);
 | 
							countriesNames.resize(countriesCount);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const CountriesByCode &countriesByCode() {
 | 
					const CountriesByCode &countriesByCode() {
 | 
				
			||||||
	initCountries();
 | 
						initCountries();
 | 
				
			||||||
| 
						 | 
					@ -196,19 +197,17 @@ void CountryInput::setText(const QString &newText) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CountrySelectBox::CountrySelectBox() : ItemListBox(st::countriesScroll, st::boxWidth)
 | 
					CountrySelectBox::CountrySelectBox() : ItemListBox(st::countriesScroll, st::boxWidth)
 | 
				
			||||||
, _inner(this)
 | 
					, _inner(this)
 | 
				
			||||||
, _filter(this, st::boxSearchField, lang(lng_country_ph))
 | 
					, _select(this, st::contactsMultiSelect, lang(lng_country_ph))
 | 
				
			||||||
, _filterCancel(this, st::boxSearchCancel)
 | 
					 | 
				
			||||||
, _topShadow(this) {
 | 
					, _topShadow(this) {
 | 
				
			||||||
	ItemListBox::init(_inner, st::boxScrollSkip, st::boxTitleHeight + _filter->height());
 | 
						_select->resizeToWidth(st::boxWidth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	connect(_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
 | 
						ItemListBox::init(_inner, st::boxScrollSkip, st::boxTitleHeight + _select->height());
 | 
				
			||||||
	connect(_filter, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
 | 
					
 | 
				
			||||||
	connect(_filterCancel, SIGNAL(clicked()), this, SLOT(onFilterCancel()));
 | 
						_select->setQueryChangedCallback([this](const QString &query) { onFilterUpdate(query); });
 | 
				
			||||||
 | 
						_select->setSubmittedCallback([this](bool) { onSubmit(); });
 | 
				
			||||||
	connect(_inner, SIGNAL(mustScrollTo(int, int)), scrollArea(), SLOT(scrollToY(int, int)));
 | 
						connect(_inner, SIGNAL(mustScrollTo(int, int)), scrollArea(), SLOT(scrollToY(int, int)));
 | 
				
			||||||
	connect(_inner, SIGNAL(countryChosen(const QString&)), this, SIGNAL(countryChosen(const QString&)));
 | 
						connect(_inner, SIGNAL(countryChosen(const QString&)), this, SIGNAL(countryChosen(const QString&)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_filterCancel->setAttribute(Qt::WA_OpaquePaintEvent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prepare();
 | 
						prepare();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,40 +238,27 @@ void CountrySelectBox::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CountrySelectBox::resizeEvent(QResizeEvent *e) {
 | 
					void CountrySelectBox::resizeEvent(QResizeEvent *e) {
 | 
				
			||||||
	ItemListBox::resizeEvent(e);
 | 
						ItemListBox::resizeEvent(e);
 | 
				
			||||||
	_filter->resize(width(), _filter->height());
 | 
					
 | 
				
			||||||
	_filter->moveToLeft(0, st::boxTitleHeight);
 | 
						_select->resizeToWidth(width());
 | 
				
			||||||
	_filterCancel->moveToRight(0, st::boxTitleHeight);
 | 
						_select->moveToLeft(0, st::boxTitleHeight);
 | 
				
			||||||
	_inner->resize(width(), _inner->height());
 | 
					
 | 
				
			||||||
	_topShadow.setGeometry(0, st::boxTitleHeight + _filter->height(), width(), st::lineWidth);
 | 
						_inner->resizeToWidth(width());
 | 
				
			||||||
 | 
						_topShadow.setGeometry(0, st::boxTitleHeight + _select->height(), width(), st::lineWidth);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CountrySelectBox::showAll() {
 | 
					void CountrySelectBox::showAll() {
 | 
				
			||||||
	_filter->show();
 | 
						_select->show();
 | 
				
			||||||
	if (_filter->getLastText().isEmpty()) {
 | 
					 | 
				
			||||||
		_filterCancel->hide();
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		_filterCancel->show();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_topShadow.show();
 | 
						_topShadow.show();
 | 
				
			||||||
	ItemListBox::showAll();
 | 
						ItemListBox::showAll();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CountrySelectBox::onFilterCancel() {
 | 
					void CountrySelectBox::onFilterUpdate(const QString &query) {
 | 
				
			||||||
	_filter->setText(QString());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void CountrySelectBox::onFilterUpdate() {
 | 
					 | 
				
			||||||
	scrollArea()->scrollToY(0);
 | 
						scrollArea()->scrollToY(0);
 | 
				
			||||||
	if (_filter->getLastText().isEmpty()) {
 | 
						_inner->updateFilter(query);
 | 
				
			||||||
		_filterCancel->hide();
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		_filterCancel->show();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_inner->updateFilter(_filter->getLastText());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CountrySelectBox::doSetInnerFocus() {
 | 
					void CountrySelectBox::doSetInnerFocus() {
 | 
				
			||||||
	_filter->setFocus();
 | 
						_select->setInnerFocus();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CountrySelectBox::Inner::Inner(QWidget *parent) : ScrolledWidget(parent)
 | 
					CountrySelectBox::Inner::Inner(QWidget *parent) : ScrolledWidget(parent)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,10 +29,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 | 
				
			||||||
QString findValidCode(QString fullCode);
 | 
					QString findValidCode(QString fullCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CountrySelect;
 | 
					class CountrySelect;
 | 
				
			||||||
class InputField;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ui {
 | 
					namespace Ui {
 | 
				
			||||||
class IconButton;
 | 
					class MultiSelect;
 | 
				
			||||||
} // namespace Ui
 | 
					} // namespace Ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CountryInput : public QWidget {
 | 
					class CountryInput : public QWidget {
 | 
				
			||||||
| 
						 | 
					@ -82,8 +81,6 @@ signals:
 | 
				
			||||||
	void countryChosen(const QString &iso);
 | 
						void countryChosen(const QString &iso);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
	void onFilterUpdate();
 | 
					 | 
				
			||||||
	void onFilterCancel();
 | 
					 | 
				
			||||||
	void onSubmit();
 | 
						void onSubmit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
| 
						 | 
					@ -95,10 +92,11 @@ protected:
 | 
				
			||||||
	void showAll() override;
 | 
						void showAll() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
						void onFilterUpdate(const QString &query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class Inner;
 | 
						class Inner;
 | 
				
			||||||
	ChildWidget<Inner> _inner;
 | 
						ChildWidget<Inner> _inner;
 | 
				
			||||||
	ChildWidget<InputField> _filter;
 | 
						ChildWidget<Ui::MultiSelect> _select;
 | 
				
			||||||
	ChildWidget<Ui::IconButton> _filterCancel;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ScrollableBoxShadow _topShadow;
 | 
						ScrollableBoxShadow _topShadow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1890,9 +1890,7 @@ void InputField::step_placeholderFg(float64 ms, bool timer) {
 | 
				
			||||||
void InputField::step_placeholderShift(float64 ms, bool timer) {
 | 
					void InputField::step_placeholderShift(float64 ms, bool timer) {
 | 
				
			||||||
	float64 dt = ms / _st.duration;
 | 
						float64 dt = ms / _st.duration;
 | 
				
			||||||
	if (dt >= 1) {
 | 
						if (dt >= 1) {
 | 
				
			||||||
		_a_placeholderShift.stop();
 | 
							finishPlaceholderAnimation();
 | 
				
			||||||
		a_placeholderLeft.finish();
 | 
					 | 
				
			||||||
		a_placeholderOpacity.finish();
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		a_placeholderLeft.update(dt, anim::linear);
 | 
							a_placeholderLeft.update(dt, anim::linear);
 | 
				
			||||||
		a_placeholderOpacity.update(dt, anim::linear);
 | 
							a_placeholderOpacity.update(dt, anim::linear);
 | 
				
			||||||
| 
						 | 
					@ -1900,6 +1898,13 @@ void InputField::step_placeholderShift(float64 ms, bool timer) {
 | 
				
			||||||
	if (timer) update();
 | 
						if (timer) update();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InputField::finishPlaceholderAnimation() {
 | 
				
			||||||
 | 
						_a_placeholderShift.stop();
 | 
				
			||||||
 | 
						a_placeholderLeft.finish();
 | 
				
			||||||
 | 
						a_placeholderOpacity.finish();
 | 
				
			||||||
 | 
						update();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void InputField::step_border(float64 ms, bool timer) {
 | 
					void InputField::step_border(float64 ms, bool timer) {
 | 
				
			||||||
	float64 dt = ms / _st.duration;
 | 
						float64 dt = ms / _st.duration;
 | 
				
			||||||
	if (dt >= 1) {
 | 
						if (dt >= 1) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -343,6 +343,7 @@ public:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	void updatePlaceholder();
 | 
						void updatePlaceholder();
 | 
				
			||||||
	void setPlaceholderHidden(bool forcePlaceholderHidden);
 | 
						void setPlaceholderHidden(bool forcePlaceholderHidden);
 | 
				
			||||||
 | 
						void finishPlaceholderAnimation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void step_placeholderFg(float64 ms, bool timer);
 | 
						void step_placeholderFg(float64 ms, bool timer);
 | 
				
			||||||
	void step_placeholderShift(float64 ms, bool timer);
 | 
						void step_placeholderShift(float64 ms, bool timer);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -433,8 +433,8 @@ QString MultiSelect::getQuery() const {
 | 
				
			||||||
	return _inner->getQuery();
 | 
						return _inner->getQuery();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MultiSelect::addItem(uint64 itemId, const QString &text, const style::color &color, PaintRoundImage paintRoundImage) {
 | 
					void MultiSelect::addItem(uint64 itemId, const QString &text, const style::color &color, PaintRoundImage paintRoundImage, AddItemWay way) {
 | 
				
			||||||
	_inner->addItem(std_::make_unique<Inner::Item>(_st.item, itemId, text, color, std_::move(paintRoundImage)));
 | 
						_inner->addItem(std_::make_unique<Inner::Item>(_st.item, itemId, text, color, std_::move(paintRoundImage)), way);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MultiSelect::setItemRemovedCallback(base::lambda_unique<void(uint64 itemId)> callback) {
 | 
					void MultiSelect::setItemRemovedCallback(base::lambda_unique<void(uint64 itemId)> callback) {
 | 
				
			||||||
| 
						 | 
					@ -710,7 +710,7 @@ void MultiSelect::Inner::mousePressEvent(QMouseEvent *e) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MultiSelect::Inner::addItem(std_::unique_ptr<Item> item) {
 | 
					void MultiSelect::Inner::addItem(std_::unique_ptr<Item> item, AddItemWay way) {
 | 
				
			||||||
	auto wasEmpty = _items.empty();
 | 
						auto wasEmpty = _items.empty();
 | 
				
			||||||
	item->setUpdateCallback([this, item = item.get()] {
 | 
						item->setUpdateCallback([this, item = item.get()] {
 | 
				
			||||||
		auto itemRect = item->paintArea(width() - _st.padding.left() - _st.padding.top());
 | 
							auto itemRect = item->paintArea(width() - _st.padding.left() - _st.padding.top());
 | 
				
			||||||
| 
						 | 
					@ -723,7 +723,12 @@ void MultiSelect::Inner::addItem(std_::unique_ptr<Item> item) {
 | 
				
			||||||
	if (wasEmpty) {
 | 
						if (wasEmpty) {
 | 
				
			||||||
		updateHasAnyItems(true);
 | 
							updateHasAnyItems(true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_items.back()->showAnimated();
 | 
						if (way != AddItemWay::SkipAnimation) {
 | 
				
			||||||
 | 
							_items.back()->showAnimated();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							_field->finishPlaceholderAnimation();
 | 
				
			||||||
 | 
							finishHeightAnimation();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MultiSelect::Inner::computeItemsGeometry(int newWidth) {
 | 
					void MultiSelect::Inner::computeItemsGeometry(int newWidth) {
 | 
				
			||||||
| 
						 | 
					@ -765,16 +770,23 @@ void MultiSelect::Inner::updateItemsGeometry() {
 | 
				
			||||||
	if (newHeight == _newHeight) return;
 | 
						if (newHeight == _newHeight) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_newHeight = newHeight;
 | 
						_newHeight = newHeight;
 | 
				
			||||||
	_height.start([this] {
 | 
						_height.start([this] { updateHeightStep(); }, height(), _newHeight, _st.item.duration);
 | 
				
			||||||
		auto newHeight = _height.current(_newHeight);
 | 
					}
 | 
				
			||||||
		if (auto heightDelta = newHeight - height()) {
 | 
					
 | 
				
			||||||
			resize(width(), newHeight);
 | 
					void MultiSelect::Inner::updateHeightStep() {
 | 
				
			||||||
			if (_resizedCallback) {
 | 
						auto newHeight = _height.current(_newHeight);
 | 
				
			||||||
				_resizedCallback(heightDelta);
 | 
						if (auto heightDelta = newHeight - height()) {
 | 
				
			||||||
			}
 | 
							resize(width(), newHeight);
 | 
				
			||||||
			update();
 | 
							if (_resizedCallback) {
 | 
				
			||||||
 | 
								_resizedCallback(heightDelta);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}, height(), _newHeight, _st.item.duration);
 | 
							update();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MultiSelect::Inner::finishHeightAnimation() {
 | 
				
			||||||
 | 
						_height.finish();
 | 
				
			||||||
 | 
						updateHeightStep();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MultiSelect::Inner::setItemText(uint64 itemId, const QString &text) {
 | 
					void MultiSelect::Inner::setItemText(uint64 itemId, const QString &text) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,8 +40,12 @@ public:
 | 
				
			||||||
	void setSubmittedCallback(base::lambda_unique<void(bool ctrlShiftEnter)> callback);
 | 
						void setSubmittedCallback(base::lambda_unique<void(bool ctrlShiftEnter)> callback);
 | 
				
			||||||
	void setResizedCallback(base::lambda_unique<void()> callback);
 | 
						void setResizedCallback(base::lambda_unique<void()> callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum class AddItemWay {
 | 
				
			||||||
 | 
							Default,
 | 
				
			||||||
 | 
							SkipAnimation,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	using PaintRoundImage = base::lambda_unique<void(Painter &p, int x, int y, int outerWidth, int size)>;
 | 
						using PaintRoundImage = base::lambda_unique<void(Painter &p, int x, int y, int outerWidth, int size)>;
 | 
				
			||||||
	void addItem(uint64 itemId, const QString &text, const style::color &color, PaintRoundImage paintRoundImage);
 | 
						void addItem(uint64 itemId, const QString &text, const style::color &color, PaintRoundImage paintRoundImage, AddItemWay way = AddItemWay::Default);
 | 
				
			||||||
	void setItemText(uint64 itemId, const QString &text);
 | 
						void setItemText(uint64 itemId, const QString &text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setItemRemovedCallback(base::lambda_unique<void(uint64 itemId)> callback);
 | 
						void setItemRemovedCallback(base::lambda_unique<void(uint64 itemId)> callback);
 | 
				
			||||||
| 
						 | 
					@ -82,7 +86,7 @@ public:
 | 
				
			||||||
	void setSubmittedCallback(base::lambda_unique<void(bool ctrlShiftEnter)> callback);
 | 
						void setSubmittedCallback(base::lambda_unique<void(bool ctrlShiftEnter)> callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class Item;
 | 
						class Item;
 | 
				
			||||||
	void addItem(std_::unique_ptr<Item> item);
 | 
						void addItem(std_::unique_ptr<Item> item, AddItemWay way);
 | 
				
			||||||
	void setItemText(uint64 itemId, const QString &text);
 | 
						void setItemText(uint64 itemId, const QString &text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setItemRemovedCallback(base::lambda_unique<void(uint64 itemId)> callback);
 | 
						void setItemRemovedCallback(base::lambda_unique<void(uint64 itemId)> callback);
 | 
				
			||||||
| 
						 | 
					@ -120,6 +124,8 @@ private:
 | 
				
			||||||
		updateSelection(QPoint(-1, -1));
 | 
							updateSelection(QPoint(-1, -1));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	void updateCursor();
 | 
						void updateCursor();
 | 
				
			||||||
 | 
						void updateHeightStep();
 | 
				
			||||||
 | 
						void finishHeightAnimation();
 | 
				
			||||||
	enum class ChangeActiveWay {
 | 
						enum class ChangeActiveWay {
 | 
				
			||||||
		Default,
 | 
							Default,
 | 
				
			||||||
		SkipSetFocus,
 | 
							SkipSetFocus,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ public:
 | 
				
			||||||
	using UpdateCallback = base::lambda_unique<void()>;
 | 
						using UpdateCallback = base::lambda_unique<void()>;
 | 
				
			||||||
	WidgetSlideWrap(QWidget *parent, Widget *entity
 | 
						WidgetSlideWrap(QWidget *parent, Widget *entity
 | 
				
			||||||
		, style::margins entityPadding
 | 
							, style::margins entityPadding
 | 
				
			||||||
		, UpdateCallback &&updateCallback
 | 
							, UpdateCallback updateCallback
 | 
				
			||||||
		, int duration = st::widgetSlideDuration) : TWidget(parent)
 | 
							, int duration = st::widgetSlideDuration) : TWidget(parent)
 | 
				
			||||||
	, _entity(entity)
 | 
						, _entity(entity)
 | 
				
			||||||
	, _padding(entityPadding)
 | 
						, _padding(entityPadding)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,11 +92,11 @@ MultiSelect {
 | 
				
			||||||
	itemSkip: pixels;
 | 
						itemSkip: pixels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	field: InputField;
 | 
						field: InputField;
 | 
				
			||||||
 | 
						fieldMinWidth: pixels;
 | 
				
			||||||
	fieldIcon: icon;
 | 
						fieldIcon: icon;
 | 
				
			||||||
	fieldIconSkip: pixels;
 | 
						fieldIconSkip: pixels;
 | 
				
			||||||
	fieldCancel: IconButton;
 | 
						fieldCancel: IconButton;
 | 
				
			||||||
	fieldCancelSkip: pixels;
 | 
						fieldCancelSkip: pixels;
 | 
				
			||||||
	fieldMinWidth: pixels;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
widgetSlideDuration: 200;
 | 
					widgetSlideDuration: 200;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue