mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-25 15:03:03 +02:00
Try scrolling to the task on jump.
This commit is contained in:
parent
bff86b90fb
commit
f2e53ea490
4 changed files with 98 additions and 10 deletions
|
@ -1498,12 +1498,21 @@ 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() && !IsSubGroupSelection(sel)) {
|
||||
} else if (const auto highlight = itemHighlight(item)
|
||||
; (!highlight.range.empty() || highlight.todoItemId)
|
||||
&& !IsSubGroupSelection(highlight.range)) {
|
||||
const auto sel = highlight.range;
|
||||
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;
|
||||
const auto todoy = sel.empty()
|
||||
? HistoryView::FindViewTaskY(view, highlight.todoItemId)
|
||||
: 0;
|
||||
const auto begin = sel.empty()
|
||||
? (todoy - 4 * single)
|
||||
: HistoryView::FindViewY(view, sel.from) - single;
|
||||
const auto end = sel.empty()
|
||||
? (todoy + 4 * single)
|
||||
: (HistoryView::FindViewY(view, sel.to, begin + single)
|
||||
+ 2 * single);
|
||||
auto result = itemTop;
|
||||
if (end > visibleAreaHeight) {
|
||||
result = std::max(result, itemTop + end - visibleAreaHeight);
|
||||
|
|
|
@ -46,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_channel.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_todo_list.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_message_reactions.h"
|
||||
|
@ -2455,6 +2456,70 @@ int FindViewY(not_null<Element*> view, uint16 symbol, int yfrom) {
|
|||
return origin.y() + (yfrom + ytill) / 2;
|
||||
}
|
||||
|
||||
int FindViewTaskY(not_null<Element*> view, int taskId, int yfrom) {
|
||||
auto request = HistoryView::StateRequest();
|
||||
request.flags = Ui::Text::StateRequest::Flag::LookupLink;
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto inner = view->innerGeometry();
|
||||
const auto origin = inner.topLeft();
|
||||
const auto top = 0;
|
||||
const auto bottom = view->height();
|
||||
if (origin.y() < top
|
||||
|| origin.y() + inner.height() > bottom
|
||||
|| inner.height() <= 0) {
|
||||
return yfrom;
|
||||
}
|
||||
const auto media = view->data()->media();
|
||||
const auto todolist = media ? media->todolist() : nullptr;
|
||||
if (!todolist) {
|
||||
return yfrom;
|
||||
}
|
||||
const auto &items = todolist->items;
|
||||
const auto indexOf = [&](int id) -> int {
|
||||
return ranges::find(items, id, &TodoListItem::id) - begin(items);
|
||||
};
|
||||
const auto index = indexOf(taskId);
|
||||
const auto count = int(items.size());
|
||||
if (index == count) {
|
||||
return yfrom;
|
||||
}
|
||||
yfrom = std::max(yfrom - origin.y(), 0);
|
||||
auto ytill = inner.height() - 1;
|
||||
const auto middle = (yfrom + ytill) / 2;
|
||||
const auto fory = [&](int y) {
|
||||
const auto state = view->textState(origin + QPoint(0, y), request);
|
||||
const auto &link = state.link;
|
||||
const auto id = link
|
||||
? link->property(kTodoListItemIdProperty).toInt()
|
||||
: -1;
|
||||
const auto index = (id >= 0) ? indexOf(id) : int(items.size());
|
||||
return (index < count) ? index : (y < middle) ? -1 : count;
|
||||
};
|
||||
auto indexfrom = fory(yfrom);
|
||||
auto indextill = fory(ytill);
|
||||
if ((yfrom >= ytill) || (indexfrom >= index)) {
|
||||
return origin.y() + yfrom;
|
||||
} else if (indextill <= index) {
|
||||
return origin.y() + ytill;
|
||||
}
|
||||
while (ytill - yfrom >= 2 * single) {
|
||||
const auto middle = (yfrom + ytill) / 2;
|
||||
const auto found = fory(middle);
|
||||
if (found == index
|
||||
|| indexfrom > found
|
||||
|| indextill < found) {
|
||||
return origin.y() + middle;
|
||||
} else if (found < index) {
|
||||
yfrom = middle;
|
||||
indexfrom = found;
|
||||
} else {
|
||||
ytill = middle;
|
||||
indextill = found;
|
||||
}
|
||||
}
|
||||
return origin.y() + (yfrom + ytill) / 2;
|
||||
}
|
||||
|
||||
Window::SessionController *ExtractController(const ClickContext &context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
if (const auto controller = my.sessionWindow.get()) {
|
||||
|
|
|
@ -747,6 +747,11 @@ private:
|
|||
uint16 symbol,
|
||||
int yfrom = 0);
|
||||
|
||||
[[nodiscard]] int FindViewTaskY(
|
||||
not_null<Element*> view,
|
||||
int taskId,
|
||||
int yfrom = 0);
|
||||
|
||||
[[nodiscard]] Window::SessionController *ExtractController(
|
||||
const ClickContext &context);
|
||||
|
||||
|
|
|
@ -716,12 +716,21 @@ std::optional<int> ListWidget::scrollTopForView(
|
|||
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)) {
|
||||
} else if (const auto highlight = _highlighter.state(view->data())
|
||||
; (!highlight.range.empty() || highlight.todoItemId)
|
||||
&& !IsSubGroupSelection(highlight.range)) {
|
||||
const auto sel = highlight.range;
|
||||
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;
|
||||
const auto todoy = sel.empty()
|
||||
? HistoryView::FindViewTaskY(view, highlight.todoItemId)
|
||||
: 0;
|
||||
const auto begin = sel.empty()
|
||||
? (todoy - 4 * single)
|
||||
: HistoryView::FindViewY(view, sel.from) - single;
|
||||
const auto end = sel.empty()
|
||||
? (todoy + 4 * single)
|
||||
: (HistoryView::FindViewY(view, sel.to, begin + single)
|
||||
+ 2 * single);
|
||||
auto result = top;
|
||||
if (end > available) {
|
||||
result = std::max(result, top + end - available);
|
||||
|
|
Loading…
Add table
Reference in a new issue