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
|
||||
// RTL one, move to previous row
|
||||
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
|
||||
return false;
|
||||
// move to last pos in previous par
|
||||
|
@ -212,6 +212,10 @@ public:
|
||||
///
|
||||
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; }
|
||||
///
|
||||
bool end_boundary() const { return end_boundary_; }
|
||||
@ -373,6 +377,8 @@ private:
|
||||
pos_type pos_ = 0;
|
||||
/// one behind last pos covered by this row
|
||||
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...)
|
||||
bool end_boundary_ = false;
|
||||
// Shall the row be flushed when it is supposed to be justified?
|
||||
|
@ -53,6 +53,8 @@ enum RowFlags {
|
||||
// (default is center)
|
||||
AlignLeft = 1 << 11,
|
||||
AlignRight = 1 << 12,
|
||||
// Forbid boundary after this element
|
||||
NoEndBoundary = 1 << 13,
|
||||
// A display element breaks row at both ends
|
||||
Display = FlushBefore | BreakBefore | BreakAfter,
|
||||
// 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!
|
||||
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?
|
||||
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
|
||||
if (checkAndActivateInset(cur, false))
|
||||
return false;
|
||||
@ -3143,33 +3130,14 @@ bool Text::cursorForward(Cursor & cur)
|
||||
|
||||
// next position is left of boundary,
|
||||
// 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.paragraph().isEnvSeparator(cur.pos()) &&
|
||||
cur.pos() + 1 == cur.lastpos() &&
|
||||
cur.pit() != cur.lastpit()) {
|
||||
// move to next paragraph
|
||||
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
||||
} else if (cur.textRow().endpos() != cur.lastpos() &&
|
||||
!cur.paragraph().isNewline(cur.pos()) &&
|
||||
!cur.paragraph().isEnvSeparator(cur.pos()) &&
|
||||
!cur.paragraph().isLineSeparator(cur.pos()) &&
|
||||
!cur.paragraph().isSeparator(cur.pos())) {
|
||||
} else if (cur.textRow().end_boundary())
|
||||
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// 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())
|
||||
row.back().rtrim();
|
||||
// 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
|
||||
row.reverseRTL();
|
||||
}
|
||||
@ -1250,6 +1252,13 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -44,9 +44,9 @@ InsetNewline::InsetNewline() : Inset(nullptr)
|
||||
int InsetNewline::rowFlags() const
|
||||
{
|
||||
if (params_.kind == InsetNewlineParams::LINEBREAK)
|
||||
return AlwaysBreakAfter;
|
||||
return AlwaysBreakAfter | NoEndBoundary;
|
||||
else
|
||||
return AlwaysBreakAfter | Flush;
|
||||
return AlwaysBreakAfter | NoEndBoundary | Flush;
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
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; }
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user