search_field_controller.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "ui/search_field_controller.h"
  8. #include "styles/style_widgets.h"
  9. #include "ui/wrap/padding_wrap.h"
  10. #include "ui/widgets/fields/input_field.h"
  11. #include "ui/widgets/shadow.h"
  12. #include "ui/widgets/buttons.h"
  13. #include "lang/lang_keys.h"
  14. namespace Ui {
  15. SearchFieldController::SearchFieldController(const QString &query)
  16. : _query(query) {
  17. }
  18. auto SearchFieldController::createRowView(
  19. QWidget *parent,
  20. const style::SearchFieldRow &st) -> RowView {
  21. auto result = base::make_unique_q<Ui::FixedHeightWidget>(
  22. parent,
  23. st.height);
  24. auto wrap = result.get();
  25. auto field = createField(wrap, st.field).release();
  26. field->show();
  27. auto cancel = CreateChild<Ui::CrossButton>(
  28. wrap,
  29. st.fieldCancel);
  30. cancel->addClickHandler([=] {
  31. field->setText(QString());
  32. });
  33. queryValue(
  34. ) | rpl::map([](const QString &value) {
  35. return !value.isEmpty();
  36. }) | rpl::start_with_next([cancel](bool shown) {
  37. cancel->toggle(shown, anim::type::normal);
  38. }, cancel->lifetime());
  39. cancel->finishAnimating();
  40. auto shadow = CreateChild<Ui::PlainShadow>(wrap);
  41. shadow->show();
  42. wrap->widthValue(
  43. ) | rpl::start_with_next([=, &st](int newWidth) {
  44. auto availableWidth = newWidth
  45. - st.fieldIconSkip
  46. - st.fieldCancelSkip;
  47. field->setGeometryToLeft(
  48. st.padding.left() + st.fieldIconSkip,
  49. st.padding.top(),
  50. availableWidth,
  51. field->height());
  52. cancel->moveToRight(0, 0);
  53. shadow->setGeometry(
  54. 0,
  55. st.height - st::lineWidth,
  56. newWidth,
  57. st::lineWidth);
  58. }, wrap->lifetime());
  59. wrap->paintRequest(
  60. ) | rpl::start_with_next([=, &st] {
  61. auto p = QPainter(wrap);
  62. st.fieldIcon.paint(
  63. p,
  64. st.padding.left(),
  65. st.padding.top(),
  66. wrap->width());
  67. }, wrap->lifetime());
  68. _view.release();
  69. _view.reset(wrap);
  70. return { std::move(result), field };
  71. }
  72. QString SearchFieldController::query() const {
  73. return _query.current();
  74. }
  75. rpl::producer<QString> SearchFieldController::queryValue() const {
  76. return _query.value();
  77. }
  78. rpl::producer<QString> SearchFieldController::queryChanges() const {
  79. return _query.changes();
  80. }
  81. void SearchFieldController::setQuery(const QString &query) {
  82. _query = query;
  83. }
  84. base::unique_qptr<Ui::InputField> SearchFieldController::createField(
  85. QWidget *parent,
  86. const style::InputField &st) {
  87. auto result = base::make_unique_q<Ui::InputField>(
  88. parent,
  89. st,
  90. tr::lng_dlg_filter(),
  91. _query.current());
  92. auto field = result.get();
  93. field->changes(
  94. ) | rpl::start_with_next([=] {
  95. _query = field->getLastText();
  96. }, field->lifetime());
  97. _view.reset(field);
  98. return result;
  99. }
  100. } // namespace Ui