Add search button to info members header.

This commit is contained in:
John Preston 2017-12-08 12:14:30 +04:00
parent 8f87cfe29d
commit b501af0b8f
11 changed files with 122 additions and 76 deletions

View file

@ -236,10 +236,10 @@ rpl::producer<SelectedItems> ContentWidget::selectedListValue() const {
void ContentWidget::refreshSearchField(bool shown) {
auto search = _controller->searchFieldController();
if (search && shown) {
_searchField = search->createRowView(
_searchWrap = search->createRowView(
this,
st::infoLayerMediaSearch);
auto field = _searchField.get();
auto field = _searchWrap.get();
widthValue()
| rpl::start_with_next([field](int newWidth) {
field->resizeToWidth(newWidth);
@ -250,7 +250,7 @@ void ContentWidget::refreshSearchField(bool shown) {
setScrollTopSkip(field->heightNoMargins() - st::lineWidth);
} else {
setFocus();
_searchField = nullptr;
_searchWrap = nullptr;
setScrollTopSkip(0);
}
}

View file

@ -112,7 +112,7 @@ private:
rpl::event_stream<int> _scrollTillBottomChanges;
object_ptr<Ui::ScrollArea> _scroll;
Ui::PaddingWrap<Ui::RpWidget> *_innerWrap = nullptr;
base::unique_qptr<Ui::RpWidget> _searchField = nullptr;
base::unique_qptr<Ui::RpWidget> _searchWrap = nullptr;
int _innerDesiredHeight = 0;
// Saving here topDelta in setGeometryWithTopMoved() to get it passed to resizeEvent().
@ -161,6 +161,12 @@ public:
bool searchEnabledByContent() const {
return _searchEnabledByContent;
}
void setSearchStartsFocused(bool focused) {
_searchStartsFocused = focused;
}
bool searchStartsFocused() const {
return _searchStartsFocused;
}
private:
const PeerId _peerId = 0;
@ -168,6 +174,7 @@ private:
int _scrollTop = 0;
QString _searchFieldQuery;
bool _searchEnabledByContent = false;
bool _searchStartsFocused = false;
};

View file

@ -137,6 +137,7 @@ void Controller::updateSearchControllers(
}, _searchFieldController->lifetime());
}
_seachEnabledByContent = memento->searchEnabledByContent();
_searchStartsFocused = memento->searchStartsFocused();
} else {
_searchFieldController = nullptr;
}

View file

@ -112,6 +112,9 @@ public:
int limitBefore,
int limitAfter) const;
rpl::producer<QString> mediaSourceQueryValue() const;
bool takeSearchStartsFocused() {
return base::take(_searchStartsFocused);
}
void saveSearchState(not_null<ContentMemento*> memento);
@ -147,6 +150,7 @@ private:
std::unique_ptr<Ui::SearchFieldController> _searchFieldController;
std::unique_ptr<Api::DelayedSearchController> _searchController;
rpl::variable<bool> _seachEnabledByContent = false;
bool _searchStartsFocused = false;
rpl::lifetime _lifetime;

View file

