The FontSettings widget now uses background_role instead of
background_color to ensure that it displays properly independently of
the active system theme.
The LexicalPath instance methods dirname(), basename(), title() and
extension() will be changed to return StringView const& in a further
commit. Due to this, users creating temporary LexicalPath objects just
to call one of those getters will recieve a StringView const& pointing
to a possible freed buffer.
To avoid this, static methods for those APIs have been added, which will
return a String by value to avoid those problems. All cases where
temporary LexicalPath objects have been used as described above haven
been changed to use the static APIs.
Since this is always set to true on the non-default constructor and
subsequently never modified, it is somewhat pointless. Furthermore,
there are arguably no invalid relative paths.
This patch brings all of LibVideo up to the east-const style in the
project. Additionally, it applies a few fixes from the reviews in #8170
that referred to older LibVideo code.
This introduces a new DOMTreeJSONModel, which provides the Model for the
InspectorWidget when the Browser is running using the
OutOfProcessWebView.
This Model is constructed with a JSON object received via IPC from the
WebContentServer.
This removes JsonObject::get_or(), which is inefficient because it has
to copy the returned value. It was only used in a few cases, some of
which resulted in copying JsonObjects, which can become quite large.
This changes JsonObject to use the new OrderedHashMap instead of an
extra vector for tracking the insertion order.
This also adds a default value for the KeyTraits template argument in
OrderedHashMap. Furthermore, it fixes two cases where code iterating
over a JsonObject relied on the value argument being copied before
invoking the callback.
If there are no search results in the list, we shouldn't do anything
when you try to active the selected result, since there isn't one.
Fix this by using an Optional<size_t> to store the selected index.
Steps to reproduce:
1. Start TextEditor and make some changes to the document.
2. Try to open an existing file.
3. When prompted choose to save the changes to the existing document.
4. Close the file picker by clicking 'Cancel'.
5. Note how the file was opened anyway and your changes were lost.
Same applies to the 'New File' action.
This replaces the naive copy algorithm that only supported rectangular
and 100% opaque selections with a more general approach that supports
any shape and alpha value.
Note that we now make a brand new bitmap with a hardcoded format instead
of just cropping the layer's existing bitmap. This is done to ensure
that the final clipboard image will have an alpha channel.
A "feather" value sets by how much the borders of the selection will be
smoothed, and a "mode" value sets how the newly selected region will
interact with an existing image selection (if any).
The Mask class represents an opacity mask over a rectangular section
of an image, linking every pixel to an alpha value ranging from 0 (not
selected) to 255 (fully selected). "Partially selected" pixels can be
used to simulate anti-aliased curves.
This class will be used as the basis for the new non-rectangular
selection feature.
Color palettes can now be stored in and read from files. The default
palette will be read from `/res/color-palettes/default.palette`
instead of being hard-coded in PaletteWidget.
The file format is one color per line, in any format that can be
understood by `Gfx::Color::from_string`.
This commit addresses two issues:
1. If you play a 96 KHz Wave file, the slider position is incorrect,
because it is assumed all files are 44.1 KHz.
2. For high-bitrate files, there are audio dropouts due to not
buffering enough audio data.
Issue 1 is addressed by scaling the number of played samples by the
ratio between the source and destination sample rates.
Issue 2 is addressed by buffering a certain number of milliseconds
worth of audio data (instead of a fixed number of bytes).
This makes the the buffer size independent of the source sample rate.
Some of the code is redesigned to be simpler. The code that did the
book-keeping of which buffers need to be loaded and which have been
already played has been removed. Instead, we enqueue a new buffer based
on a low watermark of samples remaining in the audio server queue.
Other small fixes include:
1. Disable the stop button when playback is finished.
2. Remove hard-coded instances of 44100.
3. Update the GUI every 50 ms (was 100), which improves visualizations.
This sets the stage so that DisplaySettings can configure the screen
layout and set various screen resolutions in one go. It also allows
for an easy "atomic" revert of the previous settings.
This allows WindowServer to use multiple framebuffer devices and
compose the desktop with any arbitrary layout. Currently, it is assumed
that it is configured contiguous and non-overlapping, but this should
eventually be enforced.
To make rendering efficient, each window now also tracks on which
screens it needs to be rendered. This way we don't have to iterate all
the windows for each screen but instead use the same rendering loop and
then only render to the screen (or screens) that the window actually
uses.
If you press "spacebar" while moving a selection, it will now move the
origin point of the selection; and if you press "control" it will move
it relatively to the center.
This now matches the spec's OrdinaryObjectCreate() across the board:
instead of implicitly setting the created object's prototype to
%Object.prototype% and then in many cases setting it to a nullptr right
away, it now has an 'Object* prototype' parameter with _no default
value_. This makes the code easier to compare with the spec, very clear
in terms of what prototype is being used as well as avoiding unnecessary
shape transitions.
Also fixes a couple of cases were we weren't setting the correct
prototype.
There's no reason to assume that the object would not be empty (as in
having own properties), so let's follow our existing pattern of
Type::create(...) and simply call it 'create'.
Previously `open_page` was called multiple times when opening the
application, once for the actual page, but also in
`tree_view.on_selection_change`. At startup there is no valid selection
yet, which caused an empty page to be loaded. Prevent this by early
returning if the `path` is null.
This patch adds a GUI::TabWidget to the main UI and allows having
multiple images open at the same time.
Some of the changes here are a bit hackish and mechanical and there's
still code around that needs more work to fit better in the new world.
One nice side-effect of this change is that ImageEditor now always
has one Image associated with it, and it never changes.
When opening a PP file, we were creating a layer first with an empty
bitmap, and then replacing it with the loaded bitmap from the file.
This patch reorders things so we never create the empty bitmap in
between, saving time and avoiding a memory spike.
The Selection object now tracks whether there is an ongoing interactive
selection (originating from one of the selection tools). If so it makes
sure to pump the marching ants animation.
Also clear any selection that existed before pasting. This feels a bit
more intuitive. We may also want to consider switching to the "Move"
tool automatically on paste, but I'm less sure about that.
This patch moves the marching ants painting code to Selection and
unifies the timer mechanism so that all marching ants are synchronized
which looks neat. :^)