From a8b0f2934b8e30a54ebff1b07eabbe3f3a6f8731 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 3 Oct 2024 11:53:35 +0400 Subject: [PATCH] Scroll quote selection in the draft options box. --- .../controls/history_view_draft_options.cpp | 33 +++++++++++++++++-- .../history/view/history_view_message.cpp | 23 +++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp index e93ba510664e60..d0c8ca2b8230f6 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp @@ -110,6 +110,10 @@ class PreviewWrap final : public Ui::RpWidget { const std::vector &links, const QString &usedLink); + [[nodiscard]] rpl::producer draggingScrollDelta() const { + return _draggingScrollDelta.events(); + } + private: void paintEvent(QPaintEvent *e) override; void leaveEventHook(QEvent *e) override; @@ -118,6 +122,11 @@ class PreviewWrap final : public Ui::RpWidget { void mouseReleaseEvent(QMouseEvent *e) override; void mouseDoubleClickEvent(QMouseEvent *e) override; + void visibleTopBottomUpdated(int top, int bottom) override { + _visibleTop = top; + _visibleBottom = bottom; + } + void initElement(); void highlightUsedLink( const TextWithTags &message, @@ -141,6 +150,9 @@ class PreviewWrap final : public Ui::RpWidget { rpl::lifetime _elementLifetime; QPoint _position; + rpl::event_stream _draggingScrollDelta; + int _visibleTop = 0; + int _visibleBottom = 0; base::Timer _trippleClickTimer; ClickHandlerPtr _link; @@ -423,9 +435,8 @@ void PreviewWrap::mouseMoveEvent(QMouseEvent *e) { : Flag::LookupLink), .onlyMessageText = (_section == Section::Link || _onlyMessageText), }; - auto resolved = _element->textState( - e->pos() - _position, - request); + const auto position = e->pos(); + auto resolved = _element->textState(position - _position, request); _over = true; const auto text = (_section == Section::Reply) && (resolved.cursor == CursorState::Text); @@ -450,6 +461,17 @@ void PreviewWrap::mouseMoveEvent(QMouseEvent *e) { update(); } } + + _draggingScrollDelta.fire([&] { + if (!_selecting || _visibleTop >= _visibleBottom) { + return 0; + } else if (position.y() < _visibleTop) { + return position.y() - _visibleTop; + } else if (position.y() >= _visibleBottom) { + return position.y() + 1 - _visibleBottom; + } + return 0; + }()); } void PreviewWrap::mousePressEvent(QMouseEvent *e) { @@ -814,6 +836,11 @@ void DraftOptionsBox( state->wrap = box->addRow( object_ptr(box, args.history), {}); + state->wrap->draggingScrollDelta( + ) | rpl::start_with_next([=](int delta) { + box->scrollByDraggingDelta(delta); + }, state->wrap->lifetime()); + const auto &linkRanges = args.links; state->shown.value() | rpl::start_with_next([=](Section shown) { bottom->clear(); diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index f3582b2864295f..9f8c3111fcae1d 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -2400,8 +2400,10 @@ TextState Message::textState( const auto media = this->media(); auto result = TextState(item); + const auto visibleMediaTextLen = visibleMediaTextLength(); + const auto visibleTextLen = visibleTextLength(); const auto minSymbol = (_invertMedia && request.onlyMessageText) - ? visibleMediaTextLength() + ? visibleMediaTextLen : 0; result.symbol = minSymbol; @@ -2428,6 +2430,7 @@ TextState Message::textState( g.setHeight(g.height() - reactionsHeight); const auto reactionsPosition = QPoint(reactionsLeft + g.left(), g.top() + g.height() + st::mediaInBubbleSkip); if (_reactions->getState(point - reactionsPosition, &result)) { + result.symbol += visibleMediaTextLen + visibleTextLen; return result; } } @@ -2443,6 +2446,7 @@ TextState Message::textState( auto inner = g; if (getStateCommentsButton(point, inner, &result)) { + result.symbol += visibleMediaTextLen + visibleTextLen; return result; } auto trect = inner.marginsRemoved(st::msgPadding); @@ -2460,6 +2464,7 @@ TextState Message::textState( trect.setHeight(trect.height() - reactionsHeight); const auto reactionsPosition = QPoint(trect.left(), trect.top() + trect.height() + reactionsTop); if (_reactions->getState(point - reactionsPosition, &result)) { + result.symbol += visibleMediaTextLen + visibleTextLen; return result; } } @@ -2475,6 +2480,7 @@ TextState Message::textState( ? inner : inner - heightMargins), &result)) { + result.symbol += visibleMediaTextLen + visibleTextLen; return result; } if (belowInfo) { @@ -2552,7 +2558,11 @@ TextState Message::textState( result = bottomInfoResult; } }; - if (result.symbol <= minSymbol && inBubble) { + if (!inBubble) { + if (point.y() >= g.y() + g.height()) { + result.symbol += visibleTextLen + visibleMediaTextLen; + } + } else if (result.symbol <= minSymbol) { const auto mediaHeight = mediaDisplayed ? media->height() : 0; const auto mediaLeft = trect.x() - st::msgPadding.left(); const auto mediaTop = (!mediaDisplayed || _invertMedia) @@ -2575,22 +2585,21 @@ TextState Message::textState( result.cursor = CursorState::None; } } else if (request.onlyMessageText) { - result.symbol = visibleTextLength(); + result.symbol = visibleTextLen; result.afterSymbol = false; result.cursor = CursorState::None; } else { - result.symbol += visibleTextLength(); + result.symbol += visibleTextLen; } } else if (getStateText(point, trect, &result, request)) { if (_invertMedia) { - result.symbol += visibleMediaTextLength(); + result.symbol += visibleMediaTextLen; } result.overMessageText = true; checkBottomInfoState(); return result; } else if (point.y() >= trect.y() + trect.height()) { - result.symbol = visibleTextLength() - + visibleMediaTextLength(); + result.symbol = visibleTextLen + visibleMediaTextLen; } } checkBottomInfoState();