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.
This commit removes the file extension in the presented title of images,
and fixes an issue with the previous commit wherein "save as" on an
image would always append ".pp" as an extension, even when the filename
already included this extension.
When creating a new image, a title can be entered. This title was not
used when saving the file however, so naming it was pointless, as the
title used would be whatever was entered during the first save.
This commit makes it so that the default text in the "save as" dialogue
is whatever was entered previously when the image was created.
This is useful, for instance, in games in which you can switch held
items using the scroll wheel. In order to implement this, they
previously would have to either add a hard-coded division by 4, or look
up your mouse settings to adjust correctly.
This commit adds an MouseEvent.wheel_raw_delta_x() and
MouseEvent.wheel_raw_delta_y().
We often want to zoom and fit the content of the widget into the
visible frame (or some rect within the frame), and it makes sense to
move this functionality into the AbstractZoomPanWidget to minimize
the amount of coordinate math derived classes need to do.
This commit moves the code that implements this functionality from
`PixelPaint::ImageEditor` into `AbstractZoomPanWidget` so that we
can also use it for other applications (such as ImageViewer!)
The ImageEditor tracks whether it was loaded from an image
(the alternative being a project file.) If it was loaded from an image
file we redirect save project actions to save as instead.
This allows us to request any specific editor to close itself. Earlier,
this could only be done for the currently active editor, so trying to
close inactive tabs would not work properly.
Previously the save logic was hardcoded to only work for the active
editor, so closing editors in the background would not properly
handle the unsaved changes. This patch brings us closer to be able
to fix that problem.
As noted in the latest hacking video, it doesn't seem to make much
sense to store the title and path in the image itself. These fields
have now been moved to the actual ImageEditor itself.
This allows some nice simplicfications, including getting rid of the
`image_did_change_title` hook of ImageClient (which was just a way to
report back to the editor that the title had changed).
This just allows us to ask the image editor to update the tool's
current cursor. This is useful in cases where a tool may want to
change it's cursor for some operation, and wants to invalidate the
active cursor cached in the ImageEditor.
Someone may not want to have these things enabled by default on every
startup, but toggle them on manually. So instead of having hard-coded
everything to be enabled by default, we now query LibConfig to find
out what the preference is. These values can still always be changed
from the Menus / with shortcuts.
It's not really ideal querying LibConfig twice, but when initializing
the menu we may not have an active editor, so we need to get the
value for both the menu checkbox as well as the internal property.
This shouldn't be too much of a big deal since LibConfig caches the
values anyway :^)
Because of the way rulers are implemented in the ImageEditor
currently, the `Fit Image To View` action doesn't work correctly
with them enabled. This patch makes them adjust to the effective
viewport area and account for the rulers.
This is a bit of a hack, but the correct way to deal with this would
be to put the rulers in a new widget so they don't interfere with
the actual viewport rect (which is being used all over).
Depending on the size / scaling of the UI, someone might want to
change what the threshold is to show the pixel grid. For instance
if you are working on a 50x50 image, and want to see the grid while
still fitting the whole image in the editor.
Since there's no UI for settings in PixelPaint right now, this
commit just uses LibConfig to read the following entry:
("PixelPaint", "PixelGrid", "Threshold")
which is then used when drawing the grid.
The editor now draws a grid showing the pixels if you are zoomed
in enough. Currently the threshold is a scale of 15 (so if one
pixel side on the image takes up > 15 pixels in the editor)
This is a feature I missed from Photoshop: it sets the scale and
position so that the image fits (it's longest dimension) into
the editor view. There's a 5% border left around the image to
provide context. This is just arbitrary seemed like the right
amount after some trial and error.
Showing the position only with an active tool seems a bit confusing,
if you've opened up an image just to find out the coordinates of
a pixel for instance, there shouldn't be a need to have to select
a tool first.
The ImageEditor knows more about the image than Image itself. So to save
a project with all the information known to the program about an image
it's logical that ImageEditor performs that task rather than the Image.
There isn't any additional data added yet, but now there's the
possibility to do so.
This also required adding a new hook to `ImageClient`, since there
wasn't a way of telling the ImageEditor that the full rect of the
image has changed (as when we rotate).
Previously, if you used one of the keyboard shortcuts to select a
different tool, it didn't change the cursor to the corresponding
one till you clicked somewhere / did something else to trigger an
update. This was pretty jarring since there's no indication as to
whether the tool change was successful or not.
This patch just calls `set_override_cursor()` when a valid active
tool is set to immediately update it.
Some tools (e.g. ZoomTool) doesn't need layer to work. This commit
makes mouse events fire even if there is no layer. This fixes
a bug that ZoomTool didn't work when there is no layers.
This commit adds a Tool::MouseEvent struct, which contains events that
may be needed by tools: layer-relative, image-relative and raw (editor-
relative) event.
The raw event is used by ZoomTool to properly pan the view. This fixes
a bug which caused image to snap out of sight.