Shared media multiple items selection.

This commit is contained in:
John Preston 2017-10-13 22:07:04 +03:00
parent 66146c382d
commit 54cc3e6315
23 changed files with 1117 additions and 579 deletions

View File

@ -64,12 +64,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#error Please add support for your architecture in base/build_config.h
#endif
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#if defined(__GNUC__)
#define FORCE_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)

View File

@ -109,7 +109,18 @@ public:
flat_multi_map_iterator_base_impl operator-(difference_type offset) const {
return _impl - offset;
}
difference_type operator-(const flat_multi_map_iterator_base_impl &right) const {
template <
typename other_iterator_impl,
typename other_pointer_impl,
typename other_reference_impl>
difference_type operator-(
const flat_multi_map_iterator_base_impl<
Key,
Type,
Compare,
other_iterator_impl,
other_pointer_impl,
other_reference_impl> &right) const {
return _impl - right._impl;
}
reference operator[](difference_type offset) {
@ -119,13 +130,46 @@ public:
return _impl[offset];
}
bool operator==(const flat_multi_map_iterator_base_impl &right) const {
template <
typename other_iterator_impl,
typename other_pointer_impl,
typename other_reference_impl>
bool operator==(
const flat_multi_map_iterator_base_impl<
Key,
Type,
Compare,
other_iterator_impl,
other_pointer_impl,
other_reference_impl> &right) const {
return _impl == right._impl;
}
bool operator!=(const flat_multi_map_iterator_base_impl &right) const {
template <
typename other_iterator_impl,
typename other_pointer_impl,
typename other_reference_impl>
bool operator!=(
const flat_multi_map_iterator_base_impl<
Key,
Type,
Compare,
other_iterator_impl,
other_pointer_impl,
other_reference_impl> &right) const {
return _impl != right._impl;
}
bool operator<(const flat_multi_map_iterator_base_impl &right) const {
template <
typename other_iterator_impl,
typename other_pointer_impl,
typename other_reference_impl>
bool operator<(
const flat_multi_map_iterator_base_impl<
Key,
Type,
Compare,
other_iterator_impl,
other_pointer_impl,
other_reference_impl> &right) const {
return _impl < right._impl;
}
@ -133,6 +177,15 @@ private:
iterator_impl _impl;
friend class flat_multi_map<Key, Type, Compare>;
template <
typename OtherKey,
typename OtherType,
typename OtherCompare,
typename other_iterator_impl,
typename other_pointer_impl,
typename other_reference_impl>
friend class flat_multi_map_iterator_base_impl;
};
template <typename Key, typename Type, typename Compare>
@ -418,10 +471,10 @@ public:
return (range.second - range.first);
}
iterator erase(iterator where) {
iterator erase(const_iterator where) {
return _impl.erase(where._impl);
}
iterator erase(iterator from, iterator till) {
iterator erase(const_iterator from, const_iterator till) {
return _impl.erase(from._impl, till._impl);
}
@ -525,37 +578,69 @@ public:
using parent::erase;
using parent::contains;
iterator insert(const value_type &value) {
std::pair<iterator, bool> insert(const value_type &value) {
if (this->empty() || compare()(value.first, this->front().first)) {
this->_impl.push_front(value);
return this->begin();
return { this->begin(), true };
} else if (compare()(this->back().first, value.first)) {
this->_impl.push_back(value);
return (this->end() - 1);
return { this->end() - 1, true };
}
auto where = this->getLowerBound(value.first);
if (compare()(value.first, where->first)) {
return this->_impl.insert(where, value);
return { this->_impl.insert(where, value), true };
}
return this->end();
return { where, false };
}
iterator insert(value_type &&value) {
std::pair<iterator, bool> insert(value_type &&value) {
if (this->empty() || compare()(value.first, this->front().first)) {
this->_impl.push_front(std::move(value));
return this->begin();
return { this->begin(), true };
} else if (compare()(this->back().first, value.first)) {
this->_impl.push_back(std::move(value));
return (this->end() - 1);
return { this->end() - 1, true };
}
auto where = this->getLowerBound(value.first);
if (compare()(value.first, where->first)) {
return this->_impl.insert(where, std::move(value));
return { this->_impl.insert(where, std::move(value)), true };
}
return this->end();
return { where, false };
}
template <typename... Args>
iterator emplace(Args&&... args) {
return this->insert(value_type(std::forward<Args>(args)...));
std::pair<iterator, bool> emplace(
const Key &key,
Args&&... args) {
return this->insert(value_type(
key,
Type(std::forward<Args>(args)...)));
}
template <typename... Args>
std::pair<iterator, bool> try_emplace(
const Key &key,
Args&&... args) {
if (this->empty() || compare()(key, this->front().first)) {
this->_impl.push_front(value_type(
key,
Type(std::forward<Args>(args)...)));
return { this->begin(), true };
} else if (compare()(this->back().first, key)) {
this->_impl.push_back(value_type(
key,
Type(std::forward<Args>(args)...)));
return { this->end() - 1, true };
}
auto where = this->getLowerBound(key);
if (compare()(key, where->first)) {
return {
this->_impl.insert(
where,
value_type(
key,
Type(std::forward<Args>(args)...))),
true
};
}
return { where, false };
}
bool remove(const Key &key) {

View File

@ -47,6 +47,13 @@ public:
flat_multi_set_iterator_base_impl(iterator_impl impl = iterator_impl())
: _impl(impl) {
}
template <typename other_iterator_impl>
flat_multi_set_iterator_base_impl(
const flat_multi_set_iterator_base_impl<
Type,
Compare,
other_iterator_impl> &other) : _impl(other._impl) {
}
reference operator*() const {
return *_impl;
@ -82,20 +89,40 @@ public:
flat_multi_set_iterator_base_impl operator-(difference_type offset) const {
return _impl - offset;
}
difference_type operator-(const flat_multi_set_iterator_base_impl &right) const {
template <typename other_iterator_impl>
difference_type operator-(
const flat_multi_set_iterator_base_impl<
Type,
Compare,
other_iterator_impl> &right) const {
return _impl - right._impl;
}
reference operator[](difference_type offset) const {
return _impl[offset];
}
bool operator==(const flat_multi_set_iterator_base_impl &right) const {
template <typename other_iterator_impl>
bool operator==(
const flat_multi_set_iterator_base_impl<
Type,
Compare,
other_iterator_impl> &right) const {
return _impl == right._impl;
}
bool operator!=(const flat_multi_set_iterator_base_impl &right) const {
template <typename other_iterator_impl>
bool operator!=(
const flat_multi_set_iterator_base_impl<
Type,
Compare,
other_iterator_impl> &right) const {
return _impl != right._impl;
}
bool operator<(const flat_multi_set_iterator_base_impl &right) const {
template <typename other_iterator_impl>
bool operator<(
const flat_multi_set_iterator_base_impl<
Type,
Compare,
other_iterator_impl> &right) const {
return _impl < right._impl;
}
@ -104,6 +131,12 @@ private:
friend class flat_multi_set<Type, Compare>;
friend class flat_set<Type, Compare>;
template <
typename OtherType,
typename OtherCompare,
typename other_iterator_impl>
friend class flat_multi_set_iterator_base_impl;
Type &wrapped() {
return _impl->wrapped();
}
@ -205,43 +238,24 @@ public:
using pointer = const Type*;
using reference = const Type&;
class const_iterator;
class iterator : public iterator_base {
public:
using iterator_base::iterator_base;
iterator(const iterator_base &other) : iterator_base(other) {
}
friend class const_iterator;
};
class const_iterator : public const_iterator_base {
public:
using const_iterator_base::const_iterator_base;
const_iterator(const_iterator_base other) : const_iterator_base(other) {
}
const_iterator(const iterator &other) : const_iterator_base(other._impl) {
}
};
class const_reverse_iterator;
class reverse_iterator : public reverse_iterator_base {
public:
using reverse_iterator_base::reverse_iterator_base;
reverse_iterator(reverse_iterator_base other)
: reverse_iterator_base(other) {
}
friend class const_reverse_iterator;
};
class const_reverse_iterator : public const_reverse_iterator_base {
public:
using const_reverse_iterator_base::const_reverse_iterator_base;
const_reverse_iterator(const_reverse_iterator_base other)
: const_reverse_iterator_base(other) {
}
const_reverse_iterator(const reverse_iterator &other)
: const_reverse_iterator_base(other._impl) {
}
};
@ -366,10 +380,10 @@ public:
return (range.second - range.first);
}
iterator erase(iterator where) {
iterator erase(const_iterator where) {
return _impl.erase(where._impl);
}
iterator erase(iterator from, iterator till) {
iterator erase(const_iterator from, const_iterator till) {
return _impl.erase(from._impl, till._impl);
}

View File

@ -894,7 +894,9 @@ void GifsListWidget::updateSelected() {
}
if (col < inlineItems.size()) {
sel = row * MatrixRowShift + col;
inlineItems.at(col)->getState(lnk, cursor, QPoint(sx, sy));
auto result = inlineItems[col]->getState(QPoint(sx, sy), HistoryStateRequest());
lnk = result.link;
cursor = result.cursor;
lnkhost = inlineItems.at(col);
} else {
row = col = -1;

View File

@ -1033,10 +1033,11 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
void HistoryInner::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button) {
mouseActionUpdate(screenPos);
ClickHandlerPtr activated = ClickHandler::unpressed();
auto pressedLinkItem = App::pressedLinkItem();
auto activated = ClickHandler::unpressed();
if (_mouseAction == MouseAction::Dragging) {
activated.clear();
} else if (auto pressed = App::pressedLinkItem()) {
} else if (auto pressed = pressedLinkItem) {
// if we are in selecting items mode perhaps we want to
// toggle selection instead of activating the pressed link
if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && !_selected.empty() && _selected.cbegin()->second == FullSelection && button != Qt::RightButton) {
@ -2249,23 +2250,21 @@ void HistoryInner::onUpdateSelected() {
}
}
void HistoryInner::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force) {
if (_dragSelFrom != dragSelFrom || _dragSelTo != dragSelTo || _dragSelecting != dragSelecting) {
_dragSelFrom = dragSelFrom;
_dragSelTo = dragSelTo;
int32 fromy = itemTop(_dragSelFrom), toy = itemTop(_dragSelTo);
if (fromy >= 0 && toy >= 0 && fromy > toy) {
qSwap(_dragSelFrom, _dragSelTo);
}
_dragSelecting = dragSelecting;
if (!_wasSelectedText && _dragSelFrom && _dragSelTo && _dragSelecting) {
_wasSelectedText = true;
setFocus();
}
force = true;
void HistoryInner::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting) {
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
return;
}
_dragSelFrom = dragSelFrom;
_dragSelTo = dragSelTo;
int32 fromy = itemTop(_dragSelFrom), toy = itemTop(_dragSelTo);
if (fromy >= 0 && toy >= 0 && fromy > toy) {
qSwap(_dragSelFrom, _dragSelTo);
}
_dragSelecting = dragSelecting;
if (!_wasSelectedText && _dragSelFrom && _dragSelTo && _dragSelecting) {
_wasSelectedText = true;
setFocus();
}
if (!force) return;
update();
}

View File

@ -164,7 +164,7 @@ private:
void adjustCurrent(int32 y, History *history) const;
HistoryItem *prevItem(HistoryItem *item);
HistoryItem *nextItem(HistoryItem *item);
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting);
void setToClipboard(const TextWithEntities &forClipboard, QClipboard::Mode mode = QClipboard::Clipboard);

View File

@ -91,6 +91,8 @@ struct HistoryTextState {
symbol = state.symbol;
return *this;
}
HistoryTextState(ClickHandlerPtr link) : link(link) {
}
HistoryCursorState cursor = HistoryDefaultCursorState;
ClickHandlerPtr link;
bool afterSymbol = false;
@ -656,11 +658,15 @@ public:
return false;
}
virtual HistoryTextState getState(QPoint point, HistoryStateRequest request) const WARN_UNUSED_RESULT = 0;
[[nodiscard]] virtual HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const = 0;
virtual void updatePressed(QPoint point) {
}
virtual TextSelection adjustSelection(TextSelection selection, TextSelectType type) const WARN_UNUSED_RESULT {
[[nodiscard]] virtual TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const {
return selection;
}
@ -1051,10 +1057,12 @@ protected:
return nullptr;
}
TextSelection skipTextSelection(TextSelection selection) const WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection skipTextSelection(
TextSelection selection) const {
return internal::unshiftSelection(selection, _text);
}
TextSelection unskipTextSelection(TextSelection selection) const WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection unskipTextSelection(
TextSelection selection) const {
return internal::shiftSelection(selection, _text);
}

View File

@ -93,27 +93,37 @@ public:
// if we are in selecting items mode perhaps we want to
// toggle selection instead of activating the pressed link
virtual bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const = 0;
virtual bool toggleSelectionByHandlerClick(
const ClickHandlerPtr &p) const = 0;
// if we press and drag on this media should we drag the item
virtual bool dragItem() const WARN_UNUSED_RESULT {
[[nodiscard]] virtual bool dragItem() const {
return false;
}
virtual TextSelection adjustSelection(TextSelection selection, TextSelectType type) const WARN_UNUSED_RESULT {
[[nodiscard]] virtual TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const {
return selection;
}
virtual bool consumeMessageText(const TextWithEntities &textWithEntities) WARN_UNUSED_RESULT {
[[nodiscard]] virtual bool consumeMessageText(
const TextWithEntities &textWithEntities) {
return false;
}
virtual uint16 fullSelectionLength() const WARN_UNUSED_RESULT {
[[nodiscard]] virtual uint16 fullSelectionLength() const {
return 0;
}
TextSelection skipSelection(TextSelection selection) const WARN_UNUSED_RESULT {
return internal::unshiftSelection(selection, fullSelectionLength());
[[nodiscard]] TextSelection skipSelection(
TextSelection selection) const {
return internal::unshiftSelection(
selection,
fullSelectionLength());
}
TextSelection unskipSelection(TextSelection selection) const WARN_UNUSED_RESULT {
return internal::shiftSelection(selection, fullSelectionLength());
[[nodiscard]] TextSelection unskipSelection(
TextSelection selection) const {
return internal::shiftSelection(
selection,
fullSelectionLength());
}
// if we press and drag this link should we drag the item

View File

@ -144,7 +144,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override {
return _caption.adjustSelection(selection, type);
}
uint16 fullSelectionLength() const override {
@ -230,7 +232,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override {
return _caption.adjustSelection(selection, type);
}
uint16 fullSelectionLength() const override {
@ -382,7 +386,9 @@ public:
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
void updatePressed(QPoint point) override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override {
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
return captioned->_caption.adjustSelection(selection, type);
}
@ -495,7 +501,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override {
return _caption.adjustSelection(selection, type);
}
uint16 fullSelectionLength() const override {
@ -795,7 +803,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override;
uint16 fullSelectionLength() const override {
return _title.length() + _description.length();
}
@ -902,7 +912,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override;
uint16 fullSelectionLength() const override {
return _title.length() + _description.length();
}
@ -1016,7 +1028,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override;
uint16 fullSelectionLength() const override {
return _title.length() + _description.length();
}
@ -1102,7 +1116,9 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT;
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override;
uint16 fullSelectionLength() const override {
return _title.length() + _description.length();
}

View File

@ -88,7 +88,9 @@ public:
bool hasPoint(QPoint point) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
TextSelection adjustSelection(TextSelection selection, TextSelectType type) const override WARN_UNUSED_RESULT {
[[nodiscard]] TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override {
return _text.adjustSelection(selection, type);
}

File diff suppressed because it is too large Load Diff

View File

@ -66,6 +66,18 @@ public:
rpl::producer<int> scrollToRequests() const {
return _scrollToRequests.events();
}
struct SelectedItem {
explicit SelectedItem(FullMsgId msgId) : msgId(msgId) {
}
FullMsgId msgId;
bool canDelete = false;
bool canForward = false;
};
using SelectedItems = std::vector<SelectedItem>;
rpl::producer<SelectedItems> selectedItemsValue() const {
return _selectedItemsStream.events();
}
~ListWidget();
@ -98,19 +110,51 @@ private:
std::unique_ptr<BaseLayout> item;
bool stale = false;
};
struct Context;
class Section;
struct FoundItem {
not_null<BaseLayout*> layout;
QRect geometry;
bool exact = false;
};
struct SelectionData {
explicit SelectionData(TextSelection text) : text(text) {
}
TextSelection text;
bool canDelete = false;
bool canForward = false;
};
using SelectedMap = base::flat_map<
UniversalMsgId,
SelectionData,
std::less<>>;
enum class DragSelectAction {
None,
Selecting,
Deselecting,
};
struct CursorState {
UniversalMsgId itemId = 0;
QSize size;
QPoint cursor;
bool inside = false;
inline bool operator==(const CursorState &other) const {
return (itemId == other.itemId)
&& (cursor == other.cursor);
}
inline bool operator!=(const CursorState &other) const {
return !(*this == other);
}
};
void start();
int recountHeight();
void refreshHeight();
QMargins padding() const;
void updateSelected();
bool isMyItem(not_null<const HistoryItem*> item) const;
bool isItemLayout(
not_null<const HistoryItem*> item,
@ -118,6 +162,7 @@ private:
void repaintItem(const HistoryItem *item);
void repaintItem(UniversalMsgId msgId);
void repaintItem(const BaseLayout *item);
void repaintItem(QRect itemGeometry);
void itemRemoved(not_null<const HistoryItem*> item);
void itemLayoutChanged(not_null<const HistoryItem*> item);
@ -126,12 +171,46 @@ private:
void refreshRows();
SharedMediaMergedSlice::Key sliceKey(
UniversalMsgId universalId) const;
BaseLayout *getLayout(const FullMsgId &itemId);
BaseLayout *getExistingLayout(const FullMsgId &itemId) const;
BaseLayout *getLayout(UniversalMsgId universalId);
BaseLayout *getExistingLayout(UniversalMsgId universalId) const;
std::unique_ptr<BaseLayout> createLayout(
const FullMsgId &itemId,
UniversalMsgId universalId,
Type type);
SelectedItems collectSelectedItems() const;
void pushSelectedItems();
FullMsgId computeFullId(UniversalMsgId universalId) const;
bool hasSelected() const;
bool isSelectedItem(
const SelectedMap::const_iterator &i) const;
void removeItemSelection(
const SelectedMap::const_iterator &i);
bool hasSelectedText() const;
bool hasSelectedItems() const;
void clearSelected();
void applyItemSelection(
UniversalMsgId universalId,
TextSelection selection);
void toggleItemSelection(
UniversalMsgId universalId);
SelectedMap::iterator itemUnderPressSelection();
SelectedMap::const_iterator itemUnderPressSelection() const;
bool isItemUnderPressSelected() const;
bool requiredToStartDragging(not_null<BaseLayout*> layout) const;
bool isPressInSelectedText(HistoryTextState state) const;
void applyDragSelection();
void applyDragSelection(SelectedMap &applyTo) const;
bool changeItemSelection(
SelectedMap &selected,
UniversalMsgId universalId,
TextSelection selection) const;
static bool IsAfter(
const CursorState &a,
const CursorState &b);
static bool SkipSelectFromItem(const CursorState &state);
static bool SkipSelectTillItem(const CursorState &state);
void markLayoutsStale();
void clearStaleLayouts();
std::vector<Section>::iterator findSectionByItem(
@ -157,11 +236,25 @@ private:
const QPoint &screenPos,
Qt::MouseButton button);
void mouseActionUpdate(const QPoint &screenPos);
void mouseActionUpdate();
void mouseActionFinish(
const QPoint &screenPos,
Qt::MouseButton button);
void mouseActionCancel();
void performDrag();
style::cursor computeMouseCursor() const;
void updateDragSelection();
void clearDragSelection();
void setDragSelection(
BaseLayout *dragSelectFrom,
BaseLayout *dragSelectTill,
DragSelectAction action);
void trySwitchToWordSelection();
void switchToWordSelection();
void validateTrippleClickStartTime();
void checkMoveToOtherViewer();
not_null<Window::Controller*> _controller;
not_null<PeerData*> _peer;
@ -183,29 +276,24 @@ private:
MouseAction _mouseAction = MouseAction::None;
TextSelectType _mouseSelectType = TextSelectType::Letters;
QPoint _dragStartPosition;
QPoint _mousePosition;
BaseLayout *_itemNearestToCursor = nullptr;
BaseLayout *_itemUnderCursor = nullptr;
BaseLayout *_itemUnderPress = nullptr;
CursorState _overState;
CursorState _pressState;
BaseLayout *_overLayout = nullptr;
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
// uint16 _mouseTextSymbol = 0;
uint16 _mouseTextSymbol = 0;
bool _pressWasInactive = false;
using SelectedItems = std::map<
UniversalMsgId,
TextSelection,
std::less<>>;
SelectedItems _selected;
SelectedMap _selected;
SelectedMap _dragSelected;
rpl::event_stream<SelectedItems> _selectedItemsStream;
style::cursor _cursor = style::cur_default;
BaseLayout *_dragSelFrom = nullptr;
BaseLayout *_dragSelTo = nullptr;
// bool _dragSelecting = false;
DragSelectAction _dragSelectAction = DragSelectAction::None;
bool _wasSelectedText = false; // was some text selected in current drag action
Ui::PopupMenu *_contextMenu = nullptr;
ClickHandlerPtr _contextMenuLink;
QPoint _trippleClickPoint;
QTimer _trippleClickTimer;
TimeMs _trippleClickStartTime = 0;
rpl::lifetime _viewerLifetime;

View File

@ -213,14 +213,17 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
}
}
void Gif::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Gif::getState(
QPoint point,
HistoryStateRequest request) const {
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
if (_delete && rtlpoint(point, _width).x() >= _width - st::stickerPanDeleteIconBg.width() && point.y() < st::stickerPanDeleteIconBg.height()) {
link = _delete;
return _delete;
} else {
link = _send;
return _send;
}
}
return {};
}
void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
@ -404,10 +407,13 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context)
}
}
void Sticker::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Sticker::getState(
QPoint point,
HistoryStateRequest request) const {
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
link = _send;
return _send;
}
return {};
}
void Sticker::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
@ -491,10 +497,13 @@ void Photo::paint(Painter &p, const QRect &clip, const PaintContext *context) co
}
}
void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Photo::getState(
QPoint point,
HistoryStateRequest request) const {
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
link = _send;
return _send;
}
return {};
}
PhotoData *Photo::getShownPhoto() const {
@ -633,15 +642,16 @@ void Video::paint(Painter &p, const QRect &clip, const PaintContext *context) co
}
}
void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Video::getState(
QPoint point,
HistoryStateRequest request) const {
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
link = _link;
return;
return _link;
}
if (QRect(st::inlineThumbSize + st::inlineThumbSkip, 0, _width - st::inlineThumbSize - st::inlineThumbSkip, _height).contains(point)) {
link = _send;
return;
return _send;
}
return {};
}
void Video::prepareThumb(int32 width, int32 height) const {
@ -773,16 +783,18 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
}
}
void File::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState File::getState(
QPoint point,
HistoryStateRequest request) const {
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize).contains(point)) {
link = getShownDocument()->loading() ? _cancel : _open;
return;
}
auto left = st::msgFileSize + st::inlineThumbSkip;
if (QRect(left, 0, _width - left, _height).contains(point)) {
link = _send;
return;
return getShownDocument()->loading() ? _cancel : _open;
} else {
auto left = st::msgFileSize + st::inlineThumbSkip;
if (QRect(left, 0, _width - left, _height).contains(point)) {
return _send;
}
}
return {};
}
void File::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
@ -933,15 +945,16 @@ void Contact::paint(Painter &p, const QRect &clip, const PaintContext *context)
}
}
void Contact::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) {
return;
}
auto left = (st::msgFileSize + st::inlineThumbSkip);
if (QRect(left, 0, _width - left, _height).contains(point)) {
link = _send;
return;
HistoryTextState Contact::getState(
QPoint point,
HistoryStateRequest request) const {
if (!QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) {
auto left = (st::msgFileSize + st::inlineThumbSkip);
if (QRect(left, 0, _width - left, _height).contains(point)) {
return _send;
}
}
return {};
}
void Contact::prepareThumb(int width, int height) const {
@ -1069,10 +1082,11 @@ void Article::paint(Painter &p, const QRect &clip, const PaintContext *context)
}
}
void Article::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Article::getState(
QPoint point,
HistoryStateRequest request) const {
if (_withThumb && QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
link = _link;
return;
return _link;
}
auto left = _withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0;
if (QRect(left, 0, _width - left, _height).contains(point)) {
@ -1082,13 +1096,12 @@ void Article::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint
auto descriptionLines = 2;
auto descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
if (rtlrect(left, st::inlineRowMargin + titleHeight + descriptionHeight, _urlWidth, st::normalFont->height, _width).contains(point)) {
link = _url;
return;
return _url;
}
}
link = _send;
return;
return _send;
}
return {};
}
void Article::prepareThumb(int width, int height) const {
@ -1253,16 +1266,17 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
}
}
void Game::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Game::getState(
QPoint point,
HistoryStateRequest request) const {
int left = st::inlineThumbSize + st::inlineThumbSkip;
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
link = _send;
return;
return _send;
}
if (QRect(left, 0, _width - left, _height).contains(point)) {
link = _send;
return;
return _send;
}
return {};
}
void Game::prepareThumb(int width, int height) const {

View File

@ -73,7 +73,9 @@ public:
}
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
// ClickHandlerHost interface
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
@ -130,7 +132,9 @@ public:
}
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
private:
PhotoData *getShownPhoto() const;
@ -160,7 +164,9 @@ public:
void preload() const override;
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
// ClickHandlerHost interface
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
@ -184,7 +190,9 @@ public:
void initDimensions() override;
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
private:
ClickHandlerPtr _link;
@ -231,7 +239,9 @@ public:
void initDimensions() override;
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
// ClickHandlerHost interface
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
@ -294,7 +304,9 @@ public:
int resizeGetHeight(int width) override;
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
private:
mutable QPixmap _thumb;
@ -312,7 +324,9 @@ public:
int resizeGetHeight(int width) override;
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
private:
ClickHandlerPtr _url, _link;
@ -335,7 +349,9 @@ public:
void initDimensions() override;
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
private:
void countFrameSize();

