summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGUI/TextEditor.cpp
AgeCommit message (Collapse)Author
2023-06-04TextEditor: Prevent autoscroll looping overAhmed Hussein
When a text file has only 1 line with long text autoscroll to the top will no longer loop over and set the cursor to the end of the line.
2023-06-01LibGUI: Add support for jumping to a line and column in TextEditorCaoimhe
We had support for going to a specific line before, but now we support jumping around using the `line:column` format :^)
2023-05-23LibGfx+Everywhere: Change `Gfx::Rect` to be endpoint exclusiveJelle Raaijmakers
Previously, calling `.right()` on a `Gfx::Rect` would return the last column's coordinate still inside the rectangle, or `left + width - 1`. This is called 'endpoint inclusive' and does not make a lot of sense for `Gfx::Rect<float>` where a rectangle of width 5 at position (0, 0) would return 4 as its right side. This same problem exists for `.bottom()`. This changes `Gfx::Rect` to be endpoint exclusive, which gives us the nice property that `width = right - left` and `height = bottom - top`. It enables us to treat `Gfx::Rect<int>` and `Gfx::Rect<float>` exactly the same. All users of `Gfx::Rect` have been updated accordingly.
2023-05-23Base+Userland: Apply Human Interface Guidelines to Object textthankyouverycool
Corrects a slew of titles, buttons, labels, menu items and status bars for capitalization, ellipses and punctuation. Rewords a few actions and dialogs to use uniform language and punctuation.
2023-04-18LibGUI+Userland: Improve error and font handling for InputBoxthankyouverycool
Adds fallible factories, ports DeprecatedString, and rebuilds the layout to accomodate system font changes.
2023-04-18LibGUI: Improve calculated_min_size() for single-line TextEditorthankyouverycool
TextBox now shrinks to fit the current font based on preferred line height, maintaining its historical minimum size of 40x22
2023-03-31LibGUI: Add gutter indicators to TextEditor :^)Sam Atkins
HackStudio's Editor has displayed indicators in its gutter for a long time, but each required manual code to paint them in the right place and respond to click events. All indicators on a line would be painted in the same location. If any other applications wanted to have gutter indicators, they would also need to manually implement the same code. This commit adds an API to GUI::TextEditor so it deals with these indicators. It makes sure that multiple indicators on the same line each have their own area to paint in, and provides a callback for when one is clicked. - `register_gutter_indicator()` should be called early on. It returns a `GutterIndicatorID` that is then used by the other methods. Indicators on a line are painted from right to left, in the order they were registered. - `add_gutter_indicator()` and `remove_gutter_indicator()` add the indicator to the given line. - `clear_gutter_indicators()` removes a given indicator from every line. - The `on_gutter_click` callback is called whenever the user clicks on the gutter, but *not* on an indicator.
2023-03-31LibGUI: Rename TextEditor::LineVisualData -> LineDataSam Atkins
This is going to hold other per-line data too.
2023-03-31LibGUI: Extract repeated code for populating TextEditor per-line dataSam Atkins
2023-03-24Libraries: Convert `DeprecatedFile` usages to `LibFileSystem`Cameron Youell
2023-03-16LibCore+Userland: Add DEPRECATED infix to REGISTER_STRING_PROPERTY macroKarol Kosek
2023-03-15LibGfx+Userland: Make TextAttributes::underline_style optionalSam Atkins
Rather than having a style AND a field saying whether to use the style, just make the style Optional.
2023-03-13Everywhere: Remove unintentional partial stream reads and writesTim Schumacher
2023-03-13AK: Rename Stream::{read,write} to Stream::{read_some,write_some}Tim Schumacher
Similar to POSIX read, the basic read and write functions of AK::Stream do not have a lower limit of how much data they read or write (apart from "none at all"). Rename the functions to "read some [data]" and "write some [data]" (with "data" being omitted, since everything here is reading and writing data) to make them sufficiently distinct from the functions that ensure to use the entire buffer (which should be the go-to function for most usages). No functional changes, just a lot of new FIXMEs.
2023-03-06Everywhere: Stop using NonnullOwnPtrVectorAndreas Kling
Same as NonnullRefPtrVector: weird semantics, questionable benefits.
2023-03-04Userland: Use Font::pixel_size_rounded_up() instead of glyph_height()Andreas Kling
The only remaining clients of this API are specific to bitmap fonts and editing thereof.
2023-03-03LibGUI: Compute syntax-highlighted visual text spans using float rectsTimothy Flynn
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.
2023-02-28LibSyntax+LibGUI: Let syntax highlighters assign folding regionsSam Atkins
2023-02-28LibGUI: Support folding regions in TextEditorSam Atkins
2023-02-28LibGUI: Store Utf32Views in TextEditor::LineVisualDataSam Atkins
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.
2023-02-28LibGUI: Create TextAttributes for unspanned text once, not repeatedlySam Atkins
Also, stop unnecessarily creating a RefPtr for the unspanned font - just use `font()`, which returns a reference.
2023-02-28LibGUI: Skip painting TextEditor spans that end on previous linesSam Atkins
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.
2023-02-27LibGUI: Ensure the "End" key sets the cursor to the visual line endTimothy Flynn
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.
2023-02-24LibGUI: Make Gfx- to text-positioning handle multi-code point glyphsTimothy Flynn
2023-02-22LibGUI: Wrap words at word break boundaries and don't break up emojiTimothy Flynn
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.
2023-02-22LibGUI: Convert mouse events from a visual to a physical positionTimothy Flynn
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.
2023-02-21LibGUI: Fix const-correctness issuesAndreas Kling
2023-02-20LibGUI: Use Gfx::Font::bold_variant() instead of a manual lookupSam Atkins
This has the nice side-effect of being cached in the Font, instead of being repeatedly looked up in the FontDatabase.
2023-02-20LibGUI: Use a while loop for iterating text spansSam Atkins
2023-02-20LibGUI: Validate TextDocument spans when merging them, not when paintingSam Atkins
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.
2023-02-20LibGUI: Add and use TextEditor::fixed_elements_width()Sam Atkins
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.
2023-02-20LibGUI+HackStudio: Simplify TextEditor gutter & ruler calculationsSam Atkins
- 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.
2023-02-17LibGUI: Update TextEditor to delete emoji based on gbp clusterFausto Tommasi
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
2023-02-16LibGUI: Account for `glyph_spacing()` in spansCameron Youell
2023-02-13LibGUI: Take gutter into account when measuring TextEditor content areaSam Atkins
2023-02-13LibGUI: Don't show caret cursor when hovering TextEditor's gutterSam Atkins
2023-02-13LibGUI: Combine wrapping/non-wrapping TextEditor code pathsSam Atkins
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.
2023-02-13LibGUI: Fix typo in `span_consumed` variableSam Atkins
2023-02-13LibCore: Move Stream-based file into the `Core` namespaceTim Schumacher
2023-02-13LibCore: Rename `File` to `DeprecatedFile`Tim Schumacher
As usual, this removes many unused includes and moves used includes further down the chain.
2023-02-11LibGUI: Remove the `Core::File` overload of `write_to_file()`Lucas CHOLLET
One less usage of `Core::File`, yay!
2023-02-11LibGUI: Base `write_to_file(StringView path)` on the stream overloadLucas CHOLLET
`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.
2023-02-05LibGfx: Pass font width to `FontDatabase::get()`Aliaksandr Kalenik
Width need to be passed to `FontDatabase::get()` to resolve font name unambiguously.
2023-01-26LibGfx: Remove `try_` prefix from bitmap creation functionsTim Schumacher
Those don't have any non-try counterpart, so we might as well just omit it.
2023-01-12LibCore+Userland: Make Core::Timer::create_single_shot() return ErrorOrSam Atkins
clang-format sure has some interesting opinions about where to put a method call that comes after a lambda. :thonk:
2023-01-07LibGUI: Add `TextEditor::write_to_file(Core::Stream::File&)`Lucas CHOLLET
This overload use the `Core::Stream` API instead of the now deprecated one `Core::File`.
2023-01-07Everywhere: Use ElapsedTimer::elapsed_time() for comparisonsAndrew Kaster
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.
2023-01-06LibGfx: Make Font::preferred_line_height() more correctAndreas Kling
Return a float, and fix a bogus calculation of ascender + descender.
2022-12-26LibGUI: Standardize automatic scrolling in TextEditor+GlyphMapWidgetthankyouverycool
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.
2022-12-26LibGUI: Handle Enter+Leave events for automatic cursor trackersthankyouverycool
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.