I've used the shortcuts from GIMP for the most part, since that's what
I'm used to. We can definitely iterate on these to find better options
as the app develops. :^)
You can now see what you're drawing before committing to it. This works
by passing the second_paint_event from the ImageEditor to the tool.
We also pass the active layer which makes it easier for the tool to
keep his logic in layer-relative coordinates even while drawing preview
states directly into the ImageEditor backing bitmap.
As suggested by @awesomekling in a code review and (initially) ignored
by me :^)
Implementation is roughly based on LibJS's trim_string(), but with a fix
for trimming all-whitespace strings.
This reverts commit 3d342f72a7.
This is causing trouble for macOS users. Also it's painfully slow
compared to using the sudo method. This should definitely not be
the default since it punishes people who have genext2fs installed.
There are many cases which shouldn't even parse, like
null = ...
true = ...
false = ...
123 = ...
"foo" = ...
However this *is* valid syntax:
foo() = ...
So we still have to keep the current code doing a runtime check if the
LHS value is a resolvable reference. I believe this was declared valid
syntax to *in theory* allow functions returning references - though in
practice that isn't a thing.
Fixes#2204.
Tool mouse event handlers now receive both a layer-relative mouse event
and the original event. This is needed for the move tool since it moves
the layer and thereby changes the origin of future events every time it
moves.
These two have the same semantics as GUI::Widget. The rect() is always
at location { 0, 0 }, while the relative_rect()'s location is relative
to the "parent", which in this case is the Layer's Image.
The main editing widget is now the new ImageEditor widget, which works
on an Image object, which internally has a stack of Layer objects.
Layers are composited back-to-front when painting the Image inside an
ImageEditor.
This was looking a bit too whimsical and didn't really fit with the
overall look of the window anymore. The actions are available via
the context menu still.
These are supposed to be interpreted caselessly so let's just use the
case insensitive traits throughout. This means we'll understand things
like "Content-Length" even when they send "content-length" etc.
Now most classes dictate how they are serialized and deserialized when
transmitted across LibIPC sockets. This also makes the IPC compiler
a bit simpler. :^)
We were iterating the ancestor chain of the focused widget when looking
for a matching keyboard shortcut, but we didn't actually look at the
ancestors at each step.
With this fix, we now correctly activate actions found in the ancestor
chain of the focused widgets. :^)