From eb4a2a190f2640d2a6ab7146cfcc347e70b57044 Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Sat, 18 Feb 2017 23:03:53 +0100 Subject: [PATCH] When selecting text with the mouse, inset selection happens in the middle --- src/Row.cpp | 9 +++++---- src/Row.h | 7 ++++--- src/Text3.cpp | 2 +- src/TextMetrics.cpp | 9 +++++---- src/TextMetrics.h | 8 ++++++-- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Row.cpp b/src/Row.cpp index 70e3dcafc3..cc78cff339 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -95,7 +95,7 @@ double Row::Element::pos2x(pos_type const i) const } -pos_type Row::Element::x2pos(int &x) const +pos_type Row::Element::x2pos(int &x, bool const select) const { //lyxerr << "x2pos: x=" << x << " w=" << width() << " " << *this; size_t i = 0; @@ -112,17 +112,18 @@ pos_type Row::Element::x2pos(int &x) const x = isRTL() ? int(full_width()) : 0; break; case INSET: - case SPACE: + case SPACE: { + int const boundary = select ? (full_width() + 1) / 2 : full_width(); // those elements contain only one position. Round to // the closest side. - if (x > full_width()) { + if (x > boundary) { x = int(full_width()); i = !isRTL(); } else { x = 0; i = isRTL(); } - + } } //lyxerr << "=> p=" << pos + i << " x=" << x << endl; return pos + i; diff --git a/src/Row.h b/src/Row.h index 498fd07d7f..c840698f1c 100644 --- a/src/Row.h +++ b/src/Row.h @@ -80,12 +80,13 @@ public: /** Return position in pixels (from the left) of position * \param i in the row element. */ - double pos2x(pos_type const i) const; + double pos2x(pos_type i) const; /** Return character position that is the closest to * pixel position \param x. The value \param x is * adjusted to the actual pixel position. - */ - pos_type x2pos(int &x) const; + * \param select if true, return the right edge when closer. + */ + pos_type x2pos(int & x, bool select = false) const; /** Break the element if possible, so that its width is less * than \param w. Returns true on success. When \param force * is true, the string is cut at any place, other wise it diff --git a/src/Text3.cpp b/src/Text3.cpp index cb5f0b5760..43c68ca23f 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -1690,7 +1690,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) int const wh = bv->workHeight(); int const y = max(0, min(wh - 1, cmd.y())); - tm->setCursorFromCoordinates(cur, cmd.x(), y); + tm->setCursorFromCoordinates(cur, cmd.x(), y, true); cur.setTargetX(cmd.x()); // Don't allow selecting a separator inset if (cur.pos() && cur.paragraph().isEnvSeparator(cur.pos() - 1)) diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index a93f9ba4cd..87a381eed0 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1094,7 +1094,7 @@ void TextMetrics::setRowHeight(Row & row) const // returns the column near the specified x-coordinate of the row // x is set to the real beginning of this column pos_type TextMetrics::getPosNearX(Row const & row, int & x, - bool & boundary) const + bool & boundary, bool const select) const { //LYXERR0("getPosNearX(" << x << ") row=" << row); /// For the main Text, it is possible that this pit is not @@ -1124,7 +1124,7 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x, for ( ; cit != cend; ++cit) { if (w <= x && w + cit->full_width() > x) { int x_offset = int(x - w); - pos = cit->x2pos(x_offset); + pos = cit->x2pos(x_offset, select); x = int(x_offset + w); break; } @@ -1382,7 +1382,8 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y, } -void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, int const y) +void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, + int const y, bool const select) { LASSERT(text_ == cur.text(), return); pit_type const pit = getPitNearY(y); @@ -1409,7 +1410,7 @@ void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, int const bool bound = false; int xx = x; - pos_type const pos = getPosNearX(row, xx, bound); + pos_type const pos = getPosNearX(row, xx, bound, select); LYXERR(Debug::DEBUG, "setting cursor pit: " << pit << " pos: " << pos); diff --git a/src/TextMetrics.h b/src/TextMetrics.h index 2f6181d0b0..ade98739ed 100644 --- a/src/TextMetrics.h +++ b/src/TextMetrics.h @@ -150,7 +150,8 @@ public: /// returns the position near the specified x-coordinate of the row. /// x is an absolute screen coord, it is set to the real beginning /// of this column. This takes in account horizontal cursor row scrolling. - pos_type getPosNearX(Row const & row, int & x, bool & boundary) const; + pos_type getPosNearX(Row const & row, int & x, bool & boundary, + bool select = false) const; /// returns pos in given par at given x coord. pos_type x2pos(pit_type pit, int row, int x) const; @@ -188,7 +189,10 @@ public: /// sets cursor only within this Text. /// x,y are screen coordinates - void setCursorFromCoordinates(Cursor & cur, int x, int y); + /// If select is true, move to the next position if closer to the right + /// edge. + void setCursorFromCoordinates(Cursor & cur, int x, int y, + bool select = false); /// int cursorX(CursorSlice const & cursor, bool boundary) const;