Commit graph

5481 commits

Author SHA1 Message Date
Alx Sa
ede124ff85 tools: Fix crash in passthrough composited preview
Resolves #13087
We use gimp_layer_get_effective_mode () to retrieve
a simplified layer mode for optimization purposes
(e.g. if it's effectively NORMAL, we can do less processing).
GimpTransformGridTool used this function when the user
requests Composited Preview to only apply transforms to
individual layers in a group if absolutely necessary.
This means that sometimes, it returns NORMAL instead of
PASS_THROUGH depending on the number and types of
layers in the group.

Since 71aff497, when we remove a filter we also update the
effective mode of the group layer. However, this leads to an
infinite loop scenario where the effective mode change causes
the TransformGridTool to repeatedly remove and add a filter
until GIMP crashes.

This patch changes the gimp_transform_grid_tool_add_filter ()
check to always get the actual mode rather than the effective mode.
This prevents the effective mode change from causing an infinite loop,
but does mean that we now always apply transforms to all layers of the
group even if the composite preview would work fine.
2025-08-15 06:03:13 +00:00
Ondřej Míchal
00c08e81d4 app: Make block-listing of GIMP operations optional
In an upcoming commit a new user of gimp_gegl_get_op_classes will expect
a list of all operations supported/allowed in GIMP and not just the ones
that are not exposed in the GUI.
2025-08-03 21:38:28 +00:00
Ondřej Míchal
caa61e5925 app: Separate GEGL op blacklist based on filter actions
In an upcoming commit a new user of gimp_gegl_get_op_classes will expect
a list of all operations supported/allowed in GIMP and not just the ones
that are not exposed in the GUI.

With the same change, this switches from maintaining a list of
operations exposed as an action, this now uses the actions themselves
for the filtering. During this I found some operations that were in the
"exposed in GUI sub-list" were in-fact not exposed but were straight up
blocked. I moved them to the appropriate sub-list along with the
justifications I found in the commit history.
2025-08-03 21:38:28 +00:00
Michael Natterer
b416994ed0 app: make GimpContainerView behave like a normal widget
The old API to select stuff and its signals was doing unexpected
stuff and was very confusing. Change things to be "normal":

The selection API is now set_selected() and get_selected(), with no
internal data exposed, and set_selected() emitting the expected
signal.

The signals are now "selection-changed" and "item-activated".
"selection-changed" is always emitted in response to changing the
selection, be it via the API, or by changes in the model (the internal
callbacks in from e.g. GimpContext or GimpImage simply call set_selected()
and don't do any unxpected magic).
2025-08-01 10:02:37 +02:00
Alx Sa
f7ef01f44a tools: Update Seamless Clone paste check
The experimental Seamless Clone tool assumes
that all pasted objects are GimpBuffers. With multi-select,
it's now likely that the pasted object is an image containing
layers instead. Thus, the tool would report there was no pasted
data to work with, even though there was.
This patch updates the check so that it retrieves the first selected
layer from the pasted image if it's not a GimpBuffer, allowing the
tool to function again.

Note that this patch does not improve the speed of the Seamless Clone
GEGL operation, just enables the tool to work again in GIMP.
2025-07-31 14:49:35 +00:00
Alx Sa
df8063c861 tools: Make transform boundary multi-select aware
Resolves #13589
When selecting multiple layers to transform, the boundaries
would only consider the first layer selected - leaving the other
items invisible.
This patch reuses code from gimp_edit_paste_get_viewport_offset ()
to loop through all selected layers and update the transform
boundaries to consider the total offset and dimensions of the selected
layers.
2025-07-27 04:01:27 +00:00
Michael Natterer
d4e8ab0234 app: rename GimpContainer's "children-type" property to "child-type" 2025-07-18 08:19:13 +02:00
Michael Natterer
14fb14effc app: #pragma once in app/tools 2025-07-13 09:26:04 +02:00
Michael Natterer
246f9d284f app, pdb, libgimp: use "#pragma once" instead of:
#ifndef __FOO_H__
 #define __FOO_H__

 /* declarations  */

 #endif /* __FOO_H__ */

And some cleanups while I saw the headers.
This is far from finished...
2025-07-13 03:21:37 +02:00
Alx Sa
2449d2f3ad paint, tools: Minor fixes to MyPaint Brushes code
* Anders Jonsson noticed a typo where the
'r' in "pressure" was left off in the Gain
parameter description
* Since 0.0 is an invalid value for the viewzoom
parameter in MyPaint, the cut off is adjusted
to be greater than 0, not greater than or
equal to 0.
* The default viewzoom value is set to 1.0f,
100%, rather than 0.0001, very zoomed out.
2025-07-10 01:39:36 +00:00
Alx Sa
ea8b9dc13c core, paint, tools: Port to MyPaint Brushes2
This patch ports our MyPaint code to use the
MyPaintSurface2 API, allowing us to support
version 2 MyPaint Brushes correctly.
The API update lets us take into account
the zoom factor and rotation of the canvas
when drawing. It also adds a "Gain" option
to the GUI in order to control the strength
of the input's pressure (tablet or mouse).
As a caveat, this patch does not yet
implement spectral/pigment blending.
2025-07-09 22:14:42 +00:00
Michael Natterer
89ea91df96 app, libgimp*: more g_set_str() and some other stuff in the same
spirit
2025-07-08 00:37:26 +02:00
Michael Natterer
6a3256ad69 app, menus: rename the vector-toolpath menu stuff to tool-path 2025-07-07 16:32:20 +02:00
Michael Natterer
4ce5181cc5 app, menus: vectors -> path in dialog and action identifiers 2025-07-07 16:16:48 +02:00
Michael Natterer
69f84942fa app: rename app/vectors/ to app/path/ 2025-07-07 15:44:15 +02:00
Michael Natterer
bf405d3d93 app: vector -> path in gimppathtool.[ch] and some config files 2025-07-07 14:56:41 +02:00
Michael Natterer
775c7ef825 app: vector -> path in GimpPathOptions 2025-07-07 14:33:12 +02:00
Michael Natterer
a15fa05d4c app: remove gimpvectortool,options.[ch] to gimppathtool,options.[ch]
Don't change any code just yet, just the files removed.
2025-07-07 14:24:51 +02:00
Michael Natterer
f5900020d3 app: more vectors -> path, mostly in GimpToolPath 2025-07-07 14:16:50 +02:00
Michael Natterer
bee7b8713b app, pdb: a lot of vectors -> path renaming 2025-07-07 13:18:02 +02:00
Alx Sa
58a0c1d31e tools: Don't alter merge filter status unexpectedly
Currently, some GEGL filters must always be merged because
we don't yet have a way to store GimpDrawables with filters.
When creating these filters as part of the Filter Tool, we were
changing the "merge-filter" property directly. This mean that
if you had previously set the Filter Tool to be non-destructive,
it would be destructive the next time you added a filter (even if
the filter supported NDE).

This patch creates a separate boolean variable (initialized to the
current state of "merge-filter") and uses that instead in the
gimp_filter_tool_create_filter () function. This allows us to still
force filters with aux pads to always merge, while not affecting
the user's preferences for other NDE filters.
2025-06-18 23:14:36 +00:00
Alx Sa
9a349e812b app/tools: Use NDE filter's drawable for on-canvas widgets
Resolves #14240
This patch extends a9056419 to use the existing filter's
drawable (if it exists) on all other on-canvas widgets instead
of always using the selected layer.
2025-06-12 15:11:31 +00:00
Alx Sa
0370aed02d tools: Don't run Foreground Selection without strokes
The Foreground Selection algorithm was being run when
users switched to a different tool, even if no strokes had been
painted. This caused an unnecessary delay, since no selection
will be generated.
This patch adds a check to verify we have at least one foreground
stroke made by the user before trying to create the selection.
2025-06-11 19:49:52 +00:00
Alx Sa
54c95577df widgets, tools: Allow NDE filters on channels
This patch removes restrictions on applying
NDE filters to channels in the GUI. Note
that layer masks are still restricted, not for
technical reasons but because UX/UI needs
to be considered further.
2025-06-11 16:49:12 +00:00
Michael Natterer
2baab5aa74 app: add accessors for GimpDrawableFilter::temporary and use them
instead of using the property dirtectly.  Also make sure temporary
filters don't go to the undo stack or to the XCF.
2025-05-31 14:14:02 +02:00
Michael Natterer
27b09025be app: refactoring in filters and their UI
- move the filter popover to its own file
- centralize popover sensitivity settings
- get rid of gimp_item_refresh_filters()
- lots of minor filter fixes/changes
2025-05-30 15:54:48 +02:00
Estecka
a60c1097ab core,widgets: Fix filter manipulations on invisible layers
Many actions done on layers require refreshing its filters, by toggling
the layer off and on again. When done on an invisible layer, this would
turn it visible, which could not be undone.
Now, the layer remains invisible.
2025-05-28 19:42:33 +00:00
Alx Sa
3edafcc7bc text: Add additional outline options
This creates a new "outline direction" property, that determines whether
the text outline grows outward, inward, or centered from the text.
2025-05-24 16:12:39 +00:00
Alx Sa
3879520cc2 tools, operation: Add support for loading PS Levels presets
Photoshop stores their Levels filter presets in an
.alv file. This patch adds support for loading these
and converting them to GIMP's Level format.

The .alv file is binary, and consists of a 2 byte version
followed by 29 groups of 2 byte values for input,
output, and gamma. We only read the first four for
now, since GIMP only supports composite and then
R, G, and B individual channels.
2025-05-22 18:52:30 +00:00
Alx Sa
f3afd91a95 tools, operation: Add support for loading PS Curve presets
Photoshop stores their Curve filter presets in an
.acv file. This patch adds support for loading these
and converting them to GIMP's Curves format.

The .acv file is binary, and consists of a 2 byte version
and 2 byte curve count. Then, you read in 2 bytes for
the number of curve points, followed by 2 bytes for
the Y value and 2 bytes for the X value. You repeat that
for the curve count defined in the header. PS Curves range from 2 to 19 points total.
2025-05-22 18:52:30 +00:00
Jehan
568afe809d app: do not store the filter tool's filter object.
Just swap the values in the stored GeglNode each time you undo or redo.
When undoing, the GeglNode contains the values from before this undo
step. When redoing, it stores the values to after the step.

Also fix a few leaks (GValue-s and list of properties).
2025-05-17 19:55:08 +00:00
Alx Sa
7a8a147ce3 core, tools: Editing effects stored in undo history
A new GIMP_UNDO_FILTER_MODIFIED
enum is now used to store filter properties
when an edited NDE filter is committed.
A new undo entry will be added to the
history each time the filter is edited and
committed.
2025-05-17 19:55:08 +00:00
Alx Sa
2db5875e28 tools, widgets: Don't show Fx icon for Cage Tool
Resolves #13982
This tool was missed in cc50ef99
2025-05-12 17:25:29 +00:00
Alx Sa
c92071fd28 tools: Close iscissors curve on pressing Enter
This better aligns the tool with the path tool, which also closes on 
Enter if it is not already a connected path.
2025-05-11 16:23:12 +00:00
Idriss Fekir
f9de30fd6d app/tools: Always push an undo step not just when a single property changes
The behavior of the text tool was such that an undo is pushed only when a single property changes, which is obviously not expected, because, e.g. if part of the text uses a different font this means that the markup changed and all "properties" stayed the same, so an undo wouldn't be pushed.
2025-05-10 02:22:29 +00:00
Alx Sa
33485d7e6d tools: Use NDE filter name for undo history
Resolves #13711
This patch replaces the generic "Add filter" undo history
for NDE filters with the filter's name. This makes the label
consistent with destructive filters, and is more descriptive.
We may consider adding some indicator that filters are
NDE or not in a future patch.
2025-04-30 03:28:09 +00:00
Alx Sa
d83d5929ad tools: Standardize MyPaint Brush tool layout
MyPaint Brushes have their own custom sliders for brush
options, so they were displayed lower in the dockable
compared to other paint tools like Pencil and Paintbrush.
This patch moves them up so options are in the same place
across all standard paint tools.
2025-04-27 23:18:28 +00:00
Alx Sa
cc50ef99a6 tools, widgets: Don't show Fx icon for tool-based filters
We use GEGL filters for some of our currently destructive
editing only tools, like Warp and Bucket Fill.
While eventually these will have non-destructive options,
for now it's confusing to show an Fx icon briefly when
the tools are active.
This patch sets these filters as temporary, and updates
the GimpItemTreeView code to not show the Fx icon
if there is only one filter and it is temporary.
Temporary filters can not be deleted from the NDE
pop-up, only from their tools, preventing another set
of reported crashes.
2025-04-20 15:26:07 +00:00
Alx Sa
93c3d83dd0 tools: Hide Force slider for Pencil Tool
The Force option does not affect the Pencil Tool's painting.
While Force is already set to be insensitive, hiding the
option entirely makes it even clearer that it can not
be used with this tool.
2025-04-11 02:58:42 +00:00
Alx Sa
8b0185ba8f tools: Don't crash when reading invalid Curves preset
When reading a gimp:curves preset file, we assume
that we read in at least 64 bytes for the header. If the
invalid preset file is smaller than that, g_input_stream_read_all ()
can read it just fine but the code fails when comparing the
bytes read in to the size of the header.

This means that the GError object is still NULL, so g_prefix_error ()
has no effect - and thus the calling code crashes when it tries
to get "message" from a NULL GError object.

To resolve this issue, we check if error or *error are NULL.
If so, we set the error with g_set_error () instead.
2025-04-07 18:57:31 +00:00
Alx Sa
20cf6d553a tools: Connect MoveOptions and TransformOptions to icon size
Resolves #13044
Same code as 816fb1c6, applied to the Move icon box
in GimpMoveOptions and the Transform icon box
in GimpTransformOptions.
2025-04-04 10:46:23 +00:00
Idriss Fekir
ea5fff1b3f app: Keep the current font in use if the font searched for doesn't exist
Whenever the font in the Context (e.g. through selecting another font
from the fonts list) changes, a signal is emitted to propagate the
change to the active text layer, but if the font is set to NULL in
Context, we don't want that to propagate (because this would change the
current text's font to some fallback font).

In other similar codepaths (e.g. brushes) this is not a problem because
selecting a brush that doesn't exist will prevent painting until an
existing brush is selected.
2025-03-23 21:35:53 +00:00
Alx Sa
72964efb29 app/tools: Reorder Line Art Detection options
This patch moves the Stroke Threshold spin scale to
be on top, like similar tool option groupings such as
Dynamics Fade Options.
2025-03-20 14:25:59 +00:00
Alx Sa
121a997af5 app/tools:
Resolves #12967

In cdd51740, we added a destructive option
for filters. Since toggling this moves the filter
to the bottom of the stack, we refresh the
layer.
However, layer masks and channels can not
yet have filters applied non-destructively,
so this code created unnecessary undo history
items when commited. This patch adds a
check so that we only refresh layers and
layer groups for now. Once we have NDE
filters for layer masks/channels, we should
revisit this code.
2025-03-10 01:22:12 +00:00
Jehan
3ae90906d9 app: in image graph, only demote data back to storage format after a filter when…
… this filter is meant to be merged.

In commit 2c066afff9, I made so that we had a "gegl:convert-format" only
at the latest filter over a drawable. While this was already a huge
improvement, it was still "too much".

Basically the only time when we want to convert to drawable format
(which means usually demote the output to lower bit depth) is when the
filter was just created and is meant to be merged.

This also means that from now on, during preview time, when checking and
unchecking the "Merge filter" checkbox, the preview may be slightly
different. A very good test to see the difference more obviously would
be with indexed images, because "Merge filter" preview would map to
allowed colors only.
2025-02-09 00:08:54 +01:00
Alx Sa
af4bf60477 core, tools, widget: Lock filters when editing
When editing a filter, the NDE UI is set to
insensitive so they can't be deleted.
However, closing and reopening the
popover re-enables the options.

This patch adds a new "temporary" boolean
to GimpDrawableFilter. It is only set to
TRUE if the filter is a temporary "editing"
filter. When we reopen the NDE UI, this
checks if the filter stack contains a
temporary filter, and if so, once again locks
the options.
2025-01-27 05:15:12 +00:00
Jehan
d8a8d2f138 app: the "color-options-expanded" filter option is now bogus.
I missed this together with commit c3ef79b3ef. It's of no use now.
2025-01-10 23:43:31 +01:00
Jehan
c3ef79b3ef Issue #12577: get rid of the gamma hack.
What it was doing was casting the input buffer to another TRC, basically
pretending the data was what it was not. In particular, it was casting
linear input buffers to non-linear and all other TRCs to linear.

As was noted in #1958, this was in fact a useful trick, yet it's still a
trick. Basically when it's needed, it's either:

1. because the operation implementation does not work in the technically
   correct space. Then the operation code should be fixed;
2. or because several work TRC are valid, then an option should be
   proposed by the operation;
3. or for artistic reasons, which people are free to implement as
   plug-ins or third-party filters, but it should not be a core GIMP
   feature.

Therefore for most cases where it felt needed, the real solution will be
to improve the operations' implementations.
2025-01-10 23:26:11 +01:00
Jehan
bfe842cd1d Issue #12359: encoding conversion undo does not undo the mask conversion.
In particular, we could end up with mask of wrong bytes per pixel, which
was what was happening in the report.

This commit adds a new GimpDrawableFilterMask class because we needed to
implement a specific is_attached() method for effect masks.

Note: the file is added to POTFILES but the only localized string
already existed elsewhere. So this doesn't break string freeze.
2024-12-26 15:55:05 +01:00
Alx Sa
7bcc23ec05 tools, widgets: Fix NDE restrictions when different layer selected
As noted by Thomas Manni, editing NDE filters was still affected by
restrictions on existing layers, even if the edited layer did not have
those restrictions.
This patch alters gimp_item_tree_view_effects_edited_clicked () so that
it checks if the edited filter's drawable is visible or pixel locked,
rather than the currently selected layers. It also adds checks in
GimpFilterTool tool to verify an existing filter is being edited before
preventing certain operations.
2024-12-19 17:42:43 +00:00