mirror of https://github.com/procxx/kepka.git
Fix / improve support for album items selection.
This commit is contained in:
parent
722264f634
commit
2fdc3169ce
|
@ -280,7 +280,7 @@ void BotKeyboard::updateSelected() {
|
||||||
auto p = mapFromGlobal(_lastMousePos);
|
auto p = mapFromGlobal(_lastMousePos);
|
||||||
auto x = rtl() ? st::botKbScroll.width : _st->margin;
|
auto x = rtl() ? st::botKbScroll.width : _st->margin;
|
||||||
|
|
||||||
auto link = _impl->getState(p - QPoint(x, _st->margin));
|
auto link = _impl->getLink(p - QPoint(x, _st->margin));
|
||||||
if (ClickHandler::setActive(link, this)) {
|
if (ClickHandler::setActive(link, this)) {
|
||||||
Ui::Tooltip::Hide();
|
Ui::Tooltip::Hide();
|
||||||
setCursor(link ? style::cur_pointer : style::cur_default);
|
setCursor(link ? style::cur_pointer : style::cur_default);
|
||||||
|
|
|
@ -888,7 +888,7 @@ void GifsListWidget::updateSelected() {
|
||||||
int row = -1, col = -1, sel = -1;
|
int row = -1, col = -1, sel = -1;
|
||||||
ClickHandlerPtr lnk;
|
ClickHandlerPtr lnk;
|
||||||
ClickHandlerHost *lnkhost = nullptr;
|
ClickHandlerHost *lnkhost = nullptr;
|
||||||
HistoryCursorState cursor = HistoryDefaultCursorState;
|
HistoryView::CursorState cursor = HistoryView::CursorState::None;
|
||||||
if (sy >= 0) {
|
if (sy >= 0) {
|
||||||
row = 0;
|
row = 0;
|
||||||
for (int rows = _rows.size(); row < rows; ++row) {
|
for (int rows = _rows.size(); row < rows; ++row) {
|
||||||
|
@ -913,10 +913,12 @@ void GifsListWidget::updateSelected() {
|
||||||
}
|
}
|
||||||
if (col < inlineItems.size()) {
|
if (col < inlineItems.size()) {
|
||||||
sel = row * MatrixRowShift + col;
|
sel = row * MatrixRowShift + col;
|
||||||
auto result = inlineItems[col]->getState(QPoint(sx, sy), HistoryStateRequest());
|
auto result = inlineItems[col]->getState(
|
||||||
|
QPoint(sx, sy),
|
||||||
|
HistoryView::StateRequest());
|
||||||
lnk = result.link;
|
lnk = result.link;
|
||||||
cursor = result.cursor;
|
cursor = result.cursor;
|
||||||
lnkhost = inlineItems.at(col);
|
lnkhost = inlineItems[col];
|
||||||
} else {
|
} else {
|
||||||
row = col = -1;
|
row = col = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/admin_log/history_admin_log_filter.h"
|
#include "history/admin_log/history_admin_log_filter.h"
|
||||||
#include "history/view/history_view_message.h"
|
#include "history/view/history_view_message.h"
|
||||||
#include "history/view/history_view_service_message.h"
|
#include "history/view/history_view_service_message.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
@ -451,13 +452,15 @@ void InnerWidget::updateEmptyText() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString InnerWidget::tooltipText() const {
|
QString InnerWidget::tooltipText() const {
|
||||||
if (_mouseCursorState == HistoryInDateCursorState && _mouseAction == MouseAction::None) {
|
if (_mouseCursorState == CursorState::Date
|
||||||
|
&& _mouseAction == MouseAction::None) {
|
||||||
if (const auto view = App::hoveredItem()) {
|
if (const auto view = App::hoveredItem()) {
|
||||||
auto dateText = view->data()->date.toString(
|
auto dateText = view->data()->date.toString(
|
||||||
QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
||||||
return dateText;
|
return dateText;
|
||||||
}
|
}
|
||||||
} else if (_mouseCursorState == HistoryInForwardedCursorState && _mouseAction == MouseAction::None) {
|
} else if (_mouseCursorState == CursorState::Forwarded
|
||||||
|
&& _mouseAction == MouseAction::None) {
|
||||||
if (const auto view = App::hoveredItem()) {
|
if (const auto view = App::hoveredItem()) {
|
||||||
if (const auto forwarded = view->data()->Get<HistoryMessageForwarded>()) {
|
if (const auto forwarded = view->data()->Get<HistoryMessageForwarded>()) {
|
||||||
return forwarded->text.originalText(AllTextSelection, ExpandLinksNone);
|
return forwarded->text.originalText(AllTextSelection, ExpandLinksNone);
|
||||||
|
@ -872,10 +875,10 @@ void InnerWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
void InnerWidget::mouseDoubleClickEvent(QMouseEvent *e) {
|
void InnerWidget::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||||
mouseActionStart(e->globalPos(), e->button());
|
mouseActionStart(e->globalPos(), e->button());
|
||||||
if (((_mouseAction == MouseAction::Selecting && _selectedItem != nullptr) || (_mouseAction == MouseAction::None)) && _mouseSelectType == TextSelectType::Letters && _mouseActionItem) {
|
if (((_mouseAction == MouseAction::Selecting && _selectedItem != nullptr) || (_mouseAction == MouseAction::None)) && _mouseSelectType == TextSelectType::Letters && _mouseActionItem) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = _mouseActionItem->getState(_dragStartPosition, request);
|
auto dragState = _mouseActionItem->textState(_dragStartPosition, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
_mouseSelectType = TextSelectType::Words;
|
_mouseSelectType = TextSelectType::Words;
|
||||||
if (_mouseAction == MouseAction::None) {
|
if (_mouseAction == MouseAction::None) {
|
||||||
|
@ -914,10 +917,10 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
auto mousePos = mapPointToItem(
|
auto mousePos = mapPointToItem(
|
||||||
mapFromGlobal(_mousePosition),
|
mapFromGlobal(_mousePosition),
|
||||||
App::mousedItem());
|
App::mousedItem());
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = App::mousedItem()->getState(mousePos, request);
|
auto dragState = App::mousedItem()->textState(mousePos, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState
|
if (dragState.cursor == CursorState::Text
|
||||||
&& base::in_range(dragState.symbol, selFrom, selTo)) {
|
&& base::in_range(dragState.symbol, selFrom, selTo)) {
|
||||||
isUponSelected = 1;
|
isUponSelected = 1;
|
||||||
}
|
}
|
||||||
|
@ -1275,12 +1278,12 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
}
|
}
|
||||||
if (_mouseAction == MouseAction::None && _mouseActionItem) {
|
if (_mouseAction == MouseAction::None && _mouseActionItem) {
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
|
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = _mouseActionItem->getState(_dragStartPosition, request);
|
dragState = _mouseActionItem->textState(_dragStartPosition, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
auto selection = TextSelection { dragState.symbol, dragState.symbol };
|
auto selection = TextSelection { dragState.symbol, dragState.symbol };
|
||||||
repaintItem(std::exchange(_selectedItem, _mouseActionItem));
|
repaintItem(std::exchange(_selectedItem, _mouseActionItem));
|
||||||
_selectedText = selection;
|
_selectedText = selection;
|
||||||
|
@ -1291,14 +1294,14 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
|
||||||
_trippleClickTimer.callOnce(QApplication::doubleClickInterval());
|
_trippleClickTimer.callOnce(QApplication::doubleClickInterval());
|
||||||
}
|
}
|
||||||
} else if (App::pressedItem()) {
|
} else if (App::pressedItem()) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = _mouseActionItem->getState(_dragStartPosition, request);
|
dragState = _mouseActionItem->textState(_dragStartPosition, request);
|
||||||
}
|
}
|
||||||
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
||||||
if (App::pressedItem()) {
|
if (App::pressedItem()) {
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
auto uponSelected = (dragState.cursor == HistoryInTextCursorState);
|
auto uponSelected = (dragState.cursor == CursorState::Text);
|
||||||
if (uponSelected) {
|
if (uponSelected) {
|
||||||
if (!_selectedItem || _selectedItem != _mouseActionItem) {
|
if (!_selectedItem || _selectedItem != _mouseActionItem) {
|
||||||
uponSelected = false;
|
uponSelected = false;
|
||||||
|
@ -1399,7 +1402,7 @@ void InnerWidget::updateSelected() {
|
||||||
if (item) {
|
if (item) {
|
||||||
App::mousedItem(view);
|
App::mousedItem(view);
|
||||||
itemPoint = mapPointToItem(point, view);
|
itemPoint = mapPointToItem(point, view);
|
||||||
if (view->hasPoint(itemPoint)) {
|
if (view->pointState(itemPoint) != PointState::Outside) {
|
||||||
if (App::hoveredItem() != view) {
|
if (App::hoveredItem() != view) {
|
||||||
repaintItem(App::hoveredItem());
|
repaintItem(App::hoveredItem());
|
||||||
App::hoveredItem(view);
|
App::hoveredItem(view);
|
||||||
|
@ -1411,7 +1414,7 @@ void InnerWidget::updateSelected() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
ClickHandlerHost *lnkhost = nullptr;
|
ClickHandlerHost *lnkhost = nullptr;
|
||||||
auto selectingText = _selectedItem
|
auto selectingText = _selectedItem
|
||||||
&& (view == _mouseActionItem)
|
&& (view == _mouseActionItem)
|
||||||
|
@ -1423,13 +1426,13 @@ void InnerWidget::updateSelected() {
|
||||||
InvokeQueued(this, [this] { performDrag(); });
|
InvokeQueued(this, [this] { performDrag(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
if (_mouseAction == MouseAction::Selecting) {
|
if (_mouseAction == MouseAction::Selecting) {
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
} else {
|
} else {
|
||||||
selectingText = false;
|
selectingText = false;
|
||||||
}
|
}
|
||||||
dragState = view->getState(itemPoint, request);
|
dragState = view->textState(itemPoint, request);
|
||||||
lnkhost = view;
|
lnkhost = view;
|
||||||
if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) {
|
if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) {
|
||||||
if (auto message = item->toHistoryMessage()) {
|
if (auto message = item->toHistoryMessage()) {
|
||||||
|
@ -1459,7 +1462,9 @@ void InnerWidget::updateSelected() {
|
||||||
if (lnkChanged || dragState.cursor != _mouseCursorState) {
|
if (lnkChanged || dragState.cursor != _mouseCursorState) {
|
||||||
Ui::Tooltip::Hide();
|
Ui::Tooltip::Hide();
|
||||||
}
|
}
|
||||||
if (dragState.link || dragState.cursor == HistoryInDateCursorState || dragState.cursor == HistoryInForwardedCursorState) {
|
if (dragState.link
|
||||||
|
|| dragState.cursor == CursorState::Date
|
||||||
|
|| dragState.cursor == CursorState::Forwarded) {
|
||||||
Ui::Tooltip::Show(1000, this);
|
Ui::Tooltip::Show(1000, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,9 +1473,9 @@ void InnerWidget::updateSelected() {
|
||||||
_mouseCursorState = dragState.cursor;
|
_mouseCursorState = dragState.cursor;
|
||||||
if (dragState.link) {
|
if (dragState.link) {
|
||||||
cursor = style::cur_pointer;
|
cursor = style::cur_pointer;
|
||||||
} else if (_mouseCursorState == HistoryInTextCursorState) {
|
} else if (_mouseCursorState == CursorState::Text) {
|
||||||
cursor = style::cur_text;
|
cursor = style::cur_text;
|
||||||
} else if (_mouseCursorState == HistoryInDateCursorState) {
|
} else if (_mouseCursorState == CursorState::Date) {
|
||||||
// cursor = style::cur_cross;
|
// cursor = style::cur_cross;
|
||||||
}
|
}
|
||||||
} else if (item) {
|
} else if (item) {
|
||||||
|
@ -1530,10 +1535,10 @@ void InnerWidget::performDrag() {
|
||||||
// if (!_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
|
// if (!_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
|
||||||
// uponSelected = _selected.contains(_mouseActionItem);
|
// uponSelected = _selected.contains(_mouseActionItem);
|
||||||
// } else {
|
// } else {
|
||||||
// HistoryStateRequest request;
|
// StateRequest request;
|
||||||
// request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
// request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
// auto dragState = _mouseActionItem->getState(_dragStartPosition.x(), _dragStartPosition.y(), request);
|
// auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request);
|
||||||
// uponSelected = (dragState.cursor == HistoryInTextCursorState);
|
// uponSelected = (dragState.cursor == CursorState::Text);
|
||||||
// if (uponSelected) {
|
// if (uponSelected) {
|
||||||
// if (_selected.isEmpty() ||
|
// if (_selected.isEmpty() ||
|
||||||
// _selected.cbegin().value() == FullSelection ||
|
// _selected.cbegin().value() == FullSelection ||
|
||||||
|
@ -1584,7 +1589,7 @@ void InnerWidget::performDrag() {
|
||||||
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
||||||
// if (auto pressedItem = App::pressedItem()) {
|
// if (auto pressedItem = App::pressedItem()) {
|
||||||
// pressedMedia = pressedItem->media();
|
// pressedMedia = pressedItem->media();
|
||||||
// if (_mouseCursorState == HistoryInDateCursorState
|
// if (_mouseCursorState == CursorState::Date
|
||||||
// || (pressedMedia && pressedMedia->dragItem())) {
|
// || (pressedMedia && pressedMedia->dragItem())) {
|
||||||
// forwardMimeType = qsl("application/x-td-forward");
|
// forwardMimeType = qsl("application/x-td-forward");
|
||||||
// Auth().data().setMimeForwardIds(
|
// Auth().data().setMimeForwardIds(
|
||||||
|
|
|
@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "history/view/history_view_cursor_state.h"
|
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/admin_log/history_admin_log_item.h"
|
#include "history/admin_log/history_admin_log_item.h"
|
||||||
#include "history/admin_log/history_admin_log_section.h"
|
#include "history/admin_log/history_admin_log_section.h"
|
||||||
|
@ -16,6 +15,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
class Element;
|
||||||
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
enum class CursorState : char;
|
||||||
|
enum class PointState : char;
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class PopupMenu;
|
class PopupMenu;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
@ -115,6 +122,10 @@ private:
|
||||||
TopToBottom,
|
TopToBottom,
|
||||||
BottomToTop,
|
BottomToTop,
|
||||||
};
|
};
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
using CursorState = HistoryView::CursorState;
|
||||||
|
using PointState = HistoryView::PointState;
|
||||||
|
using StateRequest = HistoryView::StateRequest;
|
||||||
|
|
||||||
void mouseActionStart(const QPoint &screenPos, Qt::MouseButton button);
|
void mouseActionStart(const QPoint &screenPos, Qt::MouseButton button);
|
||||||
void mouseActionUpdate(const QPoint &screenPos);
|
void mouseActionUpdate(const QPoint &screenPos);
|
||||||
|
@ -228,7 +239,7 @@ private:
|
||||||
QPoint _dragStartPosition;
|
QPoint _dragStartPosition;
|
||||||
QPoint _mousePosition;
|
QPoint _mousePosition;
|
||||||
Element *_mouseActionItem = nullptr;
|
Element *_mouseActionItem = nullptr;
|
||||||
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
|
CursorState _mouseCursorState = CursorState();
|
||||||
uint16 _mouseTextSymbol = 0;
|
uint16 _mouseTextSymbol = 0;
|
||||||
bool _pressWasInactive = false;
|
bool _pressWasInactive = false;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item_text.h"
|
#include "history/history_item_text.h"
|
||||||
#include "history/view/history_view_message.h"
|
#include "history/view/history_view_message.h"
|
||||||
#include "history/view/history_view_service_message.h"
|
#include "history/view/history_view_service_message.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
@ -131,7 +132,8 @@ HistoryInner::HistoryInner(
|
||||||
, _migrated(history->migrateFrom())
|
, _migrated(history->migrateFrom())
|
||||||
, _widget(historyWidget)
|
, _widget(historyWidget)
|
||||||
, _scroll(scroll)
|
, _scroll(scroll)
|
||||||
, _scrollDateCheck([this] { onScrollDateCheck(); }) {
|
, _scrollDateCheck([this] { scrollDateCheck(); })
|
||||||
|
, _scrollDateHideTimer([this] { scrollDateHideByTimer(); }) {
|
||||||
_touchSelectTimer.setSingleShot(true);
|
_touchSelectTimer.setSingleShot(true);
|
||||||
connect(&_touchSelectTimer, SIGNAL(timeout()), this, SLOT(onTouchSelect()));
|
connect(&_touchSelectTimer, SIGNAL(timeout()), this, SLOT(onTouchSelect()));
|
||||||
|
|
||||||
|
@ -140,8 +142,6 @@ HistoryInner::HistoryInner(
|
||||||
|
|
||||||
_trippleClickTimer.setSingleShot(true);
|
_trippleClickTimer.setSingleShot(true);
|
||||||
|
|
||||||
connect(&_scrollDateHideTimer, SIGNAL(timeout()), this, SLOT(onScrollDateHideByTimer()));
|
|
||||||
|
|
||||||
notifyIsBotChanged();
|
notifyIsBotChanged();
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
@ -166,9 +166,15 @@ HistoryInner::HistoryInner(
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
Auth().data().viewRepaintRequest(
|
Auth().data().viewRepaintRequest(
|
||||||
) | rpl::start_with_next(
|
) | rpl::start_with_next([this](not_null<const Element*> view) {
|
||||||
[this](auto view) { repaintItem(view); },
|
repaintItem(view);
|
||||||
lifetime());
|
}, lifetime());
|
||||||
|
Auth().data().viewLayoutChanged(
|
||||||
|
) | rpl::filter([](not_null<const Element*> view) {
|
||||||
|
return (view == view->data()->mainView()) && view->isUnderCursor();
|
||||||
|
}) | rpl::start_with_next([this](not_null<const Element*> view) {
|
||||||
|
mouseActionUpdate();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages) {
|
void HistoryInner::messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages) {
|
||||||
|
@ -423,6 +429,10 @@ void HistoryInner::enumerateDates(Method method) {
|
||||||
TextSelection HistoryInner::computeRenderSelection(
|
TextSelection HistoryInner::computeRenderSelection(
|
||||||
not_null<const SelectedItems*> selected,
|
not_null<const SelectedItems*> selected,
|
||||||
not_null<Element*> view) const {
|
not_null<Element*> view) const {
|
||||||
|
if (view->isHiddenByGroup()) {
|
||||||
|
return TextSelection();
|
||||||
|
}
|
||||||
|
const auto item = view->data();
|
||||||
const auto itemSelection = [&](not_null<HistoryItem*> item) {
|
const auto itemSelection = [&](not_null<HistoryItem*> item) {
|
||||||
auto i = selected->find(item);
|
auto i = selected->find(item);
|
||||||
if (i != selected->end()) {
|
if (i != selected->end()) {
|
||||||
|
@ -430,32 +440,30 @@ TextSelection HistoryInner::computeRenderSelection(
|
||||||
}
|
}
|
||||||
return TextSelection();
|
return TextSelection();
|
||||||
};
|
};
|
||||||
// #TODO group selection
|
const auto result = itemSelection(item);
|
||||||
//if (const auto group = view->Get<HistoryView::Group>()) {
|
if (result != TextSelection() && result != FullSelection) {
|
||||||
// if (group->leader != view) {
|
return result;
|
||||||
// return TextSelection();
|
}
|
||||||
// }
|
if (const auto group = Auth().data().groups().find(item)) {
|
||||||
// auto result = TextSelection();
|
auto parts = TextSelection();
|
||||||
// auto allFullSelected = true;
|
auto allFullSelected = true;
|
||||||
// const auto count = int(group->others.size());
|
const auto count = int(group->items.size());
|
||||||
// for (auto i = 0; i != count; ++i) {
|
for (auto i = 0; i != count; ++i) {
|
||||||
// if (itemSelection(group->others[i]->data()) == FullSelection) {
|
const auto part = group->items[i];
|
||||||
// result = AddGroupItemSelection(result, i);
|
const auto selection = itemSelection(part);
|
||||||
// } else {
|
if (part == item
|
||||||
// allFullSelected = false;
|
&& selection != FullSelection
|
||||||
// }
|
&& selection != TextSelection()) {
|
||||||
// }
|
return selection;
|
||||||
// const auto leaderSelection = itemSelection(view->data());
|
} else if (selection == FullSelection) {
|
||||||
// if (leaderSelection == FullSelection) {
|
parts = AddGroupItemSelection(parts, i);
|
||||||
// return allFullSelected
|
} else {
|
||||||
// ? FullSelection
|
allFullSelected = false;
|
||||||
// : AddGroupItemSelection(result, count);
|
}
|
||||||
// } else if (leaderSelection != TextSelection()) {
|
}
|
||||||
// return leaderSelection;
|
return allFullSelected ? FullSelection : parts;
|
||||||
// }
|
}
|
||||||
// return result;
|
return itemSelection(item);
|
||||||
//}
|
|
||||||
return itemSelection(view->data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection HistoryInner::itemRenderSelection(
|
TextSelection HistoryInner::itemRenderSelection(
|
||||||
|
@ -894,7 +902,7 @@ void HistoryInner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
|
||||||
void HistoryInner::mouseActionUpdate(const QPoint &screenPos) {
|
void HistoryInner::mouseActionUpdate(const QPoint &screenPos) {
|
||||||
_mousePosition = screenPos;
|
_mousePosition = screenPos;
|
||||||
onUpdateSelected();
|
mouseActionUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::touchScrollUpdated(const QPoint &screenPos) {
|
void HistoryInner::touchScrollUpdated(const QPoint &screenPos) {
|
||||||
|
@ -958,12 +966,12 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_mouseAction == MouseAction::None && mouseActionView) {
|
if (_mouseAction == MouseAction::None && mouseActionView) {
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
|
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = mouseActionView->getState(_dragStartPosition, request);
|
dragState = mouseActionView->textState(_dragStartPosition, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
TextSelection selStatus = { dragState.symbol, dragState.symbol };
|
TextSelection selStatus = { dragState.symbol, dragState.symbol };
|
||||||
if (selStatus != FullSelection && (_selected.empty() || _selected.cbegin()->second != FullSelection)) {
|
if (selStatus != FullSelection && (_selected.empty() || _selected.cbegin()->second != FullSelection)) {
|
||||||
if (!_selected.empty()) {
|
if (!_selected.empty()) {
|
||||||
|
@ -979,14 +987,14 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (App::pressedItem()) {
|
} else if (App::pressedItem()) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = mouseActionView->getState(_dragStartPosition, request);
|
dragState = mouseActionView->textState(_dragStartPosition, request);
|
||||||
}
|
}
|
||||||
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
||||||
if (App::pressedItem()) {
|
if (App::pressedItem()) {
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
bool uponSelected = (dragState.cursor == HistoryInTextCursorState);
|
bool uponSelected = (dragState.cursor == CursorState::Text);
|
||||||
if (uponSelected) {
|
if (uponSelected) {
|
||||||
if (_selected.empty()
|
if (_selected.empty()
|
||||||
|| _selected.cbegin()->second == FullSelection
|
|| _selected.cbegin()->second == FullSelection
|
||||||
|
@ -1002,7 +1010,8 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||||
if (uponSelected) {
|
if (uponSelected) {
|
||||||
_mouseAction = MouseAction::PrepareDrag; // start text drag
|
_mouseAction = MouseAction::PrepareDrag; // start text drag
|
||||||
} else if (!_pressWasInactive) {
|
} else if (!_pressWasInactive) {
|
||||||
if (dynamic_cast<HistorySticker*>(App::pressedItem()->media()) || _mouseCursorState == HistoryInDateCursorState) {
|
if (dynamic_cast<HistorySticker*>(App::pressedItem()->media())
|
||||||
|
|| _mouseCursorState == CursorState::Date) {
|
||||||
_mouseAction = MouseAction::PrepareDrag; // start sticker drag or by-date drag
|
_mouseAction = MouseAction::PrepareDrag; // start sticker drag or by-date drag
|
||||||
} else {
|
} else {
|
||||||
if (dragState.afterSymbol) ++_mouseTextSymbol;
|
if (dragState.afterSymbol) ++_mouseTextSymbol;
|
||||||
|
@ -1055,10 +1064,10 @@ void HistoryInner::performDrag() {
|
||||||
uponSelected = _dragStateItem
|
uponSelected = _dragStateItem
|
||||||
&& (_selected.find(_dragStateItem) != _selected.cend());
|
&& (_selected.find(_dragStateItem) != _selected.cend());
|
||||||
} else {
|
} else {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = mouseActionView->getState(_dragStartPosition, request);
|
auto dragState = mouseActionView->textState(_dragStartPosition, request);
|
||||||
uponSelected = (dragState.cursor == HistoryInTextCursorState);
|
uponSelected = (dragState.cursor == CursorState::Text);
|
||||||
if (uponSelected) {
|
if (uponSelected) {
|
||||||
if (_selected.empty()
|
if (_selected.empty()
|
||||||
|| _selected.cbegin()->second == FullSelection
|
|| _selected.cbegin()->second == FullSelection
|
||||||
|
@ -1108,7 +1117,7 @@ void HistoryInner::performDrag() {
|
||||||
auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
||||||
if (auto pressedItem = App::pressedItem()) {
|
if (auto pressedItem = App::pressedItem()) {
|
||||||
pressedMedia = pressedItem->media();
|
pressedMedia = pressedItem->media();
|
||||||
if (_mouseCursorState == HistoryInDateCursorState
|
if (_mouseCursorState == CursorState::Date
|
||||||
|| (pressedMedia && pressedMedia->dragItem())) {
|
|| (pressedMedia && pressedMedia->dragItem())) {
|
||||||
Auth().data().setMimeForwardIds(
|
Auth().data().setMimeForwardIds(
|
||||||
Auth().data().itemOrItsGroup(pressedItem->data()));
|
Auth().data().itemOrItsGroup(pressedItem->data()));
|
||||||
|
@ -1173,10 +1182,12 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
_dragSelTo = nullptr;
|
_dragSelTo = nullptr;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
onUpdateSelected();
|
mouseActionUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button) {
|
void HistoryInner::mouseActionFinish(
|
||||||
|
const QPoint &screenPos,
|
||||||
|
Qt::MouseButton button) {
|
||||||
mouseActionUpdate(screenPos);
|
mouseActionUpdate(screenPos);
|
||||||
|
|
||||||
auto activated = ClickHandler::unpressed();
|
auto activated = ClickHandler::unpressed();
|
||||||
|
@ -1290,10 +1301,10 @@ void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||||
|| (_mouseAction == MouseAction::None
|
|| (_mouseAction == MouseAction::None
|
||||||
&& (_selected.empty()
|
&& (_selected.empty()
|
||||||
|| _selected.cbegin()->second != FullSelection)))) {
|
|| _selected.cbegin()->second != FullSelection)))) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = mouseActionView->getState(_dragStartPosition, request);
|
auto dragState = mouseActionView->textState(_dragStartPosition, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
_mouseSelectType = TextSelectType::Words;
|
_mouseSelectType = TextSelectType::Words;
|
||||||
if (_mouseAction == MouseAction::None) {
|
if (_mouseAction == MouseAction::None) {
|
||||||
|
@ -1342,10 +1353,12 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
hasSelected = (selTo > selFrom) ? 1 : 0;
|
hasSelected = (selTo > selFrom) ? 1 : 0;
|
||||||
if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) {
|
if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) {
|
||||||
auto mousePos = mapPointToItem(mapFromGlobal(_mousePosition), App::mousedItem());
|
auto mousePos = mapPointToItem(mapFromGlobal(_mousePosition), App::mousedItem());
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = App::mousedItem()->getState(mousePos, request);
|
auto dragState = App::mousedItem()->textState(mousePos, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState && dragState.symbol >= selFrom && dragState.symbol < selTo) {
|
if (dragState.cursor == CursorState::Text
|
||||||
|
&& dragState.symbol >= selFrom
|
||||||
|
&& dragState.symbol < selTo) {
|
||||||
isUponSelected = 1;
|
isUponSelected = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1397,7 +1410,11 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
const auto item = _dragStateItem;
|
const auto item = _dragStateItem;
|
||||||
const auto itemId = item ? item->fullId() : FullMsgId();
|
const auto itemId = item ? item->fullId() : FullMsgId();
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
_menu->addAction(lang((isUponSelected > 1) ? lng_context_copy_selected_items : lng_context_copy_selected), this, SLOT(copySelectedText()));
|
_menu->addAction(
|
||||||
|
lang((isUponSelected > 1)
|
||||||
|
? lng_context_copy_selected_items
|
||||||
|
: lng_context_copy_selected),
|
||||||
|
[=] { copySelectedText(); });
|
||||||
}
|
}
|
||||||
addItemActions(item);
|
addItemActions(item);
|
||||||
if (lnkPhoto) {
|
if (lnkPhoto) {
|
||||||
|
@ -1503,7 +1520,11 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
|
|
||||||
const auto msg = dynamic_cast<HistoryMessage*>(item);
|
const auto msg = dynamic_cast<HistoryMessage*>(item);
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
_menu->addAction(lang((isUponSelected > 1) ? lng_context_copy_selected_items : lng_context_copy_selected), this, SLOT(copySelectedText()));
|
_menu->addAction(
|
||||||
|
lang((isUponSelected > 1)
|
||||||
|
? lng_context_copy_selected_items
|
||||||
|
: lng_context_copy_selected),
|
||||||
|
[=] { copySelectedText(); });
|
||||||
addItemActions(item);
|
addItemActions(item);
|
||||||
} else {
|
} else {
|
||||||
addItemActions(item);
|
addItemActions(item);
|
||||||
|
@ -1724,7 +1745,7 @@ void HistoryInner::copyContextText(FullMsgId itemId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::resizeEvent(QResizeEvent *e) {
|
void HistoryInner::resizeEvent(QResizeEvent *e) {
|
||||||
onUpdateSelected();
|
mouseActionUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextWithEntities HistoryInner::getSelectedText() const {
|
TextWithEntities HistoryInner::getSelectedText() const {
|
||||||
|
@ -1986,7 +2007,7 @@ void HistoryInner::visibleAreaUpdated(int top, int bottom) {
|
||||||
if (scrolledUp) {
|
if (scrolledUp) {
|
||||||
_scrollDateCheck.call();
|
_scrollDateCheck.call();
|
||||||
} else {
|
} else {
|
||||||
onScrollDateHideByTimer();
|
scrollDateHideByTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1994,7 +2015,7 @@ bool HistoryInner::displayScrollDate() const {
|
||||||
return (_visibleAreaTop <= height() - 2 * (_visibleAreaBottom - _visibleAreaTop));
|
return (_visibleAreaTop <= height() - 2 * (_visibleAreaBottom - _visibleAreaTop));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::onScrollDateCheck() {
|
void HistoryInner::scrollDateCheck() {
|
||||||
if (!_history) return;
|
if (!_history) return;
|
||||||
|
|
||||||
auto newScrollDateItem = _history->scrollTopItem ? _history->scrollTopItem : (_migrated ? _migrated->scrollTopItem : nullptr);
|
auto newScrollDateItem = _history->scrollTopItem ? _history->scrollTopItem : (_migrated ? _migrated->scrollTopItem : nullptr);
|
||||||
|
@ -2015,12 +2036,12 @@ void HistoryInner::onScrollDateCheck() {
|
||||||
}
|
}
|
||||||
_scrollDateLastItem = newScrollDateItem;
|
_scrollDateLastItem = newScrollDateItem;
|
||||||
_scrollDateLastItemTop = newScrollDateItemTop;
|
_scrollDateLastItemTop = newScrollDateItemTop;
|
||||||
_scrollDateHideTimer.start(kScrollDateHideTimeout);
|
_scrollDateHideTimer.callOnce(kScrollDateHideTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::onScrollDateHideByTimer() {
|
void HistoryInner::scrollDateHideByTimer() {
|
||||||
_scrollDateHideTimer.stop();
|
_scrollDateHideTimer.cancel();
|
||||||
if (!_scrollDateLink || ClickHandler::getPressed() != _scrollDateLink) {
|
if (!_scrollDateLink || ClickHandler::getPressed() != _scrollDateLink) {
|
||||||
scrollDateHide();
|
scrollDateHide();
|
||||||
}
|
}
|
||||||
|
@ -2036,7 +2057,7 @@ void HistoryInner::keepScrollDateForNow() {
|
||||||
if (!_scrollDateShown && _scrollDateLastItem && _scrollDateOpacity.animating()) {
|
if (!_scrollDateShown && _scrollDateLastItem && _scrollDateOpacity.animating()) {
|
||||||
toggleScrollDateShown();
|
toggleScrollDateShown();
|
||||||
}
|
}
|
||||||
_scrollDateHideTimer.start(kScrollDateHideTimeout);
|
_scrollDateHideTimer.callOnce(kScrollDateHideTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::toggleScrollDateShown() {
|
void HistoryInner::toggleScrollDateShown() {
|
||||||
|
@ -2261,7 +2282,7 @@ void HistoryInner::onTouchSelect() {
|
||||||
mouseActionStart(_touchPos, Qt::LeftButton);
|
mouseActionStart(_touchPos, Qt::LeftButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::onUpdateSelected() {
|
void HistoryInner::mouseActionUpdate() {
|
||||||
if (!_history || hasPendingResizedItems()) {
|
if (!_history || hasPendingResizedItems()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2282,7 +2303,7 @@ void HistoryInner::onUpdateSelected() {
|
||||||
|
|
||||||
App::mousedItem(view);
|
App::mousedItem(view);
|
||||||
m = mapPointToItem(point, view);
|
m = mapPointToItem(point, view);
|
||||||
if (view->hasPoint(m)) {
|
if (view->pointState(m) != PointState::Outside) {
|
||||||
if (App::hoveredItem() != view) {
|
if (App::hoveredItem() != view) {
|
||||||
repaintItem(App::hoveredItem());
|
repaintItem(App::hoveredItem());
|
||||||
App::hoveredItem(view);
|
App::hoveredItem(view);
|
||||||
|
@ -2297,7 +2318,7 @@ void HistoryInner::onUpdateSelected() {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
ClickHandlerHost *lnkhost = nullptr;
|
ClickHandlerHost *lnkhost = nullptr;
|
||||||
auto selectingText = (item == _mouseActionItem)
|
auto selectingText = (item == _mouseActionItem)
|
||||||
&& (view == App::hoveredItem())
|
&& (view == App::hoveredItem())
|
||||||
|
@ -2305,7 +2326,7 @@ void HistoryInner::onUpdateSelected() {
|
||||||
&& (_selected.cbegin()->second != FullSelection);
|
&& (_selected.cbegin()->second != FullSelection);
|
||||||
if (point.y() < _historyPaddingTop) {
|
if (point.y() < _historyPaddingTop) {
|
||||||
if (_botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
|
if (_botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
|
||||||
dragState = HistoryTextState(nullptr, _botAbout->info->text.getState(
|
dragState = TextState(nullptr, _botAbout->info->text.getState(
|
||||||
point - _botAbout->rect.topLeft() - QPoint(st::msgPadding.left(), st::msgPadding.top() + st::botDescSkip + st::msgNameFont->height),
|
point - _botAbout->rect.topLeft() - QPoint(st::msgPadding.left(), st::msgPadding.top() + st::botDescSkip + st::msgNameFont->height),
|
||||||
_botAbout->width));
|
_botAbout->width));
|
||||||
_dragStateItem = App::histItemById(dragState.itemId);
|
_dragStateItem = App::histItemById(dragState.itemId);
|
||||||
|
@ -2363,7 +2384,7 @@ void HistoryInner::onUpdateSelected() {
|
||||||
} else {
|
} else {
|
||||||
static_cast<DateClickHandler*>(_scrollDateLink.get())->setDate(item->date.date());
|
static_cast<DateClickHandler*>(_scrollDateLink.get())->setDate(item->date.date());
|
||||||
}
|
}
|
||||||
dragState = HistoryTextState(
|
dragState = TextState(
|
||||||
nullptr,
|
nullptr,
|
||||||
_scrollDateLink);
|
_scrollDateLink);
|
||||||
_dragStateItem = App::histItemById(dragState.itemId);
|
_dragStateItem = App::histItemById(dragState.itemId);
|
||||||
|
@ -2375,13 +2396,13 @@ void HistoryInner::onUpdateSelected() {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
if (!dragState.link) {
|
if (!dragState.link) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
if (_mouseAction == MouseAction::Selecting) {
|
if (_mouseAction == MouseAction::Selecting) {
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
} else {
|
} else {
|
||||||
selectingText = false;
|
selectingText = false;
|
||||||
}
|
}
|
||||||
dragState = view->getState(m, request);
|
dragState = view->textState(m, request);
|
||||||
_dragStateItem = App::histItemById(dragState.itemId);
|
_dragStateItem = App::histItemById(dragState.itemId);
|
||||||
lnkhost = view;
|
lnkhost = view;
|
||||||
if (!dragState.link && m.x() >= st::historyPhotoLeft && m.x() < st::historyPhotoLeft + st::msgPhotoSize) {
|
if (!dragState.link && m.x() >= st::historyPhotoLeft && m.x() < st::historyPhotoLeft + st::msgPhotoSize) {
|
||||||
|
@ -2398,7 +2419,7 @@ void HistoryInner::onUpdateSelected() {
|
||||||
const auto message = view->data()->toHistoryMessage();
|
const auto message = view->data()->toHistoryMessage();
|
||||||
Assert(message != nullptr);
|
Assert(message != nullptr);
|
||||||
|
|
||||||
dragState = HistoryTextState(
|
dragState = TextState(
|
||||||
nullptr,
|
nullptr,
|
||||||
message->displayFrom()->openLink());
|
message->displayFrom()->openLink());
|
||||||
_dragStateItem = App::histItemById(dragState.itemId);
|
_dragStateItem = App::histItemById(dragState.itemId);
|
||||||
|
@ -2416,7 +2437,9 @@ void HistoryInner::onUpdateSelected() {
|
||||||
if (lnkChanged || dragState.cursor != _mouseCursorState) {
|
if (lnkChanged || dragState.cursor != _mouseCursorState) {
|
||||||
Ui::Tooltip::Hide();
|
Ui::Tooltip::Hide();
|
||||||
}
|
}
|
||||||
if (dragState.link || dragState.cursor == HistoryInDateCursorState || dragState.cursor == HistoryInForwardedCursorState) {
|
if (dragState.link
|
||||||
|
|| dragState.cursor == CursorState::Date
|
||||||
|
|| dragState.cursor == CursorState::Forwarded) {
|
||||||
Ui::Tooltip::Show(1000, this);
|
Ui::Tooltip::Show(1000, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2425,9 +2448,9 @@ void HistoryInner::onUpdateSelected() {
|
||||||
_mouseCursorState = dragState.cursor;
|
_mouseCursorState = dragState.cursor;
|
||||||
if (dragState.link) {
|
if (dragState.link) {
|
||||||
cur = style::cur_pointer;
|
cur = style::cur_pointer;
|
||||||
} else if (_mouseCursorState == HistoryInTextCursorState && (_selected.empty() || _selected.cbegin()->second != FullSelection)) {
|
} else if (_mouseCursorState == CursorState::Text && (_selected.empty() || _selected.cbegin()->second != FullSelection)) {
|
||||||
cur = style::cur_text;
|
cur = style::cur_text;
|
||||||
} else if (_mouseCursorState == HistoryInDateCursorState) {
|
} else if (_mouseCursorState == CursorState::Date) {
|
||||||
//cur = style::cur_cross;
|
//cur = style::cur_cross;
|
||||||
}
|
}
|
||||||
} else if (item) {
|
} else if (item) {
|
||||||
|
@ -2457,7 +2480,8 @@ void HistoryInner::onUpdateSelected() {
|
||||||
auto selectingDown = (itemTop(_mouseActionItem) < itemTop(item)) || (_mouseActionItem == item && _dragStartPosition.y() < m.y());
|
auto selectingDown = (itemTop(_mouseActionItem) < itemTop(item)) || (_mouseActionItem == item && _dragStartPosition.y() < m.y());
|
||||||
auto dragSelFrom = _mouseActionItem->mainView();
|
auto dragSelFrom = _mouseActionItem->mainView();
|
||||||
auto dragSelTo = view;
|
auto dragSelTo = view;
|
||||||
if (!dragSelFrom->hasPoint(_dragStartPosition)) { // maybe exclude dragSelFrom
|
// Maybe exclude dragSelFrom.
|
||||||
|
if (dragSelFrom->pointState(_dragStartPosition) == PointState::Outside) {
|
||||||
if (selectingDown) {
|
if (selectingDown) {
|
||||||
if (_dragStartPosition.y() >= dragSelFrom->height() - dragSelFrom->marginBottom() || ((view == dragSelFrom) && (m.y() < _dragStartPosition.y() + QApplication::startDragDistance() || m.y() < dragSelFrom->marginTop()))) {
|
if (_dragStartPosition.y() >= dragSelFrom->height() - dragSelFrom->marginBottom() || ((view == dragSelFrom) && (m.y() < _dragStartPosition.y() + QApplication::startDragDistance() || m.y() < dragSelFrom->marginTop()))) {
|
||||||
dragSelFrom = (dragSelFrom != dragSelTo)
|
dragSelFrom = (dragSelFrom != dragSelTo)
|
||||||
|
@ -2743,9 +2767,7 @@ void HistoryInner::changeSelectionAsGroup(
|
||||||
: SelectAction::Select;
|
: SelectAction::Select;
|
||||||
}
|
}
|
||||||
auto total = int(toItems->size());
|
auto total = int(toItems->size());
|
||||||
const auto add = (action == SelectAction::Select);
|
const auto canSelect = [&] {
|
||||||
|
|
||||||
const auto adding = [&] {
|
|
||||||
for (const auto other : group->items) {
|
for (const auto other : group->items) {
|
||||||
if (!goodForSelection(toItems, other, total)) {
|
if (!goodForSelection(toItems, other, total)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2753,7 +2775,7 @@ void HistoryInner::changeSelectionAsGroup(
|
||||||
}
|
}
|
||||||
return (total <= MaxSelectedItems);
|
return (total <= MaxSelectedItems);
|
||||||
}();
|
}();
|
||||||
if (adding) {
|
if (action == SelectAction::Select && canSelect) {
|
||||||
for (const auto other : group->items) {
|
for (const auto other : group->items) {
|
||||||
addToSelection(toItems, other);
|
addToSelection(toItems, other);
|
||||||
}
|
}
|
||||||
|
@ -2880,7 +2902,8 @@ void HistoryInner::applyDragSelection(
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HistoryInner::tooltipText() const {
|
QString HistoryInner::tooltipText() const {
|
||||||
if (_mouseCursorState == HistoryInDateCursorState && _mouseAction == MouseAction::None) {
|
if (_mouseCursorState == CursorState::Date
|
||||||
|
&& _mouseAction == MouseAction::None) {
|
||||||
if (const auto view = App::hoveredItem()) {
|
if (const auto view = App::hoveredItem()) {
|
||||||
auto dateText = view->data()->date.toString(
|
auto dateText = view->data()->date.toString(
|
||||||
QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
||||||
|
@ -2893,7 +2916,8 @@ QString HistoryInner::tooltipText() const {
|
||||||
}
|
}
|
||||||
return dateText;
|
return dateText;
|
||||||
}
|
}
|
||||||
} else if (_mouseCursorState == HistoryInForwardedCursorState && _mouseAction == MouseAction::None) {
|
} else if (_mouseCursorState == CursorState::Forwarded
|
||||||
|
&& _mouseAction == MouseAction::None) {
|
||||||
if (const auto view = App::hoveredItem()) {
|
if (const auto view = App::hoveredItem()) {
|
||||||
if (const auto forwarded = view->data()->Get<HistoryMessageForwarded>()) {
|
if (const auto forwarded = view->data()->Get<HistoryMessageForwarded>()) {
|
||||||
return forwarded->text.originalText(AllTextSelection, ExpandLinksNone);
|
return forwarded->text.originalText(AllTextSelection, ExpandLinksNone);
|
||||||
|
|
|
@ -7,14 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
|
||||||
#include "history/view/history_view_top_bar_widget.h"
|
#include "history/view/history_view_top_bar_widget.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
class ElementDelegate;
|
class ElementDelegate;
|
||||||
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
enum class CursorState : char;
|
||||||
|
enum class PointState : char;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -113,18 +117,11 @@ protected:
|
||||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onUpdateSelected();
|
|
||||||
void onParentGeometryChanged();
|
void onParentGeometryChanged();
|
||||||
|
|
||||||
void copySelectedText();
|
|
||||||
|
|
||||||
void onTouchSelect();
|
void onTouchSelect();
|
||||||
void onTouchScrollTimer();
|
void onTouchScrollTimer();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onScrollDateCheck();
|
|
||||||
void onScrollDateHideByTimer();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class BotAbout;
|
class BotAbout;
|
||||||
using SelectedItems = std::map<HistoryItem*, TextSelection, std::less<>>;
|
using SelectedItems = std::map<HistoryItem*, TextSelection, std::less<>>;
|
||||||
|
@ -144,6 +141,11 @@ private:
|
||||||
TopToBottom,
|
TopToBottom,
|
||||||
BottomToTop,
|
BottomToTop,
|
||||||
};
|
};
|
||||||
|
using CursorState = HistoryView::CursorState;
|
||||||
|
using PointState = HistoryView::PointState;
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
using StateRequest = HistoryView::StateRequest;
|
||||||
|
|
||||||
// This function finds all history items that are displayed and calls template method
|
// This function finds all history items that are displayed and calls template method
|
||||||
// for each found message (in given direction) in the passed history with passed top offset.
|
// for each found message (in given direction) in the passed history with passed top offset.
|
||||||
//
|
//
|
||||||
|
@ -180,8 +182,11 @@ private:
|
||||||
template <typename Method>
|
template <typename Method>
|
||||||
void enumerateDates(Method method);
|
void enumerateDates(Method method);
|
||||||
|
|
||||||
|
void scrollDateCheck();
|
||||||
|
void scrollDateHideByTimer();
|
||||||
bool canHaveFromUserpics() const;
|
bool canHaveFromUserpics() const;
|
||||||
void mouseActionStart(const QPoint &screenPos, Qt::MouseButton button);
|
void mouseActionStart(const QPoint &screenPos, Qt::MouseButton button);
|
||||||
|
void mouseActionUpdate();
|
||||||
void mouseActionUpdate(const QPoint &screenPos);
|
void mouseActionUpdate(const QPoint &screenPos);
|
||||||
void mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button);
|
void mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button);
|
||||||
void mouseActionCancel();
|
void mouseActionCancel();
|
||||||
|
@ -265,6 +270,7 @@ private:
|
||||||
void deleteItem(not_null<HistoryItem*> item);
|
void deleteItem(not_null<HistoryItem*> item);
|
||||||
void deleteItem(FullMsgId itemId);
|
void deleteItem(FullMsgId itemId);
|
||||||
void deleteAsGroup(FullMsgId itemId);
|
void deleteAsGroup(FullMsgId itemId);
|
||||||
|
void copySelectedText();
|
||||||
|
|
||||||
// Does any of the shown histories has this flag set.
|
// Does any of the shown histories has this flag set.
|
||||||
bool hasPendingResizedItems() const;
|
bool hasPendingResizedItems() const;
|
||||||
|
@ -301,7 +307,7 @@ private:
|
||||||
QPoint _mousePosition;
|
QPoint _mousePosition;
|
||||||
HistoryItem *_mouseActionItem = nullptr;
|
HistoryItem *_mouseActionItem = nullptr;
|
||||||
HistoryItem *_dragStateItem = nullptr;
|
HistoryItem *_dragStateItem = nullptr;
|
||||||
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
|
CursorState _mouseCursorState = CursorState();
|
||||||
uint16 _mouseTextSymbol = 0;
|
uint16 _mouseTextSymbol = 0;
|
||||||
bool _pressWasInactive = false;
|
bool _pressWasInactive = false;
|
||||||
|
|
||||||
|
@ -338,7 +344,7 @@ private:
|
||||||
bool _scrollDateShown = false;
|
bool _scrollDateShown = false;
|
||||||
Animation _scrollDateOpacity;
|
Animation _scrollDateOpacity;
|
||||||
SingleQueuedInvokation _scrollDateCheck;
|
SingleQueuedInvokation _scrollDateCheck;
|
||||||
SingleTimer _scrollDateHideTimer;
|
base::Timer _scrollDateHideTimer;
|
||||||
Element *_scrollDateLastItem = nullptr;
|
Element *_scrollDateLastItem = nullptr;
|
||||||
int _scrollDateLastItemTop = 0;
|
int _scrollDateLastItemTop = 0;
|
||||||
ClickHandlerPtr _scrollDateLink;
|
ClickHandlerPtr _scrollDateLink;
|
||||||
|
|
|
@ -10,7 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/runtime_composer.h"
|
#include "base/runtime_composer.h"
|
||||||
#include "base/flags.h"
|
#include "base/flags.h"
|
||||||
#include "base/value_ordering.h"
|
#include "base/value_ordering.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
|
||||||
|
|
||||||
enum class UnreadMentionType;
|
enum class UnreadMentionType;
|
||||||
struct HistoryMessageReplyMarkup;
|
struct HistoryMessageReplyMarkup;
|
||||||
|
@ -47,6 +46,10 @@ class Controller;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
enum class CursorState : char;
|
||||||
|
enum class PointState : char;
|
||||||
enum class Context : char;
|
enum class Context : char;
|
||||||
class ElementDelegate;
|
class ElementDelegate;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -521,7 +521,7 @@ void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip, TimeMs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickHandlerPtr ReplyKeyboard::getState(QPoint point) const {
|
ClickHandlerPtr ReplyKeyboard::getLink(QPoint point) const {
|
||||||
Assert(_width > 0);
|
Assert(_width > 0);
|
||||||
|
|
||||||
for_const (auto &row, _rows) {
|
for_const (auto &row, _rows) {
|
||||||
|
|
|
@ -274,7 +274,7 @@ public:
|
||||||
int naturalHeight() const;
|
int naturalHeight() const;
|
||||||
|
|
||||||
void paint(Painter &p, int outerWidth, const QRect &clip, TimeMs ms) const;
|
void paint(Painter &p, int outerWidth, const QRect &clip, TimeMs ms) const;
|
||||||
ClickHandlerPtr getState(QPoint point) const;
|
ClickHandlerPtr getLink(QPoint point) const;
|
||||||
|
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed);
|
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed);
|
||||||
|
|
|
@ -9,9 +9,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using PointState = HistoryView::PointState;
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Storage::SharedMediaTypesMask HistoryMedia::sharedMediaTypes() const {
|
Storage::SharedMediaTypesMask HistoryMedia::sharedMediaTypes() const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -54,9 +62,15 @@ TextSelection HistoryMedia::unskipSelection(TextSelection selection) const {
|
||||||
fullSelectionLength());
|
fullSelectionLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryMedia::getStateGrouped(
|
PointState HistoryMedia::pointState(QPoint point) const {
|
||||||
|
return QRect(0, 0, width(), height()).contains(point)
|
||||||
|
? PointState::Inside
|
||||||
|
: PointState::Outside;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextState HistoryMedia::getStateGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
Unexpected("Grouping method call.");
|
Unexpected("Grouping method call.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_object.h"
|
#include "history/view/history_view_object.h"
|
||||||
|
|
||||||
struct HistoryMessageEdited;
|
struct HistoryMessageEdited;
|
||||||
struct HistoryTextState;
|
|
||||||
struct HistoryStateRequest;
|
|
||||||
struct TextSelection;
|
struct TextSelection;
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
@ -24,6 +22,14 @@ enum class SharedMediaType : char;
|
||||||
using SharedMediaTypesMask = base::enum_mask<SharedMediaType>;
|
using SharedMediaTypesMask = base::enum_mask<SharedMediaType>;
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
enum class PointState : char;
|
||||||
|
enum class CursorState : char;
|
||||||
|
enum class InfoDisplayType : char;
|
||||||
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
||||||
enum class MediaInBubbleState {
|
enum class MediaInBubbleState {
|
||||||
None,
|
None,
|
||||||
Top,
|
Top,
|
||||||
|
@ -53,6 +59,9 @@ enum HistoryMediaType : char {
|
||||||
class HistoryMedia : public HistoryView::Object {
|
class HistoryMedia : public HistoryView::Object {
|
||||||
public:
|
public:
|
||||||
using Element = HistoryView::Element;
|
using Element = HistoryView::Element;
|
||||||
|
using PointState = HistoryView::PointState;
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
using StateRequest = HistoryView::StateRequest;
|
||||||
|
|
||||||
HistoryMedia(not_null<Element*> parent) : _parent(parent) {
|
HistoryMedia(not_null<Element*> parent) : _parent(parent) {
|
||||||
}
|
}
|
||||||
|
@ -63,16 +72,9 @@ public:
|
||||||
return TextWithEntities();
|
return TextWithEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasPoint(QPoint point) const {
|
|
||||||
return QRect(0, 0, width(), height()).contains(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isDisplayed() const;
|
virtual bool isDisplayed() const;
|
||||||
virtual void updateNeedBubbleState() {
|
virtual void updateNeedBubbleState() {
|
||||||
}
|
}
|
||||||
virtual bool isAboveMessage() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
virtual bool hasTextForCopy() const {
|
virtual bool hasTextForCopy() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +87,8 @@ public:
|
||||||
virtual void refreshParentId(not_null<HistoryItem*> realParent) {
|
virtual void refreshParentId(not_null<HistoryItem*> realParent) {
|
||||||
}
|
}
|
||||||
virtual void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const = 0;
|
virtual void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const = 0;
|
||||||
virtual HistoryTextState getState(QPoint point, HistoryStateRequest request) const = 0;
|
virtual PointState pointState(QPoint point) const;
|
||||||
|
virtual TextState textState(QPoint point, StateRequest request) const = 0;
|
||||||
virtual void updatePressed(QPoint point) {
|
virtual void updatePressed(QPoint point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,10 +159,10 @@ public:
|
||||||
not_null<QPixmap*> cache) const {
|
not_null<QPixmap*> cache) const {
|
||||||
Unexpected("Grouping method call.");
|
Unexpected("Grouping method call.");
|
||||||
}
|
}
|
||||||
virtual HistoryTextState getStateGrouped(
|
virtual TextState getStateGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const;
|
StateRequest request) const;
|
||||||
virtual std::unique_ptr<HistoryMedia> takeLastFromGroup() {
|
virtual std::unique_ptr<HistoryMedia> takeLastFromGroup() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -236,6 +239,9 @@ public:
|
||||||
virtual ~HistoryMedia() = default;
|
virtual ~HistoryMedia() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
using CursorState = HistoryView::CursorState;
|
||||||
|
using InfoDisplayType = HistoryView::InfoDisplayType;
|
||||||
|
|
||||||
QSize countCurrentSize(int newWidth) override;
|
QSize countCurrentSize(int newWidth) override;
|
||||||
Text createCaption(not_null<HistoryItem*> item) const;
|
Text createCaption(not_null<HistoryItem*> item) const;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_media_types.h"
|
#include "history/history_media_types.h"
|
||||||
#include "history/history_message.h"
|
#include "history/history_message.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -19,6 +20,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_history.h"
|
#include "styles/style_history.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
using PointState = HistoryView::PointState;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
HistoryGroupedMedia::Part::Part(not_null<HistoryItem*> item)
|
HistoryGroupedMedia::Part::Part(not_null<HistoryItem*> item)
|
||||||
: item(item) {
|
: item(item) {
|
||||||
}
|
}
|
||||||
|
@ -176,7 +182,7 @@ void HistoryGroupedMedia::draw(
|
||||||
auto fullRight = width();
|
auto fullRight = width();
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
if (needInfoDisplay()) {
|
if (needInfoDisplay()) {
|
||||||
_parent->drawInfo(p, fullRight, fullBottom, width(), selected, InfoDisplayOverImage);
|
_parent->drawInfo(p, fullRight, fullBottom, width(), selected, InfoDisplayType::Image);
|
||||||
}
|
}
|
||||||
if (!_parent->hasBubble() && _parent->displayRightAction()) {
|
if (!_parent->hasBubble() && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
@ -186,9 +192,9 @@ void HistoryGroupedMedia::draw(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryGroupedMedia::getPartState(
|
TextState HistoryGroupedMedia::getPartState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
for (const auto &part : _parts) {
|
for (const auto &part : _parts) {
|
||||||
if (part.geometry.contains(point)) {
|
if (part.geometry.contains(point)) {
|
||||||
auto result = part.content->getStateGrouped(
|
auto result = part.content->getStateGrouped(
|
||||||
|
@ -199,12 +205,24 @@ HistoryTextState HistoryGroupedMedia::getPartState(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HistoryTextState(_parent->data());
|
return TextState(_parent->data());
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryGroupedMedia::getState(
|
PointState HistoryGroupedMedia::pointState(QPoint point) const {
|
||||||
|
if (!QRect(0, 0, width(), height()).contains(point)) {
|
||||||
|
return PointState::Outside;
|
||||||
|
}
|
||||||
|
for (const auto &part : _parts) {
|
||||||
|
if (part.geometry.contains(point)) {
|
||||||
|
return PointState::GroupPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PointState::Inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryView::TextState HistoryGroupedMedia::textState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
auto result = getPartState(point, request);
|
auto result = getPartState(point, request);
|
||||||
if (!result.link && !_caption.isEmpty()) {
|
if (!result.link && !_caption.isEmpty()) {
|
||||||
const auto captionw = width() - st::msgPadding.left() - st::msgPadding.right();
|
const auto captionw = width() - st::msgPadding.left() - st::msgPadding.right();
|
||||||
|
@ -212,7 +230,7 @@ HistoryTextState HistoryGroupedMedia::getState(
|
||||||
- (isBubbleBottom() ? st::msgPadding.bottom() : 0)
|
- (isBubbleBottom() ? st::msgPadding.bottom() : 0)
|
||||||
- _caption.countHeight(captionw);
|
- _caption.countHeight(captionw);
|
||||||
if (QRect(st::msgPadding.left(), captiony, captionw, height() - captiony).contains(point)) {
|
if (QRect(st::msgPadding.left(), captiony, captionw, height() - captiony).contains(point)) {
|
||||||
return HistoryTextState(_parent->data(), _caption.getState(
|
return TextState(_parent->data(), _caption.getState(
|
||||||
point - QPoint(st::msgPadding.left(), captiony),
|
point - QPoint(st::msgPadding.left(), captiony),
|
||||||
captionw,
|
captionw,
|
||||||
request.forText()));
|
request.forText()));
|
||||||
|
@ -220,8 +238,8 @@ HistoryTextState HistoryGroupedMedia::getState(
|
||||||
} else if (_parent->media() == this) {
|
} else if (_parent->media() == this) {
|
||||||
auto fullRight = width();
|
auto fullRight = width();
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayType::Image)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
if (!_parent->hasBubble() && _parent->displayRightAction()) {
|
if (!_parent->hasBubble() && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
|
|
@ -28,9 +28,10 @@ public:
|
||||||
const QRect &clip,
|
const QRect &clip,
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TimeMs ms) const override;
|
TimeMs ms) const override;
|
||||||
HistoryTextState getState(
|
PointState pointState(QPoint point) const override;
|
||||||
|
TextState textState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(
|
bool toggleSelectionByHandlerClick(
|
||||||
const ClickHandlerPtr &p) const override;
|
const ClickHandlerPtr &p) const override;
|
||||||
|
@ -107,9 +108,9 @@ private:
|
||||||
not_null<HistoryMedia*> main() const;
|
not_null<HistoryMedia*> main() const;
|
||||||
bool validateGroupParts(
|
bool validateGroupParts(
|
||||||
const std::vector<not_null<HistoryItem*>> &items) const;
|
const std::vector<not_null<HistoryItem*>> &items) const;
|
||||||
HistoryTextState getPartState(
|
TextState getPartState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const;
|
StateRequest request) const;
|
||||||
|
|
||||||
Text _caption;
|
Text _caption;
|
||||||
std::vector<Part> _parts;
|
std::vector<Part> _parts;
|
||||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
#include "history/history_message.h"
|
#include "history/history_message.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "styles/style_history.h"
|
#include "styles/style_history.h"
|
||||||
|
@ -41,6 +42,8 @@ namespace {
|
||||||
constexpr auto kMaxGifForwardedBarLines = 4;
|
constexpr auto kMaxGifForwardedBarLines = 4;
|
||||||
constexpr auto kMaxOriginalEntryLines = 8192;
|
constexpr auto kMaxOriginalEntryLines = 8192;
|
||||||
|
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
|
||||||
int documentMaxStatusWidth(DocumentData *document) {
|
int documentMaxStatusWidth(DocumentData *document) {
|
||||||
auto result = st::normalFont->width(formatDownloadText(document->size, document->size));
|
auto result = st::normalFont->width(formatDownloadText(document->size, document->size));
|
||||||
if (const auto song = document->song()) {
|
if (const auto song = document->song()) {
|
||||||
|
@ -419,7 +422,7 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
||||||
auto fullRight = paintx + paintw;
|
auto fullRight = paintx + paintw;
|
||||||
auto fullBottom = painty + painth;
|
auto fullBottom = painty + painth;
|
||||||
if (needInfoDisplay()) {
|
if (needInfoDisplay()) {
|
||||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, InfoDisplayOverImage);
|
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, InfoDisplayType::Image);
|
||||||
}
|
}
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
@ -429,8 +432,8 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryPhoto::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryPhoto::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -447,7 +450,7 @@ HistoryTextState HistoryPhoto::getState(QPoint point, HistoryStateRequest reques
|
||||||
painth -= st::msgPadding.bottom();
|
painth -= st::msgPadding.bottom();
|
||||||
}
|
}
|
||||||
if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) {
|
if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) {
|
||||||
result = HistoryTextState(_parent, _caption.getState(
|
result = TextState(_parent, _caption.getState(
|
||||||
point - QPoint(st::msgPadding.left(), painth),
|
point - QPoint(st::msgPadding.left(), painth),
|
||||||
captionw,
|
captionw,
|
||||||
request.forText()));
|
request.forText()));
|
||||||
|
@ -472,8 +475,8 @@ HistoryTextState HistoryPhoto::getState(QPoint point, HistoryStateRequest reques
|
||||||
if (_caption.isEmpty() && _parent->media() == this) {
|
if (_caption.isEmpty() && _parent->media() == this) {
|
||||||
auto fullRight = paintx + paintw;
|
auto fullRight = paintx + paintw;
|
||||||
auto fullBottom = painty + painth;
|
auto fullBottom = painty + painth;
|
||||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayType::Image)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
@ -586,15 +589,15 @@ void HistoryPhoto::drawGrouped(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryPhoto::getStateGrouped(
|
TextState HistoryPhoto::getStateGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (!geometry.contains(point)) {
|
if (!geometry.contains(point)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto delayed = _data->full->toDelayedStorageImage();
|
const auto delayed = _data->full->toDelayedStorageImage();
|
||||||
return HistoryTextState(_parent, _data->uploading()
|
return TextState(_parent, _data->uploading()
|
||||||
? _cancell
|
? _cancell
|
||||||
: _data->loaded()
|
: _data->loaded()
|
||||||
? _openl
|
? _openl
|
||||||
|
@ -870,7 +873,7 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
||||||
_caption.draw(p, st::msgPadding.left(), painty + painth + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, selection);
|
_caption.draw(p, st::msgPadding.left(), painty + painth + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, selection);
|
||||||
} else if (_parent->media() == this) {
|
} else if (_parent->media() == this) {
|
||||||
auto fullRight = paintx + paintw, fullBottom = painty + painth;
|
auto fullRight = paintx + paintw, fullBottom = painty + painth;
|
||||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, InfoDisplayOverImage);
|
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, InfoDisplayType::Image);
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||||
|
@ -879,12 +882,12 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryVideo::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryVideo::textState(QPoint point, StateRequest request) const {
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
bool loaded = _data->loaded();
|
bool loaded = _data->loaded();
|
||||||
|
|
||||||
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
||||||
|
@ -899,7 +902,7 @@ HistoryTextState HistoryVideo::getState(QPoint point, HistoryStateRequest reques
|
||||||
painth -= st::msgPadding.bottom();
|
painth -= st::msgPadding.bottom();
|
||||||
}
|
}
|
||||||
if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) {
|
if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) {
|
||||||
result = HistoryTextState(_parent, _caption.getState(
|
result = TextState(_parent, _caption.getState(
|
||||||
point - QPoint(st::msgPadding.left(), painth),
|
point - QPoint(st::msgPadding.left(), painth),
|
||||||
captionw,
|
captionw,
|
||||||
request.forText()));
|
request.forText()));
|
||||||
|
@ -916,8 +919,8 @@ HistoryTextState HistoryVideo::getState(QPoint point, HistoryStateRequest reques
|
||||||
if (_caption.isEmpty() && _parent->media() == this) {
|
if (_caption.isEmpty() && _parent->media() == this) {
|
||||||
auto fullRight = paintx + paintw;
|
auto fullRight = paintx + paintw;
|
||||||
auto fullBottom = painty + painth;
|
auto fullBottom = painty + painth;
|
||||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayType::Image)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
@ -1026,14 +1029,14 @@ void HistoryVideo::drawGrouped(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryVideo::getStateGrouped(
|
TextState HistoryVideo::getStateGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (!geometry.contains(point)) {
|
if (!geometry.contains(point)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return HistoryTextState(_parent, _data->uploading()
|
return TextState(_parent, _data->uploading()
|
||||||
? _cancell
|
? _cancell
|
||||||
: _data->loaded()
|
: _data->loaded()
|
||||||
? _openl
|
? _openl
|
||||||
|
@ -1564,8 +1567,8 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryDocument::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -1631,7 +1634,7 @@ HistoryTextState HistoryDocument::getState(QPoint point, HistoryStateRequest req
|
||||||
auto painth = height();
|
auto painth = height();
|
||||||
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
if (point.y() >= bottom) {
|
if (point.y() >= bottom) {
|
||||||
result = HistoryTextState(_parent, captioned->_caption.getState(
|
result = TextState(_parent, captioned->_caption.getState(
|
||||||
point - QPoint(st::msgPadding.left(), bottom),
|
point - QPoint(st::msgPadding.left(), bottom),
|
||||||
width() - st::msgPadding.left() - st::msgPadding.right(),
|
width() - st::msgPadding.left() - st::msgPadding.right(),
|
||||||
request.forText()));
|
request.forText()));
|
||||||
|
@ -2306,7 +2309,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isRound || needInfoDisplay()) {
|
if (isRound || needInfoDisplay()) {
|
||||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, isRound ? InfoDisplayOverBackground : InfoDisplayOverImage);
|
_parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, isRound ? InfoDisplayType::Background : InfoDisplayType::Image);
|
||||||
}
|
}
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
@ -2320,8 +2323,8 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryGif::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryGif::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -2336,7 +2339,7 @@ HistoryTextState HistoryGif::getState(QPoint point, HistoryStateRequest request)
|
||||||
painth -= st::msgPadding.bottom();
|
painth -= st::msgPadding.bottom();
|
||||||
}
|
}
|
||||||
if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) {
|
if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) {
|
||||||
result = HistoryTextState(_parent, _caption.getState(
|
result = TextState(_parent, _caption.getState(
|
||||||
point - QPoint(st::msgPadding.left(), painth),
|
point - QPoint(st::msgPadding.left(), painth),
|
||||||
captionw,
|
captionw,
|
||||||
request.forText()));
|
request.forText()));
|
||||||
|
@ -2386,16 +2389,16 @@ HistoryTextState HistoryGif::getState(QPoint point, HistoryStateRequest request)
|
||||||
if (breakEverywhere) {
|
if (breakEverywhere) {
|
||||||
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere;
|
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere;
|
||||||
}
|
}
|
||||||
result = HistoryTextState(_parent, forwarded->text.getState(
|
result = TextState(_parent, forwarded->text.getState(
|
||||||
point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()),
|
point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()),
|
||||||
innerw,
|
innerw,
|
||||||
textRequest));
|
textRequest));
|
||||||
result.symbol = 0;
|
result.symbol = 0;
|
||||||
result.afterSymbol = false;
|
result.afterSymbol = false;
|
||||||
if (breakEverywhere) {
|
if (breakEverywhere) {
|
||||||
result.cursor = HistoryInForwardedCursorState;
|
result.cursor = CursorState::Forwarded;
|
||||||
} else {
|
} else {
|
||||||
result.cursor = HistoryDefaultCursorState;
|
result.cursor = CursorState::None;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2447,8 +2450,8 @@ HistoryTextState HistoryGif::getState(QPoint point, HistoryStateRequest request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!inWebPage) {
|
if (!inWebPage) {
|
||||||
if (_parent->pointInTime(fullRight, fullBottom, point, isRound ? InfoDisplayOverBackground : InfoDisplayOverImage)) {
|
if (_parent->pointInTime(fullRight, fullBottom, point, isRound ? InfoDisplayType::Background : InfoDisplayType::Image)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
|
@ -2810,7 +2813,7 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
if (!inWebPage) {
|
if (!inWebPage) {
|
||||||
auto fullRight = usex + usew;
|
auto fullRight = usex + usew;
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
_parent->drawInfo(p, fullRight, fullBottom, usex * 2 + usew, selected, InfoDisplayOverBackground);
|
_parent->drawInfo(p, fullRight, fullBottom, usex * 2 + usew, selected, InfoDisplayType::Background);
|
||||||
if (via || reply) {
|
if (via || reply) {
|
||||||
int rectw = width() - usew - st::msgReplyPadding.left();
|
int rectw = width() - usew - st::msgReplyPadding.left();
|
||||||
int recth = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
int recth = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
||||||
|
@ -2850,8 +2853,8 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistorySticker::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistorySticker::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2904,8 +2907,8 @@ HistoryTextState HistorySticker::getState(QPoint point, HistoryStateRequest requ
|
||||||
if (_parent->media() == this) {
|
if (_parent->media() == this) {
|
||||||
auto fullRight = usex + usew;
|
auto fullRight = usex + usew;
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayType::Image)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
if (_parent->displayRightAction()) {
|
if (_parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
@ -3112,8 +3115,8 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
p.drawTextLeft(nameleft, statustop, paintw, _phone);
|
p.drawTextLeft(nameleft, statustop, paintw, _phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryContact::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryContact::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
||||||
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
|
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
|
||||||
|
@ -3210,8 +3213,8 @@ void HistoryCall::draw(Painter &p, const QRect &r, TextSelection selection, Time
|
||||||
icon.paint(p, paintw - st::historyCallIconPosition.x() - icon.width(), st::historyCallIconPosition.y() - topMinus, paintw);
|
icon.paint(p, paintw - st::historyCallIconPosition.x() - icon.width(), st::historyCallIconPosition.y() - topMinus, paintw);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryCall::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryCall::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
if (QRect(0, 0, width(), height()).contains(point)) {
|
if (QRect(0, 0, width(), height()).contains(point)) {
|
||||||
result.link = _link;
|
result.link = _link;
|
||||||
return result;
|
return result;
|
||||||
|
@ -3626,8 +3629,8 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryWebPage::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryWebPage::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -3660,7 +3663,7 @@ HistoryTextState HistoryWebPage::getState(QPoint point, HistoryStateRequest requ
|
||||||
if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) {
|
if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) {
|
||||||
Text::StateRequestElided titleRequest = request.forText();
|
Text::StateRequestElided titleRequest = request.forText();
|
||||||
titleRequest.lines = _titleLines;
|
titleRequest.lines = _titleLines;
|
||||||
result = HistoryTextState(_parent, _title.getStateElidedLeft(
|
result = TextState(_parent, _title.getStateElidedLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -3676,13 +3679,13 @@ HistoryTextState HistoryWebPage::getState(QPoint point, HistoryStateRequest requ
|
||||||
if (_descriptionLines > 0) {
|
if (_descriptionLines > 0) {
|
||||||
Text::StateRequestElided descriptionRequest = request.forText();
|
Text::StateRequestElided descriptionRequest = request.forText();
|
||||||
descriptionRequest.lines = _descriptionLines;
|
descriptionRequest.lines = _descriptionLines;
|
||||||
result = HistoryTextState(_parent, _description.getStateElidedLeft(
|
result = TextState(_parent, _description.getStateElidedLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
descriptionRequest));
|
descriptionRequest));
|
||||||
} else {
|
} else {
|
||||||
result = HistoryTextState(_parent, _description.getStateLeft(
|
result = TextState(_parent, _description.getStateLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -3703,7 +3706,7 @@ HistoryTextState HistoryWebPage::getState(QPoint point, HistoryStateRequest requ
|
||||||
auto attachLeft = padding.left() - bubble.left();
|
auto attachLeft = padding.left() - bubble.left();
|
||||||
auto attachTop = tshift - bubble.top();
|
auto attachTop = tshift - bubble.top();
|
||||||
if (rtl()) attachLeft = width() - attachLeft - _attach->width();
|
if (rtl()) attachLeft = width() - attachLeft - _attach->width();
|
||||||
result = _attach->getState(point - QPoint(attachLeft, attachTop), request);
|
result = _attach->textState(point - QPoint(attachLeft, attachTop), request);
|
||||||
|
|
||||||
if (result.link && !_data->document && _data->photo && _attach->isReadyForOpen()) {
|
if (result.link && !_data->document && _data->photo && _attach->isReadyForOpen()) {
|
||||||
if (_data->type == WebPageProfile || _data->type == WebPageVideo) {
|
if (_data->type == WebPageProfile || _data->type == WebPageVideo) {
|
||||||
|
@ -4059,8 +4062,8 @@ void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, Time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryGame::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryGame::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -4083,7 +4086,7 @@ HistoryTextState HistoryGame::getState(QPoint point, HistoryStateRequest request
|
||||||
if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) {
|
if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) {
|
||||||
Text::StateRequestElided titleRequest = request.forText();
|
Text::StateRequestElided titleRequest = request.forText();
|
||||||
titleRequest.lines = _titleLines;
|
titleRequest.lines = _titleLines;
|
||||||
result = HistoryTextState(_parent, _title.getStateElidedLeft(
|
result = TextState(_parent, _title.getStateElidedLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -4097,7 +4100,7 @@ HistoryTextState HistoryGame::getState(QPoint point, HistoryStateRequest request
|
||||||
if (point.y() >= tshift && point.y() < tshift + _descriptionLines * lineHeight) {
|
if (point.y() >= tshift && point.y() < tshift + _descriptionLines * lineHeight) {
|
||||||
Text::StateRequestElided descriptionRequest = request.forText();
|
Text::StateRequestElided descriptionRequest = request.forText();
|
||||||
descriptionRequest.lines = _descriptionLines;
|
descriptionRequest.lines = _descriptionLines;
|
||||||
result = HistoryTextState(_parent, _description.getStateElidedLeft(
|
result = TextState(_parent, _description.getStateElidedLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -4125,7 +4128,7 @@ HistoryTextState HistoryGame::getState(QPoint point, HistoryStateRequest request
|
||||||
result.link = _openl;
|
result.link = _openl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = _attach->getState(point - QPoint(attachLeft, attachTop), request);
|
result = _attach->textState(point - QPoint(attachLeft, attachTop), request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4473,8 +4476,8 @@ void HistoryInvoice::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryInvoice::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryInvoice::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -4496,7 +4499,7 @@ HistoryTextState HistoryInvoice::getState(QPoint point, HistoryStateRequest requ
|
||||||
if (point.y() >= tshift && point.y() < tshift + _titleHeight) {
|
if (point.y() >= tshift && point.y() < tshift + _titleHeight) {
|
||||||
Text::StateRequestElided titleRequest = request.forText();
|
Text::StateRequestElided titleRequest = request.forText();
|
||||||
titleRequest.lines = _titleHeight / lineHeight;
|
titleRequest.lines = _titleHeight / lineHeight;
|
||||||
result = HistoryTextState(_parent, _title.getStateElidedLeft(
|
result = TextState(_parent, _title.getStateElidedLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -4508,7 +4511,7 @@ HistoryTextState HistoryInvoice::getState(QPoint point, HistoryStateRequest requ
|
||||||
}
|
}
|
||||||
if (_descriptionHeight) {
|
if (_descriptionHeight) {
|
||||||
if (point.y() >= tshift && point.y() < tshift + _descriptionHeight) {
|
if (point.y() >= tshift && point.y() < tshift + _descriptionHeight) {
|
||||||
result = HistoryTextState(_parent, _description.getStateLeft(
|
result = TextState(_parent, _description.getStateLeft(
|
||||||
point - QPoint(padding.left(), tshift),
|
point - QPoint(padding.left(), tshift),
|
||||||
paintw,
|
paintw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -4527,7 +4530,7 @@ HistoryTextState HistoryInvoice::getState(QPoint point, HistoryStateRequest requ
|
||||||
if (rtl()) attachLeft = width() - attachLeft - _attach->width();
|
if (rtl()) attachLeft = width() - attachLeft - _attach->width();
|
||||||
|
|
||||||
if (QRect(attachLeft, tshift, _attach->width(), height() - tshift - bshift).contains(point)) {
|
if (QRect(attachLeft, tshift, _attach->width(), height() - tshift - bshift).contains(point)) {
|
||||||
result = _attach->getState(point - QPoint(attachLeft, attachTop), request);
|
result = _attach->textState(point - QPoint(attachLeft, attachTop), request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4753,7 +4756,7 @@ void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection,
|
||||||
if (_parent->media() == this) {
|
if (_parent->media() == this) {
|
||||||
auto fullRight = paintx + paintw;
|
auto fullRight = paintx + paintw;
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
_parent->drawInfo(p, fullRight, fullBottom, paintx * 2 + paintw, selected, InfoDisplayOverImage);
|
_parent->drawInfo(p, fullRight, fullBottom, paintx * 2 + paintw, selected, InfoDisplayType::Image);
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||||
|
@ -4762,8 +4765,8 @@ void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState HistoryLocation::getState(QPoint point, HistoryStateRequest request) const {
|
TextState HistoryLocation::textState(QPoint point, StateRequest request) const {
|
||||||
auto result = HistoryTextState(_parent);
|
auto result = TextState(_parent);
|
||||||
auto symbolAdd = 0;
|
auto symbolAdd = 0;
|
||||||
|
|
||||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
|
@ -4784,7 +4787,7 @@ HistoryTextState HistoryLocation::getState(QPoint point, HistoryStateRequest req
|
||||||
if (!_title.isEmpty()) {
|
if (!_title.isEmpty()) {
|
||||||
auto titleh = qMin(_title.countHeight(textw), 2 * st::webPageTitleFont->height);
|
auto titleh = qMin(_title.countHeight(textw), 2 * st::webPageTitleFont->height);
|
||||||
if (point.y() >= painty && point.y() < painty + titleh) {
|
if (point.y() >= painty && point.y() < painty + titleh) {
|
||||||
result = HistoryTextState(_parent, _title.getStateLeft(
|
result = TextState(_parent, _title.getStateLeft(
|
||||||
point - QPoint(paintx + st::msgPadding.left(), painty),
|
point - QPoint(paintx + st::msgPadding.left(), painty),
|
||||||
textw,
|
textw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -4798,7 +4801,7 @@ HistoryTextState HistoryLocation::getState(QPoint point, HistoryStateRequest req
|
||||||
if (!_description.isEmpty()) {
|
if (!_description.isEmpty()) {
|
||||||
auto descriptionh = qMin(_description.countHeight(textw), 3 * st::webPageDescriptionFont->height);
|
auto descriptionh = qMin(_description.countHeight(textw), 3 * st::webPageDescriptionFont->height);
|
||||||
if (point.y() >= painty && point.y() < painty + descriptionh) {
|
if (point.y() >= painty && point.y() < painty + descriptionh) {
|
||||||
result = HistoryTextState(_parent, _description.getStateLeft(
|
result = TextState(_parent, _description.getStateLeft(
|
||||||
point - QPoint(paintx + st::msgPadding.left(), painty),
|
point - QPoint(paintx + st::msgPadding.left(), painty),
|
||||||
textw,
|
textw,
|
||||||
width(),
|
width(),
|
||||||
|
@ -4819,8 +4822,8 @@ HistoryTextState HistoryLocation::getState(QPoint point, HistoryStateRequest req
|
||||||
if (_parent->media() == this) {
|
if (_parent->media() == this) {
|
||||||
auto fullRight = paintx + paintw;
|
auto fullRight = paintx + paintw;
|
||||||
auto fullBottom = height();
|
auto fullBottom = height();
|
||||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayType::Image)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
if (!bubble && _parent->displayRightAction()) {
|
if (!bubble && _parent->displayRightAction()) {
|
||||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||||
|
|
|
@ -141,7 +141,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &clip, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &clip, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
|
@ -171,10 +171,10 @@ public:
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const override;
|
not_null<QPixmap*> cache) const override;
|
||||||
HistoryTextState getStateGrouped(
|
TextState getStateGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
bool hasReplyPreview() const override {
|
bool hasReplyPreview() const override {
|
||||||
return !_data->thumb->isNull();
|
return !_data->thumb->isNull();
|
||||||
|
@ -233,7 +233,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
|
@ -263,10 +263,10 @@ public:
|
||||||
RectParts corners,
|
RectParts corners,
|
||||||
not_null<uint64*> cacheKey,
|
not_null<uint64*> cacheKey,
|
||||||
not_null<QPixmap*> cache) const override;
|
not_null<QPixmap*> cache) const override;
|
||||||
HistoryTextState getStateGrouped(
|
TextState getStateGrouped(
|
||||||
const QRect &geometry,
|
const QRect &geometry,
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
bool uploading() const override {
|
bool uploading() const override {
|
||||||
return _data->uploading();
|
return _data->uploading();
|
||||||
|
@ -328,7 +328,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
void updatePressed(QPoint point) override;
|
void updatePressed(QPoint point) override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
@ -400,7 +400,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
|
@ -501,7 +501,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
||||||
return true;
|
return true;
|
||||||
|
@ -562,7 +562,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
||||||
return true;
|
return true;
|
||||||
|
@ -619,7 +619,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
|
||||||
return true;
|
return true;
|
||||||
|
@ -665,7 +665,7 @@ public:
|
||||||
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
bool hideMessageText() const override {
|
bool hideMessageText() const override {
|
||||||
return false;
|
return false;
|
||||||
|
@ -772,7 +772,7 @@ public:
|
||||||
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
void refreshParentId(not_null<HistoryItem*> realParent) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
|
@ -780,9 +780,6 @@ public:
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override {
|
||||||
return _title.length() + _description.length();
|
return _title.length() + _description.length();
|
||||||
}
|
}
|
||||||
bool isAboveMessage() const override {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool hasTextForCopy() const override {
|
bool hasTextForCopy() const override {
|
||||||
return false; // we do not add _title and _description in FullSelection text copy.
|
return false; // we do not add _title and _description in FullSelection text copy.
|
||||||
}
|
}
|
||||||
|
@ -881,7 +878,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
|
@ -962,7 +959,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
|
||||||
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
|
|
|
@ -666,14 +666,6 @@ HistoryWidget::HistoryWidget(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Auth().data().viewLayoutChanged(
|
|
||||||
) | rpl::start_with_next([this](auto view) {
|
|
||||||
if (view == view->data()->mainView()) {
|
|
||||||
if (view->isUnderCursor() && _list) {
|
|
||||||
_list->onUpdateSelected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, lifetime());
|
|
||||||
_topBar->membersShowAreaActive(
|
_topBar->membersShowAreaActive(
|
||||||
) | rpl::start_with_next([=](bool active) {
|
) | rpl::start_with_next([=](bool active) {
|
||||||
setMembersShowAreaActive(active);
|
setMembersShowAreaActive(active);
|
||||||
|
|
|
@ -10,43 +10,61 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
|
||||||
HistoryTextState::HistoryTextState(not_null<const HistoryItem*> item)
|
namespace HistoryView {
|
||||||
|
|
||||||
|
TextState::TextState(not_null<const HistoryItem*> item)
|
||||||
: itemId(item->fullId()) {
|
: itemId(item->fullId()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState::HistoryTextState(
|
TextState::TextState(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
const Text::StateResult &state)
|
const Text::StateResult &state)
|
||||||
: itemId(item->fullId())
|
: itemId(item->fullId())
|
||||||
, cursor(state.uponSymbol
|
, cursor(state.uponSymbol
|
||||||
? HistoryInTextCursorState
|
? CursorState::Text
|
||||||
: HistoryDefaultCursorState)
|
: CursorState::None)
|
||||||
, link(state.link)
|
, link(state.link)
|
||||||
, afterSymbol(state.afterSymbol)
|
, afterSymbol(state.afterSymbol)
|
||||||
, symbol(state.symbol) {
|
, symbol(state.symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState::HistoryTextState(
|
TextState::TextState(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
ClickHandlerPtr link)
|
ClickHandlerPtr link)
|
||||||
: itemId(item->fullId())
|
: itemId(item->fullId())
|
||||||
, link(link) {
|
, link(link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextState::TextState(
|
||||||
HistoryTextState::HistoryTextState(
|
|
||||||
not_null<const HistoryView::Element*> view)
|
not_null<const HistoryView::Element*> view)
|
||||||
: HistoryTextState(view->data()) {
|
: TextState(view->data()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState::HistoryTextState(
|
TextState::TextState(
|
||||||
not_null<const HistoryView::Element*> view,
|
not_null<const HistoryView::Element*> view,
|
||||||
const Text::StateResult &state)
|
const Text::StateResult &state)
|
||||||
: HistoryTextState(view->data(), state) {
|
: TextState(view->data(), state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState::HistoryTextState(
|
TextState::TextState(
|
||||||
not_null<const HistoryView::Element*> view,
|
not_null<const HistoryView::Element*> view,
|
||||||
ClickHandlerPtr link)
|
ClickHandlerPtr link)
|
||||||
: HistoryTextState(view->data(), link) {
|
: TextState(view->data(), link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextState::TextState(
|
||||||
|
std::nullptr_t,
|
||||||
|
const Text::StateResult &state)
|
||||||
|
: cursor(state.uponSymbol
|
||||||
|
? CursorState::Text
|
||||||
|
: CursorState::None)
|
||||||
|
, link(state.link)
|
||||||
|
, afterSymbol(state.afterSymbol)
|
||||||
|
, symbol(state.symbol) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TextState::TextState(std::nullptr_t, ClickHandlerPtr link)
|
||||||
|
: link(link) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
|
@ -7,58 +7,54 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace HistoryView {
|
|
||||||
class Element;
|
|
||||||
} // namespace HistoryView
|
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
|
||||||
enum HistoryCursorState {
|
namespace HistoryView {
|
||||||
HistoryDefaultCursorState,
|
|
||||||
HistoryInTextCursorState,
|
class Element;
|
||||||
HistoryInDateCursorState,
|
|
||||||
HistoryInForwardedCursorState,
|
enum class PointState : char {
|
||||||
|
Outside,
|
||||||
|
Inside,
|
||||||
|
GroupPart,
|
||||||
|
};
|
||||||
|
enum class CursorState : char {
|
||||||
|
None,
|
||||||
|
Text,
|
||||||
|
Date,
|
||||||
|
Forwarded,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryTextState {
|
struct TextState {
|
||||||
HistoryTextState() = default;
|
TextState() = default;
|
||||||
HistoryTextState(not_null<const HistoryItem*> item);
|
TextState(not_null<const HistoryItem*> item);
|
||||||
HistoryTextState(
|
TextState(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
const Text::StateResult &state);
|
const Text::StateResult &state);
|
||||||
HistoryTextState(
|
TextState(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
ClickHandlerPtr link);
|
ClickHandlerPtr link);
|
||||||
HistoryTextState(not_null<const HistoryView::Element*> view);
|
TextState(not_null<const HistoryView::Element*> view);
|
||||||
HistoryTextState(
|
TextState(
|
||||||
not_null<const HistoryView::Element*> view,
|
not_null<const HistoryView::Element*> view,
|
||||||
const Text::StateResult &state);
|
const Text::StateResult &state);
|
||||||
HistoryTextState(
|
TextState(
|
||||||
not_null<const HistoryView::Element*> view,
|
not_null<const HistoryView::Element*> view,
|
||||||
ClickHandlerPtr link);
|
ClickHandlerPtr link);
|
||||||
HistoryTextState(
|
TextState(
|
||||||
std::nullptr_t,
|
std::nullptr_t,
|
||||||
const Text::StateResult &state)
|
const Text::StateResult &state);
|
||||||
: cursor(state.uponSymbol
|
TextState(std::nullptr_t, ClickHandlerPtr link);
|
||||||
? HistoryInTextCursorState
|
|
||||||
: HistoryDefaultCursorState)
|
|
||||||
, link(state.link)
|
|
||||||
, afterSymbol(state.afterSymbol)
|
|
||||||
, symbol(state.symbol) {
|
|
||||||
}
|
|
||||||
HistoryTextState(std::nullptr_t, ClickHandlerPtr link)
|
|
||||||
: link(link) {
|
|
||||||
}
|
|
||||||
|
|
||||||
FullMsgId itemId;
|
FullMsgId itemId;
|
||||||
HistoryCursorState cursor = HistoryDefaultCursorState;
|
CursorState cursor = CursorState::None;
|
||||||
ClickHandlerPtr link;
|
ClickHandlerPtr link;
|
||||||
bool afterSymbol = false;
|
bool afterSymbol = false;
|
||||||
uint16 symbol = 0;
|
uint16 symbol = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryStateRequest {
|
struct StateRequest {
|
||||||
Text::StateRequest::Flags flags = Text::StateRequest::Flag::LookupLink;
|
Text::StateRequest::Flags flags = Text::StateRequest::Flag::LookupLink;
|
||||||
Text::StateRequest forText() const {
|
Text::StateRequest forText() const {
|
||||||
Text::StateRequest result;
|
Text::StateRequest result;
|
||||||
|
@ -67,8 +63,10 @@ struct HistoryStateRequest {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum InfoDisplayType : char {
|
enum class InfoDisplayType : char {
|
||||||
InfoDisplayDefault,
|
Default,
|
||||||
InfoDisplayOverImage,
|
Image,
|
||||||
InfoDisplayOverBackground,
|
Background,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
|
@ -17,12 +17,14 @@ class HistoryMessage;
|
||||||
class HistoryService;
|
class HistoryService;
|
||||||
class HistoryMedia;
|
class HistoryMedia;
|
||||||
class HistoryWebPage;
|
class HistoryWebPage;
|
||||||
struct HistoryTextState;
|
|
||||||
struct HistoryStateRequest;
|
|
||||||
enum InfoDisplayType : char;
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
enum class PointState : char;
|
||||||
|
enum class InfoDisplayType : char;
|
||||||
|
struct StateRequest;
|
||||||
|
struct TextState;
|
||||||
|
|
||||||
enum class Context : char {
|
enum class Context : char {
|
||||||
History,
|
History,
|
||||||
Feed,
|
Feed,
|
||||||
|
@ -166,10 +168,10 @@ public:
|
||||||
QRect clip,
|
QRect clip,
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TimeMs ms) const = 0;
|
TimeMs ms) const = 0;
|
||||||
[[nodiscard]] virtual bool hasPoint(QPoint point) const = 0;
|
[[nodiscard]] virtual PointState pointState(QPoint point) const = 0;
|
||||||
[[nodiscard]] virtual HistoryTextState getState(
|
[[nodiscard]] virtual TextState textState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const = 0;
|
StateRequest request) const = 0;
|
||||||
virtual void updatePressed(QPoint point) = 0;
|
virtual void updatePressed(QPoint point) = 0;
|
||||||
virtual void drawInfo(
|
virtual void drawInfo(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/view/history_view_message.h"
|
#include "history/view/history_view_message.h"
|
||||||
#include "history/view/history_view_service_message.h"
|
#include "history/view/history_view_service_message.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
@ -44,6 +45,20 @@ constexpr auto kPreloadedScreensCountFull
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
ListWidget::MouseState::MouseState() : pointState(PointState::Outside) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ListWidget::MouseState::MouseState(
|
||||||
|
FullMsgId itemId,
|
||||||
|
int height,
|
||||||
|
QPoint point,
|
||||||
|
PointState pointState)
|
||||||
|
: itemId(itemId)
|
||||||
|
, height(height)
|
||||||
|
, point(point)
|
||||||
|
, pointState(pointState) {
|
||||||
|
}
|
||||||
|
|
||||||
template <ListWidget::EnumItemsDirection direction, typename Method>
|
template <ListWidget::EnumItemsDirection direction, typename Method>
|
||||||
void ListWidget::enumerateItems(Method method) {
|
void ListWidget::enumerateItems(Method method) {
|
||||||
constexpr auto TopToBottom = (direction == EnumItemsDirection::TopToBottom);
|
constexpr auto TopToBottom = (direction == EnumItemsDirection::TopToBottom);
|
||||||
|
@ -501,40 +516,151 @@ bool ListWidget::hasSelectedItems() const {
|
||||||
return !_selected.empty();
|
return !_selected.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::applyItemSelection(
|
bool ListWidget::overSelectedItems() const {
|
||||||
SelectedMap &applyTo,
|
if (_overState.pointState == PointState::GroupPart) {
|
||||||
FullMsgId itemId) const {
|
return _overItemExact
|
||||||
if (applyTo.size() >= MaxSelectedItems) {
|
&& _selected.contains(_overItemExact->fullId());
|
||||||
return false;
|
} else if (_overState.pointState == PointState::Inside) {
|
||||||
|
return _overElement
|
||||||
|
&& isSelectedAsGroup(_selected, _overElement->data());
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//bool ListWidget::applyItemSelection(
|
||||||
|
// SelectedMap &applyTo,
|
||||||
|
// FullMsgId itemId) const {
|
||||||
|
// if (applyTo.size() >= MaxSelectedItems) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// auto [iterator, ok] = applyTo.try_emplace(
|
||||||
|
// itemId,
|
||||||
|
// SelectionData());
|
||||||
|
// if (!ok) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// const auto item = App::histItemById(itemId);
|
||||||
|
// if (!item) {
|
||||||
|
// applyTo.erase(iterator);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// iterator->second.canDelete = item->canDelete();
|
||||||
|
// iterator->second.canForward = item->allowsForward();
|
||||||
|
// return true;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void ListWidget::toggleItemSelection(FullMsgId itemId) {
|
||||||
|
// auto it = _selected.find(itemId);
|
||||||
|
// if (it == _selected.cend()) {
|
||||||
|
// if (_selectedTextItem) {
|
||||||
|
// clearTextSelection();
|
||||||
|
// }
|
||||||
|
// if (applyItemSelection(_selected, itemId)) {
|
||||||
|
// repaintItem(itemId);
|
||||||
|
// pushSelectedItems();
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// removeItemSelection(it);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool ListWidget::isSelectedAsGroup(
|
||||||
|
const SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item) const {
|
||||||
|
if (const auto group = Auth().data().groups().find(item)) {
|
||||||
|
for (const auto other : group->items) {
|
||||||
|
if (!applyTo.contains(other->fullId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return applyTo.contains(item->fullId());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListWidget::isGoodForSelection(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
int &totalCount) const {
|
||||||
|
if (!IsServerMsgId(item->id) || item->serviceMsg()) {
|
||||||
|
return false;
|
||||||
|
} else if (!applyTo.contains(item->fullId())) {
|
||||||
|
++totalCount;
|
||||||
|
}
|
||||||
|
return (totalCount <= MaxSelectedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListWidget::addToSelection(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item) const {
|
||||||
|
const auto itemId = item->fullId();
|
||||||
auto [iterator, ok] = applyTo.try_emplace(
|
auto [iterator, ok] = applyTo.try_emplace(
|
||||||
itemId,
|
itemId,
|
||||||
SelectionData());
|
SelectionData());
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto item = App::histItemById(itemId);
|
|
||||||
if (!item) {
|
|
||||||
applyTo.erase(iterator);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
iterator->second.canDelete = item->canDelete();
|
iterator->second.canDelete = item->canDelete();
|
||||||
iterator->second.canForward = item->allowsForward();
|
iterator->second.canForward = item->allowsForward();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::toggleItemSelection(FullMsgId itemId) {
|
bool ListWidget::removeFromSelection(
|
||||||
auto it = _selected.find(itemId);
|
SelectedMap &applyTo,
|
||||||
if (it == _selected.cend()) {
|
FullMsgId itemId) const {
|
||||||
if (_selectedTextItem) {
|
return applyTo.remove(itemId);
|
||||||
clearTextSelection();
|
}
|
||||||
}
|
|
||||||
if (applyItemSelection(_selected, itemId)) {
|
void ListWidget::changeSelection(
|
||||||
repaintItem(itemId);
|
SelectedMap &applyTo,
|
||||||
pushSelectedItems();
|
not_null<HistoryItem*> item,
|
||||||
|
SelectAction action) const {
|
||||||
|
const auto itemId = item->fullId();
|
||||||
|
if (action == SelectAction::Invert) {
|
||||||
|
action = applyTo.contains(itemId)
|
||||||
|
? SelectAction::Deselect
|
||||||
|
: SelectAction::Select;
|
||||||
|
}
|
||||||
|
if (action == SelectAction::Select) {
|
||||||
|
auto already = int(applyTo.size());
|
||||||
|
if (isGoodForSelection(applyTo, item, already)) {
|
||||||
|
addToSelection(applyTo, item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
removeItemSelection(it);
|
removeFromSelection(applyTo, itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListWidget::changeSelectionAsGroup(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
SelectAction action) const {
|
||||||
|
const auto group = Auth().data().groups().find(item);
|
||||||
|
if (!group) {
|
||||||
|
return changeSelection(applyTo, item, action);
|
||||||
|
}
|
||||||
|
if (action == SelectAction::Invert) {
|
||||||
|
action = isSelectedAsGroup(applyTo, item)
|
||||||
|
? SelectAction::Deselect
|
||||||
|
: SelectAction::Select;
|
||||||
|
}
|
||||||
|
auto already = int(applyTo.size());
|
||||||
|
const auto canSelect = [&] {
|
||||||
|
for (const auto other : group->items) {
|
||||||
|
if (!isGoodForSelection(applyTo, other, already)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}();
|
||||||
|
if (action == SelectAction::Select && canSelect) {
|
||||||
|
for (const auto other : group->items) {
|
||||||
|
addToSelection(applyTo, other);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const auto other : group->items) {
|
||||||
|
removeFromSelection(applyTo, other->fullId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,21 +669,23 @@ bool ListWidget::isItemUnderPressSelected() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ListWidget::itemUnderPressSelection() -> SelectedMap::iterator {
|
auto ListWidget::itemUnderPressSelection() -> SelectedMap::iterator {
|
||||||
return (_pressState.itemId && _pressState.inside)
|
return (_pressState.itemId
|
||||||
|
&& _pressState.pointState != PointState::Outside)
|
||||||
? _selected.find(_pressState.itemId)
|
? _selected.find(_pressState.itemId)
|
||||||
: _selected.end();
|
: _selected.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ListWidget::itemUnderPressSelection() const
|
auto ListWidget::itemUnderPressSelection() const
|
||||||
-> SelectedMap::const_iterator {
|
-> SelectedMap::const_iterator {
|
||||||
return (_pressState.itemId && _pressState.inside)
|
return (_pressState.itemId
|
||||||
|
&& _pressState.pointState != PointState::Outside)
|
||||||
? _selected.find(_pressState.itemId)
|
? _selected.find(_pressState.itemId)
|
||||||
: _selected.end();
|
: _selected.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::requiredToStartDragging(
|
bool ListWidget::requiredToStartDragging(
|
||||||
not_null<Element*> view) const {
|
not_null<Element*> view) const {
|
||||||
if (_mouseCursorState == HistoryInDateCursorState) {
|
if (_mouseCursorState == CursorState::Date) {
|
||||||
return true;
|
return true;
|
||||||
} else if (const auto media = view->media()) {
|
} else if (const auto media = view->media()) {
|
||||||
return media->type() == MediaTypeSticker;
|
return media->type() == MediaTypeSticker;
|
||||||
|
@ -565,8 +693,8 @@ bool ListWidget::requiredToStartDragging(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::isPressInSelectedText(HistoryTextState state) const {
|
bool ListWidget::isPressInSelectedText(TextState state) const {
|
||||||
if (state.cursor != HistoryInTextCursorState) {
|
if (state.cursor != CursorState::Text) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!hasSelectedText()
|
if (!hasSelectedText()
|
||||||
|
@ -692,13 +820,13 @@ void ListWidget::checkMoveToOtherViewer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ListWidget::tooltipText() const {
|
QString ListWidget::tooltipText() const {
|
||||||
const auto item = (_overItem && _mouseAction == MouseAction::None)
|
const auto item = (_overElement && _mouseAction == MouseAction::None)
|
||||||
? _overItem->data().get()
|
? _overElement->data().get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (_mouseCursorState == HistoryInDateCursorState && item) {
|
if (_mouseCursorState == CursorState::Date && item) {
|
||||||
return item->date.toString(
|
return item->date.toString(
|
||||||
QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
QLocale::system().dateTimeFormat(QLocale::LongFormat));
|
||||||
} else if (_mouseCursorState == HistoryInForwardedCursorState && item) {
|
} else if (_mouseCursorState == CursorState::Forwarded && item) {
|
||||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||||
return forwarded->text.originalText(
|
return forwarded->text.originalText(
|
||||||
AllTextSelection,
|
AllTextSelection,
|
||||||
|
@ -730,7 +858,7 @@ std::unique_ptr<Element> ListWidget::elementCreate(
|
||||||
|
|
||||||
bool ListWidget::elementUnderCursor(
|
bool ListWidget::elementUnderCursor(
|
||||||
not_null<const HistoryView::Element*> view) {
|
not_null<const HistoryView::Element*> view) {
|
||||||
return (_overItem == view);
|
return (_overElement == view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::elementAnimationAutoplayAsync(
|
void ListWidget::elementAnimationAutoplayAsync(
|
||||||
|
@ -974,11 +1102,17 @@ void ListWidget::applyDragSelection() {
|
||||||
void ListWidget::applyDragSelection(SelectedMap &applyTo) const {
|
void ListWidget::applyDragSelection(SelectedMap &applyTo) const {
|
||||||
if (_dragSelectAction == DragSelectAction::Selecting) {
|
if (_dragSelectAction == DragSelectAction::Selecting) {
|
||||||
for (const auto itemId : _dragSelected) {
|
for (const auto itemId : _dragSelected) {
|
||||||
applyItemSelection(applyTo, itemId);
|
if (applyTo.size() >= MaxSelectedItems) {
|
||||||
|
break;
|
||||||
|
} else if (!applyTo.contains(itemId)) {
|
||||||
|
if (const auto item = App::histItemById(itemId)) {
|
||||||
|
addToSelection(applyTo, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (_dragSelectAction == DragSelectAction::Deselecting) {
|
} else if (_dragSelectAction == DragSelectAction::Deselecting) {
|
||||||
for (const auto itemId : _dragSelected) {
|
for (const auto itemId : _dragSelected) {
|
||||||
applyTo.remove(itemId);
|
removeFromSelection(applyTo, itemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1132,7 +1266,7 @@ void ListWidget::trySwitchToWordSelection() {
|
||||||
&& hasSelectedText();
|
&& hasSelectedText();
|
||||||
auto willSelectSome = (_mouseAction == MouseAction::None)
|
auto willSelectSome = (_mouseAction == MouseAction::None)
|
||||||
&& !hasSelectedItems();
|
&& !hasSelectedItems();
|
||||||
auto checkSwitchToWordSelection = _overItem
|
auto checkSwitchToWordSelection = _overElement
|
||||||
&& (_mouseSelectType == TextSelectType::Letters)
|
&& (_mouseSelectType == TextSelectType::Letters)
|
||||||
&& (selectingSome || willSelectSome);
|
&& (selectingSome || willSelectSome);
|
||||||
if (checkSwitchToWordSelection) {
|
if (checkSwitchToWordSelection) {
|
||||||
|
@ -1141,19 +1275,19 @@ void ListWidget::trySwitchToWordSelection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::switchToWordSelection() {
|
void ListWidget::switchToWordSelection() {
|
||||||
Expects(_overItem != nullptr);
|
Expects(_overElement != nullptr);
|
||||||
|
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = _overItem->getState(_pressState.cursor, request);
|
auto dragState = _overElement->textState(_pressState.point, request);
|
||||||
if (dragState.cursor != HistoryInTextCursorState) {
|
if (dragState.cursor != CursorState::Text) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
_mouseSelectType = TextSelectType::Words;
|
_mouseSelectType = TextSelectType::Words;
|
||||||
if (_mouseAction == MouseAction::None) {
|
if (_mouseAction == MouseAction::None) {
|
||||||
_mouseAction = MouseAction::Selecting;
|
_mouseAction = MouseAction::Selecting;
|
||||||
setTextSelection(_overItem, TextSelection(
|
setTextSelection(_overElement, TextSelection(
|
||||||
dragState.symbol,
|
dragState.symbol,
|
||||||
dragState.symbol
|
dragState.symbol
|
||||||
));
|
));
|
||||||
|
@ -1184,8 +1318,10 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
|
|
||||||
ContextMenuRequest request;
|
ContextMenuRequest request;
|
||||||
request.link = ClickHandler::getActive();
|
request.link = ClickHandler::getActive();
|
||||||
request.view = _overItem;
|
request.view = _overElement;
|
||||||
request.overView = _overItem && _overState.inside;
|
// #TODO group part context menu using _overItemExact
|
||||||
|
request.overView = _overElement
|
||||||
|
&& (_overState.pointState != PointState::Outside);
|
||||||
request.selectedText = _selectedText;
|
request.selectedText = _selectedText;
|
||||||
const auto itemId = request.view
|
const auto itemId = request.view
|
||||||
? request.view->data()->fullId()
|
? request.view->data()->fullId()
|
||||||
|
@ -1202,12 +1338,12 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
const auto pointInItem = mapPointToItem(
|
const auto pointInItem = mapPointToItem(
|
||||||
mapFromGlobal(_mousePosition),
|
mapFromGlobal(_mousePosition),
|
||||||
request.view);
|
request.view);
|
||||||
HistoryStateRequest stateRequest;
|
StateRequest stateRequest;
|
||||||
stateRequest.flags |= Text::StateRequest::Flag::LookupSymbol;
|
stateRequest.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
const auto dragState = request.view->getState(
|
const auto dragState = request.view->textState(
|
||||||
pointInItem,
|
pointInItem,
|
||||||
stateRequest);
|
stateRequest);
|
||||||
if (dragState.cursor == HistoryInTextCursorState
|
if (dragState.cursor == CursorState::Text
|
||||||
&& base::in_range(
|
&& base::in_range(
|
||||||
dragState.symbol,
|
dragState.symbol,
|
||||||
_selectedTextRange.from,
|
_selectedTextRange.from,
|
||||||
|
@ -1257,10 +1393,10 @@ void ListWidget::enterEventHook(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::leaveEventHook(QEvent *e) {
|
void ListWidget::leaveEventHook(QEvent *e) {
|
||||||
if (const auto view = _overItem) {
|
if (const auto view = _overElement) {
|
||||||
if (_overState.inside) {
|
if (_overState.pointState != PointState::Outside) {
|
||||||
repaintItem(view);
|
repaintItem(view);
|
||||||
_overState.inside = false;
|
_overState.pointState = PointState::Outside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClickHandler::clearActive();
|
ClickHandler::clearActive();
|
||||||
|
@ -1276,7 +1412,7 @@ void ListWidget::updateDragSelection() {
|
||||||
if (!_overState.itemId || !_pressState.itemId) {
|
if (!_overState.itemId || !_pressState.itemId) {
|
||||||
clearDragSelection();
|
clearDragSelection();
|
||||||
return;
|
return;
|
||||||
} else if (_items.empty() || !_overItem || !_selectEnabled) {
|
} else if (_items.empty() || !_overElement || !_selectEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto pressItem = App::histItemById(_pressState.itemId);
|
const auto pressItem = App::histItemById(_pressState.itemId);
|
||||||
|
@ -1284,7 +1420,7 @@ void ListWidget::updateDragSelection() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto overView = _overItem;
|
const auto overView = _overElement;
|
||||||
const auto pressView = viewForItem(pressItem);
|
const auto pressView = viewForItem(pressItem);
|
||||||
const auto selectingUp = _delegate->listIsLessInOrder(
|
const auto selectingUp = _delegate->listIsLessInOrder(
|
||||||
overView->data(),
|
overView->data(),
|
||||||
|
@ -1309,14 +1445,37 @@ void ListWidget::updateDragSelection() {
|
||||||
[](auto view) { return view.get(); })
|
[](auto view) { return view.get(); })
|
||||||
: end(_items);
|
: end(_items);
|
||||||
Assert(from <= till);
|
Assert(from <= till);
|
||||||
|
const auto &groups = Auth().data().groups();
|
||||||
|
const auto changeItem = [&](not_null<HistoryItem*> item, bool add) {
|
||||||
|
const auto itemId = item->fullId();
|
||||||
|
if (add) {
|
||||||
|
_dragSelected.emplace(itemId);
|
||||||
|
} else {
|
||||||
|
_dragSelected.remove(itemId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto changeGroup = [&](not_null<HistoryItem*> item, bool add) {
|
||||||
|
if (const auto group = groups.find(item)) {
|
||||||
|
for (const auto item : group->items) {
|
||||||
|
changeItem(item, add);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
changeItem(item, add);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto changeView = [&](not_null<Element*> view, bool add) {
|
||||||
|
if (!view->isHiddenByGroup()) {
|
||||||
|
changeGroup(view->data(), add);
|
||||||
|
}
|
||||||
|
};
|
||||||
for (auto i = begin(_items); i != from; ++i) {
|
for (auto i = begin(_items); i != from; ++i) {
|
||||||
_dragSelected.remove((*i)->data()->fullId());
|
changeView(*i, false);
|
||||||
}
|
}
|
||||||
for (auto i = from; i != till; ++i) {
|
for (auto i = from; i != till; ++i) {
|
||||||
_dragSelected.emplace((*i)->data()->fullId());
|
changeView(*i, true);
|
||||||
}
|
}
|
||||||
for (auto i = till; i != end(_items); ++i) {
|
for (auto i = till; i != end(_items); ++i) {
|
||||||
_dragSelected.remove((*i)->data()->fullId());
|
changeView(*i, false);
|
||||||
}
|
}
|
||||||
_dragSelectAction = [&] {
|
_dragSelectAction = [&] {
|
||||||
if (_dragSelected.empty()) {
|
if (_dragSelected.empty()) {
|
||||||
|
@ -1363,7 +1522,7 @@ void ListWidget::mouseActionStart(
|
||||||
_pressState = _overState;
|
_pressState = _overState;
|
||||||
repaintItem(_overState.itemId);
|
repaintItem(_overState.itemId);
|
||||||
}
|
}
|
||||||
const auto pressedItem = _overItem;
|
const auto pressedView = _overElement;
|
||||||
|
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
_pressWasInactive = _controller->window()->wasInactivePress();
|
_pressWasInactive = _controller->window()->wasInactivePress();
|
||||||
|
@ -1371,18 +1530,24 @@ void ListWidget::mouseActionStart(
|
||||||
|
|
||||||
if (ClickHandler::getPressed()) {
|
if (ClickHandler::getPressed()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
} else if (hasSelectedItems()) {
|
||||||
|
if (overSelectedItems()) {
|
||||||
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
} else if (!_pressWasInactive) {
|
||||||
|
_mouseAction = MouseAction::PrepareSelect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_mouseAction == MouseAction::None && pressedItem) {
|
if (_mouseAction == MouseAction::None && pressedView) {
|
||||||
validateTrippleClickStartTime();
|
validateTrippleClickStartTime();
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
auto startDistance = (globalPosition - _trippleClickPoint).manhattanLength();
|
auto startDistance = (globalPosition - _trippleClickPoint).manhattanLength();
|
||||||
auto validStartPoint = startDistance < QApplication::startDragDistance();
|
auto validStartPoint = startDistance < QApplication::startDragDistance();
|
||||||
if (_trippleClickStartTime != 0 && validStartPoint) {
|
if (_trippleClickStartTime != 0 && validStartPoint) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = pressedItem->getState(_pressState.cursor, request);
|
dragState = pressedView->textState(_pressState.point, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
setTextSelection(pressedItem, TextSelection(
|
setTextSelection(pressedView, TextSelection(
|
||||||
dragState.symbol,
|
dragState.symbol,
|
||||||
dragState.symbol
|
dragState.symbol
|
||||||
));
|
));
|
||||||
|
@ -1392,23 +1557,22 @@ void ListWidget::mouseActionStart(
|
||||||
mouseActionUpdate();
|
mouseActionUpdate();
|
||||||
_trippleClickStartTime = getms();
|
_trippleClickStartTime = getms();
|
||||||
}
|
}
|
||||||
} else if (pressedItem) {
|
} else if (pressedView) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = pressedItem->getState(_pressState.cursor, request);
|
dragState = pressedView->textState(_pressState.point, request);
|
||||||
}
|
}
|
||||||
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
if (isPressInSelectedText(dragState)) {
|
if (isPressInSelectedText(dragState)) {
|
||||||
_mouseAction = MouseAction::PrepareDrag; // start text drag
|
_mouseAction = MouseAction::PrepareDrag; // start text drag
|
||||||
} else if (!_pressWasInactive) {
|
} else if (!_pressWasInactive) {
|
||||||
if (requiredToStartDragging(pressedItem)) {
|
if (requiredToStartDragging(pressedView)) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
} else {
|
} else {
|
||||||
if (dragState.afterSymbol) ++_mouseTextSymbol;
|
if (dragState.afterSymbol) ++_mouseTextSymbol;
|
||||||
;
|
|
||||||
if (!hasSelectedItems()) {
|
if (!hasSelectedItems()) {
|
||||||
setTextSelection(pressedItem, TextSelection(
|
setTextSelection(pressedView, TextSelection(
|
||||||
_mouseTextSymbol,
|
_mouseTextSymbol,
|
||||||
_mouseTextSymbol));
|
_mouseTextSymbol));
|
||||||
_mouseAction = MouseAction::Selecting;
|
_mouseAction = MouseAction::Selecting;
|
||||||
|
@ -1419,7 +1583,7 @@ void ListWidget::mouseActionStart(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pressedItem) {
|
if (!pressedView) {
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
} else if (_mouseAction == MouseAction::None) {
|
} else if (_mouseAction == MouseAction::None) {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
|
@ -1432,7 +1596,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::mouseActionCancel() {
|
void ListWidget::mouseActionCancel() {
|
||||||
_pressState = CursorState();
|
_pressState = MouseState();
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
clearDragSelection();
|
clearDragSelection();
|
||||||
_wasSelectedText = false;
|
_wasSelectedText = false;
|
||||||
|
@ -1444,33 +1608,63 @@ void ListWidget::mouseActionFinish(
|
||||||
Qt::MouseButton button) {
|
Qt::MouseButton button) {
|
||||||
mouseActionUpdate(globalPosition);
|
mouseActionUpdate(globalPosition);
|
||||||
|
|
||||||
auto activated = ClickHandler::unpressed();
|
|
||||||
if (_mouseAction == MouseAction::Dragging) {
|
|
||||||
activated = nullptr;
|
|
||||||
}
|
|
||||||
auto pressState = base::take(_pressState);
|
auto pressState = base::take(_pressState);
|
||||||
repaintItem(pressState.itemId);
|
repaintItem(pressState.itemId);
|
||||||
|
|
||||||
|
const auto toggleByHandler = [&](const ClickHandlerPtr &handler) {
|
||||||
|
if (_overElement) {
|
||||||
|
// If we are in selecting items mode perhaps we want to
|
||||||
|
// toggle selection instead of activating the pressed link.
|
||||||
|
if (const auto media = _overElement->media()) {
|
||||||
|
if (media->toggleSelectionByHandlerClick(handler)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto activated = ClickHandler::unpressed();
|
||||||
|
|
||||||
auto simpleSelectionChange = pressState.itemId
|
auto simpleSelectionChange = pressState.itemId
|
||||||
&& pressState.inside
|
&& (pressState.pointState != PointState::Outside)
|
||||||
&& !_pressWasInactive
|
&& !_pressWasInactive
|
||||||
&& (button != Qt::RightButton)
|
&& (button != Qt::RightButton)
|
||||||
&& (_mouseAction == MouseAction::PrepareDrag
|
&& (_mouseAction == MouseAction::PrepareSelect
|
||||||
|| _mouseAction == MouseAction::PrepareSelect);
|
|| _mouseAction == MouseAction::PrepareDrag);
|
||||||
auto needItemSelectionToggle = simpleSelectionChange
|
auto needItemSelectionToggle = simpleSelectionChange
|
||||||
|
&& (!activated || toggleByHandler(activated))
|
||||||
&& hasSelectedItems();
|
&& hasSelectedItems();
|
||||||
auto needTextSelectionClear = simpleSelectionChange
|
auto needTextSelectionClear = simpleSelectionChange
|
||||||
&& hasSelectedText();
|
&& hasSelectedText();
|
||||||
|
|
||||||
_wasSelectedText = false;
|
_wasSelectedText = false;
|
||||||
|
|
||||||
if (activated) {
|
if (_mouseAction == MouseAction::Dragging
|
||||||
|
|| _mouseAction == MouseAction::Selecting
|
||||||
|
|| needItemSelectionToggle) {
|
||||||
|
activated = nullptr;
|
||||||
|
} else if (activated) {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
App::activateClickHandler(activated, button);
|
App::activateClickHandler(activated, button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (needItemSelectionToggle) {
|
if (needItemSelectionToggle) {
|
||||||
toggleItemSelection(pressState.itemId);
|
if (const auto item = App::histItemById(pressState.itemId)) {
|
||||||
|
clearTextSelection();
|
||||||
|
if (pressState.pointState == PointState::GroupPart) {
|
||||||
|
changeSelection(
|
||||||
|
_selected,
|
||||||
|
_overItemExact ? _overItemExact : item,
|
||||||
|
SelectAction::Invert);
|
||||||
|
} else {
|
||||||
|
changeSelectionAsGroup(
|
||||||
|
_selected,
|
||||||
|
item,
|
||||||
|
SelectAction::Invert);
|
||||||
|
}
|
||||||
|
pushSelectedItems();
|
||||||
|
}
|
||||||
} else if (needTextSelectionClear) {
|
} else if (needTextSelectionClear) {
|
||||||
clearTextSelection();
|
clearTextSelection();
|
||||||
} else if (_mouseAction == MouseAction::Selecting) {
|
} else if (_mouseAction == MouseAction::Selecting) {
|
||||||
|
@ -1506,26 +1700,26 @@ void ListWidget::mouseActionUpdate() {
|
||||||
const auto view = strictFindItemByY(point.y());
|
const auto view = strictFindItemByY(point.y());
|
||||||
const auto item = view ? view->data().get() : nullptr;
|
const auto item = view ? view->data().get() : nullptr;
|
||||||
const auto itemPoint = mapPointToItem(point, view);
|
const auto itemPoint = mapPointToItem(point, view);
|
||||||
_overState = CursorState{
|
_overState = MouseState{
|
||||||
item ? item->fullId() : FullMsgId(),
|
item ? item->fullId() : FullMsgId(),
|
||||||
view ? view->height() : 0,
|
view ? view->height() : 0,
|
||||||
itemPoint,
|
itemPoint,
|
||||||
view ? view->hasPoint(itemPoint) : false
|
view ? view->pointState(itemPoint) : PointState::Outside
|
||||||
};
|
};
|
||||||
if (_overItem != view) {
|
if (_overElement != view) {
|
||||||
repaintItem(_overItem);
|
repaintItem(_overElement);
|
||||||
_overItem = view;
|
_overElement = view;
|
||||||
repaintItem(_overItem);
|
repaintItem(_overElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
ClickHandlerHost *lnkhost = nullptr;
|
ClickHandlerHost *lnkhost = nullptr;
|
||||||
auto inTextSelection = _overState.inside
|
auto inTextSelection = (_overState.pointState != PointState::Outside)
|
||||||
&& (_overState.itemId == _pressState.itemId)
|
&& (_overState.itemId == _pressState.itemId)
|
||||||
&& hasSelectedText();
|
&& hasSelectedText();
|
||||||
if (view) {
|
if (view) {
|
||||||
auto cursorDeltaLength = [&] {
|
auto cursorDeltaLength = [&] {
|
||||||
auto cursorDelta = (_overState.cursor - _pressState.cursor);
|
auto cursorDelta = (_overState.point - _pressState.point);
|
||||||
return cursorDelta.manhattanLength();
|
return cursorDelta.manhattanLength();
|
||||||
};
|
};
|
||||||
auto dragStartLength = [] {
|
auto dragStartLength = [] {
|
||||||
|
@ -1540,14 +1734,15 @@ void ListWidget::mouseActionUpdate() {
|
||||||
_mouseAction = MouseAction::Selecting;
|
_mouseAction = MouseAction::Selecting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
if (_mouseAction == MouseAction::Selecting) {
|
if (_mouseAction == MouseAction::Selecting) {
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
} else {
|
} else {
|
||||||
inTextSelection = false;
|
inTextSelection = false;
|
||||||
}
|
}
|
||||||
// #TODO enumerate dates like HistoryInner
|
// #TODO enumerate dates like HistoryInner
|
||||||
dragState = view->getState(itemPoint, request);
|
dragState = view->textState(itemPoint, request);
|
||||||
|
_overItemExact = App::histItemById(dragState.itemId);
|
||||||
lnkhost = view;
|
lnkhost = view;
|
||||||
if (!dragState.link
|
if (!dragState.link
|
||||||
&& itemPoint.x() >= st::historyPhotoLeft
|
&& itemPoint.x() >= st::historyPhotoLeft
|
||||||
|
@ -1564,7 +1759,10 @@ void ListWidget::mouseActionUpdate() {
|
||||||
const auto message = view->data()->toHistoryMessage();
|
const auto message = view->data()->toHistoryMessage();
|
||||||
Assert(message != nullptr);
|
Assert(message != nullptr);
|
||||||
|
|
||||||
dragState.link = message->from()->openLink();
|
dragState = TextState(
|
||||||
|
nullptr,
|
||||||
|
message->displayFrom()->openLink());
|
||||||
|
_overItemExact = App::histItemById(dragState.itemId);
|
||||||
lnkhost = view;
|
lnkhost = view;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1578,8 +1776,8 @@ void ListWidget::mouseActionUpdate() {
|
||||||
Ui::Tooltip::Hide();
|
Ui::Tooltip::Hide();
|
||||||
}
|
}
|
||||||
if (dragState.link
|
if (dragState.link
|
||||||
|| dragState.cursor == HistoryInDateCursorState
|
|| dragState.cursor == CursorState::Date
|
||||||
|| dragState.cursor == HistoryInForwardedCursorState) {
|
|| dragState.cursor == CursorState::Forwarded) {
|
||||||
Ui::Tooltip::Show(1000, this);
|
Ui::Tooltip::Show(1000, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1617,7 +1815,8 @@ void ListWidget::mouseActionUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Voice message seek support.
|
// Voice message seek support.
|
||||||
if (_pressState.inside && ClickHandler::getPressed()) {
|
if (_pressState.pointState != PointState::Outside
|
||||||
|
&& ClickHandler::getPressed()) {
|
||||||
if (const auto item = App::histItemById(_pressState.itemId)) {
|
if (const auto item = App::histItemById(_pressState.itemId)) {
|
||||||
if (const auto view = viewForItem(item)) {
|
if (const auto view = viewForItem(item)) {
|
||||||
auto adjustedPoint = mapPointToItem(point, view);
|
auto adjustedPoint = mapPointToItem(point, view);
|
||||||
|
@ -1637,7 +1836,7 @@ style::cursor ListWidget::computeMouseCursor() const {
|
||||||
if (ClickHandler::getPressed() || ClickHandler::getActive()) {
|
if (ClickHandler::getPressed() || ClickHandler::getActive()) {
|
||||||
return style::cur_pointer;
|
return style::cur_pointer;
|
||||||
} else if (!hasSelectedItems()
|
} else if (!hasSelectedItems()
|
||||||
&& (_mouseCursorState == HistoryInTextCursorState)) {
|
&& (_mouseCursorState == CursorState::Text)) {
|
||||||
return style::cur_text;
|
return style::cur_text;
|
||||||
}
|
}
|
||||||
return style::cur_default;
|
return style::cur_default;
|
||||||
|
@ -1651,10 +1850,10 @@ void ListWidget::performDrag() {
|
||||||
// if (!_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
|
// if (!_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
|
||||||
// uponSelected = _selected.contains(_mouseActionItem);
|
// uponSelected = _selected.contains(_mouseActionItem);
|
||||||
// } else {
|
// } else {
|
||||||
// HistoryStateRequest request;
|
// StateRequest request;
|
||||||
// request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
// request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
// auto dragState = _mouseActionItem->getState(_dragStartPosition.x(), _dragStartPosition.y(), request);
|
// auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request);
|
||||||
// uponSelected = (dragState.cursor == HistoryInTextCursorState);
|
// uponSelected = (dragState.cursor == CursorState::Text);
|
||||||
// if (uponSelected) {
|
// if (uponSelected) {
|
||||||
// if (_selected.isEmpty() ||
|
// if (_selected.isEmpty() ||
|
||||||
// _selected.cbegin().value() == FullSelection ||
|
// _selected.cbegin().value() == FullSelection ||
|
||||||
|
@ -1705,7 +1904,7 @@ void ListWidget::performDrag() {
|
||||||
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
||||||
// if (auto pressedItem = App::pressedItem()) { // #TODO no App::
|
// if (auto pressedItem = App::pressedItem()) { // #TODO no App::
|
||||||
// pressedMedia = pressedItem->media();
|
// pressedMedia = pressedItem->media();
|
||||||
// if (_mouseCursorState == HistoryInDateCursorState
|
// if (_mouseCursorState == CursorState::Date
|
||||||
// || (pressedMedia && pressedMedia->dragItem())) {
|
// || (pressedMedia && pressedMedia->dragItem())) {
|
||||||
// Auth().data().setMimeForwardIds(
|
// Auth().data().setMimeForwardIds(
|
||||||
// Auth().data().itemOrItsGroup(pressedItem->data()));
|
// Auth().data().itemOrItsGroup(pressedItem->data()));
|
||||||
|
@ -1779,7 +1978,8 @@ void ListWidget::refreshAttachmentsAtIndex(int index) {
|
||||||
return index;
|
return index;
|
||||||
}();
|
}();
|
||||||
const auto till = [&] {
|
const auto till = [&] {
|
||||||
for (auto i = index + 1, count = int(_items.size()); i != count; ) {
|
const auto count = int(_items.size());
|
||||||
|
for (auto i = index + 1; i != count; ++i) {
|
||||||
if (!_items[i]->isHiddenByGroup()) {
|
if (!_items[i]->isHiddenByGroup()) {
|
||||||
return i + 1;
|
return i + 1;
|
||||||
}
|
}
|
||||||
|
@ -1835,13 +2035,16 @@ void ListWidget::refreshItem(not_null<const Element*> view) {
|
||||||
void ListWidget::viewReplaced(not_null<const Element*> was, Element *now) {
|
void ListWidget::viewReplaced(not_null<const Element*> was, Element *now) {
|
||||||
if (_visibleTopItem == was) _visibleTopItem = now;
|
if (_visibleTopItem == was) _visibleTopItem = now;
|
||||||
if (_scrollDateLastItem == was) _scrollDateLastItem = now;
|
if (_scrollDateLastItem == was) _scrollDateLastItem = now;
|
||||||
if (_overItem == was) _overItem = now;
|
if (_overElement == was) _overElement = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
void ListWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
if (_selectedTextItem == item) {
|
if (_selectedTextItem == item) {
|
||||||
clearTextSelection();
|
clearTextSelection();
|
||||||
}
|
}
|
||||||
|
if (_overItemExact == item) {
|
||||||
|
_overItemExact = nullptr;
|
||||||
|
}
|
||||||
const auto i = _views.find(item);
|
const auto i = _views.find(item);
|
||||||
if (i == end(_views)) {
|
if (i == end(_views)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "data/data_messages.h"
|
#include "data/data_messages.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -25,6 +24,10 @@ class Controller;
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
enum class CursorState : char;
|
||||||
|
enum class PointState : char;
|
||||||
enum class Context : char;
|
enum class Context : char;
|
||||||
|
|
||||||
struct SelectedItem {
|
struct SelectedItem {
|
||||||
|
@ -166,17 +169,24 @@ protected:
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CursorState {
|
struct MouseState {
|
||||||
|
MouseState();
|
||||||
|
MouseState(
|
||||||
|
FullMsgId itemId,
|
||||||
|
int height,
|
||||||
|
QPoint point,
|
||||||
|
PointState pointState);
|
||||||
|
|
||||||
FullMsgId itemId;
|
FullMsgId itemId;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
QPoint cursor;
|
QPoint point;
|
||||||
bool inside = false;
|
PointState pointState;
|
||||||
|
|
||||||
inline bool operator==(const CursorState &other) const {
|
inline bool operator==(const MouseState &other) const {
|
||||||
return (itemId == other.itemId)
|
return (itemId == other.itemId)
|
||||||
&& (cursor == other.cursor);
|
&& (point == other.point);
|
||||||
}
|
}
|
||||||
inline bool operator!=(const CursorState &other) const {
|
inline bool operator!=(const MouseState &other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +202,11 @@ private:
|
||||||
PrepareSelect,
|
PrepareSelect,
|
||||||
Selecting,
|
Selecting,
|
||||||
};
|
};
|
||||||
|
enum class SelectAction {
|
||||||
|
Select,
|
||||||
|
Deselect,
|
||||||
|
Invert,
|
||||||
|
};
|
||||||
enum class EnumItemsDirection {
|
enum class EnumItemsDirection {
|
||||||
TopToBottom,
|
TopToBottom,
|
||||||
BottomToTop,
|
BottomToTop,
|
||||||
|
@ -202,6 +217,8 @@ private:
|
||||||
Deselecting,
|
Deselecting,
|
||||||
};
|
};
|
||||||
using ScrollTopState = ListMemento::ScrollTopState;
|
using ScrollTopState = ListMemento::ScrollTopState;
|
||||||
|
using PointState = HistoryView::PointState;
|
||||||
|
using CursorState = HistoryView::CursorState;
|
||||||
|
|
||||||
void refreshViewer();
|
void refreshViewer();
|
||||||
void updateAroundPositionFromRows();
|
void updateAroundPositionFromRows();
|
||||||
|
@ -264,18 +281,42 @@ private:
|
||||||
const SelectedMap::const_iterator &i);
|
const SelectedMap::const_iterator &i);
|
||||||
bool hasSelectedText() const;
|
bool hasSelectedText() const;
|
||||||
bool hasSelectedItems() const;
|
bool hasSelectedItems() const;
|
||||||
|
bool overSelectedItems() const;
|
||||||
void clearTextSelection();
|
void clearTextSelection();
|
||||||
void clearSelected();
|
void clearSelected();
|
||||||
void setTextSelection(
|
void setTextSelection(
|
||||||
not_null<Element*> view,
|
not_null<Element*> view,
|
||||||
TextSelection selection);
|
TextSelection selection);
|
||||||
bool applyItemSelection(SelectedMap &applyTo, FullMsgId itemId) const;
|
//bool applyItemSelection(SelectedMap &applyTo, FullMsgId itemId) const;
|
||||||
void toggleItemSelection(FullMsgId itemId);
|
//void toggleItemSelection(FullMsgId itemId);
|
||||||
|
|
||||||
|
bool isGoodForSelection(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
int &totalCount) const;
|
||||||
|
bool addToSelection(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item) const;
|
||||||
|
bool removeFromSelection(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
FullMsgId itemId) const;
|
||||||
|
void changeSelection(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
SelectAction action) const;
|
||||||
|
bool isSelectedAsGroup(
|
||||||
|
const SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item) const;
|
||||||
|
void changeSelectionAsGroup(
|
||||||
|
SelectedMap &applyTo,
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
SelectAction action) const;
|
||||||
|
|
||||||
SelectedMap::iterator itemUnderPressSelection();
|
SelectedMap::iterator itemUnderPressSelection();
|
||||||
SelectedMap::const_iterator itemUnderPressSelection() const;
|
SelectedMap::const_iterator itemUnderPressSelection() const;
|
||||||
bool isItemUnderPressSelected() const;
|
bool isItemUnderPressSelected() const;
|
||||||
bool requiredToStartDragging(not_null<Element*> view) const;
|
bool requiredToStartDragging(not_null<Element*> view) const;
|
||||||
bool isPressInSelectedText(HistoryTextState state) const;
|
bool isPressInSelectedText(TextState state) const;
|
||||||
void updateDragSelection();
|
void updateDragSelection();
|
||||||
void clearDragSelection();
|
void clearDragSelection();
|
||||||
void applyDragSelection();
|
void applyDragSelection();
|
||||||
|
@ -345,10 +386,11 @@ private:
|
||||||
MouseAction _mouseAction = MouseAction::None;
|
MouseAction _mouseAction = MouseAction::None;
|
||||||
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
||||||
QPoint _mousePosition;
|
QPoint _mousePosition;
|
||||||
CursorState _overState;
|
MouseState _overState;
|
||||||
CursorState _pressState;
|
MouseState _pressState;
|
||||||
Element *_overItem = nullptr;
|
Element *_overElement = nullptr;
|
||||||
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
|
HistoryItem *_overItemExact = nullptr;
|
||||||
|
CursorState _mouseCursorState = CursorState();
|
||||||
uint16 _mouseTextSymbol = 0;
|
uint16 _mouseTextSymbol = 0;
|
||||||
bool _pressWasInactive = false;
|
bool _pressWasInactive = false;
|
||||||
|
|
||||||
|
|
|
@ -435,31 +435,15 @@ void Message::draw(
|
||||||
if (entry) {
|
if (entry) {
|
||||||
trect.setHeight(trect.height() - entry->height());
|
trect.setHeight(trect.height() - entry->height());
|
||||||
}
|
}
|
||||||
auto needDrawInfo = mediaOnBottom
|
paintText(p, trect, selection);
|
||||||
? !(entry
|
|
||||||
? entry->customInfoLayout()
|
|
||||||
: media->customInfoLayout())
|
|
||||||
: true;
|
|
||||||
if (mediaDisplayed) {
|
if (mediaDisplayed) {
|
||||||
auto mediaAboveText = media->isAboveMessage();
|
|
||||||
auto mediaHeight = media->height();
|
auto mediaHeight = media->height();
|
||||||
auto mediaLeft = g.left();
|
auto mediaLeft = g.left();
|
||||||
auto mediaTop = mediaAboveText ? trect.y() : (trect.y() + trect.height() - mediaHeight);
|
auto mediaTop = (trect.y() + trect.height() - mediaHeight);
|
||||||
if (!mediaAboveText) {
|
|
||||||
paintText(p, trect, selection);
|
|
||||||
}
|
|
||||||
p.translate(mediaLeft, mediaTop);
|
p.translate(mediaLeft, mediaTop);
|
||||||
media->draw(p, clip.translated(-mediaLeft, -mediaTop), skipTextSelection(selection), ms);
|
media->draw(p, clip.translated(-mediaLeft, -mediaTop), skipTextSelection(selection), ms);
|
||||||
p.translate(-mediaLeft, -mediaTop);
|
p.translate(-mediaLeft, -mediaTop);
|
||||||
|
|
||||||
if (mediaAboveText) {
|
|
||||||
trect.setY(trect.y() + mediaHeight);
|
|
||||||
paintText(p, trect, selection);
|
|
||||||
} else {
|
|
||||||
needDrawInfo = !media->customInfoLayout();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
paintText(p, trect, selection);
|
|
||||||
}
|
}
|
||||||
if (entry) {
|
if (entry) {
|
||||||
auto entryLeft = g.left();
|
auto entryLeft = g.left();
|
||||||
|
@ -472,8 +456,13 @@ void Message::draw(
|
||||||
entry->draw(p, clip.translated(-entryLeft, -entryTop), entrySelection, ms);
|
entry->draw(p, clip.translated(-entryLeft, -entryTop), entrySelection, ms);
|
||||||
p.translate(-entryLeft, -entryTop);
|
p.translate(-entryLeft, -entryTop);
|
||||||
}
|
}
|
||||||
|
const auto needDrawInfo = entry
|
||||||
|
? !entry->customInfoLayout()
|
||||||
|
: (mediaDisplayed
|
||||||
|
? !media->customInfoLayout()
|
||||||
|
: true);
|
||||||
if (needDrawInfo) {
|
if (needDrawInfo) {
|
||||||
drawInfo(p, g.left() + g.width(), g.top() + g.height(), 2 * g.left() + g.width(), selected, InfoDisplayDefault);
|
drawInfo(p, g.left() + g.width(), g.top() + g.height(), 2 * g.left() + g.width(), selected, InfoDisplayType::Default);
|
||||||
}
|
}
|
||||||
if (displayRightAction()) {
|
if (displayRightAction()) {
|
||||||
const auto fastShareSkip = snap(
|
const auto fastShareSkip = snap(
|
||||||
|
@ -618,20 +607,56 @@ void Message::paintText(Painter &p, QRect &trect, TextSelection selection) const
|
||||||
item->_text.draw(p, trect.x(), trect.y(), trect.width(), style::al_left, 0, -1, selection);
|
item->_text.draw(p, trect.x(), trect.y(), trect.width(), style::al_left, 0, -1, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Message::hasPoint(QPoint point) const {
|
PointState Message::pointState(QPoint point) const {
|
||||||
const auto g = countGeometry();
|
const auto g = countGeometry();
|
||||||
if (g.width() < 1) {
|
if (g.width() < 1) {
|
||||||
return false;
|
return PointState::Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto media = this->media();
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (drawBubble()) {
|
if (drawBubble()) {
|
||||||
return g.contains(point);
|
if (!g.contains(point)) {
|
||||||
} else if (const auto media = this->media()) {
|
return PointState::Outside;
|
||||||
return media->hasPoint(point - g.topLeft());
|
}
|
||||||
} else {
|
if (const auto mediaDisplayed = media && media->isDisplayed()) {
|
||||||
return false;
|
// Hack for grouped media point state.
|
||||||
|
auto entry = logEntryOriginal();
|
||||||
|
|
||||||
|
// Entry page is always a bubble bottom.
|
||||||
|
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
|
||||||
|
auto mediaOnTop = (mediaDisplayed && media->isBubbleTop()) || (entry && entry->isBubbleTop());
|
||||||
|
|
||||||
|
auto trect = g.marginsRemoved(st::msgPadding);
|
||||||
|
if (mediaOnBottom) {
|
||||||
|
trect.setHeight(trect.height() + st::msgPadding.bottom());
|
||||||
|
}
|
||||||
|
//if (mediaOnTop) {
|
||||||
|
// trect.setY(trect.y() - st::msgPadding.top());
|
||||||
|
//} else {
|
||||||
|
// if (getStateFromName(point, trect, &result)) return result;
|
||||||
|
// if (getStateForwardedInfo(point, trect, &result, request)) return result;
|
||||||
|
// if (getStateReplyInfo(point, trect, &result)) return result;
|
||||||
|
// if (getStateViaBotIdInfo(point, trect, &result)) return result;
|
||||||
|
//}
|
||||||
|
if (entry) {
|
||||||
|
auto entryHeight = entry->height();
|
||||||
|
trect.setHeight(trect.height() - entryHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mediaHeight = media->height();
|
||||||
|
auto mediaLeft = trect.x() - st::msgPadding.left();
|
||||||
|
auto mediaTop = (trect.y() + trect.height() - mediaHeight);
|
||||||
|
|
||||||
|
if (point.y() >= mediaTop && point.y() < mediaTop + mediaHeight) {
|
||||||
|
return media->pointState(point - QPoint(mediaLeft, mediaTop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PointState::Inside;
|
||||||
|
} else if (media) {
|
||||||
|
return media->pointState(point - g.topLeft());
|
||||||
}
|
}
|
||||||
|
return PointState::Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Message::displayFromPhoto() const {
|
bool Message::displayFromPhoto() const {
|
||||||
|
@ -661,13 +686,13 @@ bool Message::hasFromPhoto() const {
|
||||||
Unexpected("Context in Message::hasFromPhoto.");
|
Unexpected("Context in Message::hasFromPhoto.");
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Message::getState(
|
TextState Message::textState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
|
|
||||||
auto result = HistoryTextState(item);
|
auto result = TextState(item);
|
||||||
|
|
||||||
auto g = countGeometry();
|
auto g = countGeometry();
|
||||||
if (g.width() < 1) {
|
if (g.width() < 1) {
|
||||||
|
@ -707,7 +732,7 @@ HistoryTextState Message::getState(
|
||||||
auto entryLeft = g.left();
|
auto entryLeft = g.left();
|
||||||
auto entryTop = trect.y() + trect.height();
|
auto entryTop = trect.y() + trect.height();
|
||||||
if (point.y() >= entryTop && point.y() < entryTop + entryHeight) {
|
if (point.y() >= entryTop && point.y() < entryTop + entryHeight) {
|
||||||
result = entry->getState(
|
result = entry->textState(
|
||||||
point - QPoint(entryLeft, entryTop),
|
point - QPoint(entryLeft, entryTop),
|
||||||
request);
|
request);
|
||||||
result.symbol += item->_text.length() + (mediaDisplayed ? media->fullSelectionLength() : 0);
|
result.symbol += item->_text.length() + (mediaDisplayed ? media->fullSelectionLength() : 0);
|
||||||
|
@ -720,28 +745,22 @@ HistoryTextState Message::getState(
|
||||||
: media->customInfoLayout())
|
: media->customInfoLayout())
|
||||||
: true;
|
: true;
|
||||||
if (mediaDisplayed) {
|
if (mediaDisplayed) {
|
||||||
auto mediaAboveText = media->isAboveMessage();
|
|
||||||
auto mediaHeight = media->height();
|
auto mediaHeight = media->height();
|
||||||
auto mediaLeft = trect.x() - st::msgPadding.left();
|
auto mediaLeft = trect.x() - st::msgPadding.left();
|
||||||
auto mediaTop = mediaAboveText ? trect.y() : (trect.y() + trect.height() - mediaHeight);
|
auto mediaTop = (trect.y() + trect.height() - mediaHeight);
|
||||||
|
|
||||||
if (point.y() >= mediaTop && point.y() < mediaTop + mediaHeight) {
|
if (point.y() >= mediaTop && point.y() < mediaTop + mediaHeight) {
|
||||||
result = media->getState(point - QPoint(mediaLeft, mediaTop), request);
|
result = media->textState(point - QPoint(mediaLeft, mediaTop), request);
|
||||||
result.symbol += item->_text.length();
|
result.symbol += item->_text.length();
|
||||||
} else {
|
} else if (trect.contains(point)) {
|
||||||
if (mediaAboveText) {
|
getStateText(point, trect, &result, request);
|
||||||
trect.setY(trect.y() + mediaHeight);
|
|
||||||
}
|
|
||||||
if (trect.contains(point)) {
|
|
||||||
getStateText(point, trect, &result, request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (trect.contains(point)) {
|
} else if (trect.contains(point)) {
|
||||||
getStateText(point, trect, &result, request);
|
getStateText(point, trect, &result, request);
|
||||||
}
|
}
|
||||||
if (needDateCheck) {
|
if (needDateCheck) {
|
||||||
if (pointInTime(g.left() + g.width(), g.top() + g.height(), point, InfoDisplayDefault)) {
|
if (pointInTime(g.left() + g.width(), g.top() + g.height(), point, InfoDisplayType::Default)) {
|
||||||
result.cursor = HistoryInDateCursorState;
|
result.cursor = CursorState::Date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (displayRightAction()) {
|
if (displayRightAction()) {
|
||||||
|
@ -761,14 +780,14 @@ HistoryTextState Message::getState(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (media && media->isDisplayed()) {
|
} else if (media && media->isDisplayed()) {
|
||||||
result = media->getState(point - g.topLeft(), request);
|
result = media->textState(point - g.topLeft(), request);
|
||||||
result.symbol += item->_text.length();
|
result.symbol += item->_text.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyboard && !item->isLogEntry()) {
|
if (keyboard && !item->isLogEntry()) {
|
||||||
auto keyboardTop = g.top() + g.height() + st::msgBotKbButton.margin;
|
auto keyboardTop = g.top() + g.height() + st::msgBotKbButton.margin;
|
||||||
if (QRect(g.left(), keyboardTop, g.width(), keyboardHeight).contains(point)) {
|
if (QRect(g.left(), keyboardTop, g.width(), keyboardHeight).contains(point)) {
|
||||||
result.link = keyboard->getState(point - QPoint(g.left(), keyboardTop));
|
result.link = keyboard->getLink(point - QPoint(g.left(), keyboardTop));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,7 +798,7 @@ HistoryTextState Message::getState(
|
||||||
bool Message::getStateFromName(
|
bool Message::getStateFromName(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult) const {
|
not_null<TextState*> outResult) const {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (displayFromName()) {
|
if (displayFromName()) {
|
||||||
const auto replyWidth = [&] {
|
const auto replyWidth = [&] {
|
||||||
|
@ -828,8 +847,8 @@ bool Message::getStateFromName(
|
||||||
bool Message::getStateForwardedInfo(
|
bool Message::getStateForwardedInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult,
|
not_null<TextState*> outResult,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (displayForwardedFrom()) {
|
if (displayForwardedFrom()) {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
auto forwarded = item->Get<HistoryMessageForwarded>();
|
auto forwarded = item->Get<HistoryMessageForwarded>();
|
||||||
|
@ -840,16 +859,16 @@ bool Message::getStateForwardedInfo(
|
||||||
if (breakEverywhere) {
|
if (breakEverywhere) {
|
||||||
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere;
|
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere;
|
||||||
}
|
}
|
||||||
*outResult = HistoryTextState(item, forwarded->text.getState(
|
*outResult = TextState(item, forwarded->text.getState(
|
||||||
point - trect.topLeft(),
|
point - trect.topLeft(),
|
||||||
trect.width(),
|
trect.width(),
|
||||||
textRequest));
|
textRequest));
|
||||||
outResult->symbol = 0;
|
outResult->symbol = 0;
|
||||||
outResult->afterSymbol = false;
|
outResult->afterSymbol = false;
|
||||||
if (breakEverywhere) {
|
if (breakEverywhere) {
|
||||||
outResult->cursor = HistoryInForwardedCursorState;
|
outResult->cursor = CursorState::Forwarded;
|
||||||
} else {
|
} else {
|
||||||
outResult->cursor = HistoryDefaultCursorState;
|
outResult->cursor = CursorState::None;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -861,7 +880,7 @@ bool Message::getStateForwardedInfo(
|
||||||
bool Message::getStateReplyInfo(
|
bool Message::getStateReplyInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult) const {
|
not_null<TextState*> outResult) const {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (auto reply = item->Get<HistoryMessageReply>()) {
|
if (auto reply = item->Get<HistoryMessageReply>()) {
|
||||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||||
|
@ -879,7 +898,7 @@ bool Message::getStateReplyInfo(
|
||||||
bool Message::getStateViaBotIdInfo(
|
bool Message::getStateViaBotIdInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult) const {
|
not_null<TextState*> outResult) const {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (!displayFromName() && !item->Has<HistoryMessageForwarded>()) {
|
if (!displayFromName() && !item->Has<HistoryMessageForwarded>()) {
|
||||||
if (auto via = item->Get<HistoryMessageVia>()) {
|
if (auto via = item->Get<HistoryMessageVia>()) {
|
||||||
|
@ -896,14 +915,14 @@ bool Message::getStateViaBotIdInfo(
|
||||||
bool Message::getStateText(
|
bool Message::getStateText(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult,
|
not_null<TextState*> outResult,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (!hasVisibleText()) {
|
if (!hasVisibleText()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
if (trect.contains(point)) {
|
if (trect.contains(point)) {
|
||||||
*outResult = HistoryTextState(item, item->_text.getState(
|
*outResult = TextState(item, item->_text.getState(
|
||||||
point - trect.topLeft(),
|
point - trect.topLeft(),
|
||||||
trect.width(),
|
trect.width(),
|
||||||
request.forText()));
|
request.forText()));
|
||||||
|
@ -954,10 +973,9 @@ void Message::updatePressed(QPoint point) {
|
||||||
|
|
||||||
auto needDateCheck = true;
|
auto needDateCheck = true;
|
||||||
if (mediaDisplayed) {
|
if (mediaDisplayed) {
|
||||||
auto mediaAboveText = media->isAboveMessage();
|
|
||||||
auto mediaHeight = media->height();
|
auto mediaHeight = media->height();
|
||||||
auto mediaLeft = trect.x() - st::msgPadding.left();
|
auto mediaLeft = trect.x() - st::msgPadding.left();
|
||||||
auto mediaTop = mediaAboveText ? trect.y() : (trect.y() + trect.height() - mediaHeight);
|
auto mediaTop = (trect.y() + trect.height() - mediaHeight);
|
||||||
media->updatePressed(point - QPoint(mediaLeft, mediaTop));
|
media->updatePressed(point - QPoint(mediaLeft, mediaTop));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1054,23 +1072,23 @@ void Message::drawInfo(
|
||||||
p.setFont(st::msgDateFont);
|
p.setFont(st::msgDateFont);
|
||||||
|
|
||||||
bool outbg = hasOutLayout();
|
bool outbg = hasOutLayout();
|
||||||
bool invertedsprites = (type == InfoDisplayOverImage)
|
bool invertedsprites = (type == InfoDisplayType::Image)
|
||||||
|| (type == InfoDisplayOverBackground);
|
|| (type == InfoDisplayType::Background);
|
||||||
int32 infoRight = right, infoBottom = bottom;
|
int32 infoRight = right, infoBottom = bottom;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case InfoDisplayDefault:
|
case InfoDisplayType::Default:
|
||||||
infoRight -= st::msgPadding.right() - st::msgDateDelta.x();
|
infoRight -= st::msgPadding.right() - st::msgDateDelta.x();
|
||||||
infoBottom -= st::msgPadding.bottom() - st::msgDateDelta.y();
|
infoBottom -= st::msgPadding.bottom() - st::msgDateDelta.y();
|
||||||
p.setPen(selected
|
p.setPen(selected
|
||||||
? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected)
|
? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected)
|
||||||
: (outbg ? st::msgOutDateFg : st::msgInDateFg));
|
: (outbg ? st::msgOutDateFg : st::msgInDateFg));
|
||||||
break;
|
break;
|
||||||
case InfoDisplayOverImage:
|
case InfoDisplayType::Image:
|
||||||
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
|
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
|
||||||
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
|
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||||
p.setPen(st::msgDateImgFg);
|
p.setPen(st::msgDateImgFg);
|
||||||
break;
|
break;
|
||||||
case InfoDisplayOverBackground:
|
case InfoDisplayType::Background:
|
||||||
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
|
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
|
||||||
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
|
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||||
p.setPen(st::msgServiceFg);
|
p.setPen(st::msgServiceFg);
|
||||||
|
@ -1083,10 +1101,10 @@ void Message::drawInfo(
|
||||||
|
|
||||||
auto dateX = infoRight - infoW;
|
auto dateX = infoRight - infoW;
|
||||||
auto dateY = infoBottom - st::msgDateFont->height;
|
auto dateY = infoBottom - st::msgDateFont->height;
|
||||||
if (type == InfoDisplayOverImage) {
|
if (type == InfoDisplayType::Image) {
|
||||||
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
||||||
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||||
} else if (type == InfoDisplayOverBackground) {
|
} else if (type == InfoDisplayType::Background) {
|
||||||
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
||||||
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
|
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
|
||||||
}
|
}
|
||||||
|
@ -1143,11 +1161,11 @@ bool Message::pointInTime(
|
||||||
auto infoRight = right;
|
auto infoRight = right;
|
||||||
auto infoBottom = bottom;
|
auto infoBottom = bottom;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case InfoDisplayDefault:
|
case InfoDisplayType::Default:
|
||||||
infoRight -= st::msgPadding.right() - st::msgDateDelta.x();
|
infoRight -= st::msgPadding.right() - st::msgDateDelta.x();
|
||||||
infoBottom -= st::msgPadding.bottom() - st::msgDateDelta.y();
|
infoBottom -= st::msgPadding.bottom() - st::msgDateDelta.y();
|
||||||
break;
|
break;
|
||||||
case InfoDisplayOverImage:
|
case InfoDisplayType::Image:
|
||||||
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
|
infoRight -= st::msgDateImgDelta + st::msgDateImgPadding.x();
|
||||||
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
|
infoBottom -= st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||||
break;
|
break;
|
||||||
|
@ -1414,11 +1432,7 @@ void Message::updateMediaInBubbleState() {
|
||||||
mediaHasSomethingAbove = getMediaHasSomethingAbove();
|
mediaHasSomethingAbove = getMediaHasSomethingAbove();
|
||||||
}
|
}
|
||||||
if (hasVisibleText()) {
|
if (hasVisibleText()) {
|
||||||
if (media->isAboveMessage()) {
|
mediaHasSomethingAbove = true;
|
||||||
mediaHasSomethingBelow = true;
|
|
||||||
} else {
|
|
||||||
mediaHasSomethingAbove = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const auto state = [&] {
|
const auto state = [&] {
|
||||||
if (mediaHasSomethingAbove) {
|
if (mediaHasSomethingAbove) {
|
||||||
|
|
|
@ -37,10 +37,10 @@ public:
|
||||||
QRect clip,
|
QRect clip,
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TimeMs ms) const override;
|
TimeMs ms) const override;
|
||||||
bool hasPoint(QPoint point) const override;
|
PointState pointState(QPoint point) const override;
|
||||||
HistoryTextState getState(
|
TextState textState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
void updatePressed(QPoint point) override;
|
void updatePressed(QPoint point) override;
|
||||||
void drawInfo(
|
void drawInfo(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
@ -104,25 +104,25 @@ private:
|
||||||
bool getStateFromName(
|
bool getStateFromName(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult) const;
|
not_null<TextState*> outResult) const;
|
||||||
bool getStateForwardedInfo(
|
bool getStateForwardedInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult,
|
not_null<TextState*> outResult,
|
||||||
HistoryStateRequest request) const;
|
StateRequest request) const;
|
||||||
bool getStateReplyInfo(
|
bool getStateReplyInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult) const;
|
not_null<TextState*> outResult) const;
|
||||||
bool getStateViaBotIdInfo(
|
bool getStateViaBotIdInfo(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult) const;
|
not_null<TextState*> outResult) const;
|
||||||
bool getStateText(
|
bool getStateText(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
QRect &trect,
|
QRect &trect,
|
||||||
not_null<HistoryTextState*> outResult,
|
not_null<TextState*> outResult,
|
||||||
HistoryStateRequest request) const;
|
StateRequest request) const;
|
||||||
|
|
||||||
void updateMediaInBubbleState();
|
void updateMediaInBubbleState();
|
||||||
QRect countGeometry() const;
|
QRect countGeometry() const;
|
||||||
|
|
|
@ -436,13 +436,13 @@ void Service::draw(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Service::hasPoint(QPoint point) const {
|
PointState Service::pointState(QPoint point) const {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
|
|
||||||
auto g = countGeometry();
|
auto g = countGeometry();
|
||||||
if (g.width() < 1) {
|
if (g.width() < 1) {
|
||||||
return false;
|
return PointState::Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto dateh = displayedDateHeight()) {
|
if (const auto dateh = displayedDateHeight()) {
|
||||||
|
@ -454,14 +454,14 @@ bool Service::hasPoint(QPoint point) const {
|
||||||
if (media) {
|
if (media) {
|
||||||
g.setHeight(g.height() - (st::msgServiceMargin.top() + media->height()));
|
g.setHeight(g.height() - (st::msgServiceMargin.top() + media->height()));
|
||||||
}
|
}
|
||||||
return g.contains(point);
|
return g.contains(point) ? PointState::Inside : PointState::Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Service::getState(QPoint point, HistoryStateRequest request) const {
|
TextState Service::textState(QPoint point, StateRequest request) const {
|
||||||
const auto item = message();
|
const auto item = message();
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
|
|
||||||
auto result = HistoryTextState(item);
|
auto result = TextState(item);
|
||||||
|
|
||||||
auto g = countGeometry();
|
auto g = countGeometry();
|
||||||
if (g.width() < 1) {
|
if (g.width() < 1) {
|
||||||
|
@ -485,21 +485,25 @@ HistoryTextState Service::getState(QPoint point, HistoryStateRequest request) co
|
||||||
if (trect.contains(point)) {
|
if (trect.contains(point)) {
|
||||||
auto textRequest = request.forText();
|
auto textRequest = request.forText();
|
||||||
textRequest.align = style::al_center;
|
textRequest.align = style::al_center;
|
||||||
result = HistoryTextState(item, item->_text.getState(
|
result = TextState(item, item->_text.getState(
|
||||||
point - trect.topLeft(),
|
point - trect.topLeft(),
|
||||||
trect.width(),
|
trect.width(),
|
||||||
textRequest));
|
textRequest));
|
||||||
if (auto gamescore = item->Get<HistoryServiceGameScore>()) {
|
if (auto gamescore = item->Get<HistoryServiceGameScore>()) {
|
||||||
if (!result.link && result.cursor == HistoryInTextCursorState && g.contains(point)) {
|
if (!result.link
|
||||||
|
&& result.cursor == CursorState::Text
|
||||||
|
&& g.contains(point)) {
|
||||||
result.link = gamescore->lnk;
|
result.link = gamescore->lnk;
|
||||||
}
|
}
|
||||||
} else if (auto payment = item->Get<HistoryServicePayment>()) {
|
} else if (auto payment = item->Get<HistoryServicePayment>()) {
|
||||||
if (!result.link && result.cursor == HistoryInTextCursorState && g.contains(point)) {
|
if (!result.link
|
||||||
|
&& result.cursor == CursorState::Text
|
||||||
|
&& g.contains(point)) {
|
||||||
result.link = payment->lnk;
|
result.link = payment->lnk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (media) {
|
} else if (media) {
|
||||||
result = media->getState(point - QPoint(st::msgServiceMargin.left() + (g.width() - media->maxWidth()) / 2, st::msgServiceMargin.top() + g.height() + st::msgServiceMargin.top()), request);
|
result = media->textState(point - QPoint(st::msgServiceMargin.left() + (g.width() - media->maxWidth()) / 2, st::msgServiceMargin.top() + g.height() + st::msgServiceMargin.top()), request);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,10 @@ public:
|
||||||
QRect clip,
|
QRect clip,
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TimeMs ms) const override;
|
TimeMs ms) const override;
|
||||||
bool hasPoint(QPoint point) const override;
|
PointState pointState(QPoint point) const override;
|
||||||
HistoryTextState getState(
|
TextState textState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
void updatePressed(QPoint point) override;
|
void updatePressed(QPoint point) override;
|
||||||
TextWithEntities selectedText(TextSelection selection) const override;
|
TextWithEntities selectedText(TextSelection selection) const override;
|
||||||
TextSelection adjustSelection(
|
TextSelection adjustSelection(
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
|
@ -151,8 +152,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ListWidget::IsAfter(
|
bool ListWidget::IsAfter(
|
||||||
const CursorState &a,
|
const MouseState &a,
|
||||||
const CursorState &b) {
|
const MouseState &b) {
|
||||||
if (a.itemId != b.itemId) {
|
if (a.itemId != b.itemId) {
|
||||||
return (a.itemId < b.itemId);
|
return (a.itemId < b.itemId);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +162,7 @@ bool ListWidget::IsAfter(
|
||||||
return (xAfter + yAfter >= 0);
|
return (xAfter + yAfter >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::SkipSelectFromItem(const CursorState &state) {
|
bool ListWidget::SkipSelectFromItem(const MouseState &state) {
|
||||||
if (state.cursor.y() >= state.size.height()
|
if (state.cursor.y() >= state.size.height()
|
||||||
|| state.cursor.x() >= state.size.width()) {
|
|| state.cursor.x() >= state.size.width()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -169,7 +170,7 @@ bool ListWidget::SkipSelectFromItem(const CursorState &state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::SkipSelectTillItem(const CursorState &state) {
|
bool ListWidget::SkipSelectTillItem(const MouseState &state) {
|
||||||
if (state.cursor.x() < 0 || state.cursor.y() < 0) {
|
if (state.cursor.x() < 0 || state.cursor.y() < 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1440,10 +1441,10 @@ void ListWidget::trySwitchToWordSelection() {
|
||||||
void ListWidget::switchToWordSelection() {
|
void ListWidget::switchToWordSelection() {
|
||||||
Expects(_overLayout != nullptr);
|
Expects(_overLayout != nullptr);
|
||||||
|
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = _overLayout->getState(_pressState.cursor, request);
|
auto dragState = _overLayout->getState(_pressState.cursor, request);
|
||||||
if (dragState.cursor != HistoryInTextCursorState) {
|
if (dragState.cursor != CursorState::Text) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
|
@ -1535,15 +1536,15 @@ auto ListWidget::itemUnderPressSelection() const
|
||||||
|
|
||||||
bool ListWidget::requiredToStartDragging(
|
bool ListWidget::requiredToStartDragging(
|
||||||
not_null<BaseLayout*> layout) const {
|
not_null<BaseLayout*> layout) const {
|
||||||
if (_mouseCursorState == HistoryInDateCursorState) {
|
if (_mouseCursorState == CursorState::Date) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// return dynamic_cast<HistorySticker*>(layout->getMedia());
|
// return dynamic_cast<HistorySticker*>(layout->getMedia());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::isPressInSelectedText(HistoryTextState state) const {
|
bool ListWidget::isPressInSelectedText(TextState state) const {
|
||||||
if (state.cursor != HistoryInTextCursorState) {
|
if (state.cursor != CursorState::Text) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!hasSelectedText()
|
if (!hasSelectedText()
|
||||||
|
@ -1616,7 +1617,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) {
|
||||||
auto local = mapFromGlobal(_mousePosition);
|
auto local = mapFromGlobal(_mousePosition);
|
||||||
auto point = clampMousePosition(local);
|
auto point = clampMousePosition(local);
|
||||||
auto [layout, geometry, inside] = findItemByPoint(point);
|
auto [layout, geometry, inside] = findItemByPoint(point);
|
||||||
auto state = CursorState {
|
auto state = MouseState{
|
||||||
GetUniversalId(layout),
|
GetUniversalId(layout),
|
||||||
geometry.size(),
|
geometry.size(),
|
||||||
point - geometry.topLeft(),
|
point - geometry.topLeft(),
|
||||||
|
@ -1630,7 +1631,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) {
|
||||||
}
|
}
|
||||||
_overState = state;
|
_overState = state;
|
||||||
|
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
ClickHandlerHost *lnkhost = nullptr;
|
ClickHandlerHost *lnkhost = nullptr;
|
||||||
auto inTextSelection = _overState.inside
|
auto inTextSelection = _overState.inside
|
||||||
&& (_overState.itemId == _pressState.itemId)
|
&& (_overState.itemId == _pressState.itemId)
|
||||||
|
@ -1652,7 +1653,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) {
|
||||||
_mouseAction = MouseAction::Selecting;
|
_mouseAction = MouseAction::Selecting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
if (_mouseAction == MouseAction::Selecting) {
|
if (_mouseAction == MouseAction::Selecting) {
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1709,7 +1710,7 @@ style::cursor ListWidget::computeMouseCursor() const {
|
||||||
if (ClickHandler::getPressed() || ClickHandler::getActive()) {
|
if (ClickHandler::getPressed() || ClickHandler::getActive()) {
|
||||||
return style::cur_pointer;
|
return style::cur_pointer;
|
||||||
} else if (!hasSelectedItems()
|
} else if (!hasSelectedItems()
|
||||||
&& (_mouseCursorState == HistoryInTextCursorState)) {
|
&& (_mouseCursorState == CursorState::Text)) {
|
||||||
return style::cur_text;
|
return style::cur_text;
|
||||||
}
|
}
|
||||||
return style::cur_default;
|
return style::cur_default;
|
||||||
|
@ -1814,14 +1815,14 @@ void ListWidget::mouseActionStart(
|
||||||
}
|
}
|
||||||
if (_mouseAction == MouseAction::None && pressLayout) {
|
if (_mouseAction == MouseAction::None && pressLayout) {
|
||||||
validateTrippleClickStartTime();
|
validateTrippleClickStartTime();
|
||||||
HistoryTextState dragState;
|
TextState dragState;
|
||||||
auto startDistance = (globalPosition - _trippleClickPoint).manhattanLength();
|
auto startDistance = (globalPosition - _trippleClickPoint).manhattanLength();
|
||||||
auto validStartPoint = startDistance < QApplication::startDragDistance();
|
auto validStartPoint = startDistance < QApplication::startDragDistance();
|
||||||
if (_trippleClickStartTime != 0 && validStartPoint) {
|
if (_trippleClickStartTime != 0 && validStartPoint) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = pressLayout->getState(_pressState.cursor, request);
|
dragState = pressLayout->getState(_pressState.cursor, request);
|
||||||
if (dragState.cursor == HistoryInTextCursorState) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
TextSelection selStatus = { dragState.symbol, dragState.symbol };
|
TextSelection selStatus = { dragState.symbol, dragState.symbol };
|
||||||
if (selStatus != FullSelection && !hasSelectedItems()) {
|
if (selStatus != FullSelection && !hasSelectedItems()) {
|
||||||
clearSelected();
|
clearSelected();
|
||||||
|
@ -1834,7 +1835,7 @@ void ListWidget::mouseActionStart(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = pressLayout->getState(_pressState.cursor, request);
|
dragState = pressLayout->getState(_pressState.cursor, request);
|
||||||
}
|
}
|
||||||
|
@ -1873,7 +1874,7 @@ void ListWidget::mouseActionStart(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::mouseActionCancel() {
|
void ListWidget::mouseActionCancel() {
|
||||||
_pressState = CursorState();
|
_pressState = MouseState();
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
clearDragSelection();
|
clearDragSelection();
|
||||||
_wasSelectedText = false;
|
_wasSelectedText = false;
|
||||||
|
@ -1889,7 +1890,7 @@ void ListWidget::performDrag() {
|
||||||
uponSelected = isItemUnderPressSelected();
|
uponSelected = isItemUnderPressSelected();
|
||||||
} else if (auto pressLayout = getExistingLayout(
|
} else if (auto pressLayout = getExistingLayout(
|
||||||
_pressState.itemId)) {
|
_pressState.itemId)) {
|
||||||
HistoryStateRequest request;
|
StateRequest request;
|
||||||
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
auto dragState = pressLayout->getState(
|
auto dragState = pressLayout->getState(
|
||||||
_pressState.cursor,
|
_pressState.cursor,
|
||||||
|
@ -1932,7 +1933,7 @@ void ListWidget::performDrag() {
|
||||||
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
||||||
// if (auto pressedItem = _pressState.layout) {
|
// if (auto pressedItem = _pressState.layout) {
|
||||||
// pressedMedia = pressedItem->getMedia();
|
// pressedMedia = pressedItem->getMedia();
|
||||||
// if (_mouseCursorState == HistoryInDateCursorState || (pressedMedia && pressedMedia->dragItem())) {
|
// if (_mouseCursorState == CursorState::Date || (pressedMedia && pressedMedia->dragItem())) {
|
||||||
// Auth().data().setMimeForwardIds(Auth().data().itemOrItsGroup(pressedItem));
|
// Auth().data().setMimeForwardIds(Auth().data().itemOrItsGroup(pressedItem));
|
||||||
// forwardMimeType = qsl("application/x-td-forward");
|
// forwardMimeType = qsl("application/x-td-forward");
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -10,10 +10,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
#include "data/data_shared_media.h"
|
#include "data/data_shared_media.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
|
||||||
|
|
||||||
class DeleteMessagesBox;
|
class DeleteMessagesBox;
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
enum class CursorState : char;
|
||||||
|
enum class PointState : char;
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class PopupMenu;
|
class PopupMenu;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
@ -80,6 +86,11 @@ protected:
|
||||||
void leaveEventHook(QEvent *e) override;
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Context;
|
||||||
|
class Section;
|
||||||
|
using CursorState = HistoryView::CursorState;
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
using StateRequest = HistoryView::StateRequest;
|
||||||
enum class MouseAction {
|
enum class MouseAction {
|
||||||
None,
|
None,
|
||||||
PrepareDrag,
|
PrepareDrag,
|
||||||
|
@ -94,8 +105,6 @@ private:
|
||||||
std::unique_ptr<BaseLayout> item;
|
std::unique_ptr<BaseLayout> item;
|
||||||
bool stale = false;
|
bool stale = false;
|
||||||
};
|
};
|
||||||
struct Context;
|
|
||||||
class Section;
|
|
||||||
struct FoundItem {
|
struct FoundItem {
|
||||||
not_null<BaseLayout*> layout;
|
not_null<BaseLayout*> layout;
|
||||||
QRect geometry;
|
QRect geometry;
|
||||||
|
@ -118,17 +127,17 @@ private:
|
||||||
Selecting,
|
Selecting,
|
||||||
Deselecting,
|
Deselecting,
|
||||||
};
|
};
|
||||||
struct CursorState {
|
struct MouseState {
|
||||||
UniversalMsgId itemId = 0;
|
UniversalMsgId itemId = 0;
|
||||||
QSize size;
|
QSize size;
|
||||||
QPoint cursor;
|
QPoint cursor;
|
||||||
bool inside = false;
|
bool inside = false;
|
||||||
|
|
||||||
inline bool operator==(const CursorState &other) const {
|
inline bool operator==(const MouseState &other) const {
|
||||||
return (itemId == other.itemId)
|
return (itemId == other.itemId)
|
||||||
&& (cursor == other.cursor);
|
&& (cursor == other.cursor);
|
||||||
}
|
}
|
||||||
inline bool operator!=(const CursorState &other) const {
|
inline bool operator!=(const MouseState &other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +207,7 @@ private:
|
||||||
SelectedMap::const_iterator itemUnderPressSelection() const;
|
SelectedMap::const_iterator itemUnderPressSelection() const;
|
||||||
bool isItemUnderPressSelected() const;
|
bool isItemUnderPressSelected() const;
|
||||||
bool requiredToStartDragging(not_null<BaseLayout*> layout) const;
|
bool requiredToStartDragging(not_null<BaseLayout*> layout) const;
|
||||||
bool isPressInSelectedText(HistoryTextState state) const;
|
bool isPressInSelectedText(TextState state) const;
|
||||||
void applyDragSelection();
|
void applyDragSelection();
|
||||||
void applyDragSelection(SelectedMap &applyTo) const;
|
void applyDragSelection(SelectedMap &applyTo) const;
|
||||||
bool changeItemSelection(
|
bool changeItemSelection(
|
||||||
|
@ -207,10 +216,10 @@ private:
|
||||||
TextSelection selection) const;
|
TextSelection selection) const;
|
||||||
|
|
||||||
static bool IsAfter(
|
static bool IsAfter(
|
||||||
const CursorState &a,
|
const MouseState &a,
|
||||||
const CursorState &b);
|
const MouseState &b);
|
||||||
static bool SkipSelectFromItem(const CursorState &state);
|
static bool SkipSelectFromItem(const MouseState &state);
|
||||||
static bool SkipSelectTillItem(const CursorState &state);
|
static bool SkipSelectTillItem(const MouseState &state);
|
||||||
|
|
||||||
void markLayoutsStale();
|
void markLayoutsStale();
|
||||||
void clearStaleLayouts();
|
void clearStaleLayouts();
|
||||||
|
@ -281,11 +290,11 @@ private:
|
||||||
MouseAction _mouseAction = MouseAction::None;
|
MouseAction _mouseAction = MouseAction::None;
|
||||||
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
||||||
QPoint _mousePosition;
|
QPoint _mousePosition;
|
||||||
CursorState _overState;
|
MouseState _overState;
|
||||||
CursorState _pressState;
|
MouseState _pressState;
|
||||||
BaseLayout *_overLayout = nullptr;
|
BaseLayout *_overLayout = nullptr;
|
||||||
UniversalMsgId _contextUniversalId = 0;
|
UniversalMsgId _contextUniversalId = 0;
|
||||||
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
|
CursorState _mouseCursorState = CursorState();
|
||||||
uint16 _mouseTextSymbol = 0;
|
uint16 _mouseTextSymbol = 0;
|
||||||
bool _pressWasInactive = false;
|
bool _pressWasInactive = false;
|
||||||
SelectedMap _selected;
|
SelectedMap _selected;
|
||||||
|
|
|
@ -28,6 +28,8 @@ namespace InlineBots {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
|
||||||
FileBase::FileBase(not_null<Context*> context, Result *result) : ItemBase(context, result) {
|
FileBase::FileBase(not_null<Context*> context, Result *result) : ItemBase(context, result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,9 +210,9 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Gif::getState(
|
TextState Gif::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
||||||
if (_delete && rtlpoint(point, _width).x() >= _width - st::stickerPanDeleteIconBg.width() && point.y() < st::stickerPanDeleteIconBg.height()) {
|
if (_delete && rtlpoint(point, _width).x() >= _width - st::stickerPanDeleteIconBg.width() && point.y() < st::stickerPanDeleteIconBg.height()) {
|
||||||
return { nullptr, _delete };
|
return { nullptr, _delete };
|
||||||
|
@ -402,9 +404,9 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Sticker::getState(
|
TextState Sticker::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
||||||
return { nullptr, _send };
|
return { nullptr, _send };
|
||||||
}
|
}
|
||||||
|
@ -492,9 +494,9 @@ void Photo::paint(Painter &p, const QRect &clip, const PaintContext *context) co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Photo::getState(
|
TextState Photo::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
if (QRect(0, 0, _width, st::inlineMediaHeight).contains(point)) {
|
||||||
return { nullptr, _send };
|
return { nullptr, _send };
|
||||||
}
|
}
|
||||||
|
@ -637,9 +639,9 @@ void Video::paint(Painter &p, const QRect &clip, const PaintContext *context) co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Video::getState(
|
TextState Video::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
||||||
return { nullptr, _link };
|
return { nullptr, _link };
|
||||||
}
|
}
|
||||||
|
@ -778,9 +780,9 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState File::getState(
|
TextState File::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize).contains(point)) {
|
if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize).contains(point)) {
|
||||||
return { nullptr, getShownDocument()->loading() ? _cancel : _open };
|
return { nullptr, getShownDocument()->loading() ? _cancel : _open };
|
||||||
} else {
|
} else {
|
||||||
|
@ -938,9 +940,9 @@ void Contact::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Contact::getState(
|
TextState Contact::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (!QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) {
|
if (!QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) {
|
||||||
auto left = (st::msgFileSize + st::inlineThumbSkip);
|
auto left = (st::msgFileSize + st::inlineThumbSkip);
|
||||||
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
if (QRect(left, 0, _width - left, _height).contains(point)) {
|
||||||
|
@ -1075,9 +1077,9 @@ void Article::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Article::getState(
|
TextState Article::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (_withThumb && QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
if (_withThumb && QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
||||||
return { nullptr, _link };
|
return { nullptr, _link };
|
||||||
}
|
}
|
||||||
|
@ -1259,9 +1261,9 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Game::getState(
|
TextState Game::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
int left = st::inlineThumbSize + st::inlineThumbSkip;
|
int left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||||
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
if (QRect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize).contains(point)) {
|
||||||
return { nullptr, _send };
|
return { nullptr, _send };
|
||||||
|
|
|
@ -60,9 +60,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
@ -121,9 +121,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PhotoData *getShownPhoto() const;
|
PhotoData *getShownPhoto() const;
|
||||||
|
@ -153,9 +153,9 @@ public:
|
||||||
void preload() const override;
|
void preload() const override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
@ -179,9 +179,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClickHandlerPtr _link;
|
ClickHandlerPtr _link;
|
||||||
|
@ -228,9 +228,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
@ -292,9 +292,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QPixmap _thumb;
|
mutable QPixmap _thumb;
|
||||||
|
@ -312,9 +312,9 @@ public:
|
||||||
int resizeGetHeight(int width) override;
|
int resizeGetHeight(int width) override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClickHandlerPtr _url, _link;
|
ClickHandlerPtr _url, _link;
|
||||||
|
@ -337,9 +337,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
|
|
||||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void countFrameSize();
|
void countFrameSize();
|
||||||
|
|
|
@ -607,14 +607,14 @@ void Inner::updateSelected() {
|
||||||
int row = -1, col = -1, sel = -1;
|
int row = -1, col = -1, sel = -1;
|
||||||
ClickHandlerPtr lnk;
|
ClickHandlerPtr lnk;
|
||||||
ClickHandlerHost *lnkhost = nullptr;
|
ClickHandlerHost *lnkhost = nullptr;
|
||||||
HistoryCursorState cursor = HistoryDefaultCursorState;
|
HistoryView::CursorState cursor = HistoryView::CursorState::None;
|
||||||
if (sy >= 0) {
|
if (sy >= 0) {
|
||||||
row = 0;
|
row = 0;
|
||||||
for (int rows = _rows.size(); row < rows; ++row) {
|
for (int rows = _rows.size(); row < rows; ++row) {
|
||||||
if (sy < _rows.at(row).height) {
|
if (sy < _rows[row].height) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sy -= _rows.at(row).height;
|
sy -= _rows[row].height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sx >= 0 && row >= 0 && row < _rows.size()) {
|
if (sx >= 0 && row >= 0 && row < _rows.size()) {
|
||||||
|
@ -632,7 +632,9 @@ void Inner::updateSelected() {
|
||||||
}
|
}
|
||||||
if (col < inlineItems.size()) {
|
if (col < inlineItems.size()) {
|
||||||
sel = row * MatrixRowShift + col;
|
sel = row * MatrixRowShift + col;
|
||||||
auto result = inlineItems[col]->getState(QPoint(sx, sy), HistoryStateRequest());
|
auto result = inlineItems[col]->getState(
|
||||||
|
QPoint(sx, sy),
|
||||||
|
HistoryView::StateRequest());
|
||||||
lnk = result.link;
|
lnk = result.link;
|
||||||
cursor = result.cursor;
|
cursor = result.cursor;
|
||||||
lnkhost = inlineItems[col];
|
lnkhost = inlineItems[col];
|
||||||
|
|
|
@ -223,9 +223,9 @@ msp mst paf pif ps1 reg rgs sct shb shs u3p vb vbe vbs vbscript ws wsf\
|
||||||
return (lastDotIndex >= 0) && (executableTypes->indexOf(filename.mid(lastDotIndex + 1).toLower()) >= 0);
|
return (lastDotIndex >= 0) && (executableTypes->indexOf(filename.mid(lastDotIndex + 1).toLower()) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HistoryTextState LayoutItemBase::getState(
|
[[nodiscard]] HistoryView::TextState LayoutItemBase::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "base/runtime_composer.h"
|
#include "base/runtime_composer.h"
|
||||||
|
|
||||||
struct HistoryTextState;
|
namespace HistoryView {
|
||||||
struct HistoryStateRequest;
|
struct TextState;
|
||||||
|
struct StateRequest;
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
||||||
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
||||||
|
|
||||||
|
@ -82,6 +84,9 @@ class LayoutItemBase
|
||||||
: public RuntimeComposer<LayoutItemBase>
|
: public RuntimeComposer<LayoutItemBase>
|
||||||
, public ClickHandlerHost {
|
, public ClickHandlerHost {
|
||||||
public:
|
public:
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
using StateRequest = HistoryView::StateRequest;
|
||||||
|
|
||||||
LayoutItemBase() {
|
LayoutItemBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +106,9 @@ public:
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual HistoryTextState getState(
|
[[nodiscard]] virtual TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const;
|
StateRequest request) const;
|
||||||
[[nodiscard]] virtual TextSelection adjustSelection(
|
[[nodiscard]] virtual TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TextSelectType type) const;
|
TextSelectType type) const;
|
||||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "ui/effects/round_checkbox.h"
|
#include "ui/effects/round_checkbox.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ namespace Overview {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using TextState = HistoryView::TextState;
|
||||||
|
|
||||||
TextParseOptions _documentNameOptions = {
|
TextParseOptions _documentNameOptions = {
|
||||||
TextParseMultiline | TextParseRichText | TextParseLinks | TextParseMarkdown, // flags
|
TextParseMultiline | TextParseRichText | TextParseLinks | TextParseMarkdown, // flags
|
||||||
0, // maxw
|
0, // maxw
|
||||||
|
@ -350,9 +353,9 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Photo::getState(
|
TextState Photo::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
if (hasPoint(point)) {
|
if (hasPoint(point)) {
|
||||||
return { parent(), _link };
|
return { parent(), _link };
|
||||||
}
|
}
|
||||||
|
@ -505,9 +508,9 @@ bool Video::iconAnimated() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Video::getState(
|
TextState Video::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
bool loaded = _data->loaded();
|
bool loaded = _data->loaded();
|
||||||
|
|
||||||
if (hasPoint(point)) {
|
if (hasPoint(point)) {
|
||||||
|
@ -676,9 +679,9 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Voice::getState(
|
TextState Voice::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
const auto loaded = _data->loaded();
|
const auto loaded = _data->loaded();
|
||||||
|
|
||||||
const auto nameleft = _st.songPadding.left()
|
const auto nameleft = _st.songPadding.left()
|
||||||
|
@ -702,7 +705,7 @@ HistoryTextState Voice::getState(
|
||||||
: _openl;
|
: _openl;
|
||||||
return { parent(), link };
|
return { parent(), link };
|
||||||
}
|
}
|
||||||
auto result = HistoryTextState(parent());
|
auto result = TextState(parent());
|
||||||
const auto statusmaxwidth = _width - nameleft - nameright;
|
const auto statusmaxwidth = _width - nameleft - nameright;
|
||||||
const auto statusrect = rtlrect(
|
const auto statusrect = rtlrect(
|
||||||
nameleft,
|
nameleft,
|
||||||
|
@ -714,7 +717,9 @@ HistoryTextState Voice::getState(
|
||||||
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
|
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
|
||||||
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
|
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
|
||||||
result.link = textState.link;
|
result.link = textState.link;
|
||||||
result.cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
result.cursor = textState.uponSymbol
|
||||||
|
? HistoryView::CursorState::Text
|
||||||
|
: HistoryView::CursorState::None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto namewidth = std::min(
|
const auto namewidth = std::min(
|
||||||
|
@ -1000,9 +1005,9 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Document::getState(
|
TextState Document::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
const auto loaded = _data->loaded()
|
const auto loaded = _data->loaded()
|
||||||
|| Local::willStickerImageLoad(_data->mediaKey());
|
|| Local::willStickerImageLoad(_data->mediaKey());
|
||||||
const auto wthumb = withThumb();
|
const auto wthumb = withThumb();
|
||||||
|
@ -1426,9 +1431,9 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
|
||||||
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Link::getState(
|
TextState Link::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
StateRequest request) const {
|
||||||
int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
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)) {
|
if (rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width).contains(point)) {
|
||||||
return { parent(), _photol };
|
return { parent(), _photol };
|
||||||
|
|
|
@ -12,8 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/radial_animation.h"
|
#include "ui/effects/radial_animation.h"
|
||||||
#include "styles/style_overview.h"
|
#include "styles/style_overview.h"
|
||||||
|
|
||||||
struct HistoryTextState;
|
|
||||||
struct HistoryStateRequest;
|
|
||||||
class HistoryMedia;
|
class HistoryMedia;
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
@ -202,9 +200,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int32 resizeGetHeight(int32 width) override;
|
int32 resizeGetHeight(int32 width) override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
not_null<PhotoData*> _data;
|
not_null<PhotoData*> _data;
|
||||||
|
@ -224,9 +222,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int32 resizeGetHeight(int32 width) override;
|
int32 resizeGetHeight(int32 width) override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float64 dataProgress() const override;
|
float64 dataProgress() const override;
|
||||||
|
@ -255,9 +253,9 @@ public:
|
||||||
|
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float64 dataProgress() const override;
|
float64 dataProgress() const override;
|
||||||
|
@ -290,9 +288,9 @@ public:
|
||||||
|
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
virtual DocumentData *getDocument() const override {
|
virtual DocumentData *getDocument() const override {
|
||||||
return _data;
|
return _data;
|
||||||
|
@ -334,9 +332,9 @@ public:
|
||||||
void initDimensions() override;
|
void initDimensions() override;
|
||||||
int32 resizeGetHeight(int32 width) override;
|
int32 resizeGetHeight(int32 width) override;
|
||||||
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
|
||||||
HistoryTextState getState(
|
TextState getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
StateRequest request) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const style::RoundCheckbox &checkboxStyle() const override;
|
const style::RoundCheckbox &checkboxStyle() const override;
|
||||||
|
|
Loading…
Reference in New Issue