Deduplicated poll overlay setup into ShowAddPollOptionOverlay.

This commit is contained in:
23rd
2026-03-23 22:29:41 +03:00
parent bb6a008309
commit 7a5eefcc70
7 changed files with 93 additions and 86 deletions
+3 -1
View File
@@ -120,7 +120,9 @@ historyPollAddOptionAttach: IconButton(defaultIconButton) {
height: 26px;
icon: icon {{ "poll/general/outline_poll_attach-22x22", historyComposeIconFg }};
iconOver: icon {{ "poll/general/outline_poll_attach-22x22", historyComposeIconFgOver }};
rippleAreaSize: 0px;
rippleAreaPosition: point(0px, 0px);
rippleAreaSize: 26px;
ripple: defaultRippleAnimationBgOver;
}
pollBoxOutlinePollEmojiIcon: icon{{ "poll/general/outline_poll_emoji", activeButtonFg }};
@@ -4301,41 +4301,13 @@ void HistoryInner::elementShowAddPollOption(
not_null<PollData*> poll,
FullMsgId context,
QRect optionRect) {
auto widget = base::make_unique_q<
HistoryView::AddPollOptionWidget>(
this,
poll,
context,
_controller);
const auto raw = widget.get();
_overlayHost->show(
HistoryView::ShowAddPollOptionOverlay(
*_overlayHost,
this,
view,
poll,
context,
std::move(widget),
rpl::merge(raw->submitted(), raw->cancelled()),
[raw](not_null<Element*> v, int top) {
const auto media = v->media();
if (!media) {
return false;
}
const auto mediaPos = v->mediaTopLeft();
const auto innerWidth = v->innerGeometry().width()
- st::msgPadding.left()
- st::msgPadding.right();
const auto rect = media->addOptionRect(innerWidth);
raw->updatePosition(
QPoint(
mediaPos.x() + rect.x(),
top + mediaPos.y() + rect.y()),
rect.width());
return true;
},
[](not_null<Element*> v, bool active) {
if (const auto media = v->media()) {
media->setAddOptionActive(active);
}
},
[raw] { raw->triggerSubmit(); });
_controller);
}
void HistoryInner::elementSubmitAddPollOption(FullMsgId context) {
@@ -7,6 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_add_poll_option.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_element_overlay.h"
#include "history/view/media/history_view_media.h"
#include "api/api_polls.h"
#include "apiwrap.h"
#include "base/event_filter.h"
@@ -74,9 +77,10 @@ void AddPollOptionWidget::setupField() {
this,
st::historyPollAddOptionEmoji);
_attach = Ui::CreateChild<Ui::IconButton>(
_attach = Ui::CreateChild<PollMediaUpload::PollMediaButton>(
this,
st::historyPollAddOptionAttach);
st::historyPollAddOptionAttach,
_mediaState);
_field->setMaxLength(100);
@@ -170,7 +174,13 @@ void AddPollOptionWidget::setupAttach() {
return;
}
_attach->addClickHandler([=] {
_uploader->choosePhotoOrVideo(this, _mediaState);
if (_mediaState->uploading) {
_uploader->clearMedia(_mediaState);
} else if (_mediaState->media) {
_uploader->clearMedia(_mediaState);
} else {
_uploader->choosePhotoOrVideo(this, _mediaState);
}
});
_uploader->installDropToField(_field, _mediaState, false);
}
@@ -251,4 +261,47 @@ rpl::producer<> AddPollOptionWidget::cancelled() const {
return _cancelledEvents.events();
}
void ShowAddPollOptionOverlay(
ElementOverlayHost &host,
not_null<QWidget*> parent,
not_null<Element*> view,
not_null<PollData*> poll,
FullMsgId context,
not_null<Window::SessionController*> controller) {
auto widget = base::make_unique_q<AddPollOptionWidget>(
parent,
poll,
context,
controller);
const auto raw = widget.get();
host.show(
view,
context,
std::move(widget),
rpl::merge(raw->submitted(), raw->cancelled()),
[raw](not_null<Element*> v, int top) {
const auto media = v->media();
if (!media) {
return false;
}
const auto mediaPos = v->mediaTopLeft();
const auto innerWidth = v->innerGeometry().width()
- st::msgPadding.left()
- st::msgPadding.right();
const auto rect = media->addOptionRect(innerWidth);
raw->updatePosition(
QPoint(
mediaPos.x() + rect.x(),
top + mediaPos.y() + rect.y()),
rect.width());
return true;
},
[](not_null<Element*> v, bool active) {
if (const auto media = v->media()) {
media->setAddOptionActive(active);
}
},
[raw] { raw->triggerSubmit(); });
}
} // namespace HistoryView
@@ -16,6 +16,7 @@ class TabbedPanel;
} // namespace ChatHelpers
namespace PollMediaUpload {
class PollMediaButton;
struct PollMediaState;
class PollMediaUploader;
} // namespace PollMediaUpload
@@ -35,6 +36,9 @@ class SessionController;
namespace HistoryView {
class Element;
class ElementOverlayHost;
class AddPollOptionWidget final : public Ui::RpWidget {
public:
AddPollOptionWidget(
@@ -63,7 +67,7 @@ private:
Ui::InputField *_field = nullptr;
Ui::IconButton *_emoji = nullptr;
Ui::IconButton *_attach = nullptr;
PollMediaUpload::PollMediaButton *_attach = nullptr;
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
std::unique_ptr<PollMediaUpload::PollMediaUploader> _uploader;
std::shared_ptr<PollMediaUpload::PollMediaState> _mediaState;
@@ -73,4 +77,12 @@ private:
};
void ShowAddPollOptionOverlay(
ElementOverlayHost &host,
not_null<QWidget*> parent,
not_null<Element*> view,
not_null<PollData*> poll,
FullMsgId context,
not_null<Window::SessionController*> controller);
} // namespace HistoryView
@@ -59,25 +59,20 @@ void ElementOverlayHost::hide() {
if (!_widget) {
return;
}
if (_view && _mediaStateFn) {
_mediaStateFn(_view, false);
}
_widget = nullptr;
_view = nullptr;
_context = FullMsgId();
_positionFn = nullptr;
_mediaStateFn = nullptr;
_submitFn = nullptr;
_closeLifetime.destroy();
if (const auto callback = _hiddenCallback) {
callback();
}
cleanup(true);
}
void ElementOverlayHost::viewGone(not_null<const Element*> view) {
if (_view != view.get()) {
return;
}
cleanup(false);
}
void ElementOverlayHost::cleanup(bool notifyMedia) {
if (notifyMedia && _view && _mediaStateFn) {
_mediaStateFn(_view, false);
}
_widget = nullptr;
_view = nullptr;
_context = FullMsgId();
@@ -103,9 +98,9 @@ void ElementOverlayHost::updatePosition() {
}
}
bool ElementOverlayHost::handleClickOutside(QPoint clickPos) {
void ElementOverlayHost::handleClickOutside(QPoint clickPos) {
if (!_widget || !_view) {
return false;
return;
}
const auto top = _itemTopFn(_view);
const auto viewRect = (top >= 0)
@@ -113,9 +108,7 @@ bool ElementOverlayHost::handleClickOutside(QPoint clickPos) {
: QRect();
if (!viewRect.contains(clickPos)) {
hide();
return true;
}
return false;
}
void ElementOverlayHost::triggerSubmit(FullMsgId context) {
@@ -40,7 +40,7 @@ public:
void hide();
void viewGone(not_null<const Element*> view);
void updatePosition();
bool handleClickOutside(QPoint clickPos);
void handleClickOutside(QPoint clickPos);
void triggerSubmit(FullMsgId context);
void setHiddenCallback(Fn<void()> callback);
@@ -48,6 +48,8 @@ public:
[[nodiscard]] FullMsgId context() const;
private:
void cleanup(bool notifyMedia);
const not_null<QWidget*> _container;
const ItemTopFn _itemTopFn;
@@ -1904,40 +1904,13 @@ void ListWidget::elementShowAddPollOption(
not_null<PollData*> poll,
FullMsgId context,
QRect optionRect) {
auto widget = base::make_unique_q<AddPollOptionWidget>(
ShowAddPollOptionOverlay(
*_overlayHost,
this,
view,
poll,
context,
controller());
const auto raw = widget.get();
_overlayHost->show(
view,
context,
std::move(widget),
rpl::merge(raw->submitted(), raw->cancelled()),
[raw](not_null<Element*> v, int top) {
const auto media = v->media();
if (!media) {
return false;
}
const auto mediaPos = v->mediaTopLeft();
const auto innerWidth = v->innerGeometry().width()
- st::msgPadding.left()
- st::msgPadding.right();
const auto rect = media->addOptionRect(innerWidth);
raw->updatePosition(
QPoint(
mediaPos.x() + rect.x(),
top + mediaPos.y() + rect.y()),
rect.width());
return true;
},
[](not_null<Element*> v, bool active) {
if (const auto media = v->media()) {
media->setAddOptionActive(active);
}
},
[raw] { raw->triggerSubmit(); });
}
void ListWidget::elementSubmitAddPollOption(FullMsgId context) {