commit 50f54cf30aaa07dd391ee154073fbdeec1d6f7b8
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Tue Jul 22 21:04:00 2025 +0200
Make Update::SinglePar work in a breakable inset.
It does not make sense to apply this flag to the broken inset, since
it lives inside another one. Therefore, the optimization should be
applied to the host paragraph.
The difficulty here is that we need an equivalent of
DocIterator::innerTextSlice() that also checks whether the inset is
breakable. It appears that isBreakable requires a BufferView const &
argument[*], so that one would have to add a dependency on BufferView
in DocIterator, whih is not a good idea.
The solution is a innerSlice() method that takes as parameter a
predicate in the form of a lambda function, and have this lambda
function capture the BufferView object.
[*] only because a collapsible inset can be auto-opened when
searching, so that it will be open in some views and closed in
others.
What works:
* the contents drawing
* insets breaking
* nesting in other insets (e.g. Note)
* SinglePar optimization inside a breakable inset
* text justification across normal text and broken insets
* setting cursor using mouse
What sort of works:
* very basic decoration
* navigation with cursor left/right (mostly, see below)
What does not work:
* Right-to-Left rows drawing
* selection support
* entering an inset by the right with cursor left
* up/down navigation
---
src/BufferView.cpp | 12 ++++++------
src/DocIterator.cpp | 18 ++++++++++++++++++
src/DocIterator.h | 5 ++++-
3 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 00ff2502ce..f86b599295 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3288,12 +3288,12 @@ Cursor const & BufferView::cursor() const
bool BufferView::singleParUpdate()
{
// Find the first paragraph that is not in a breakable inset.
- CursorSlice const & its = d->cursor_.innerTextSlice();
- // FIXME : make SinglePar update work for breakable insets.
- if (its.inset().isBreakable(*this)) {
- LYXERR(Debug::PAINTING, "SinglePar optimization failed:
breakable inset.");
- return false;
- }
+ auto not_breakable_insettext =
+ [this] (CursorSlice const & sl) -> bool
+ { return sl.text() && !sl.inset().isBreakable(*this); };
+ CursorSlice const & its =
d->cursor_.innerSlice(not_breakable_insettext);
+ LASSERT(not_breakable_insettext(its), return false);
+
pit_type const pit = its.pit();
TextMetrics & tm = textMetrics(its.text());
Dimension const old_dim = tm.parMetrics(pit).dim();
diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp
index 7d18c36547..ed15ab0abb 100644
--- a/src/DocIterator.cpp
+++ b/src/DocIterator.cpp
@@ -222,6 +222,24 @@ CursorSlice const & DocIterator::innerTextSlice() const
}
+CursorSlice const & DocIterator::innerSlice(function<bool(CursorSlice const
&)> func) const
+{
+ LBUFERR(!empty());
+ // go up until first non-0 text is hit
+ // (innermost text is 0 in mathed)
+ for (int i = depth() - 1; i >= 0; --i)
+ if (func(slices_[i]))
+ return slices_[i];
+
+ // This case is in principle not possible. We _must_
+ // be inside a Text.
+ LBUFERR(false);
+ // Squash warning
+ static const CursorSlice c;
+ return c;
+}
+
+
docstring DocIterator::paragraphGotoArgument(bool const nopos) const
{
CursorSlice const & s = innerTextSlice();
diff --git a/src/DocIterator.h b/src/DocIterator.h
index f46d57598f..60ef23e962 100644
--- a/src/DocIterator.h
+++ b/src/DocIterator.h
@@ -14,8 +14,9 @@
#include "CursorSlice.h"
-#include <vector>
#include <algorithm> // std::min in MSVC 2017
+#include <functional> // std::function
+#include <vector>
namespace lyx {
@@ -171,6 +172,8 @@ public:
Paragraph & innerParagraph() const;
/// return the inner text slice.
CursorSlice const & innerTextSlice() const;
+ /// return the inner slice that satisfies func(CursorSlice);
+ CursorSlice const & innerSlice(std::function<bool(CursorSlice const &)>
func) const;
/// convert a DocIterator into an argument to LFUN_PARAGRAPH_GOTO
/// \p nopos determines whether the cursor position is returned
docstring paragraphGotoArgument(bool const nopos = false) const;
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs