diff --git a/Telegram/SourceFiles/boxes/create_poll_box.cpp b/Telegram/SourceFiles/boxes/create_poll_box.cpp index a50e4d8dd3..02ac174af2 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.cpp +++ b/Telegram/SourceFiles/boxes/create_poll_box.cpp @@ -67,6 +67,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/fade_wrap.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" +#include "ui/wrap/vertical_layout_reorder.h" #include "ui/ui_utility.h" #include "window/section_widget.h" #include "window/window_session_controller.h" @@ -559,17 +560,19 @@ private: [[nodiscard]] rpl::producer removeClicks() const; + [[nodiscard]] Ui::RpWidget *handleWidget() const; + private: void createRemove(); void createAttach(); void createWarning(); - void toggleCorrectSpace(bool visible); + void createHandle(); void updateFieldGeometry(); base::unique_qptr> _wrap; not_null _content; base::unique_qptr> _correct; - Ui::Animations::Simple _correctShown; + base::unique_qptr> _handle; bool _hasCorrect = false; Ui::InputField *_field = nullptr; base::unique_qptr _shadow; @@ -596,6 +599,8 @@ private: int findField(not_null field) const; [[nodiscard]] auto createChooseCorrectGroup() -> std::shared_ptr; + void setupReorder(); + void restartReorder(); not_null _box; not_null _container; @@ -607,7 +612,9 @@ private: std::shared_ptr _chooseCorrectGroup; bool _multiCorrect = false; Fn _multiCorrectChanged; - int _position = 0; + Ui::VerticalLayout *_optionsLayout = nullptr; + std::unique_ptr _reorder; + int _reordering = 0; std::vector> _list; std::vector> _destroyed; rpl::variable _usedCount = 0; @@ -726,6 +733,12 @@ Options::Option::Option( _wrap->hide(anim::type::instant); + _content->paintRequest( + ) | rpl::on_next([content = _content.get()] { + auto p = QPainter(content); + p.fillRect(content->rect(), st::boxBg); + }, _content->lifetime()); + _content->widthValue( ) | rpl::on_next([=] { updateFieldGeometry(); @@ -741,6 +754,8 @@ Options::Option::Option( Ui::PostponeCall(crl::guard(_field, [=] { if (_hasCorrect) { _correct->toggle(isGood(), anim::type::normal); + } else if (_handle) { + _handle->toggle(isGood(), anim::type::normal); } })); }, _field->lifetime()); @@ -749,11 +764,14 @@ Options::Option::Option( createRemove(); createAttach(); createWarning(); + createHandle(); enableChooseCorrect(group); - _correctShown.stop(); if (_correct) { _correct->finishAnimating(); } + if (_handle) { + _handle->finishAnimating(); + } updateFieldGeometry(); } @@ -878,6 +896,38 @@ void Options::Option::createWarning() { }, warning->lifetime()); } +void Options::Option::createHandle() { + auto widget = object_ptr(_content.get()); + const auto raw = widget.data(); + const auto &icon = st::pollBoxMenuPollOrderIcon; + raw->resize(icon.width(), icon.height()); + raw->setCursor(Qt::SizeVerCursor); + raw->paintRequest( + ) | rpl::on_next([=] { + auto p = QPainter(raw); + icon.paint(p, 0, 0, raw->width()); + }, raw->lifetime()); + + const auto wrap = Ui::CreateChild>( + _content.get(), + std::move(widget)); + wrap->hide(anim::type::instant); + + _content->sizeValue( + ) | rpl::on_next([=](QSize size) { + const auto left = st::createPollFieldPadding.left(); + wrap->moveToLeft( + left, + (size.height() - wrap->heightNoMargins()) / 2); + }, wrap->lifetime()); + + _handle.reset(wrap); +} + +Ui::RpWidget *Options::Option::handleWidget() const { + return _handle ? _handle->entity() : nullptr; +} + bool Options::Option::isEmpty() const { return field()->getLastText().trimmed().isEmpty(); } @@ -923,10 +973,12 @@ void Options::Option::enableChooseCorrect( bool multiCorrect, Fn checkboxChanged) { if (!group && !multiCorrect) { + _hasCorrect = false; if (_correct) { - _hasCorrect = false; _correct->hide(anim::type::normal); - toggleCorrectSpace(false); + } + if (_handle) { + _handle->toggle(isGood(), anim::type::normal); } return; } @@ -971,24 +1023,16 @@ void Options::Option::enableChooseCorrect( } else { _correct->hide(anim::type::instant); } - toggleCorrectSpace(true); -} - -void Options::Option::toggleCorrectSpace(bool visible) { - _correctShown.start( - [=] { updateFieldGeometry(); }, - visible ? 0. : 1., - visible ? 1. : 0., - st::fadeWrapDuration); + if (_handle) { + _handle->hide(anim::type::normal); + } } void Options::Option::updateFieldGeometry() { - const auto shown = _correctShown.value(_hasCorrect ? 1. : 0.); const auto skip = st::defaultRadio.diameter + st::defaultCheckbox.textPosition.x(); - const auto left = anim::interpolate(0, skip, shown); - _field->resizeToWidth(_content->width() - left); - _field->moveToLeft(left, 0); + _field->resizeToWidth(_content->width() - skip); + _field->moveToLeft(skip, 0); } not_null Options::Option::field() const { @@ -1039,8 +1083,11 @@ Options::Options( , _widgetDropCallback(std::move(widgetDropCallback)) , _chooseCorrectGroup(chooseCorrectEnabled ? createChooseCorrectGroup() - : nullptr) -, _position(_container->count()) { + : nullptr) { + auto optionsObj = object_ptr(container); + _optionsLayout = optionsObj.data(); + container->add(std::move(optionsObj)); + setupReorder(); checkLastOption(); } @@ -1147,6 +1194,7 @@ void Options::enableChooseCorrect(bool enabled, bool multiCorrect) { } } validateState(); + restartReorder(); } bool Options::correctShadows() const { @@ -1195,6 +1243,9 @@ void Options::removeEmptyTail() { } void Options::destroy(std::unique_ptr