mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-31 17:41:16 +00:00
Moved out highlight scroll logic from sections to single place.
This commit is contained in:
@@ -1595,62 +1595,15 @@ int HistoryWidget::itemTopForHighlight(
|
||||
const auto heightLeft = (visibleAreaHeight - viewHeight);
|
||||
if (heightLeft >= 0) {
|
||||
return std::max(itemTop - (heightLeft / 2), 0);
|
||||
} else if (const auto highlight = itemHighlight(item)
|
||||
; (!highlight.range.empty()
|
||||
|| highlight.todoItemId
|
||||
|| !highlight.pollOption.isEmpty())
|
||||
&& !IsSubGroupSelection(highlight.range)) {
|
||||
const auto sel = highlight.range;
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto todoy = sel.empty()
|
||||
? (highlight.todoItemId
|
||||
? HistoryView::FindViewTaskY(view, highlight.todoItemId)
|
||||
: !highlight.pollOption.isEmpty()
|
||||
? HistoryView::FindViewPollOptionY(view, highlight.pollOption)
|
||||
: 0)
|
||||
: 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);
|
||||
}
|
||||
if (itemTop + begin < result) {
|
||||
result = itemTop + begin;
|
||||
}
|
||||
return result;
|
||||
} else if (IsSubGroupSelection(highlight.range)) {
|
||||
if (const auto media = view->media()) {
|
||||
for (auto i = 0; i != 15; ++i) {
|
||||
if (!IsGroupItemSelection(highlight.range, i)) {
|
||||
continue;
|
||||
}
|
||||
const auto rect = media->groupItemRect(i);
|
||||
if (rect.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
const auto inner = view->innerGeometry();
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto begin = inner.y() + rect.y() - 2 * single;
|
||||
const auto end = inner.y() + rect.y()
|
||||
+ rect.height() + 2 * single;
|
||||
auto result = itemTop;
|
||||
if (end > visibleAreaHeight) {
|
||||
result = std::max(
|
||||
result,
|
||||
itemTop + end - visibleAreaHeight);
|
||||
}
|
||||
if (itemTop + begin < result) {
|
||||
result = itemTop + begin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto highlight = itemHighlight(item);
|
||||
if (const auto range = HistoryView::FindHighlightYRange(
|
||||
view,
|
||||
highlight)) {
|
||||
return HistoryView::AdjustScrollForRange(
|
||||
itemTop,
|
||||
visibleAreaHeight,
|
||||
range);
|
||||
} else if (reactionCenter >= 0) {
|
||||
const auto maxSize = st::reactionInlineImage;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "chat_helpers/stickers_emoji_pack.h"
|
||||
#include "payments/payments_reaction_process.h" // TryAddingPaidReaction.
|
||||
#include "window/window_session_controller.h"
|
||||
#include "ui/chat/chat_style.h"
|
||||
#include "ui/effects/glare.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "ui/effects/reaction_fly_animation.h"
|
||||
@@ -3139,6 +3140,61 @@ int FindViewPollOptionY(
|
||||
return origin.y() + (yfrom + ytill) / 2;
|
||||
}
|
||||
|
||||
HighlightYRange FindHighlightYRange(
|
||||
not_null<Element*> view,
|
||||
const Ui::ChatPaintHighlight &highlight) {
|
||||
const auto sel = highlight.range;
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
if (IsSubGroupSelection(sel)) {
|
||||
const auto index = FirstGroupItemIndex(sel);
|
||||
if (index < 0) {
|
||||
return {};
|
||||
}
|
||||
const auto media = view->media();
|
||||
if (!media) {
|
||||
return {};
|
||||
}
|
||||
const auto rect = media->groupItemRect(index);
|
||||
if (rect.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
const auto inner = view->innerGeometry();
|
||||
return {
|
||||
inner.y() + rect.y() - 2 * single,
|
||||
inner.y() + rect.y() + rect.height() + 2 * single,
|
||||
};
|
||||
}
|
||||
if (highlight.todoItemId) {
|
||||
const auto y = FindViewTaskY(view, highlight.todoItemId);
|
||||
return { y - 4 * single, y + 4 * single };
|
||||
}
|
||||
if (!highlight.pollOption.isEmpty()) {
|
||||
const auto y = FindViewPollOptionY(view, highlight.pollOption);
|
||||
return { y - 4 * single, y + 4 * single };
|
||||
}
|
||||
if (!sel.empty()) {
|
||||
const auto begin = FindViewY(view, sel.from) - single;
|
||||
const auto end = FindViewY(view, sel.to, begin + single)
|
||||
+ 2 * single;
|
||||
return { begin, end };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int AdjustScrollForRange(
|
||||
int viewTop,
|
||||
int available,
|
||||
HighlightYRange range) {
|
||||
auto result = viewTop;
|
||||
if (range.end > available) {
|
||||
result = std::max(result, viewTop + range.end - available);
|
||||
}
|
||||
if (viewTop + range.begin < result) {
|
||||
result = viewTop + range.begin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Window::SessionController *ExtractController(const ClickContext &context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
if (const auto controller = my.sessionWindow.get()) {
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace Ui {
|
||||
class PathShiftGradient;
|
||||
struct BubblePattern;
|
||||
struct ChatPaintContext;
|
||||
struct ChatPaintHighlight;
|
||||
class ChatStyle;
|
||||
struct ReactionFlyAnimationArgs;
|
||||
class ReactionFlyAnimation;
|
||||
@@ -807,6 +808,24 @@ private:
|
||||
const QByteArray &option,
|
||||
int yfrom = 0);
|
||||
|
||||
struct HighlightYRange {
|
||||
int begin = 0;
|
||||
int end = 0;
|
||||
|
||||
explicit operator bool() const {
|
||||
return begin != end;
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] HighlightYRange FindHighlightYRange(
|
||||
not_null<Element*> view,
|
||||
const Ui::ChatPaintHighlight &highlight);
|
||||
|
||||
[[nodiscard]] int AdjustScrollForRange(
|
||||
int viewTop,
|
||||
int available,
|
||||
HighlightYRange range);
|
||||
|
||||
[[nodiscard]] Window::SessionController *ExtractController(
|
||||
const ClickContext &context);
|
||||
|
||||
|
||||
@@ -769,60 +769,10 @@ std::optional<int> ListWidget::scrollTopForView(
|
||||
const auto heightLeft = (available - height);
|
||||
if (heightLeft >= 0) {
|
||||
return std::max(top - (heightLeft / 2), 0);
|
||||
} else if (const auto highlight = _highlighter.state(view->data())
|
||||
; (!highlight.range.empty()
|
||||
|| highlight.todoItemId
|
||||
|| !highlight.pollOption.isEmpty())
|
||||
&& !IsSubGroupSelection(highlight.range)) {
|
||||
const auto sel = highlight.range;
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto todoy = sel.empty()
|
||||
? (highlight.todoItemId
|
||||
? HistoryView::FindViewTaskY(view, highlight.todoItemId)
|
||||
: !highlight.pollOption.isEmpty()
|
||||
? HistoryView::FindViewPollOptionY(view, highlight.pollOption)
|
||||
: 0)
|
||||
: 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);
|
||||
}
|
||||
if (top + begin < result) {
|
||||
result = top + begin;
|
||||
}
|
||||
return result;
|
||||
} else if (IsSubGroupSelection(highlight.range)) {
|
||||
if (const auto media = view->media()) {
|
||||
for (auto i = 0; i != 15; ++i) {
|
||||
if (!IsGroupItemSelection(highlight.range, i)) {
|
||||
continue;
|
||||
}
|
||||
const auto rect = media->groupItemRect(i);
|
||||
if (rect.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
const auto inner = view->innerGeometry();
|
||||
const auto single = st::messageTextStyle.font->height;
|
||||
const auto begin = inner.y() + rect.y() - 2 * single;
|
||||
const auto end = inner.y() + rect.y()
|
||||
+ rect.height() + 2 * single;
|
||||
auto result = top;
|
||||
if (end > available) {
|
||||
result = std::max(result, top + end - available);
|
||||
}
|
||||
if (top + begin < result) {
|
||||
result = top + begin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto highlight = _highlighter.state(view->data());
|
||||
if (const auto range = FindHighlightYRange(view, highlight)) {
|
||||
return AdjustScrollForRange(top, available, range);
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
@@ -14,15 +14,27 @@ bool IsSubGroupSelection(TextSelection selection) {
|
||||
bool IsGroupItemSelection(
|
||||
TextSelection selection,
|
||||
int index) {
|
||||
Expects(index >= 0 && index < 0x0F);
|
||||
Expects(index >= 0 && index < kMaxGroupSelectionItems);
|
||||
|
||||
return IsSubGroupSelection(selection) && (selection.to & (1 << index));
|
||||
}
|
||||
|
||||
int FirstGroupItemIndex(TextSelection selection) {
|
||||
if (!IsSubGroupSelection(selection)) {
|
||||
return -1;
|
||||
}
|
||||
for (auto i = 0; i != kMaxGroupSelectionItems; ++i) {
|
||||
if (selection.to & (1 << i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
TextSelection AddGroupItemSelection(
|
||||
TextSelection selection,
|
||||
int index) {
|
||||
Expects(index >= 0 && index < 0x0F);
|
||||
Expects(index >= 0 && index < kMaxGroupSelectionItems);
|
||||
|
||||
const auto bit = uint16(1U << index);
|
||||
return TextSelection(
|
||||
@@ -33,7 +45,7 @@ TextSelection AddGroupItemSelection(
|
||||
TextSelection RemoveGroupItemSelection(
|
||||
TextSelection selection,
|
||||
int index) {
|
||||
Expects(index >= 0 && index < 0x0F);
|
||||
Expects(index >= 0 && index < kMaxGroupSelectionItems);
|
||||
|
||||
const auto bit = uint16(1U << index);
|
||||
return IsSubGroupSelection(selection)
|
||||
|
||||
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/text/text.h"
|
||||
|
||||
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
||||
constexpr auto kMaxGroupSelectionItems = 0x0F;
|
||||
|
||||
[[nodiscard]] bool IsSubGroupSelection(TextSelection selection);
|
||||
|
||||
@@ -17,6 +18,8 @@ constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
||||
TextSelection selection,
|
||||
int index);
|
||||
|
||||
[[nodiscard]] int FirstGroupItemIndex(TextSelection selection);
|
||||
|
||||
[[nodiscard]] TextSelection AddGroupItemSelection(
|
||||
TextSelection selection,
|
||||
int index);
|
||||
|
||||
Reference in New Issue
Block a user