mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Highlight album part that had a reply clicked.
This commit is contained in:
parent
39f9147790
commit
3a34881488
19 changed files with 154 additions and 63 deletions
|
@ -556,7 +556,7 @@ bool InnerWidget::elementUnderCursor(
|
||||||
}
|
}
|
||||||
|
|
||||||
crl::time InnerWidget::elementHighlightTime(
|
crl::time InnerWidget::elementHighlightTime(
|
||||||
not_null<const HistoryView::Element*> element) {
|
not_null<const HistoryItem*> item) {
|
||||||
return crl::time(0);
|
return crl::time(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ public:
|
||||||
bool elementUnderCursor(
|
bool elementUnderCursor(
|
||||||
not_null<const HistoryView::Element*> view) override;
|
not_null<const HistoryView::Element*> view) override;
|
||||||
crl::time elementHighlightTime(
|
crl::time elementHighlightTime(
|
||||||
not_null<const HistoryView::Element*> element) override;
|
not_null<const HistoryItem*> item) override;
|
||||||
bool elementInSelectionMode() override;
|
bool elementInSelectionMode() override;
|
||||||
bool elementIntersectsRange(
|
bool elementIntersectsRange(
|
||||||
not_null<const HistoryView::Element*> view,
|
not_null<const HistoryView::Element*> view,
|
||||||
|
|
|
@ -2520,9 +2520,9 @@ void HistoryInner::elementStartStickerLoop(
|
||||||
_animatedStickersPlayed.emplace(view->data());
|
_animatedStickersPlayed.emplace(view->data());
|
||||||
}
|
}
|
||||||
|
|
||||||
crl::time HistoryInner::elementHighlightTime(not_null<const Element*> view) {
|
crl::time HistoryInner::elementHighlightTime(
|
||||||
const auto fullAnimMs = _controller->content()->highlightStartTime(
|
not_null<const HistoryItem*> item) {
|
||||||
view->data());
|
const auto fullAnimMs = _controller->content()->highlightStartTime(item);
|
||||||
if (fullAnimMs > 0) {
|
if (fullAnimMs > 0) {
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
if (fullAnimMs < now) {
|
if (fullAnimMs < now) {
|
||||||
|
@ -3421,8 +3421,8 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
|
||||||
return (App::hoveredItem() == view);
|
return (App::hoveredItem() == view);
|
||||||
}
|
}
|
||||||
crl::time elementHighlightTime(
|
crl::time elementHighlightTime(
|
||||||
not_null<const Element*> view) override {
|
not_null<const HistoryItem*> item) override {
|
||||||
return Instance ? Instance->elementHighlightTime(view) : 0;
|
return Instance ? Instance->elementHighlightTime(item) : 0;
|
||||||
}
|
}
|
||||||
bool elementInSelectionMode() override {
|
bool elementInSelectionMode() override {
|
||||||
return Instance ? Instance->inSelectionMode() : false;
|
return Instance ? Instance->inSelectionMode() : false;
|
||||||
|
|
|
@ -84,7 +84,7 @@ public:
|
||||||
int till) const;
|
int till) const;
|
||||||
void elementStartStickerLoop(not_null<const Element*> view);
|
void elementStartStickerLoop(not_null<const Element*> view);
|
||||||
[[nodiscard]] crl::time elementHighlightTime(
|
[[nodiscard]] crl::time elementHighlightTime(
|
||||||
not_null<const Element*> view);
|
not_null<const HistoryItem*> item);
|
||||||
void elementShowPollResults(
|
void elementShowPollResults(
|
||||||
not_null<PollData*> poll,
|
not_null<PollData*> poll,
|
||||||
FullMsgId context);
|
FullMsgId context);
|
||||||
|
|
|
@ -1045,11 +1045,6 @@ void HistoryWidget::scrollToAnimationCallback(
|
||||||
|
|
||||||
void HistoryWidget::enqueueMessageHighlight(
|
void HistoryWidget::enqueueMessageHighlight(
|
||||||
not_null<HistoryView::Element*> view) {
|
not_null<HistoryView::Element*> view) {
|
||||||
if (const auto group = session().data().groups().find(view->data())) {
|
|
||||||
if (const auto leader = group->items.front()->mainView()) {
|
|
||||||
view = leader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto enqueueMessageId = [this](MsgId universalId) {
|
auto enqueueMessageId = [this](MsgId universalId) {
|
||||||
if (_highlightQueue.empty() && !_highlightTimer.isActive()) {
|
if (_highlightQueue.empty() && !_highlightTimer.isActive()) {
|
||||||
highlightMessage(universalId);
|
highlightMessage(universalId);
|
||||||
|
@ -1096,7 +1091,7 @@ void HistoryWidget::checkNextHighlight() {
|
||||||
|
|
||||||
void HistoryWidget::updateHighlightedMessage() {
|
void HistoryWidget::updateHighlightedMessage() {
|
||||||
const auto item = getItemFromHistoryOrMigrated(_highlightedMessageId);
|
const auto item = getItemFromHistoryOrMigrated(_highlightedMessageId);
|
||||||
const auto view = item ? item->mainView() : nullptr;
|
auto view = item ? item->mainView() : nullptr;
|
||||||
if (!view) {
|
if (!view) {
|
||||||
return stopMessageHighlight();
|
return stopMessageHighlight();
|
||||||
}
|
}
|
||||||
|
@ -1105,6 +1100,11 @@ void HistoryWidget::updateHighlightedMessage() {
|
||||||
return stopMessageHighlight();
|
return stopMessageHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto group = session().data().groups().find(view->data())) {
|
||||||
|
if (const auto leader = group->items.front()->mainView()) {
|
||||||
|
view = leader;
|
||||||
|
}
|
||||||
|
}
|
||||||
session().data().requestViewRepaint(view);
|
session().data().requestViewRepaint(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ bool SimpleElementDelegate::elementUnderCursor(
|
||||||
}
|
}
|
||||||
|
|
||||||
crl::time SimpleElementDelegate::elementHighlightTime(
|
crl::time SimpleElementDelegate::elementHighlightTime(
|
||||||
not_null<const Element*> element) {
|
not_null<const HistoryItem*> item) {
|
||||||
return crl::time(0);
|
return crl::time(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,29 +280,44 @@ void Element::refreshDataIdHook() {
|
||||||
void Element::paintHighlight(
|
void Element::paintHighlight(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int geometryHeight) const {
|
int geometryHeight) const {
|
||||||
const auto animms = delegate()->elementHighlightTime(this);
|
|
||||||
if (!animms
|
|
||||||
|| animms >= st::activeFadeInDuration + st::activeFadeOutDuration) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto top = marginTop();
|
const auto top = marginTop();
|
||||||
const auto bottom = marginBottom();
|
const auto bottom = marginBottom();
|
||||||
const auto fill = qMin(top, bottom);
|
const auto fill = qMin(top, bottom);
|
||||||
const auto skiptop = top - fill;
|
const auto skiptop = top - fill;
|
||||||
const auto fillheight = fill + geometryHeight + fill;
|
const auto fillheight = fill + geometryHeight + fill;
|
||||||
|
|
||||||
const auto dt = (animms > st::activeFadeInDuration)
|
paintCustomHighlight(p, skiptop, fillheight, data());
|
||||||
|
}
|
||||||
|
|
||||||
|
float64 Element::highlightOpacity(not_null<const HistoryItem*> item) const {
|
||||||
|
const auto animms = delegate()->elementHighlightTime(item);
|
||||||
|
if (!animms
|
||||||
|
|| animms >= st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||||
|
return 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (animms > st::activeFadeInDuration)
|
||||||
? (1. - (animms - st::activeFadeInDuration)
|
? (1. - (animms - st::activeFadeInDuration)
|
||||||
/ float64(st::activeFadeOutDuration))
|
/ float64(st::activeFadeOutDuration))
|
||||||
: (animms / float64(st::activeFadeInDuration));
|
: (animms / float64(st::activeFadeInDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Element::paintCustomHighlight(
|
||||||
|
Painter &p,
|
||||||
|
int y,
|
||||||
|
int height,
|
||||||
|
not_null<const HistoryItem*> item) const {
|
||||||
|
const auto opacity = highlightOpacity(item);
|
||||||
|
if (opacity == 0.) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto o = p.opacity();
|
const auto o = p.opacity();
|
||||||
p.setOpacity(o * dt);
|
p.setOpacity(o * opacity);
|
||||||
p.fillRect(
|
p.fillRect(
|
||||||
0,
|
0,
|
||||||
skiptop,
|
y,
|
||||||
width(),
|
width(),
|
||||||
fillheight,
|
height,
|
||||||
st::defaultTextPalette.selectOverlay);
|
st::defaultTextPalette.selectOverlay);
|
||||||
p.setOpacity(o);
|
p.setOpacity(o);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
Element *replacing = nullptr) = 0;
|
Element *replacing = nullptr) = 0;
|
||||||
virtual bool elementUnderCursor(not_null<const Element*> view) = 0;
|
virtual bool elementUnderCursor(not_null<const Element*> view) = 0;
|
||||||
virtual crl::time elementHighlightTime(
|
virtual crl::time elementHighlightTime(
|
||||||
not_null<const Element*> element) = 0;
|
not_null<const HistoryItem*> item) = 0;
|
||||||
virtual bool elementInSelectionMode() = 0;
|
virtual bool elementInSelectionMode() = 0;
|
||||||
virtual bool elementIntersectsRange(
|
virtual bool elementIntersectsRange(
|
||||||
not_null<const Element*> view,
|
not_null<const Element*> view,
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
Element *replacing = nullptr) override;
|
Element *replacing = nullptr) override;
|
||||||
bool elementUnderCursor(not_null<const Element*> view) override;
|
bool elementUnderCursor(not_null<const Element*> view) override;
|
||||||
crl::time elementHighlightTime(
|
crl::time elementHighlightTime(
|
||||||
not_null<const Element*> element) override;
|
not_null<const HistoryItem*> item) override;
|
||||||
bool elementInSelectionMode() override;
|
bool elementInSelectionMode() override;
|
||||||
bool elementIntersectsRange(
|
bool elementIntersectsRange(
|
||||||
not_null<const Element*> view,
|
not_null<const Element*> view,
|
||||||
|
@ -301,6 +301,13 @@ public:
|
||||||
virtual void unloadHeavyPart();
|
virtual void unloadHeavyPart();
|
||||||
void checkHeavyPart();
|
void checkHeavyPart();
|
||||||
|
|
||||||
|
void paintCustomHighlight(
|
||||||
|
Painter &p,
|
||||||
|
int y,
|
||||||
|
int height,
|
||||||
|
not_null<const HistoryItem*> item) const;
|
||||||
|
float64 highlightOpacity(not_null<const HistoryItem*> item) const;
|
||||||
|
|
||||||
// Legacy blocks structure.
|
// Legacy blocks structure.
|
||||||
HistoryBlock *block();
|
HistoryBlock *block();
|
||||||
const HistoryBlock *block() const;
|
const HistoryBlock *block() const;
|
||||||
|
|
|
@ -482,7 +482,7 @@ void ListWidget::highlightMessage(FullMsgId itemId) {
|
||||||
_highlightedMessageId = itemId;
|
_highlightedMessageId = itemId;
|
||||||
_highlightTimer.callEach(AnimationTimerDelta);
|
_highlightTimer.callEach(AnimationTimerDelta);
|
||||||
|
|
||||||
repaintItem(view);
|
repaintHighlightedItem(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,10 +496,24 @@ void ListWidget::showAroundPosition(
|
||||||
refreshViewer();
|
refreshViewer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ListWidget::repaintHighlightedItem(not_null<const Element*> view) {
|
||||||
|
if (view->isHiddenByGroup()) {
|
||||||
|
if (const auto group = session().data().groups().find(view->data())) {
|
||||||
|
if (const auto leader = viewForItem(group->items.front())) {
|
||||||
|
if (!leader->isHiddenByGroup()) {
|
||||||
|
repaintItem(leader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repaintItem(view);
|
||||||
|
}
|
||||||
|
|
||||||
void ListWidget::updateHighlightedMessage() {
|
void ListWidget::updateHighlightedMessage() {
|
||||||
if (const auto item = session().data().message(_highlightedMessageId)) {
|
if (const auto item = session().data().message(_highlightedMessageId)) {
|
||||||
if (const auto view = viewForItem(item)) {
|
if (const auto view = viewForItem(item)) {
|
||||||
repaintItem(view);
|
repaintHighlightedItem(view);
|
||||||
auto duration = st::activeFadeInDuration + st::activeFadeOutDuration;
|
auto duration = st::activeFadeInDuration + st::activeFadeOutDuration;
|
||||||
if (crl::now() - _highlightStart <= duration) {
|
if (crl::now() - _highlightStart <= duration) {
|
||||||
return;
|
return;
|
||||||
|
@ -1244,8 +1258,8 @@ bool ListWidget::elementUnderCursor(
|
||||||
}
|
}
|
||||||
|
|
||||||
crl::time ListWidget::elementHighlightTime(
|
crl::time ListWidget::elementHighlightTime(
|
||||||
not_null<const HistoryView::Element*> element) {
|
not_null<const HistoryItem*> item) {
|
||||||
if (element->data()->fullId() == _highlightedMessageId) {
|
if (item->fullId() == _highlightedMessageId) {
|
||||||
if (_highlightTimer.isActive()) {
|
if (_highlightTimer.isActive()) {
|
||||||
return crl::now() - _highlightStart;
|
return crl::now() - _highlightStart;
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,7 @@ public:
|
||||||
Element *replacing = nullptr) override;
|
Element *replacing = nullptr) override;
|
||||||
bool elementUnderCursor(not_null<const Element*> view) override;
|
bool elementUnderCursor(not_null<const Element*> view) override;
|
||||||
crl::time elementHighlightTime(
|
crl::time elementHighlightTime(
|
||||||
not_null<const Element*> element) override;
|
not_null<const HistoryItem*> item) override;
|
||||||
bool elementInSelectionMode() override;
|
bool elementInSelectionMode() override;
|
||||||
bool elementIntersectsRange(
|
bool elementIntersectsRange(
|
||||||
not_null<const Element*> view,
|
not_null<const Element*> view,
|
||||||
|
@ -340,6 +340,7 @@ private:
|
||||||
int itemTop(not_null<const Element*> view) const;
|
int itemTop(not_null<const Element*> view) const;
|
||||||
void repaintItem(FullMsgId itemId);
|
void repaintItem(FullMsgId itemId);
|
||||||
void repaintItem(const Element *view);
|
void repaintItem(const Element *view);
|
||||||
|
void repaintHighlightedItem(not_null<const Element*> view);
|
||||||
void resizeItem(not_null<Element*> view);
|
void resizeItem(not_null<Element*> view);
|
||||||
void refreshItem(not_null<const Element*> view);
|
void refreshItem(not_null<const Element*> view);
|
||||||
void itemRemoved(not_null<const HistoryItem*> item);
|
void itemRemoved(not_null<const HistoryItem*> item);
|
||||||
|
|
|
@ -570,7 +570,40 @@ void Message::draw(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
paintHighlight(p, g.height());
|
auto entry = logEntryOriginal();
|
||||||
|
auto mediaDisplayed = media && media->isDisplayed();
|
||||||
|
|
||||||
|
// Entry page is always a bubble bottom.
|
||||||
|
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
|
||||||
|
auto mediaOnTop = (mediaDisplayed && media->isBubbleTop()) || (entry && entry->isBubbleTop());
|
||||||
|
|
||||||
|
auto mediaSelectionIntervals = (!selected && mediaDisplayed)
|
||||||
|
? media->getBubbleSelectionIntervals(selection)
|
||||||
|
: std::vector<BubbleSelectionInterval>();
|
||||||
|
auto localMediaTop = 0;
|
||||||
|
const auto customHighlight = mediaDisplayed && media->customHighlight();
|
||||||
|
if (!mediaSelectionIntervals.empty() || customHighlight) {
|
||||||
|
auto localMediaBottom = g.top() + g.height();
|
||||||
|
if (data()->repliesAreComments() || data()->externalReply()) {
|
||||||
|
localMediaBottom -= st::historyCommentsButtonHeight;
|
||||||
|
}
|
||||||
|
if (!mediaOnBottom) {
|
||||||
|
localMediaBottom -= st::msgPadding.bottom();
|
||||||
|
}
|
||||||
|
if (entry) {
|
||||||
|
localMediaBottom -= entry->height();
|
||||||
|
}
|
||||||
|
localMediaTop = localMediaBottom - media->height();
|
||||||
|
for (auto &[top, height] : mediaSelectionIntervals) {
|
||||||
|
top += localMediaTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customHighlight) {
|
||||||
|
media->drawHighlight(p, localMediaTop);
|
||||||
|
} else {
|
||||||
|
paintHighlight(p, g.height());
|
||||||
|
}
|
||||||
|
|
||||||
const auto roll = media ? media->bubbleRoll() : Media::BubbleRoll();
|
const auto roll = media ? media->bubbleRoll() : Media::BubbleRoll();
|
||||||
if (roll) {
|
if (roll) {
|
||||||
|
@ -602,34 +635,6 @@ void Message::draw(
|
||||||
fromNameUpdated(g.width());
|
fromNameUpdated(g.width());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto entry = logEntryOriginal();
|
|
||||||
auto mediaDisplayed = media && media->isDisplayed();
|
|
||||||
|
|
||||||
// Entry page is always a bubble bottom.
|
|
||||||
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
|
|
||||||
auto mediaOnTop = (mediaDisplayed && media->isBubbleTop()) || (entry && entry->isBubbleTop());
|
|
||||||
|
|
||||||
|
|
||||||
auto mediaSelectionIntervals = (!selected && mediaDisplayed)
|
|
||||||
? media->getBubbleSelectionIntervals(selection)
|
|
||||||
: std::vector<BubbleSelectionInterval>();
|
|
||||||
if (!mediaSelectionIntervals.empty()) {
|
|
||||||
auto localMediaBottom = g.top() + g.height();
|
|
||||||
if (data()->repliesAreComments() || data()->externalReply()) {
|
|
||||||
localMediaBottom -= st::historyCommentsButtonHeight;
|
|
||||||
}
|
|
||||||
if (!mediaOnBottom) {
|
|
||||||
localMediaBottom -= st::msgPadding.bottom();
|
|
||||||
}
|
|
||||||
if (entry) {
|
|
||||||
localMediaBottom -= entry->height();
|
|
||||||
}
|
|
||||||
const auto localMediaTop = localMediaBottom - media->height();
|
|
||||||
for (auto &[top, height] : mediaSelectionIntervals) {
|
|
||||||
top += localMediaTop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto skipTail = isAttachedToNext()
|
auto skipTail = isAttachedToNext()
|
||||||
|| (media && media->skipBubbleTail())
|
|| (media && media->skipBubbleTail())
|
||||||
|| (keyboard != nullptr)
|
|| (keyboard != nullptr)
|
||||||
|
|
|
@ -951,6 +951,7 @@ void Document::drawGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const {
|
not_null<QPixmap*> cache) const {
|
||||||
p.translate(geometry.topLeft());
|
p.translate(geometry.topLeft());
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const override;
|
not_null<QPixmap*> cache) const override;
|
||||||
TextState getStateGrouped(
|
TextState getStateGrouped(
|
||||||
|
|
|
@ -901,6 +901,7 @@ void Gif::drawGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const {
|
not_null<QPixmap*> cache) const {
|
||||||
ensureDataMediaCreated();
|
ensureDataMediaCreated();
|
||||||
|
@ -989,8 +990,16 @@ void Gif::drawGrouped(
|
||||||
p.drawPixmap(geometry, *cache);
|
p.drawPixmap(geometry, *cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected) {
|
const auto overlayOpacity = selected
|
||||||
|
? (1. - highlightOpacity)
|
||||||
|
: highlightOpacity;
|
||||||
|
if (overlayOpacity > 0.) {
|
||||||
|
p.setOpacity(overlayOpacity);
|
||||||
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||||
|
if (!selected) {
|
||||||
|
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||||
|
}
|
||||||
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radial
|
if (radial
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const override;
|
not_null<QPixmap*> cache) const override;
|
||||||
TextState getStateGrouped(
|
TextState getStateGrouped(
|
||||||
|
|
|
@ -84,6 +84,8 @@ public:
|
||||||
}
|
}
|
||||||
virtual void refreshParentId(not_null<HistoryItem*> realParent) {
|
virtual void refreshParentId(not_null<HistoryItem*> realParent) {
|
||||||
}
|
}
|
||||||
|
virtual void drawHighlight(Painter &p, int top) const {
|
||||||
|
}
|
||||||
virtual void draw(
|
virtual void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &r,
|
const QRect &r,
|
||||||
|
@ -177,6 +179,7 @@ public:
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const {
|
not_null<QPixmap*> cache) const {
|
||||||
Unexpected("Grouping method call.");
|
Unexpected("Grouping method call.");
|
||||||
|
@ -274,6 +277,9 @@ public:
|
||||||
const QRect &bubble,
|
const QRect &bubble,
|
||||||
crl::time ms) const {
|
crl::time ms) const {
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] virtual bool customHighlight() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool hasHeavyPart() const {
|
virtual bool hasHeavyPart() const {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -268,6 +268,18 @@ QMargins GroupedMedia::groupedPadding() const {
|
||||||
(normal.bottom() - grouped.bottom()) + addToBottom);
|
(normal.bottom() - grouped.bottom()) + addToBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupedMedia::drawHighlight(Painter &p, int top) const {
|
||||||
|
if (_mode != Mode::Column) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto skip = top + groupedPadding().top();
|
||||||
|
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
|
||||||
|
const auto &part = _parts[i];
|
||||||
|
const auto rect = part.geometry.translated(0, skip);
|
||||||
|
_parent->paintCustomHighlight(p, rect.y(), rect.height(), part.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GroupedMedia::draw(
|
void GroupedMedia::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &clip,
|
const QRect &clip,
|
||||||
|
@ -290,6 +302,9 @@ void GroupedMedia::draw(
|
||||||
if (textSelection) {
|
if (textSelection) {
|
||||||
selection = part.content->skipSelection(selection);
|
selection = part.content->skipSelection(selection);
|
||||||
}
|
}
|
||||||
|
const auto highlightOpacity = (_mode == Mode::Grid)
|
||||||
|
? _parent->highlightOpacity(part.item)
|
||||||
|
: 0.;
|
||||||
part.content->drawGrouped(
|
part.content->drawGrouped(
|
||||||
p,
|
p,
|
||||||
clip,
|
clip,
|
||||||
|
@ -298,6 +313,7 @@ void GroupedMedia::draw(
|
||||||
part.geometry.translated(0, groupPadding.top()),
|
part.geometry.translated(0, groupPadding.top()),
|
||||||
part.sides,
|
part.sides,
|
||||||
cornersFromSides(part.sides),
|
cornersFromSides(part.sides),
|
||||||
|
highlightOpacity,
|
||||||
&part.cacheKey,
|
&part.cacheKey,
|
||||||
&part.cache);
|
&part.cache);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
|
|
||||||
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
||||||
|
|
||||||
|
void drawHighlight(Painter &p, int top) const override;
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &clip,
|
const QRect &clip,
|
||||||
|
@ -87,6 +88,9 @@ public:
|
||||||
bool allowsFastShare() const override {
|
bool allowsFastShare() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool customHighlight() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void stopAnimation() override;
|
void stopAnimation() override;
|
||||||
void checkAnimation() override;
|
void checkAnimation() override;
|
||||||
|
|
|
@ -485,6 +485,7 @@ void Photo::drawGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const {
|
not_null<QPixmap*> cache) const {
|
||||||
ensureDataMediaCreated();
|
ensureDataMediaCreated();
|
||||||
|
@ -509,9 +510,18 @@ void Photo::drawGrouped(
|
||||||
// App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners);
|
// App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners);
|
||||||
}
|
}
|
||||||
p.drawPixmap(geometry.topLeft(), *cache);
|
p.drawPixmap(geometry.topLeft(), *cache);
|
||||||
if (selected) {
|
|
||||||
|
const auto overlayOpacity = selected
|
||||||
|
? (1. - highlightOpacity)
|
||||||
|
: highlightOpacity;
|
||||||
|
if (overlayOpacity > 0.) {
|
||||||
|
p.setOpacity(overlayOpacity);
|
||||||
const auto roundRadius = ImageRoundRadius::Large;
|
const auto roundRadius = ImageRoundRadius::Large;
|
||||||
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||||
|
if (!selected) {
|
||||||
|
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||||
|
}
|
||||||
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto displayState = radial
|
const auto displayState = radial
|
||||||
|
|
|
@ -68,6 +68,7 @@ public:
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
RectParts sides,
|
RectParts sides,
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
|
float64 highlightOpacity,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const override;
|
not_null<QPixmap*> cache) const override;
|
||||||
TextState getStateGrouped(
|
TextState getStateGrouped(
|
||||||
|
|
Loading…
Add table
Reference in a new issue