View File

@ -644,8 +644,10 @@ void Inner::updateSelected() {
}
if (col < inlineItems.size()) {
sel = row * MatrixRowShift + col;
inlineItems.at(col)->getState(lnk, cursor, QPoint(sx, sy));
lnkhost = inlineItems.at(col);
auto result = inlineItems[col]->getState(QPoint(sx, sy), HistoryStateRequest());
lnk = result.link;
cursor = result.cursor;
lnkhost = inlineItems[col];
} else {
row = col = -1;
}

View File

@ -119,14 +119,15 @@ public:
return _height;
}
virtual void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
link.clear();
cursor = HistoryDefaultCursorState;
[[nodiscard]] virtual HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const {
return {};
}
virtual void getSymbol(uint16 &symbol, bool &after, bool &upon, QPoint point) const { // from text
upon = hasPoint(point);
symbol = upon ? 0xFFFF : 0;
after = false;
[[nodiscard]] virtual TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const {
return selection;
}
int width() const {

View File

@ -104,7 +104,9 @@ void ListWidget::mouseMoveEvent(QMouseEvent *e) {
if (y <= m.y()) {
if (auto media = layout->toMediaItem()) {
item = media->getItem();
media->getState(lnk, cursorState, m - QPoint(0, y));
auto result = media->getState(m - QPoint(0, y), HistoryStateRequest());
lnk = result.link;
cursorState = result.cursor;
lnkhost = media;
}
}

View File

@ -1153,7 +1153,11 @@ void MediaView::refreshMediaViewer() {
}
void MediaView::showPhoto(not_null<PhotoData*> photo, HistoryItem *context) {
setContext(context);
if (context) {
setContext(context);
} else {
setContext(base::none);
}
_firstOpenedPeerPhoto = false;
_saveMsgStarted = 0;

View File

@ -214,39 +214,39 @@ public:
SpecificRequestBuilder(SpecificRequestBuilder &&other) = default;
public:
SpecificRequestBuilder &toDC(ShiftedDcId dcId) noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &toDC(ShiftedDcId dcId) noexcept {
setToDC(dcId);
return *this;
}
SpecificRequestBuilder &canWait(TimeMs ms) noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &canWait(TimeMs ms) noexcept {
setCanWait(ms);
return *this;
}
SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result)> callback) WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result)> callback) {
setDoneHandler(MakeShared<DoneHandler<typename Request::ResponseType, DonePlainPolicy>>(sender(), std::move(callback)));
return *this;
}
SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result, mtpRequestId requestId)> callback) WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &done(base::lambda_once<void(const typename Request::ResponseType &result, mtpRequestId requestId)> callback) {
setDoneHandler(MakeShared<DoneHandler<typename Request::ResponseType, DoneRequestIdPolicy>>(sender(), std::move(callback)));
return *this;
}
SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error)> callback) noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error)> callback) noexcept {
setFailHandler(std::move(callback));
return *this;
}
SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error, mtpRequestId requestId)> callback) noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &fail(base::lambda_once<void(const RPCError &error, mtpRequestId requestId)> callback) noexcept {
setFailHandler(std::move(callback));
return *this;
}
SpecificRequestBuilder &handleFloodErrors() noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &handleFloodErrors() noexcept {
setFailSkipPolicy(FailSkipPolicy::HandleFlood);
return *this;
}
SpecificRequestBuilder &handleAllErrors() noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &handleAllErrors() noexcept {
setFailSkipPolicy(FailSkipPolicy::HandleAll);
return *this;
}
SpecificRequestBuilder &after(mtpRequestId requestId) noexcept WARN_UNUSED_RESULT {
[[nodiscard]] SpecificRequestBuilder &after(mtpRequestId requestId) noexcept {
setAfter(requestId);
return *this;
}
@ -280,11 +280,11 @@ public:
};
template <typename Request, typename = std::enable_if_t<std::is_rvalue_reference<Request&&>::value>, typename = typename Request::Unboxed>
SpecificRequestBuilder<Request> request(Request &&request) noexcept WARN_UNUSED_RESULT;
[[nodiscard]] SpecificRequestBuilder<Request> request(Request &&request) noexcept;
SentRequestWrap request(mtpRequestId requestId) noexcept WARN_UNUSED_RESULT;
[[nodiscard]] SentRequestWrap request(mtpRequestId requestId) noexcept;
decltype(auto) requestCanceller() noexcept WARN_UNUSED_RESULT {
[[nodiscard]] decltype(auto) requestCanceller() noexcept {
return [this](mtpRequestId requestId) {
request(requestId).cancel();
};

View File

@ -66,12 +66,16 @@ TextWithEntities ComposeNameWithEntities(DocumentData *document) {
} // namespace
void ItemBase::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
void ItemBase::clickHandlerActiveChanged(
const ClickHandlerPtr &action,
bool active) {
App::hoveredLinkItem(active ? _parent.get() : nullptr);
Auth().data().requestItemRepaint(_parent);
}
void ItemBase::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) {
void ItemBase::clickHandlerPressedChanged(
const ClickHandlerPtr &action,
bool pressed) {
App::pressedLinkItem(pressed ? _parent.get() : nullptr);
Auth().data().requestItemRepaint(_parent);
}
@ -306,10 +310,13 @@ void Photo::ensureCheckboxCreated() {
});
}
void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Photo::getState(
QPoint point,
HistoryStateRequest request) const {
if (hasPoint(point)) {
link = _link;
return _link;
}
return {};
}
void Photo::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
@ -506,12 +513,15 @@ bool Video::iconAnimated() const {
return true;
}
void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Video::getState(
QPoint point,
HistoryStateRequest request) const {
bool loaded = _data->loaded();
if (hasPoint(point)) {
link = loaded ? _openl : (_data->loading() ? _cancell : _savel);
return loaded ? _openl : (_data->loading() ? _cancell : _savel);
}
return {};
}
void Video::updateStatusText() {
@ -664,7 +674,9 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
}
}
void Voice::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Voice::getState(
QPoint point,
HistoryStateRequest request) const {
bool loaded = _data->loaded();
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
@ -676,20 +688,20 @@ void Voice::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint p
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
if (inner.contains(point)) {
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
return;
return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
}
auto result = HistoryTextState();
if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(point)) {
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
link = textState.link;
cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState;
result.link = textState.link;
result.cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState;
}
}
if (hasPoint(point) && !link && !_data->loading()) {
link = _namel;
return;
if (hasPoint(point) && !result.link && !_data->loading()) {
return _namel;
}
return result;
}
float64 Voice::dataProgress() const {
@ -954,7 +966,9 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
}
}
void Document::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Document::getState(
QPoint point,
HistoryStateRequest request) const {
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey());
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
@ -968,12 +982,10 @@ void Document::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoin
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
if (inner.contains(point)) {
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
return;
return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
}
if (hasPoint(point) && !_data->loading()) {
link = _namel;
return;
return _namel;
}
} else {
nameleft = _st.fileThumbSize + _st.filePadding.right();
@ -984,27 +996,24 @@ void Document::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoin
auto rthumb = rtlrect(0, st::linksBorder + _st.filePadding.top(), _st.fileThumbSize, _st.fileThumbSize, _width);
if (rthumb.contains(point)) {
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel);
return;
return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel);
}
if (_data->status != FileUploadFailed) {
if (rtlrect(nameleft, datetop, _datew, st::normalFont->height, _width).contains(point)) {
link = _msgl;
return;
return _msgl;
}
}
if (!_data->loading() && _data->isValid()) {
if (loaded && rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(point)) {
link = _namel;
return;
return _namel;
}
if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _name.maxWidth()), st::semiboldFont->height, _width).contains(point)) {
link = _namel;
return;
return _namel;
}
}
}
return {};
}
float64 Document::dataProgress() const {
@ -1301,11 +1310,12 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
}
}
void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const {
HistoryTextState Link::getState(
QPoint point,
HistoryStateRequest request) const {
int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
if (rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width).contains(point)) {
link = _photol;
return;
return _photol;
}
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
@ -1313,8 +1323,7 @@ void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint po
}
if (!_title.isEmpty()) {
if (rtlrect(left, top, qMin(w, _titlew), st::semiboldFont->height, _width).contains(point)) {
link = _photol;
return;
return _photol;
}
top += st::webPageTitleFont->height;
}
@ -1323,11 +1332,11 @@ void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint po
}
for (int32 i = 0, l = _links.size(); i < l; ++i) {
if (rtlrect(left, top, qMin(w, _links.at(i).width), st::normalFont->height, _width).contains(point)) {
link = _links.at(i).lnk;
return;
return _links.at(i).lnk;
}
top += st::normalFont->height;
}
return {};
}
Link::LinkEntry::LinkEntry(const QString &url, const QString &text)

