mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 15:47:11 +02:00
Fix long message parts highlighting in topics.
This commit is contained in:
parent
99a7a13218
commit
2b53df98cd
4 changed files with 86 additions and 52 deletions
|
@ -1433,41 +1433,12 @@ int HistoryWidget::itemTopForHighlight(
|
|||
const auto heightLeft = (visibleAreaHeight - viewHeight);
|
||||
if (heightLeft >= 0) {
|
||||
return std::max(itemTop - (heightLeft / 2), 0);
|
||||
} else if (const auto sel = itemHighlight(item).range; !sel.empty()) {
|
||||
auto request = HistoryView::StateRequest();
|
||||
request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
|
||||
} else if (const auto sel = itemHighlight(item).range
|
||||
; !sel.empty() && !IsSubGroupSelection(sel)) {
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto findy = [&](int symbol, int yfrom = 0) {
|
||||
const auto fory = [&](int y) {
|
||||
return view->textState(QPoint(0, y), request).symbol;
|
||||
};
|
||||
auto ytill = view->height() - 1;
|
||||
auto symbolfrom = fory(yfrom);
|
||||
auto symboltill = fory(ytill);
|
||||
if ((yfrom >= ytill) || (symbolfrom >= symbol)) {
|
||||
return yfrom;
|
||||
} else if (symboltill <= symbol) {
|
||||
return ytill;
|
||||
}
|
||||
while (ytill - yfrom >= 2 * single) {
|
||||
const auto middle = (yfrom + ytill) / 2;
|
||||
const auto found = fory(middle);
|
||||
if (found == symbol
|
||||
|| symbolfrom > found
|
||||
|| symboltill < found) {
|
||||
return middle;
|
||||
} else if (found < symbol) {
|
||||
yfrom = middle;
|
||||
symbolfrom = found;
|
||||
} else {
|
||||
ytill = middle;
|
||||
symboltill = found;
|
||||
}
|
||||
}
|
||||
return (yfrom + ytill) / 2;
|
||||
};
|
||||
const auto begin = findy(sel.from) - single;
|
||||
const auto end = findy(sel.to, begin + single) + 2 * single;
|
||||
const auto begin = HistoryView::FindViewY(view, sel.from) - single;
|
||||
const auto end = HistoryView::FindViewY(view, sel.to, begin + single)
|
||||
+ 2 * single;
|
||||
auto result = itemTop;
|
||||
if (end > visibleAreaHeight) {
|
||||
result = std::max(result, itemTop + end - visibleAreaHeight);
|
||||
|
|
|
@ -2015,4 +2015,37 @@ void Element::ClearGlobal() {
|
|||
MousedElement = nullptr;
|
||||
}
|
||||
|
||||
int FindViewY(not_null<Element*> view, uint16 symbol, int yfrom) {
|
||||
auto request = HistoryView::StateRequest();
|
||||
request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto fory = [&](int y) {
|
||||
return view->textState(QPoint(0, y), request).symbol;
|
||||
};
|
||||
auto ytill = view->height() - 1;
|
||||
auto symbolfrom = fory(yfrom);
|
||||
auto symboltill = fory(ytill);
|
||||
if ((yfrom >= ytill) || (symbolfrom >= symbol)) {
|
||||
return yfrom;
|
||||
} else if (symboltill <= symbol) {
|
||||
return ytill;
|
||||
}
|
||||
while (ytill - yfrom >= 2 * single) {
|
||||
const auto middle = (yfrom + ytill) / 2;
|
||||
const auto found = fory(middle);
|
||||
if (found == symbol
|
||||
|| symbolfrom > found
|
||||
|| symboltill < found) {
|
||||
return middle;
|
||||
} else if (found < symbol) {
|
||||
yfrom = middle;
|
||||
symbolfrom = found;
|
||||
} else {
|
||||
ytill = middle;
|
||||
symboltill = found;
|
||||
}
|
||||
}
|
||||
return (yfrom + ytill) / 2;
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -668,4 +668,9 @@ private:
|
|||
|
||||
};
|
||||
|
||||
[[nodiscard]] int FindViewY(
|
||||
not_null<Element*> view,
|
||||
uint16 symbol,
|
||||
int yfrom = 0);
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -711,7 +711,25 @@ std::optional<int> ListWidget::scrollTopForView(
|
|||
const auto top = view->y();
|
||||
const auto height = view->height();
|
||||
const auto available = _visibleBottom - _visibleTop;
|
||||
return top - std::max((available - height) / 2, 0);
|
||||
const auto heightLeft = (available - height);
|
||||
if (heightLeft >= 0) {
|
||||
return std::max(top - (heightLeft / 2), 0);
|
||||
} else if (const auto sel = _highlighter.state(view->data()).range
|
||||
; !sel.empty() && !IsSubGroupSelection(sel)) {
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto begin = HistoryView::FindViewY(view, sel.from) - single;
|
||||
const auto end = HistoryView::FindViewY(view, sel.to, begin + single)
|
||||
+ 2 * single;
|
||||
auto result = top;
|
||||
if (end > available) {
|
||||
result = std::max(result, top + end - available);
|
||||
}
|
||||
if (top + begin < result) {
|
||||
result = top + begin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
void ListWidget::scrollTo(
|
||||
|
@ -873,24 +891,31 @@ bool ListWidget::showAtPositionNow(
|
|||
Data::MessagePosition position,
|
||||
const Window::SectionShow ¶ms,
|
||||
Fn<void(bool found)> done) {
|
||||
if (const auto scrollTop = scrollTopForPosition(position)) {
|
||||
computeScrollTo(*scrollTop, position, params.animated);
|
||||
if (position != Data::MaxMessagePosition
|
||||
&& position != Data::UnreadMessagePosition) {
|
||||
highlightMessage(
|
||||
position.fullId,
|
||||
params.highlightPart,
|
||||
params.highlightPartOffsetHint);
|
||||
}
|
||||
if (done) {
|
||||
const auto found = !position.fullId.peer
|
||||
|| !IsServerMsgId(position.fullId.msg)
|
||||
|| viewForItem(position.fullId);
|
||||
done(found);
|
||||
}
|
||||
return true;
|
||||
auto scrollTop = scrollTopForPosition(position);
|
||||
if (!scrollTop.has_value()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
if (position != Data::MaxMessagePosition
|
||||
&& position != Data::UnreadMessagePosition) {
|
||||
const auto hasHighlight = !params.highlightPart.empty();
|
||||
highlightMessage(
|
||||
position.fullId,
|
||||
params.highlightPart,
|
||||
params.highlightPartOffsetHint);
|
||||
if (hasHighlight) {
|
||||
// We may want to scroll to a different part of the message.
|
||||
scrollTop = scrollTopForPosition(position);
|
||||
Assert(scrollTop.has_value());
|
||||
}
|
||||
}
|
||||
computeScrollTo(*scrollTop, position, params.animated);
|
||||
if (done) {
|
||||
const auto found = !position.fullId.peer
|
||||
|| !IsServerMsgId(position.fullId.msg)
|
||||
|| viewForItem(position.fullId);
|
||||
done(found);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ListWidget::computeScrollTo(
|
||||
|
|
Loading…
Add table
Reference in a new issue