Merge pull request #13103 from RomanPudashkin/multiple_clicks_in_text_fields

[MU4] Fix #10242: double and triple-click in text fields do not highlight the word or paragraph
This commit is contained in:
Elnur Ismailzada 2022-09-02 10:19:26 +02:00 committed by GitHub
commit 15c0b1e616
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 32 deletions

View file

@ -523,7 +523,7 @@ bool TextCursor::movePosition(TextCursor::MoveOperation op, TextCursor::MoveMode
// doubleClickSelect
//---------------------------------------------------------
void TextCursor::doubleClickSelect()
void TextCursor::selectWord()
{
clearSelection();
@ -2231,18 +2231,13 @@ void TextBase::selectAll(TextCursor* cursor)
cursor->setColumn(cursor->curLine().columns());
}
//---------------------------------------------------------
// multiClickSelect
// for double and triple clicks
//---------------------------------------------------------
void TextBase::multiClickSelect(EditData& editData, MultiClick clicks)
void TextBase::select(EditData& editData, SelectTextType type)
{
switch (clicks) {
case MultiClick::Double:
cursorFromEditData(editData)->doubleClickSelect();
switch (type) {
case SelectTextType::Word:
cursorFromEditData(editData)->selectWord();
break;
case MultiClick::Triple:
case SelectTextType::All:
selectAll(cursorFromEditData(editData));
break;
}

View file

@ -68,8 +68,8 @@ using FormatValue = std::variant<std::monostate, bool, int, double, String>;
// MultiClick
//---------------------------------------------------------
enum class MultiClick : char {
Double, Triple
enum class SelectTextType : char {
Word, All
};
//---------------------------------------------------------
@ -185,7 +185,7 @@ public:
TextBlock& curLine() const;
mu::RectF cursorRect() const;
bool movePosition(TextCursor::MoveOperation op, TextCursor::MoveMode mode = TextCursor::MoveMode::MoveAnchor, int count = 1);
void doubleClickSelect();
void selectWord();
void moveCursorToEnd() { movePosition(TextCursor::MoveOperation::End); }
void moveCursorToStart() { movePosition(TextCursor::MoveOperation::Start); }
Char currentCharacter() const;
@ -402,7 +402,7 @@ public:
bool deleteSelectedText(EditData&);
void selectAll(TextCursor*);
void multiClickSelect(EditData&, MultiClick);
void select(EditData&, SelectTextType);
bool isPrimed() const { return _primed; }
void setPrimed(bool primed) { _primed = primed; }

View file

@ -132,6 +132,7 @@ public:
virtual void editText(QInputMethodEvent* event) = 0;
virtual void endEditText() = 0;
virtual void changeTextCursorPosition(const PointF& newCursorPos) = 0;
virtual void selectText(mu::engraving::SelectTextType type) = 0;
virtual const TextBase* editedText() const = 0;
virtual async::Notification textEditingStarted() const = 0;
virtual async::Notification textEditingChanged() const = 0;

View file

@ -2675,27 +2675,17 @@ void NotationInteraction::startEditText(EngravingItem* element, const PointF& cu
return;
}
if (isTextEditingStarted()) {
mu::engraving::TextBase* textBase = mu::engraving::toTextBase(m_editData.element);
m_editData.startMove = bindCursorPosToText(cursorPos, textBase);
m_editData.clear();
// double click on a textBase element that is being edited - select word
textBase->multiClickSelect(m_editData, mu::engraving::MultiClick::Double);
textBase->endHexState(m_editData);
textBase->setPrimed(false);
if (element->isTBox()) {
m_editData.element = toTBox(element)->text();
} else {
m_editData.clear();
if (element->isTBox()) {
m_editData.element = toTBox(element)->text();
} else {
m_editData.element = element;
}
m_editData.startMove = bindCursorPosToText(cursorPos, m_editData.element);
m_editData.element->startEdit(m_editData);
m_editData.element = element;
}
m_editData.startMove = bindCursorPosToText(cursorPos, m_editData.element);
m_editData.element->startEdit(m_editData);
notifyAboutTextEditingStarted();
notifyAboutTextEditingChanged();
}
@ -2865,6 +2855,20 @@ void NotationInteraction::changeTextCursorPosition(const PointF& newCursorPos)
notifyAboutTextEditingChanged();
}
void NotationInteraction::selectText(mu::engraving::SelectTextType type)
{
if (!isTextEditingStarted()) {
return;
}
mu::engraving::TextBase* text = mu::engraving::toTextBase(m_editData.element);
text->select(m_editData, type);
text->endHexState(m_editData);
text->setPrimed(false);
notifyAboutTextEditingChanged();
}
const TextBase* NotationInteraction::editedText() const
{
return mu::engraving::toTextBase(m_editData.element);

View file

@ -138,6 +138,7 @@ public:
void editText(QInputMethodEvent* event) override;
void endEditText() override;
void changeTextCursorPosition(const PointF& newCursorPos) override;
void selectText(mu::engraving::SelectTextType type) override;
const TextBase* editedText() const override;
async::Notification textEditingStarted() const override;
async::Notification textEditingChanged() const override;

View file

@ -519,6 +519,13 @@ void NotationViewInputController::mousePressEvent(QMouseEvent* event)
return;
}
if (m_tripleClickPending) {
if (viewInteraction()->isTextEditingStarted()) {
viewInteraction()->selectText(mu::engraving::SelectTextType::All);
return;
}
}
m_beginPoint = logicPos;
EngravingItem* hitElement = nullptr;
@ -800,6 +807,17 @@ void NotationViewInputController::mouseDoubleClickEvent(QMouseEvent* event)
return;
}
QTimer::singleShot(QApplication::doubleClickInterval(), [this]() {
m_tripleClickPending = false;
});
m_tripleClickPending = true;
if (viewInteraction()->isTextEditingStarted()) {
viewInteraction()->selectText(mu::engraving::SelectTextType::Word);
return;
}
PointF logicPos = m_view->toLogical(event->pos());
const EngravingItem* hitElement = viewInteraction()->hitElement(logicPos, hitWidth());

View file

@ -175,6 +175,7 @@ private:
bool m_readonly = false;
bool m_isCanvasDragged = false;
bool m_tripleClickPending = false;
PointF m_beginPoint;