@ -126,10 +126,20 @@ void TopBar::enableBackButton() {
void TopBar::createSearchView(
not_null<Ui::SearchFieldController*> controller,
rpl::producer<bool> &&shown) {
rpl::producer<bool> &&shown,
bool startsFocused) {
setSearchField(
controller->createField(this, _st.searchRow.field),
std::move(shown));
std::move(shown),
startsFocused);
}
bool TopBar::focusSearchField() {
if (_searchField && _searchField->isVisible()) {
_searchField->setFocus();
return true;
}
return false;
}
Ui::FadeWrap<Ui::RpWidget> *TopBar::pushButton(
@ -157,17 +167,20 @@ Ui::FadeWrap<Ui::RpWidget> *TopBar::pushButton(
void TopBar::setSearchField(
base::unique_qptr<Ui::InputField> field,
rpl::producer<bool> &&shown) {
if (auto value = field.release()) {
createSearchView(value, std::move(shown));
} else {
_searchView = nullptr;
}
rpl::producer<bool> &&shown,
bool startsFocused) {
Expects(field != nullptr);
createSearchView(field.release(), std::move(shown), startsFocused);
}
void TopBar::clearSearchField() {
_searchView = nullptr;
}
void TopBar::createSearchView(
not_null<Ui::InputField*> field,
rpl::producer<bool> &&shown) {
rpl::producer<bool> &&shown,
bool startsFocused) {
_searchView = base::make_unique_q<Ui::FixedHeightWidget>(
this,
_st.searchRow.height);
@ -176,6 +189,7 @@ void TopBar::createSearchView(
wrap->setVisible(!selectionMode() && _searchModeAvailable);
});
_searchField = field;
auto fieldWrap = Ui::CreateChild<Ui::FadeWrap<Ui::InputField>>(
wrap,
object_ptr<Ui::InputField>::fromRaw(field),
@ -261,10 +275,10 @@ void TopBar::createSearchView(
| rpl::start_with_done([=] {
field->setParent(nullptr);
removeButton(search);
setSearchField(nullptr, rpl::never<bool>());
clearSearchField();
}, _searchView->lifetime());
_searchModeEnabled = !field->getLastText().isEmpty();
_searchModeEnabled = !field->getLastText().isEmpty() || startsFocused;
updateControlsVisibility(anim::type::instant);
std::move(shown)

View file

@ -70,7 +70,9 @@ public:
void createSearchView(
not_null<Ui::SearchFieldController*> controller,
rpl::producer<bool> &&shown);
rpl::producer<bool> &&shown,
bool startsFocused);
bool focusSearchField();
void setSelectedItems(SelectedItems &&items);
SelectedItems takeSelectedItems();
@ -108,10 +110,13 @@ private:
void setSearchField(
base::unique_qptr<Ui::InputField> field,
rpl::producer<bool> &&shown);
rpl::producer<bool> &&shown,
bool startsFocused);
void clearSearchField();
void createSearchView(
not_null<Ui::InputField*> field,
rpl::producer<bool> &&shown);
rpl::producer<bool> &&shown,
bool startsFocused);
template <typename Callback>
void registerUpdateControlCallback(QObject *guard, Callback &&callback);
@ -129,6 +134,7 @@ private:
bool _searchModeEnabled = false;
bool _searchModeAvailable = false;
base::unique_qptr<Ui::RpWidget> _searchView;
QPointer<Ui::InputField> _searchField;
rpl::event_stream<> _backClicks;

View file

@ -347,7 +347,8 @@ void WrapWidget::createTopBar() {
Assert(search != nullptr);
_topBar->createSearchView(
search,
_controller->searchEnabledByContent());
_controller->searchEnabledByContent(),
_controller->takeSearchStartsFocused());
}
if (_controller->section().type() == Section::Type::Profile
&& (wrapValue != Wrap::Side || hasStackHistory())) {
@ -669,7 +670,9 @@ void WrapWidget::showAnimatedHook(
}
void WrapWidget::doSetInnerFocus() {
_content->setInnerFocus();
if (!_topBar->focusSearchField()) {
_content->setInnerFocus();
}
}
void WrapWidget::showFinishedHook() {
@ -815,6 +818,9 @@ void WrapWidget::showNewContent(
showNewContent(memento);
}
if (animationParams) {
if (Ui::InFocusChain(this)) {
setFocus();
}
showAnimated(
saveToStack
? SlideDirection::FromRight

View file

@ -22,7 +22,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "info/profile/info_profile_members.h"
#include "info/info_controller.h"
#include "ui/search_field_controller.h"
#include "ui/widgets/scroll_area.h"
#include "styles/style_info.h"

View file

@ -25,10 +25,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
struct PeerListState;
namespace Ui {
class SearchFieldController;
} // namespace Ui
namespace Info {
namespace Profile {
class Members;
@ -43,7 +39,7 @@ class Memento final : public ContentMemento {
public:
Memento(not_null<Controller*> controller);
Memento(PeerId peerId, PeerId migratedPeerId)
: ContentMemento(peerId, migratedPeerId) {
: ContentMemento(peerId, migratedPeerId) {
}
object_ptr<ContentWidget> createWidget(

View file

@ -70,6 +70,11 @@ Members::Members(
peerListScrollToTop();
content()->searchQueryChanged(std::move(query));
}, lifetime());
MembersCountValue(_peer)
| rpl::start_with_next([this](int count) {
const auto enabled = (count >= kEnableSearchMembersAfterCount);
_controller->setSearchEnabledByContent(enabled);
});
}
int Members::desiredHeight() const {
@ -109,7 +114,7 @@ void Members::restoreState(std::unique_ptr<MembersState> state) {
return;
}
_listController->restoreState(std::move(state->list));
updateSearchEnabledByContent();
//updateSearchEnabledByContent();
//if (!_controller->searchFieldController()->query().isEmpty()) {
// if (!_searchShown) {
// toggleSearch(anim::type::instant);
@ -145,9 +150,9 @@ void Members::setupHeader() {
//_searchField = _controller->searchFieldController()->createField(
// parent,
// st::infoMembersSearchField);
//_search = Ui::CreateChild<Ui::IconButton>(
// parent,
// st::infoMembersSearch);
_search = Ui::CreateChild<Ui::IconButton>(
_openMembers,
st::infoMembersSearch);
//_cancelSearch = Ui::CreateChild<Ui::CrossButton>(
// parent,
// st::infoMembersCancelSearch);
@ -182,13 +187,7 @@ void Members::setupButtons() {
using namespace rpl::mappers;
_openMembers->addClickHandler([this] {
auto contentMemento = std::make_unique<Info::Members::Memento>(
_controller);
contentMemento->setState(saveState());
auto mementoStack = std::vector<std::unique_ptr<ContentMemento>>();
mementoStack.push_back(std::move(contentMemento));
_controller->showSection(
Info::Memento(std::move(mementoStack)));
showMembersWithSearch(false);
});
//_searchField->hide();
@ -201,22 +200,21 @@ void Members::setupButtons() {
this->addMember();
});
//auto searchShown = MembersCountValue(_peer)
// | rpl::map(_1 >= kEnableSearchMembersAfterCount)
// | rpl::distinct_until_changed()
// | rpl::start_spawning(lifetime());
//_search->showOn(rpl::duplicate(searchShown));
//_search->addClickHandler([this] {
// this->showSearch();
//});
auto searchShown = MembersCountValue(_peer)
| rpl::map(_1 >= kEnableSearchMembersAfterCount)
| rpl::distinct_until_changed()
| rpl::start_spawning(lifetime());
_search->showOn(rpl::duplicate(searchShown));
_search->addClickHandler([this] { // TODO throttle(ripple duration)
this->showMembersWithSearch(true);
});
//_cancelSearch->addClickHandler([this] {
// this->cancelSearch();
//});
//rpl::combine(
// std::move(addMemberShown),
// std::move(searchShown))
std::move(addMemberShown)
rpl::combine(
std::move(addMemberShown),
std::move(searchShown))
| rpl::start_with_next([this] {
updateHeaderControlsGeometry(width());
}, lifetime());
@ -263,10 +261,10 @@ int Members::resizeGetHeight(int newWidth) {
return heightNoMargins();
}
void Members::updateSearchEnabledByContent() {
_controller->setSearchEnabledByContent(
peerListFullRowsCount() >= kEnableSearchMembersAfterCount);
}
//void Members::updateSearchEnabledByContent() {
// _controller->setSearchEnabledByContent(
// peerListFullRowsCount() >= kEnableSearchMembersAfterCount);
//}
void Members::updateHeaderControlsGeometry(int newWidth) {
_openMembers->setGeometry(0, st::infoProfileSkip, newWidth, st::infoMembersHeader - st::infoProfileSkip - st::infoMembersHeaderPaddingBottom);
@ -298,6 +296,13 @@ void Members::updateHeaderControlsGeometry(int newWidth) {
availableWidth - _addMember->width(),
st::infoMembersButtonPosition.y(),
newWidth);
if (!_addMember->isHidden()) {
availableWidth -= st::infoMembersSearch.width;
}
_search->moveToLeft(
availableWidth - _search->width(),
st::infoMembersButtonPosition.y(),
newWidth);
//auto fieldLeft = anim::interpolate(
// cancelLeft,
@ -341,12 +346,20 @@ void Members::addMember() {
}
}
//void Members::showSearch() {
// if (!_searchShown) {
// toggleSearch();
// }
//}
//
void Members::showMembersWithSearch(bool withSearch) {
//if (!_searchShown) {
// toggleSearch();
//}
auto contentMemento = std::make_unique<Info::Members::Memento>(
_controller);
contentMemento->setState(saveState());
contentMemento->setSearchStartsFocused(withSearch);
auto mementoStack = std::vector<std::unique_ptr<ContentMemento>>();
mementoStack.push_back(std::move(contentMemento));
_controller->showSection(
Info::Memento(std::move(mementoStack)));
}
//void Members::toggleSearch(anim::type animated) {
// _searchShown = !_searchShown;
// _cancelSearch->toggle(_searchShown, animated);

View file

@ -91,20 +91,20 @@ private:
void peerListSetDescription(
object_ptr<Ui::FlatLabel> description) override;
void peerListAppendRow(
std::unique_ptr<PeerListRow> row) override {
PeerListContentDelegate::peerListAppendRow(std::move(row));
updateSearchEnabledByContent();
}
void peerListPrependRow(
std::unique_ptr<PeerListRow> row) override {
PeerListContentDelegate::peerListPrependRow(std::move(row));
updateSearchEnabledByContent();
}
void peerListRemoveRow(not_null<PeerListRow*> row) override {
PeerListContentDelegate::peerListRemoveRow(row);
updateSearchEnabledByContent();
}
//void peerListAppendRow(
// std::unique_ptr<PeerListRow> row) override {
// PeerListContentDelegate::peerListAppendRow(std::move(row));
// updateSearchEnabledByContent();
//}
//void peerListPrependRow(
// std::unique_ptr<PeerListRow> row) override {
// PeerListContentDelegate::peerListPrependRow(std::move(row));
// updateSearchEnabledByContent();
//}
//void peerListRemoveRow(not_null<PeerListRow*> row) override {
// PeerListContentDelegate::peerListRemoveRow(row);
// updateSearchEnabledByContent();
//}
void setupHeader();
object_ptr<Ui::FlatLabel> setupTitle();
@ -114,12 +114,12 @@ private:
//void updateSearchOverrides();
void addMember();
//void showSearch();
void showMembersWithSearch(bool withSearch);
//void toggleSearch(anim::type animated = anim::type::normal);
//void cancelSearch();
//void searchAnimationCallback();
void updateHeaderControlsGeometry(int newWidth);
void updateSearchEnabledByContent();
//void updateSearchEnabledByContent();
//Wrap _wrap;
not_null<Controller*> _controller;
@ -133,7 +133,7 @@ private:
Ui::FlatLabel *_title = nullptr;
Ui::IconButton *_addMember = nullptr;
//base::unique_qptr<Ui::InputField> _searchField;
//Ui::IconButton *_search = nullptr;
Ui::IconButton *_search = nullptr;
//Ui::CrossButton *_cancelSearch = nullptr;
//Animation _searchShownAnimation;