When viewing a deeply nested path, there may be very little of the
PathBreadcrumbbar itself visible to double-click on. This solves that
by allowing double-clicks on its segment buttons to behave the same.
(With the caveat that it first selects the double-clicked segment.)
In order to make this work, `on_double_click` now takes the modifiers
instead of the MouseEvent. In this case we don't use it so that's fine,
but maybe we should make all mouse callbacks consistently take the
MouseEvent& as a parameter.
This Widget wraps both a Breadcrumbbar and a TextBox for editing the
path manually, based heavily on the existing code in FileManager.
Breadcrumbbar itself requires outside code to micro-manage what it does.
This class provides a simpler interface for it: Users don't have to
worry about segments, they just give/receive a string for the current
path.
This just calls Layout::try_add_spacer(), but saves you having to access
the Widget's Layout directly.
We verify that the Widget has a Layout, since it would be a programming
error if we tried to do so without one.
Currently, if you use the left/right arrow keys to move over a multi-
code point glyph, we will move through that glyph one code point at a
time. This means you can "pause" your movement in the middle of a glyph
and delete a subsection of a grapheme cluster. This now moves the cursor
across the entire cluster.
Visually, we will need to separately track physical and virtual cursor
positions. That is, when you move across a multi-code point glyph, the
visual cursor should only move one position at a time, while a physical
cursor stores the "real" position in terms of number of code points.
This also converts a couple of ints to auto - these are actually size_t,
and are being passed to functions that expect size_t, so let's not cast
them to ints.
Updated TextDocument and TextEditor to use calls to
`find_grapheme_segmentation_boundary` in order to make "correct-feeling"
deletions on backspace and delete keys being pressed
Note that for traversing words with ctrl+(left or right arrow) on the
keyboard, we want to "skip" some boundaries. Consider the text:
The ("quick") fox can't jump 32.3 feet, right?
Using "|" to denote word break boundaries, we will have:
|The| |(|"|quick|"|)| |fox| |can't| |jump| |32.3| |feet|,| |right|?|
When starting at "The" and using ctrl+right to move rightward in this
text, it is unlikely that users will want to break at every single one
of those boundaries. Most text editors, for example, will skip from the
end of "The" to the end of "quick", not breaking at the parentheses or
opening quotation marks.
We try to mimic such desired behavior here. It likely isn't perfect, but
we can improve upon it as we find edge cases.
The `is_wrapping_enabled()` paths function just fine when wrapping is
disabled. We already calculate `m_line_visual_data`. The only reason to
use a special path is for speed, since you can skip some steps if you
know each line is only 1 line high visually.
However, with code-folding being added, we can't make assumptions about
line height because a line could be hidden and have an effective height
of 0px. So `text_position_at_content_position()` always needs to loop
through the lines to see what our position is, and that function always
needs to be called to calculate the real position.
This change also adds non-deprecated text() and set_text() functions and
helper constructors for Button, CheckBox, and RadioButton to call the
strings directly.
The whole codebase at this point is still using the deprecated string
functions, which the class will quietly convert to a new String.
`write_to_file(StringView path)` was based on the `Core::File` overload.
The return type also changed from `bool` to `ErrorOr<void>` to ease
error propagation.
Add a fast path to Variant::to_deprecated_string() to return a copy
if the underlying data is of type DeprecatedString. This improves the
performance of models with a lot of string data.
We essentially just end up moving `release_value_but_fixme_...` one
layer down, but it makes adding more fallible operations in the
serialization function more comfortable.