This class had slightly confusing semantics and the added weirdness
doesn't seem worth it just so we can say "." instead of "->" when
iterating over a vector of NNRPs.
This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
This also removes DirIterator::error_string(), since the same strerror()
string will be included when you print the Error itself. Except in `ls`
which is still using fprintf() for now.
This widget originally used text, but at the time we did not support
painting multi-code point emoji as text at all. So it was changed to
paint emoji with their bitmaps in commit 8190120f95.
Now that we can paint text with multi-code point emoji, revert this
widget to use text again. This has the added benefit that the dialog has
a what-you-see-is-what-you-get effect; any emoji with text presentation
in the font (e.g. U+00A9 Copyright) will be displayed as such in the
dialog, which is how the text would be painted when selected anyways.
Note that to accommodate some emoji sizes, this also had to bump the
button sizes a bit, otherwise they would be displayed with an ellipsis.
The EmojiInputDialog, for example, will want its toolbar buttons to have
a tooltip which differs from its text. If no tooltip override has been
provided, we fall back to the button text still.
For vector fonts in particular, we need to take care to compute offsets
using floating point math. For example, with Berkeley Mono at font size
16, with syntax highlighting enabled, we are currently truncating these
offsets to integers. This results in a leftward-drift when we paint the
text.
This changes the rect in which we paint syntax-highlighted text spans to
a float rect. As we traverse the spans, we now no longer truncate any of
the text offsets, and we draw the text in the correct positions.
This is likely not a complete solution. TextEditor blindly casts ints to
floats all over, and we will want to make all of these (hundred+) float-
aware. But this should be a step in the right direction and makes vector
fonts immediately more comfortable to use.
This feature allows any application to easily install an automatically
updating list of recently open files in a GUI::Menu.
There are three main pieces to this mechanism:
- GUI::Application::set_config_domain(domain): This must be called
before using the recent files feature. It informs the Application
object about which config domain to find the relevant RecentFiles
list under.
- GUI::Menu::add_recently_open_files(callback): This inserts the list
in a menu. A callback must be provided to handle actually opening
the recent file in some application-specific way.
- GUI::Application::set_most_recently_open_file(path): This updates
the list of recently open files, both in the configuration files,
and in the GUI menu.
Each {} block is now treated as a folding region, so that they can be
collapsed and expanded in TextEditor, GML Playground, HackStudio, and
anywhere else that uses the syntax highlighter. :^)
Previously this stored the position of each visual line break, meaning
that all the text would always be painted. By storing each visual
line's Utf32View, we can skip over parts of the text, such as for code
folding.
This only becomes a problem with folding, since arbitrary lines may be
invisible, meaning we try to apply a span for an invisible line N, on
line N+X instead, causing occasional crashes.
This check means we can remove the loop that skips spans occurring at
the end of the line.
We are currently setting the physical mouse position to the visual
cursor content location. In a line containing only a multi-code point
emoji, this would set the cursor to column 1 rather than however many
code points there are.
Nobody made use of the ErrorOr return value and it just added more
chance of confusion, since it was not clear if failing to sniff an
image should return an error or false. The answer was false, if you
returned Error you'd crash the ImageDecoder.
Changed the Action destructor to fix an issue where global scoped
actions without shortcuts were not being properly unregistered from the
application. Previously, this could cause crashes when attempting to
open the command palette.
We will currently only wrap "words" at ASCII spaces and, when wrapping,
will break up multi-code point emoji. This changes word wrapping to
behave as follows:
When the wrapping mode is "anywhere", use the iterator-based font width
computation overload. This will compute the width of multi-code point
emoji, whereas we currently only handle single-code point.
When the wrapping mode is "word", use the Unicode word segmentation
boundaries to break lines.
When clicking a position within a TextEditor, we should interpret that
position as a visual location. That location should be converted to a
"physical" location before using it to set the physical cursor position.
For example, consider a document with 2 emoji, each consisting of 3 code
points. Visually, these will occupy 2 columns. When a mouse click occurs
between these columns, we need to convert the visual column number 1 to
the physical column number 3 when storing the new cursor location.
TextDocument::merge_span_collections() automatically makes sure that the
spans are valid, move forwards, are in order, and do not overlap. This
means we don't have to check these things every time TextEditor paints
the document.
merge_span_collections() now does these checks instead. I am not certain
they are still useful, but someone in the past certainly did. I have
modified them to take advantage of the operator overloads and Formatter
that we now have.
We were manually adding together the gutter and ruler widths in several
places. Soon we'll have a third section that needs to be included in
this width, so let's abstract it now.
- Make gutter/ruler_content_rect() return rectangles relative to the
TextEditor widget.
- Re-order painting code to translate the Painter after the gutter/ruler
has been painted, to use those coordinates.
- Consistently put gutter before ruler in code, because that's the order
they physically appear.