View File

@ -189,7 +189,9 @@ public:
void initDimensions() override;
int32 resizeGetHeight(int32 width) override;
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
@ -220,7 +222,9 @@ public:
void initDimensions() override;
int32 resizeGetHeight(int32 width) override;
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
@ -260,7 +264,9 @@ public:
void initDimensions() override;
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
protected:
float64 dataProgress() const override;
@ -292,7 +298,9 @@ public:
void initDimensions() override;
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
virtual DocumentData *getDocument() const override {
return _data;
@ -333,7 +341,9 @@ public:
void initDimensions() override;
int32 resizeGetHeight(int32 width) override;
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, QPoint point) const override;
HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const override;
private:
ClickHandlerPtr _photol;

View File

@ -900,7 +900,9 @@ void OverviewInner::onUpdateSelected() {
item = media->getItem();
index = i;
if (upon) {
media->getState(lnk, cursorState, m - QPoint(col * w + st::overviewPhotoSkip, _marginTop + row * vsize + st::overviewPhotoSkip));
auto result = media->getState(m - QPoint(col * w + st::overviewPhotoSkip, _marginTop + row * vsize + st::overviewPhotoSkip), HistoryStateRequest());
lnk = result.link;
cursorState = result.cursor;
lnkhost = media;
}
}
@ -936,7 +938,9 @@ void OverviewInner::onUpdateSelected() {
if (auto media = _items.at(i)->toMediaItem()) {
item = media->getItem();
index = i;
media->getState(lnk, cursorState, m - QPoint(_rowsLeft, _marginTop + top));
auto result = media->getState(m - QPoint(_rowsLeft, _marginTop + top), HistoryStateRequest());
lnk = result.link;
cursorState = result.cursor;
lnkhost = media;
}
break;

View File

@ -165,7 +165,7 @@ public:
return getStateElided(rtlpoint(point, outerw), width, request);
}
TextSelection adjustSelection(TextSelection selection, TextSelectType selectType) const WARN_UNUSED_RESULT;
[[nodiscard]] TextSelection adjustSelection(TextSelection selection, TextSelectType selectType) const;
bool isFullSelection(TextSelection selection) const {
return (selection.from == 0) && (selection.to >= _text.size());
}