Simplify a lot of uses of ElapsedTimer by converting the callers to
elapsed_time from elapsed, as the AK::Time returned is better for unit
conversions and comparisons against constants.
Both widgets now make use of their base class's scrolling timer and
now always accept drag selection updates on mousemove_event().
This guarantees much snappier feeling selections when actively moving
the mouse.
Previously, automatic cursor tracking widgets consumed all mouse
events but did not update their own hover state while active, meaning
Enter and Leave events were not being dispatched.
Fixes TextEditor's automatic selection scroll timer failing to stop
and start while autotracking. Its manual workaround in mousedown
is no longer needed.
This adds shortcut for inserting a new empty indented line
above/below current cursor position.
- <Ctrl-Return> for inserting line below.
- <Ctrl-Shift-Return> for inserting line above.
When you select a text area in "bottom-up" way (e.g. from line 10
to line 5), then type the shortcut, the text editor will not
comment those text for you.
Normalize the text range can easily fix this minor bug.
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.
One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
Previously, pressing Shift+Tab would indent the line if no selection was
given. While with a selection, it would be unindented. With this change,
pressing Shift+Tab with no selection unindents the current line.
For this, add unindent_line() helper function. This function unindents the
current line by at most one tab width if it starts with whitespace,
regardless of cursor position.
Currently, LibGUI modifies the Ctrl+Alt+Space key event to instead
represent the emoji that was selected through EmojiInputDialog. This is
limited to a single code point.
For multiple code point emoji support, individual widgets now set a hook
to be notified of the emoji selection with a UTF-8 encoded string. This
replaces the previous set_accepts_emoji_input() method.
This has two advantages: First the picker no longer changes the active
window state of its parent. Visually this is an additional hint that the
dialog is "fragile" and will close on loss of focus. Second, because
it contains a search box, its own input won't be preempted by global
application shortcuts when typing (pending #15129). This is a problem
in apps like PixelPaint which use shortcuts without modifiers.
Instead of having to negate every focusable widget or textbox, let
windows override all their widgets. These two Dialogs now block
themselves and each other.
Noticed that mouse-overing the ruler area in the TextEditor
does not change the cursor to the default cursor, instead, the
beam cursor is used, which does not look nice.
This PR extends the mousemove event and introduces a new
set_editing_cursor() function that takes care of setting the
cursor for the editor area.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
Since 00f51d42d2aeb44ec4813ca13be787c2f5ca55ff we would not allow the
deletion for a selection by typing if it would match the conditions to
indent on pressing tab.
As any single line TextEditor would always match the indent conditions,
it was impossible to replace selected text by typing in a TextBox,
PasswordBox or UrlBox.
A missing return, as pointed out in https://github.com/SerenityOS/serenity/pull/13269#discussion_r900866416
was the cause for the additional checks in
TextEditor::insert_at_cursor_or_replace_selection, described in https://github.com/SerenityOS/serenity/pull/13269#discussion_r901009457
With the early return in place the additional checks are not aiding with
the indented behavior but cause the regression described above.
This patch removes the unnecessary conditions.
If selected text is less than a whole line, usual delete/replace takes
place. Otherwise, if the selected text is a whole line or spans
multiple lines, the selection will be indented.
This moves all code comprehension-related code to a new library,
LibCodeComprehension.
This also moves some types related to code comprehension tasks (such as
autocomplete, find declaration) out of LibGUI and into
LibCodeComprehension.
Previous check did not allow AltGr+letter to be used due to
AltGr being emulated as Ctrl+Alt. That caused .ctrl() to be true.
In the new code we check that ctrl() is not set or if it is set,
it is with altgr() and if so, we pass the character into the editor.
This is the only Widget that ran its callback in deferred_invoke(). It
seems to be a holdover from when syntax-highlighting ran whenever the
text changed, but that has not been true since
bec2b3086c. Running the callback
immediately has no obvious downsides, but does make it a lot easier to
reason about. (I might have spent an hour confused as to why things
were happening in the wrong order...)
If an icon exists and the horizontal scroll value is larger than 0,
translate the TextEditor painter by the icon size and padding.
The text would scroll over the icon when the text was long enough to
trigger a horizontal scroll.
Fixes#13669.
The issue was caused by the usage of the
selection_end_column_within_line variable as if it was the visual line.
This is fixed by taking the minimum between this value and the length of
a visual line.
This adds a search API to TextEditor.
The API that is similar to "find_text" of TextDocument (which is used
internally to do the search).
All search results (as well as the current one) are highlighted with
a "span collection", which is pretty neat :^)
TextDocument::set_spans() now also takes a "span collection index"
argument.
TextDocument keeps a map between a span collection index and its spans.
It merges the spans from all collections into a single set of spans
whenever set_spans() is called.
This allows us to style a document with multiple layers of spans, where
as previously we only supported a single layer of spans that was set
from the SyntaxHighlighter.
The last commit fixes a bug, but also exposes the fact that trailing
space highlighting isn't really supported on multiple lines. This patch
correct the wrong behavior by adding an offset to adjust rectangle's
position.
Before this patch the highlighted rectangle wasn't placed on the right
spot. Now the red highlighting is correctly placed at the end of the
line. This was due to a function called with a wrong argument.
Fonts now provide their preferred line height based on maximum
height and requested line gap. TTFs provide a preferred line gap
from table metrics while BitmapFonts are hardcoded at the previous
default for now.