Similar logics as Fuzzy Select (see my previous commit), which is that
if multiple layers are selected (and sample merged unchecked), it
selects as though through a composited image containing only the
selected layers.
When several layers are selected, and using the Fuzzy select tool
without sample merged (with sample merged, nothing changes, it just uses
the whole image), the selection will be based off a composited render of
the image with only selected layers.
This is equivalent to only making selected layers visible, running fuzzy
select with sample merged, then making other layers visible again.
In gimp_edit_selection_tool_translate(), perform the active-item
checks even when the effective translation offset is 0, and only
bail afterwards. This avoids erroneously calling
gimp_tool_message_literal() with a NULL message in this case.
Even though this engine is optional, we already have the code to detect
its absence at runtime, and to fallback to "gegl:matting-global". So it
won't be a problem even then.
When the operation is present though, it definitely makes a lot more
sense than matting global as default, because it performs a lot better
in most cases (as far as I could see as well as others).
So it seems that pango_attr_iterator_range() could return G_MAXINT for
a Pango attribute when it is at the end of the preedit string. Looking
at Pango code, I see they initialize the attribute end property to
PANGO_ATTR_INDEX_TO_TEXT_END (G_MAXUINT), later clamped to G_MAXINT by
pango_attr_iterator_range(). So I guess for the specific case where we
are at the text end, it is normal. Only weird thing is that this didn't
happen at all on X11, only in Wayland.
So let's do our own pre-check. Also double the check by adding a UTF-8
validation.
This fixes preedit text not being displayed and the following warning:
> Gtk-CRITICAL **: 12:31:25.118: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, NULL)' failed
Even worse, this was potentially an out-of-range reading, though
fortunately checked early enough.
In GimpDrawableFilter and GimpFilterTool, use an absolute offset
for the split-preview guide position, instead of storing it as a
fraction of the drawable's width/height. The latter could
introduce rounding error, which would result in wrong coordinates
when converted back to an absolute offset.
In GimpGuideTool, when a custom guide (whose position is updated
directly on motion) is moved past the display bounds, keep updating
the corresponding GimpGuide's position, even though the guide will
be removed on release, to avoid leaving the guide at its old
position.
This affects the filter tool's split-preview guide.
This implied a lot of other core changes, which also pushed me into
improving some of the edit actions and PDB calls to be multi-layer aware
in the same time.
Note that it is still work-in-progress, but I just had to commit
something in an acceptable intermediate state otherwise I was just going
crazy.
In particular now the various transform tools are multi-layer aware and
work simultaneously on all selected layers (and the linked layers if any
of the selected layers is linked too). Both preview and final transform
processing works.
In the limitations, preview doesn't work well (only one layer in the
preview) when there is a selection (though the actual transform works).
Also I am left to wonder how we should process this case of canvas
selection+transform on multi-layers. Indeed currently I am just creating
a floating selection (like we used to for the selection+transform case)
containing a transform result of the composited version of all selected
layers. This is a possible expected result, but another could be to get
several transformed layers (without composition). But then should the
"Floating Selection" concept allow for multiple Floating Selections?
Sooo many questions left to answer.
This function returns a new list of items from an input list. The output
list will optionally contains linked items if any of the input item is
linked so we don't have to rewrite the same duplicated code for every
feature where item links matter.
Moreover it also filters descendants if any of the input items is an
item group, hence avoiding to apply a transformation twice to a
descendant item.
Use this new function already in 2 places, hence skimming quite a bit of
redundant code.
Right now I don't change the logics of any of the tools, except that the
GimpTool class now stores a list of drawables instead of a single
drawable. This can be later used on a case-by-case basis to make various
tools actually work on multiple drawables.
Override GimpTool::get_popup() in GimpDrawTool, forwarding the
request to the tool widget, if one exists.
Remove the same code in GimpVectorTool -- this now works for all
tools/widgets.
Partially revert commit c73710e410,
avoiding updating tool widgets unconditionally on tool resume in
GimpDrawTool -- it's too expensive in general.
Instead, handle display-shell changes in GimpToolWidget, by adding
GimpToolWidget::update_on_{scale,scroll,rotate} flags, which
subclasses can use to request an update on any of these events.
Set the flags as necessary for the affected widgets.
Wherever we store arbitrary-format colors in an opaque buffer, use
double for the buffer, instead of char, so that it has a strict-
enough alignment to handle all our used pixel formats.
It means forbidding gradient tool to work (with appropriate error
message) on multiple selection. Applying gradient on several layers at
once is not supported at this point.
Multi-drawable selection for text tool only matters for positionning the
newly created text layer, if relevant. If a single layer is selected, it
will be same as before.
With multiple selection, the new layer just ends up to the top in case
of layers from different containers.
Color picking on a single layer still works as it used to. On multiple
layer, it will now pick on the composited color, similarly to sample
merged if only selected layers were made visible.
The PDB/libgimp function gimp_image_pick_color() is also updated to work
on multiple drawables too, giving the same ability to plug-ins (the only
call to this function in core plug-ins have been updated).
These actions raise a GimpViewableDialog. For this to work, I made this
widget work with a list of GimpViewable, not a single viewable anymore
(so maybe the widget class name should change?).
When this list contains only a single GimpViewable, it will display
exactly like before, with a viewable preview. With several viewables,
the preview won't show.
This allows to add masks to all selected layers at once, with the same
basic options for all masks, as set in the dialog.
After much thought, tests and discussions with Aryeom, we decided adding
back an active item concept additionally to the selected items ones is a
bad idea as it makes only usage unecessarily complex.
We will just have selected layers. Some kind of operations will work
when more than one item (layers, channels, vectors) are selected while
others will require exacty one item.
In particular, let's replace instances of gimp_image_(s|g)et_active_*()
by corresponding gimp_image_(s|g)et_selected_*(). Also replace single
item in various undo classes by GList of items.
Also "active-*-changed" GimpImage signals are no more, fully replaced by
"selected-*s-changed".
This is still work-in-progress.
Though it's not finished yet, I am changing "active layer" into
"selected layers" logics. Probably the "active layer" concept will be
back eventually (i.e. even in a multi-selection a specific layer could
be said "active", highlighted in the list a bit differently, hence one
could edit this specific layer only). But for simplicity, for now, it's
better to first get rid of it, otherwise it's just messy.
gegl:focus-blur blurs the image around a focal point. It can be
used to create fake depth-of-field effects.
Add a prop-gui constructor which uses a FOCUS controller to control
the focus geometry.
In GimpDrawTool, update the tool widget on GIMP_TOOL_ACTION_RESUME,
so that it can respond to changes in the display-shell scale/
offset. We'd previously done that for individual tools/widgets,
but let's just do it in one place.
Properly initialize GimpSelectionTool::saved_operation upon
modifer-key press, even when some modifiers are masked out by
GimpPolygonSelectTool while the tool is active. This avoids
erroneously "restoring" the operation to a previously-saved state
once the modifier keys are released.
... which copies a TransInfo array to the current info array,
possibly with modifications. While the default implementation
simply copies the array as-is, the following commit will override
the function for the Unified Transform tool, to avoid copying the
pivot position when the pivot is locked.
Use the function in GimpTransformGridTool, instead of copying the
array directly, as necessary.
In GimpTransformGridTool, keep the transform-direction chain-button
insensitive while the tool is not active, and always unlink the
button when halting the tool. This avoids the directions from
accidentally being kept linked, resulting in the tool seemingly
having no effect.
In gimp_filter_tool_real_config_notify(), make sure the incoming
pspec in not NULL before accessing it.
gimp_operation_tool_aux_input_notify() may emit "notify" on the
config object with a NULL pspec.
In GimpCurveTool, don't reset the curve config manually, and rather
let GimpFilterTool reset it, only maintaining the active channel
(similarly to GimpLevelsTool), so that the common operation
settings are also reset.
Note that this also avoids keeping the channel curve types, which
should work correctly after last commit.
In gimp_operation_config_sync_node(), when the operation has a
property of the config object's type, don't skip the other
properties. This makes sure to set the "trc" property of
GimpOperation{Curves,Levels} according to the config object. We'd
previously done it manually in GimpFilterTool, but the setting was
not applied when repeating the filter.
As per commit ed7ea51fb7, reintroduce
the "Fade" functionality for filters, by incorporating it directly
into GimpFilterTool.
Add "mode" and "opacity" options to GimpOperationSettings, and add
a corresponding "Fade" expander to the GimpFilterTool dialog
allowing to control them.
Reintroduce the FADE layer-mode context, and use it to mark the
layer modes avaialable for fading.
Remove the common operation settings from GimpFilterOptions, and
instead, in GimpFilterTool, store these settings in the operation's
config object, which is now a GimpOperationSettings subclass, as
per last commit.