mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-13 09:15:50 +00:00
Improve cursor movement with boundaries
Introduce a new NoEndBoundary flag for insets like InsetNewline. Indroduce Row::start_boundary() that is true when previous Row has end_boundary() set. Use this to improve cursor movement around row boundaries (both for logical ad visible cursor movement). The new code remove some of the newline/separator hardcoding.
This commit is contained in:
parent
33442b17ee
commit
ecac032a94
@ -1288,7 +1288,9 @@ bool Cursor::posVisToNewRow(bool movingLeft)
|
|||||||
// if moving left in an LTR paragraph or moving right in an
|
// if moving left in an LTR paragraph or moving right in an
|
||||||
// RTL one, move to previous row
|
// RTL one, move to previous row
|
||||||
if (par_is_LTR == movingLeft) {
|
if (par_is_LTR == movingLeft) {
|
||||||
if (row.pos() == 0) { // we're at first row in paragraph
|
if (row.start_boundary())
|
||||||
|
boundary(true);
|
||||||
|
else if (row.pos() == 0) { // we're at first row in paragraph
|
||||||
if (pit() == 0) // no previous paragraph! don't move
|
if (pit() == 0) // no previous paragraph! don't move
|
||||||
return false;
|
return false;
|
||||||
// move to last pos in previous par
|
// move to last pos in previous par
|
||||||
|
@ -212,6 +212,10 @@ public:
|
|||||||
///
|
///
|
||||||
pos_type endpos() const { return end_; }
|
pos_type endpos() const { return end_; }
|
||||||
///
|
///
|
||||||
|
void start_boundary(bool b) { start_boundary_ = b; }
|
||||||
|
///
|
||||||
|
bool start_boundary() const { return start_boundary_; }
|
||||||
|
///
|
||||||
void end_boundary(bool b) { end_boundary_ = b; }
|
void end_boundary(bool b) { end_boundary_ = b; }
|
||||||
///
|
///
|
||||||
bool end_boundary() const { return end_boundary_; }
|
bool end_boundary() const { return end_boundary_; }
|
||||||
@ -373,6 +377,8 @@ private:
|
|||||||
pos_type pos_ = 0;
|
pos_type pos_ = 0;
|
||||||
/// one behind last pos covered by this row
|
/// one behind last pos covered by this row
|
||||||
pos_type end_ = 0;
|
pos_type end_ = 0;
|
||||||
|
// Is there a boundary at the start of the row (display inset...)
|
||||||
|
bool start_boundary_ = false;
|
||||||
// Is there a boundary at the end of the row (display inset...)
|
// Is there a boundary at the end of the row (display inset...)
|
||||||
bool end_boundary_ = false;
|
bool end_boundary_ = false;
|
||||||
// Shall the row be flushed when it is supposed to be justified?
|
// Shall the row be flushed when it is supposed to be justified?
|
||||||
|
@ -53,6 +53,8 @@ enum RowFlags {
|
|||||||
// (default is center)
|
// (default is center)
|
||||||
AlignLeft = 1 << 11,
|
AlignLeft = 1 << 11,
|
||||||
AlignRight = 1 << 12,
|
AlignRight = 1 << 12,
|
||||||
|
// Forbid boundary after this element
|
||||||
|
NoEndBoundary = 1 << 13,
|
||||||
// A display element breaks row at both ends
|
// A display element breaks row at both ends
|
||||||
Display = FlushBefore | BreakBefore | BreakAfter,
|
Display = FlushBefore | BreakBefore | BreakAfter,
|
||||||
// Flags that concern breaking after element
|
// Flags that concern breaking after element
|
||||||
|
50
src/Text.cpp
50
src/Text.cpp
@ -3054,29 +3054,16 @@ bool Text::cursorBackward(Cursor & cur)
|
|||||||
// Tell BufferView to test for FitCursor in any case!
|
// Tell BufferView to test for FitCursor in any case!
|
||||||
cur.screenUpdateFlags(Update::FitCursor);
|
cur.screenUpdateFlags(Update::FitCursor);
|
||||||
|
|
||||||
|
// if on right side of a row boundary (at row start), skip it,
|
||||||
|
// i.e. set boundary to true, i.e. go only logically left
|
||||||
|
if (!cur.boundary()
|
||||||
|
&& cur.textRow().pos() == cur.pos()
|
||||||
|
&& cur.textRow().start_boundary()) {
|
||||||
|
return setCursor(cur, cur.pit(), cur.pos(), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
// not at paragraph start?
|
// not at paragraph start?
|
||||||
if (cur.pos() > 0) {
|
if (cur.pos() > 0) {
|
||||||
// if on right side of boundary (i.e. not at paragraph end, but line end)
|
|
||||||
// -> skip it, i.e. set boundary to true, i.e. go only logically left
|
|
||||||
// there are some exceptions to ignore this: lineseps, newlines, spaces
|
|
||||||
#if 0
|
|
||||||
// some effectless debug code to see the values in the debugger
|
|
||||||
bool bound = cur.boundary();
|
|
||||||
int rowpos = cur.textRow().pos();
|
|
||||||
int pos = cur.pos();
|
|
||||||
bool sep = cur.paragraph().isSeparator(cur.pos() - 1);
|
|
||||||
bool newline = cur.paragraph().isNewline(cur.pos() - 1);
|
|
||||||
bool linesep = cur.paragraph().isLineSeparator(cur.pos() - 1);
|
|
||||||
#endif
|
|
||||||
if (!cur.boundary() &&
|
|
||||||
cur.textRow().pos() == cur.pos() &&
|
|
||||||
!cur.paragraph().isLineSeparator(cur.pos() - 1) &&
|
|
||||||
!cur.paragraph().isNewline(cur.pos() - 1) &&
|
|
||||||
!cur.paragraph().isEnvSeparator(cur.pos() - 1) &&
|
|
||||||
!cur.paragraph().isSeparator(cur.pos() - 1)) {
|
|
||||||
return setCursor(cur, cur.pit(), cur.pos(), true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// go left and try to enter inset
|
// go left and try to enter inset
|
||||||
if (checkAndActivateInset(cur, false))
|
if (checkAndActivateInset(cur, false))
|
||||||
return false;
|
return false;
|
||||||
@ -3143,33 +3130,14 @@ bool Text::cursorForward(Cursor & cur)
|
|||||||
|
|
||||||
// next position is left of boundary,
|
// next position is left of boundary,
|
||||||
// but go to next line for special cases like space, newline, linesep
|
// but go to next line for special cases like space, newline, linesep
|
||||||
#if 0
|
|
||||||
// some effectless debug code to see the values in the debugger
|
|
||||||
int endpos = cur.textRow().endpos();
|
|
||||||
int lastpos = cur.lastpos();
|
|
||||||
int pos = cur.pos();
|
|
||||||
bool linesep = cur.paragraph().isLineSeparator(cur.pos());
|
|
||||||
bool newline = cur.paragraph().isNewline(cur.pos());
|
|
||||||
bool sep = cur.paragraph().isSeparator(cur.pos());
|
|
||||||
if (cur.pos() != cur.lastpos()) {
|
|
||||||
bool linesep2 = cur.paragraph().isLineSeparator(cur.pos()+1);
|
|
||||||
bool newline2 = cur.paragraph().isNewline(cur.pos()+1);
|
|
||||||
bool sep2 = cur.paragraph().isSeparator(cur.pos()+1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (cur.textRow().endpos() == cur.pos() + 1) {
|
if (cur.textRow().endpos() == cur.pos() + 1) {
|
||||||
if (cur.paragraph().isEnvSeparator(cur.pos()) &&
|
if (cur.paragraph().isEnvSeparator(cur.pos()) &&
|
||||||
cur.pos() + 1 == cur.lastpos() &&
|
cur.pos() + 1 == cur.lastpos() &&
|
||||||
cur.pit() != cur.lastpit()) {
|
cur.pit() != cur.lastpit()) {
|
||||||
// move to next paragraph
|
// move to next paragraph
|
||||||
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
||||||
} else if (cur.textRow().endpos() != cur.lastpos() &&
|
} else if (cur.textRow().end_boundary())
|
||||||
!cur.paragraph().isNewline(cur.pos()) &&
|
|
||||||
!cur.paragraph().isEnvSeparator(cur.pos()) &&
|
|
||||||
!cur.paragraph().isLineSeparator(cur.pos()) &&
|
|
||||||
!cur.paragraph().isSeparator(cur.pos())) {
|
|
||||||
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
|
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// in front of RTL boundary? Stay on this side of the boundary because:
|
// in front of RTL boundary? Stay on this side of the boundary because:
|
||||||
|
@ -1147,7 +1147,9 @@ void cleanupRow(Row & row, bool at_end)
|
|||||||
if (!at_end && !row.flushed())
|
if (!at_end && !row.flushed())
|
||||||
row.back().rtrim();
|
row.back().rtrim();
|
||||||
// boundary exists when there was no space at the end of row
|
// boundary exists when there was no space at the end of row
|
||||||
row.end_boundary(!at_end && row.back().endpos == row.endpos());
|
row.end_boundary(!at_end
|
||||||
|
&& row.back().endpos == row.endpos()
|
||||||
|
&& !(row.back().row_flags & NoEndBoundary));
|
||||||
// make sure that the RTL elements are in reverse ordering
|
// make sure that the RTL elements are in reverse ordering
|
||||||
row.reverseRTL();
|
row.reverseRTL();
|
||||||
}
|
}
|
||||||
@ -1250,6 +1252,13 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
|||||||
rows.back().needsChangeBar(true);
|
rows.back().needsChangeBar(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set start_boundary to be equal to the previous row's end boundary
|
||||||
|
bool sb = false;
|
||||||
|
for (auto & row : rows) {
|
||||||
|
row.start_boundary(sb);
|
||||||
|
sb = row.end_boundary();
|
||||||
|
}
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,9 +44,9 @@ InsetNewline::InsetNewline() : Inset(nullptr)
|
|||||||
int InsetNewline::rowFlags() const
|
int InsetNewline::rowFlags() const
|
||||||
{
|
{
|
||||||
if (params_.kind == InsetNewlineParams::LINEBREAK)
|
if (params_.kind == InsetNewlineParams::LINEBREAK)
|
||||||
return AlwaysBreakAfter;
|
return AlwaysBreakAfter | NoEndBoundary;
|
||||||
else
|
else
|
||||||
return AlwaysBreakAfter | Flush;
|
return AlwaysBreakAfter | NoEndBoundary | Flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
return docstring();
|
return docstring();
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
int rowFlags() const override { return BreakAfter | Flush; }
|
int rowFlags() const override { return BreakAfter | Flush | NoEndBoundary; }
|
||||||
///
|
///
|
||||||
bool nextnoindent() const { return params_.kind == InsetSeparatorParams::PLAIN; }
|
bool nextnoindent() const { return params_.kind == InsetSeparatorParams::PLAIN; }
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user