Fixed double click selection.

This commit is contained in:
Cranken 2018-10-06 13:43:21 +02:00 committed by pajlada
parent 335b889efe
commit 4c4d1d2042
4 changed files with 131 additions and 12 deletions

View file

@ -76,4 +76,14 @@ struct Selection {
} }
}; };
struct DoubleClickSelection {
int originalStart = 0;
int originalEnd = 0;
int origMessageIndex;
bool selectingLeft = false;
bool selectingRight = false;
SelectionItem origStartItem;
SelectionItem origEndItem;
};
} // namespace chatterino } // namespace chatterino

View file

@ -485,7 +485,7 @@ int MessageLayoutContainer::getSelectionIndex(QPoint point)
} }
// this is the word // this is the word
if (point.x() < this->elements_[i]->getRect().right()) { if (point.x() <= this->elements_[i]->getRect().right()) {
index += this->elements_[i]->getMouseOverIndex(point); index += this->elements_[i]->getMouseOverIndex(point);
break; break;
} }

View file

@ -884,6 +884,94 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
tooltipWidget->hide(); tooltipWidget->hide();
return; return;
} }
if (this->isDoubleClick_) {
int wordStart;
int wordEnd;
this->getWordBounds(layout.get(), hoverLayoutElement, relativePos,
wordStart, wordEnd);
SelectionItem newStart(messageIndex, wordStart);
SelectionItem newEnd(messageIndex, wordEnd);
// Selection changed in same message
if (messageIndex == this->dCSelection_.origMessageIndex) {
// Selecting to the left
if (wordStart < this->selection_.start.charIndex &&
!this->dCSelection_.selectingRight) {
this->dCSelection_.selectingLeft = true;
this->setSelection(newStart, this->selection_.end);
// Selecting to the right
} else if (wordEnd > this->selection_.end.charIndex &&
!this->dCSelection_.selectingLeft) {
this->dCSelection_.selectingRight = true;
this->setSelection(this->selection_.start, newEnd);
}
// Swapping from selecting left to selecting right
if (wordStart > this->selection_.start.charIndex &&
!this->dCSelection_.selectingRight) {
if (wordStart > this->dCSelection_.originalEnd) {
this->dCSelection_.selectingLeft = false;
this->dCSelection_.selectingRight = true;
this->setSelection(this->dCSelection_.origStartItem,
newEnd);
} else {
this->setSelection(newStart, this->selection_.end);
}
// Swapping from selecting right to selecting left
} else if (wordEnd < this->selection_.end.charIndex &&
!this->dCSelection_.selectingLeft) {
if (wordEnd < this->dCSelection_.originalStart) {
this->dCSelection_.selectingLeft = true;
this->dCSelection_.selectingRight = false;
this->setSelection(newStart,
this->dCSelection_.origEndItem);
} else {
this->setSelection(this->selection_.start, newEnd);
}
}
// Selection changed in a different message
} else {
// Message over the original
if (messageIndex < this->selection_.start.messageIndex) {
// Swapping from left to right selecting
if (!this->dCSelection_.selectingLeft) {
this->dCSelection_.selectingLeft = true;
this->dCSelection_.selectingRight = false;
}
if (wordStart < this->selection_.start.charIndex &&
!this->dCSelection_.selectingRight) {
this->dCSelection_.selectingLeft = true;
}
this->setSelection(newStart, this->dCSelection_.origEndItem);
// Message under the original
} else if (messageIndex > this->selection_.end.messageIndex) {
// Swapping from right to left selecting
if (!this->dCSelection_.selectingRight) {
this->dCSelection_.selectingLeft = false;
this->dCSelection_.selectingRight = true;
}
if (wordEnd > this->selection_.end.charIndex &&
!this->dCSelection_.selectingLeft) {
this->dCSelection_.selectingRight = true;
}
this->setSelection(this->dCSelection_.origStartItem, newEnd);
// Selection changed in non original message
} else {
if (this->dCSelection_.selectingLeft) {
this->setSelection(newStart, this->selection_.end);
} else {
this->setSelection(this->selection_.start, newEnd);
}
}
}
// Reset direction of selection
if (wordStart == this->dCSelection_.originalStart &&
wordEnd == this->dCSelection_.originalEnd) {
this->dCSelection_.selectingLeft =
this->dCSelection_.selectingRight = false;
}
}
const auto &tooltip = hoverLayoutElement->getCreator().getTooltip(); const auto &tooltip = hoverLayoutElement->getCreator().getTooltip();
bool isLinkValid = hoverLayoutElement->getLink().isValid(); bool isLinkValid = hoverLayoutElement->getLink().isValid();
@ -970,6 +1058,8 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event)
{ {
// check if mouse was pressed // check if mouse was pressed
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
this->isDoubleClick_ = this->dCSelection_.selectingLeft =
this->dCSelection_.selectingRight = false;
if (this->isMouseDown_) { if (this->isMouseDown_) {
this->isMouseDown_ = false; this->isMouseDown_ = false;
@ -1194,23 +1284,24 @@ void ChannelView::mouseDoubleClickEvent(QMouseEvent *event)
return; return;
} }
if (!this->isMouseDown_) { if (!this->isMouseDown_) {
this->isMouseDown_ = true; this->isDoubleClick_ = true;
const int mouseInWordIndex = int wordStart;
hoverLayoutElement->getMouseOverIndex(relativePos); int wordEnd;
const int wordStart = this->getWordBounds(layout.get(), hoverLayoutElement, relativePos,
layout->getSelectionIndex(relativePos) - mouseInWordIndex; wordStart, wordEnd);
const int selectionLength =
hoverLayoutElement->getSelectionIndexCount();
const int length = hoverLayoutElement->hasTrailingSpace()
? selectionLength - 1
: selectionLength;
const int wordEnd = wordStart + length;
this->clickTimer_->start(); this->clickTimer_->start();
SelectionItem wordMin(messageIndex, wordStart); SelectionItem wordMin(messageIndex, wordStart);
SelectionItem wordMax(messageIndex, wordEnd); SelectionItem wordMax(messageIndex, wordEnd);
this->dCSelection_.originalStart = wordStart;
this->dCSelection_.originalEnd = wordEnd;
this->dCSelection_.origMessageIndex = messageIndex;
this->dCSelection_.origStartItem = wordMin;
this->dCSelection_.origEndItem = wordMax;
this->setSelection(wordMin, wordMax); this->setSelection(wordMin, wordMax);
} }
@ -1316,4 +1407,17 @@ void ChannelView::selectWholeMessage(MessageLayout *layout, int &messageIndex)
this->setSelection(msgStart, msgEnd); this->setSelection(msgStart, msgEnd);
} }
void ChannelView::getWordBounds(MessageLayout *layout,
const MessageLayoutElement *element,
const QPoint &relativePos, int &wordStart,
int &wordEnd)
{
const int mouseInWordIndex = element->getMouseOverIndex(relativePos);
wordStart = layout->getSelectionIndex(relativePos) - mouseInWordIndex;
const int selectionLength = element->getSelectionIndexCount();
const int length =
element->hasTrailingSpace() ? selectionLength - 1 : selectionLength;
wordEnd = wordStart + length;
}
} // namespace chatterino } // namespace chatterino

View file

@ -106,6 +106,9 @@ private:
MessageElementFlags getFlags() const; MessageElementFlags getFlags() const;
bool isPaused(); bool isPaused();
void selectWholeMessage(MessageLayout *layout, int &messageIndex); void selectWholeMessage(MessageLayout *layout, int &messageIndex);
void getWordBounds(MessageLayout *layout,
const MessageLayoutElement *element,
const QPoint &relativePos, int &wordStart, int &wordEnd);
void handleMouseClick(QMouseEvent *event, void handleMouseClick(QMouseEvent *event,
const MessageLayoutElement *hoverLayoutElement, const MessageLayoutElement *hoverLayoutElement,
@ -148,6 +151,8 @@ private:
// Mouse event variables // Mouse event variables
bool isMouseDown_ = false; bool isMouseDown_ = false;
bool isRightMouseDown_ = false; bool isRightMouseDown_ = false;
bool isDoubleClick_ = false;
DoubleClickSelection dCSelection_;
QPointF lastPressPosition_; QPointF lastPressPosition_;
QPointF lastRightPressPosition_; QPointF lastRightPressPosition_;
QTimer *clickTimer_; QTimer *clickTimer_;