forked from blue/squawk
first successfull attempt to visualize selection on message body
This commit is contained in:
parent
c3a45ec58c
commit
0340db7f2f
@ -52,7 +52,10 @@ FeedView::FeedView(QWidget* parent):
|
|||||||
dividerFont(),
|
dividerFont(),
|
||||||
dividerMetrics(dividerFont),
|
dividerMetrics(dividerFont),
|
||||||
mousePressed(false),
|
mousePressed(false),
|
||||||
anchorHovered(false)
|
dragging(false),
|
||||||
|
anchorHovered(false),
|
||||||
|
dragStartPoint(),
|
||||||
|
dragEndPoint()
|
||||||
{
|
{
|
||||||
horizontalScrollBar()->setRange(0, 0);
|
horizontalScrollBar()->setRange(0, 0);
|
||||||
verticalScrollBar()->setSingleStep(approximateSingleMessageHeight);
|
verticalScrollBar()->setSingleStep(approximateSingleMessageHeight);
|
||||||
@ -304,7 +307,7 @@ bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewIt
|
|||||||
|
|
||||||
void FeedView::paintEvent(QPaintEvent* event)
|
void FeedView::paintEvent(QPaintEvent* event)
|
||||||
{
|
{
|
||||||
//qDebug() << "paint" << event->rect();
|
qDebug() << "paint" << event->rect();
|
||||||
const QAbstractItemModel* m = model();
|
const QAbstractItemModel* m = model();
|
||||||
QWidget* vp = viewport();
|
QWidget* vp = viewport();
|
||||||
QRect zone = event->rect().translated(0, -vo);
|
QRect zone = event->rect().translated(0, -vo);
|
||||||
@ -427,19 +430,31 @@ void FeedView::mouseMoveEvent(QMouseEvent* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mousePressed = false;
|
dragEndPoint = event->localPos().toPoint();
|
||||||
//qDebug() << event;
|
if (mousePressed) {
|
||||||
|
QPoint distance = dragStartPoint - dragEndPoint;
|
||||||
|
if (distance.manhattanLength() > 5) {
|
||||||
|
dragging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QAbstractItemView::mouseMoveEvent(event);
|
QAbstractItemView::mouseMoveEvent(event);
|
||||||
|
|
||||||
if (specialDelegate) {
|
if (specialDelegate) {
|
||||||
QPoint point = event->localPos().toPoint();
|
QModelIndex index = indexAt(dragEndPoint);
|
||||||
QModelIndex index = indexAt(point);
|
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
QRect rect = visualRect(index);
|
QRect rect = visualRect(index);
|
||||||
MessageDelegate* del = static_cast<MessageDelegate*>(itemDelegate());
|
if (rect.contains(dragEndPoint)) {
|
||||||
if (rect.contains(point)) {
|
MessageDelegate* del = static_cast<MessageDelegate*>(itemDelegate());
|
||||||
setAnchorHovered(del->isAnchorHovered(point, index, rect));
|
if (dragging) {
|
||||||
|
setAnchorHovered(false);
|
||||||
|
if (del->mouseDrag(dragStartPoint, dragEndPoint, index, rect)) {
|
||||||
|
qDebug() << "asking to repaint" << rect;
|
||||||
|
setDirtyRegion(rect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAnchorHovered(del->isAnchorHovered(dragEndPoint, index, rect));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setAnchorHovered(false);
|
setAnchorHovered(false);
|
||||||
}
|
}
|
||||||
@ -453,22 +468,29 @@ void FeedView::mousePressEvent(QMouseEvent* event)
|
|||||||
{
|
{
|
||||||
QAbstractItemView::mousePressEvent(event);
|
QAbstractItemView::mousePressEvent(event);
|
||||||
mousePressed = event->button() == Qt::LeftButton;
|
mousePressed = event->button() == Qt::LeftButton;
|
||||||
|
if (mousePressed) {
|
||||||
|
dragStartPoint = event->localPos().toPoint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedView::mouseReleaseEvent(QMouseEvent* event)
|
void FeedView::mouseReleaseEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
QAbstractItemView::mouseReleaseEvent(event);
|
QAbstractItemView::mouseReleaseEvent(event);
|
||||||
|
|
||||||
if (mousePressed && specialDelegate) {
|
if (mousePressed) {
|
||||||
QPoint point = event->localPos().toPoint();
|
if (!dragging && specialDelegate) {
|
||||||
QModelIndex index = indexAt(point);
|
QPoint point = event->localPos().toPoint();
|
||||||
if (index.isValid()) {
|
QModelIndex index = indexAt(point);
|
||||||
QRect rect = visualRect(index);
|
if (index.isValid()) {
|
||||||
MessageDelegate* del = static_cast<MessageDelegate*>(itemDelegate());
|
QRect rect = visualRect(index);
|
||||||
if (rect.contains(point)) {
|
MessageDelegate* del = static_cast<MessageDelegate*>(itemDelegate());
|
||||||
del->leftClick(point, index, rect);
|
if (rect.contains(point)) {
|
||||||
|
del->leftClick(point, index, rect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dragging = false;
|
||||||
|
mousePressed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,10 @@ private:
|
|||||||
QFont dividerFont;
|
QFont dividerFont;
|
||||||
QFontMetrics dividerMetrics;
|
QFontMetrics dividerMetrics;
|
||||||
bool mousePressed;
|
bool mousePressed;
|
||||||
|
bool dragging;
|
||||||
bool anchorHovered;
|
bool anchorHovered;
|
||||||
|
QPoint dragStartPoint;
|
||||||
|
QPoint dragEndPoint;
|
||||||
|
|
||||||
static const std::set<int> geometryChangingRoles;
|
static const std::set<int> geometryChangingRoles;
|
||||||
|
|
||||||
|
@ -56,7 +56,9 @@ MessageDelegate::MessageDelegate(QObject* parent):
|
|||||||
pencilIcons(new std::map<QString, QLabel*>()),
|
pencilIcons(new std::map<QString, QLabel*>()),
|
||||||
previews(new std::map<QString, Preview*>()),
|
previews(new std::map<QString, Preview*>()),
|
||||||
idsToKeep(new std::set<QString>()),
|
idsToKeep(new std::set<QString>()),
|
||||||
clearingWidgets(false)
|
clearingWidgets(false),
|
||||||
|
currentId(""),
|
||||||
|
selection(0, 0)
|
||||||
{
|
{
|
||||||
bodyRenderer->setDocumentMargin(0);
|
bodyRenderer->setDocumentMargin(0);
|
||||||
|
|
||||||
@ -438,6 +440,37 @@ bool MessageDelegate::isAnchorHovered(const QPoint& point, const QModelIndex& in
|
|||||||
return anchor.size() > 0;
|
return anchor.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MessageDelegate::mouseDrag(const QPoint& start, const QPoint& end, const QModelIndex& index, const QRect& sizeHint)
|
||||||
|
{
|
||||||
|
QVariant vi = index.data(Models::MessageFeed::Bulk);
|
||||||
|
Models::FeedItem data = qvariant_cast<Models::FeedItem>(vi);
|
||||||
|
if (data.text.size() > 0) {
|
||||||
|
QRect localHint = getHoveredMessageBodyRect(index, data, sizeHint);
|
||||||
|
|
||||||
|
if (localHint.contains(start)) {
|
||||||
|
QPoint translated = start - localHint.topLeft();
|
||||||
|
|
||||||
|
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
|
||||||
|
bodyRenderer->setTextWidth(localHint.size().width());
|
||||||
|
selection.first = bodyRenderer->documentLayout()->hitTest(translated, Qt::HitTestAccuracy::FuzzyHit);
|
||||||
|
selection.second = bodyRenderer->documentLayout()->hitTest(end - localHint.topLeft(), Qt::HitTestAccuracy::FuzzyHit);
|
||||||
|
|
||||||
|
currentId = data.id;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MessageDelegate::clearSelection()
|
||||||
|
{
|
||||||
|
QString lastSelectedId = currentId;
|
||||||
|
currentId = "";
|
||||||
|
selection = std::pair(0, 0);
|
||||||
|
return lastSelectedId;
|
||||||
|
}
|
||||||
|
|
||||||
void MessageDelegate::initializeFonts(const QFont& font)
|
void MessageDelegate::initializeFonts(const QFont& font)
|
||||||
{
|
{
|
||||||
bodyFont = font;
|
bodyFont = font;
|
||||||
@ -664,32 +697,21 @@ int MessageDelegate::paintBody(const Models::FeedItem& data, QPainter* painter,
|
|||||||
if (data.text.size() > 0) {
|
if (data.text.size() > 0) {
|
||||||
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
|
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
|
||||||
bodyRenderer->setTextWidth(option.rect.size().width());
|
bodyRenderer->setTextWidth(option.rect.size().width());
|
||||||
painter->setBackgroundMode(Qt::BGMode::OpaqueMode);
|
|
||||||
painter->save();
|
painter->save();
|
||||||
// QTextCursor cursor(bodyRenderer);
|
|
||||||
// cursor.setPosition(2, QTextCursor::KeepAnchor);
|
|
||||||
painter->translate(option.rect.topLeft());
|
painter->translate(option.rect.topLeft());
|
||||||
// QTextFrameFormat format = bodyRenderer->rootFrame()->frameFormat();
|
|
||||||
// format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
|
if (data.id == currentId) {
|
||||||
// bodyRenderer->rootFrame()->setFrameFormat(format);
|
QTextCursor cursor(bodyRenderer);
|
||||||
|
cursor.setPosition(selection.first, QTextCursor::MoveAnchor);
|
||||||
|
cursor.setPosition(selection.second, QTextCursor::KeepAnchor);
|
||||||
|
QTextCharFormat format = cursor.charFormat();
|
||||||
|
format.setBackground(option.palette.color(QPalette::Active, QPalette::Highlight));
|
||||||
|
format.setForeground(option.palette.color(QPalette::Active, QPalette::HighlightedText));
|
||||||
|
cursor.setCharFormat(format);
|
||||||
|
}
|
||||||
|
|
||||||
bodyRenderer->drawContents(painter);
|
bodyRenderer->drawContents(painter);
|
||||||
// QColor c = option.palette.color(QPalette::Active, QPalette::Highlight);
|
|
||||||
// QTextBlock b = bodyRenderer->begin();
|
|
||||||
// QTextBlockFormat format = b.blockFormat();
|
|
||||||
// format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
|
|
||||||
// format.setProperty(QTextFormat::BackgroundBrush, option.palette.brush(QPalette::Active, QPalette::Highlight));
|
|
||||||
// QTextCursor cursor(bodyRenderer);
|
|
||||||
// cursor.setBlockFormat(format);
|
|
||||||
// b = bodyRenderer->begin();
|
|
||||||
// while (b.isValid() > 0) {
|
|
||||||
// QTextLayout* lay = b.layout();
|
|
||||||
// QTextLayout::FormatRange range;
|
|
||||||
// range.format = b.charFormat();
|
|
||||||
// range.start = 0;
|
|
||||||
// range.length = 2;
|
|
||||||
// lay->draw(painter, option.rect.topLeft(), {range});
|
|
||||||
// b = b.next();
|
|
||||||
// }
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
QSize bodySize(std::ceil(bodyRenderer->idealWidth()), std::ceil(bodyRenderer->size().height()));
|
QSize bodySize(std::ceil(bodyRenderer->idealWidth()), std::ceil(bodyRenderer->size().height()));
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ public:
|
|||||||
void beginClearWidgets();
|
void beginClearWidgets();
|
||||||
void leftClick(const QPoint& point, const QModelIndex& index, const QRect& sizeHint) const;
|
void leftClick(const QPoint& point, const QModelIndex& index, const QRect& sizeHint) const;
|
||||||
bool isAnchorHovered(const QPoint& point, const QModelIndex& index, const QRect& sizeHint) const;
|
bool isAnchorHovered(const QPoint& point, const QModelIndex& index, const QRect& sizeHint) const;
|
||||||
|
bool mouseDrag(const QPoint& start, const QPoint& end, const QModelIndex& index, const QRect& sizeHint);
|
||||||
|
QString clearSelection();
|
||||||
|
|
||||||
static int avatarHeight;
|
static int avatarHeight;
|
||||||
static int margin;
|
static int margin;
|
||||||
@ -116,7 +118,8 @@ private:
|
|||||||
std::map<QString, Preview*>* previews;
|
std::map<QString, Preview*>* previews;
|
||||||
std::set<QString>* idsToKeep;
|
std::set<QString>* idsToKeep;
|
||||||
bool clearingWidgets;
|
bool clearingWidgets;
|
||||||
|
QString currentId;
|
||||||
|
std::pair<int, int> selection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESSAGEDELEGATE_H
|
#endif // MESSAGEDELEGATE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user