Commit f5cb1fed85, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
First WIP commit, adds:
- enum GimpGradientBlendColorSpace { RGB_PERCEPTUAL, RGB_LINEAR }
- linear blending mode for gradient segments
- tool options GUI for the blend and paint tools which use gradients
Most expected behavior in normal transform is to see the preview,
whereas you usually don't want to see it in corrective mode. In 2.8
actually, it seems like it was not even possible to see the image
preview in corrective mode.
So let's set "show-preview" to these defaults when "direction" property
is updated. It is still possible to change it manually for any specific
use cases (i.e. you can hide the preview in normal transform, and
oppositely you can show it in corrective transform), but at least now
defaults are sane.
... or during rotation.
If checked before rotation, it works as expected, i.e. one sees only the
original or the rotated image.
While rotation is in progress: if unchecked, one sees neither the
original nor the image preview; if checked, one sees both original and
rotated preview.
Let's make the behavior consistent and only show exactly one version at
all time.
In GimpPaintTool, brush outline generation took place during
gimp_paint_tool_draw() even while painting. This function is run
concurrently with the paint thread. When using dynamics, this
introduced a race conidition between updating the brush mask in the
paint thread, and updating the brush boundary in the main thread.
Move brush outline generation during painting to
gimppainttool-paint.c, and perform it in the display-update
timeout, while the main thread and the paint thread are
synchronized.
After last commit, all paint tools work correctly with a separate
paint thread, so we can remove the option for specific paint tools
to opt out. Particularly, GimpMybrushTool now uses a separate
paint thread too.
Note that the separate paint thread can still be disabled through
the GIMP_NO_PAINT_THREAD environment variable.
Reorganize/clean up gimppainttool-paint. In particular, move all
paint-core interaction during painting to gimppainttool-paint.c, so
that we can have more control over what's going on; specifically,
enter the drawable into paint mode *before* starting the paint
core, so that it picks up the correct buffer. This fixes painting
with the paint thread using GimpApplicator, and enables us to use
the paint thread with GimpMybrushTool.
Add gimppainttool-paint.[ch], which takes care of painting during
motion events in GimpPaintTool. Perform the actual painting in a
separate thread, so that display updates, which can have a
significant synchronization overhead, don't stall painting.
Allow specific paint tools to opt-out of a separate paint thread,
and avoid it in GimpMybrushTool, since it doesn't seem to work.
The separate paint thread can be explicitly disabled by setting the
GIMP_NO_PAINT_THREAD environment variable.
Similar to commit 845eb522b6, I had a CRITICAL which happened on a
device_changed, triggering gimp_display_shell_update_focus(), this time
in focus in.
Commit fd6d4931c8 accidentally
introduced a bug that caused Wilber's eyes to misbehave. This
commit is an attempt to fix this issue. Unfortunately, it seems
like the bug can still be triggered through a certain sequence of
actions...
Add signal GimpTextBuffer::color-applied which is emitted when text is
inserted or when color is applied to a span of text.
In GimpTextTool, connect to the signal and update the global color
history.
Unrelated: rename gimp_text_tag_get_color() to get_fg_color() and add
boolean return values to get_fg_color() and get_fg_color() which
indicates if a color is set on the tag at all. This ended up unneeded
in the fix but is an improvement regardless.
Add a crop_input parameter to gimp_gegl_apply_[cached_]operation().
When TRUE, the functions crop the op's input to the destination
rect. This is particularly useful for functions that process the
entire input in one go (by means of get_cached_region()). See the
next commit.
Pass crop_input = FALSE at all call sites for now, to keep the
current behavior.
Focus change events were expecting the current tool control to be
inactive, which was the case most of the time. Yet with stylus, the
canvas was sometimes receiving GDK_BUTTON_PRESS events before
GDK_FOCUS_CHANGE. In particular the canvas was receiving a button press
before the focus out, then button release and focus in. Therefore by the
time the focus out event happens, the tool control is active, which
broke a few calls.
Therefore I add a few checks and returns immediately when
gimp_tool_control_is_active() return TRUE, especially since we also run
gimp_display_shell_update_focus() calls after a button press anyway so
the state should already be consistent.
Add a gimp_filter_tool_reset_widget() function, which resets the
tool widget associated with the filter's controller -- i.e., it
resets those properties of the widget that aren't controlled by the
op's properties to some "default" state. For most controller types
this is a NOP; for transform-grid controllers, we move the pivot
back to the center of the drawable, w.r.t. the current transform.
Call gimp_filter_tool_reset_widget() after resetting or reloading
the tool's config.
...only remembers horizontal radius, duplicates it for vertical
Keep a list of the GUI's chain buttons around. When changing the
entire config object like on reset or selecting saved settings, unlik
them all after remembering their "active" state, and after changing
the settings activate the ones that were active before, but only if
the values they link are still the same.
... when gradient_type >= GIMP_GRADIENT_SHAPEBURST_ANGULAR.
Our current GUI code for the Blend tool options disables the "Repeat"
widget with any of the shaped and spiral gradient types, which means (I
assume) no repeat mode is allowed on these gradients. Nevertheless it
was possible to change the repeat mode in another gradient type, then
switch to one of these and get the repeat processed even though the GUI
shows insensitive.
I could simply reset the repeat mode to GIMP_REPEAT_NONE when setting
one of these gradient types, but I think you'd want the repeat to stay
at its value (being insensitive is enough to mean whatever value is set
is not taken into account). So instead, I just unsync this specific
property when appropriate.
Note also I don't do this in the gimp:blend operation code because I am
not sure this specific behavior is meant to be a generic blend behavior
or just relative to the tool (render of the shaped gradients is barely
different with a repeat, but there is still a difference).
It seems old blend tool (from GIMP 2.8) was using manhattan distance,
whereas the new one uses euclidean. I guess there must be use cases for
both. In any case, it is a good idea to simply propose the option since
the property exists in the "gegl:distance-transform" operation.
See also bug 781621.
When starting the tool with one of the gradient types for which the
repeat option should be deactivated, it is not. Run the handler function
once at GUI creation.
Also compare the gradient type with an enum value, which makes the test
clearer than using an int.
... which allows ops to create a transform-grid widget, similar to
the unified-transform tool, which can be used to control a
transformation matrix.
Implement the transform-grid controller in GimpFilterTool.
... current aspect ratio
In gimp_{rectangle_select,crop}_tool_start(), move
GimpToolRectangle signal connection to the end of the function. In
particular, connect the signals *after* the call to
gimp_{rectangle_select,crop}_tool_update_option_defaults(), since
it may result in an emission of a "change-complete" signal, whose
handler calls the function again with ignore_pending == FALSE, which
would override the ratio set with ignore_pending == TRUE.
Don't choke when calling gimp_tool_rectangle_set_constraint() while
there's no active image, or while the active image has no active
layer, which can happen when updating the default aspect ratio of
the crop tool. This would previously result in CRITICALs.
Additionally, use weak pointers for the crop tool's current_image
and current_layer members, to avoid potential dangling pointers.
While not currently necessary, this makes the code less dependent
on the exact order of events.
... current aspect ratio
When updating the default aspect ratio of a widget-less crop tool,
construct a temporary GimpToolRectangle widget, so that we can use
it to call gimp_tool_rectangle_constraint_size_set() and pick the
correct ratio, instead of just bailing.
When halting the crop tool, update the default aspect ratio, which
now does the right thing, as per the above.
Update the default aspect ratio upon changes to the active layer of
the current image, and to the size of the active layer, which
affect the default aspect ratio when "current layer only" is
toggled.
... current aspect ratio
When starting the rectangle-select (and ellipse-select) tools,
properly reset their default aspect ratio to 1:1. This fixes an
issue where the tool would use the aspect ratio of the last
rectangle when there's no user-overriden aspect ratio specified.
This restores the 2.8 behavior, except for the fact that the aspect
ratio resets to 1:1 when the tool is commited (if there's no user-
overriden ratio), rather than keeping the aspect ratio of the last
rectangle (i.e. "Current"); in 2.8 this only happend when halting.
The current behavior seems more consistent anyway.
Set the scale of the GimpRectangleOptions highlight-opacity
spinscale to 100, so that the spinscale's range is 0-100, instead
of 0-1, like the rest of our opacity spinscales.
... a selection.
The crash was the result of an unmatched gimp_item_end_move() call,
which is an error. Add the matching gimp_item_start_move() call
when starting to drag a selection in GimpEditSelectionTool. Revert
last commit, so that unmatched gimp_layer_end_move() calls are not
silently ignored, and add a check instead.
which is just a #define to g_assert for now, but can now easily be
turned into something that does some nicer debugging using our new
stack trace infrastructure. This commit also reverts all constructed()
functions to use assert again.
A tool commit can be triggered in various cases, and the tool manager
relies on gimp_tool_has_display() to decide whether to run a tool
action. This function does much more than just checking GimpTool's
display. It also checks status_displays, and for a transform tool in
particular, it checks GimpDrawTool's display. This may be right for
other tools (I have no idea), so I can't just change this function.
Anyway we have to assume it is not a programming error if a transform
tool gets a COMMIT action while display is NULL (i.e. tool is halted).
When this happens, let's simply ignore.
This fixes the edge case raised by Ell, in comment 2 of bug 793150: when
an image has no layer, transform tools can't work and display is NULL.
But it still outputs status messages and therefore status_displays is
not empty. So the tool manager will still run a COMMIT action, which is
not an error. We only have to discard such COMMIT silently.
Improving previous commit. Rather than calling:
> GIMP_TOOL_GET_CLASS (tool)->control (tool,
GIMP_TOOL_ACTION_HALT,
display)
> gimp_tool_clear_status()
... in the COMMIT action, which is basically what the HALT action does,
simply pass through from one case to the other. It also adds the call to
gimp_tool_control_halt() which is most likely right anyway since we are
halting the tool. This also makes the code consistent and any future
changes to HALT case will be directly enabled after COMMIT.
... 'GIMP_IS_DISPLAY (display)' failed.
This may happen when committing first a transform tool, then switching
to another tool. In this case, the tool manager will attempt to commit
again because gimp_tool_has_display() returns TRUE since status displays
were not cleared. Unfortunately transform tools don't handle very well
trying to commit when it was already done (hence both GimpTool and
GimpDrawTool displays are NULL).
The proposed solution is to clear the statuses after committing.
Add gimp_item_{start,end}_move(), and corresponding
GimpItem::{start,end}_move() virtual functions, which should be
called before/after "moving" the item (i.e., translating, scaling,
resizing, flipping, rotating, or transforming the item). Moves
performed between the outermost pair of start/end calls are treated
atomically.
What exactly does "treated atomically" entail depends on the
subclasses -- GimpItem doesn't provide a default implementation for
these functions, so the current commit doesn't change any behavior.
The next commit, which adds layer-mask support for group layers,
uses the functions to avoid cropping the mask too early while a
child is moving.
GimpItem calls {start,end}_move() in the various "move" functions
(gimp_item_{translate,scale,...}(), before performing the actual
operation. Additionally we call the functions in the
gimp_image_item_list_foo() functions, for each participating item,
so that the items are moved as a unit. We call the functions in
the various gimp_image_remove_foo() functions, since removing an
item may affect the size of its ancestors, and is therefore akin to
moving. We also call the functions in GimpEditSelectionTool, so
that the move tool moves items atomically while dragging.
This reverts 2069496af3 for
gimpmeasuretool.c, we can't use gimp_display_shell_get_line_status()
here because the angle to show is *not* the angle as shown in the
paint tools (between x1,y1 and x2,y2), it is determined by a possible
third point.
Also, the info window and the statusbar were using different
coordintates to detemine the line length. This would have been easily
fixable, but the wrong angle wasn't.
Derive GimpUnifiedTransformTool, GimpPerspectiveTool, and
GimpHandleTransformTool from GimpGenericTransformTool, eliminating
their common logic.
Remove gimp_transform_matrix_handles(), which is no longer used.
A subclass of GimpTransformTool, to be used as a base class for
transform tools that calculate their matrix based on 4 pairs of
input/output points, and that display the transform matrix as their
GUI (this includes the unified, perspective, and handle transform
tools; the next commit ports them over to
GimpGenericTransformTool).
When the resulting matrix of the input/output mapping sends any of
the output points to, or past, infinity, GimpGenericTransformTool
sets GimpTransformTool::transform_valid to FALSE, and displays an
appropriate message in the tool GUI, instead of showing the matrix.
... which specifies whether the transform matrix is valid.
Subclasses can then set this member to indicate that the current
transformation is invalid (which can happen in the unified,
perspective, and handle transform tools). When the transform is
invalid, GimpTransformTool doesn't apply it upon committing, and
returns an error instead.
This commit doesn't set the transform_valid member in any of the
subclasses, so there's no effective change. The next commit adds a
GimpGenericTransformTool subclass, that will use the new member.
The four remaining "classic" color tools (Brightness-Contrast, Curves,
Levels and Threshold) are in fact just special UIs for otherwise
completely normal filter ops.
Add normal filter actions for them and invoke them like all
other filters, which makes them show up in the filter history
automatically.
The only small hack needed is to special case them in
gimp_gegl_procedure_execute_async() so the right tools are created
instead of the default GimpOperationTool. Also, blacklist the
automatically generated tools actions from action search and the
shortcut editor.
...instead of center
The scale tool implicitly uses GimpToolTransformGrid's "pivot-x" and
"pivot-y" properties, so they need to be properly initialized and
updated to be at the grid's center.
Also add a tool options toggle "Around center".
When the active modifier mode is GIMP_TOOL_ACTIVE_MODIFIERS_SAME (the
tool does not want to distinguish between modifier states depending
on whether or not the first mouse button down), we need to make sure
these states are in sync in GimpTool's bookkeeping, and we must not
generate synthetic modifier releases when the mouse button is
released.
...and present linear RGB Histograms
This is step one: implement the feature at all (without new defaults
or proper GUI, cough).
Add boolean "linear" properties to GimpOperationPointFilter,
GimpCurvesConfig and GimpLevelsConfig.
In the filter, simply set the input/output formats to linear in
prepare().
In the curves and levels tools, add "Linear" toggles from hell,
like in the histogram dockable, and make sure things work right
wrt changing and resetting the property, switching from levels
to curves, and picking colors.
The result currently changes when switching a non-nop curves/levels
between perceptual and linear, because adjusting the parameters
between the spaces is not implemented yet.
Add "clamp-input" (which clamps the input values to [0..1])
and "clamp-output" (which clips the final result to [0..1]),
properties, parameters and GUI to:
- GimpLevelsConfig
- GimpOperationLevels
- The levels tool dialog
- The gimp_drawable_levels() PDB API
The old deprecated gimp_levels() PDB API now sets both clamping
options to TRUE which restores the 2.8 behavior.
Also reorder some stuff in GimpLevelsConfig and elsewhere so the
levels parameters are always in the same order.
...outside area of Crop Tool -> Highlight option
Add "highlight-opacity" property and turn the controlling GUI into an
expanding toggle that reveals an opacity slider.
If the user enters a value in the shear tool dialog, that value must
be honored. Always set the shear direction to the edited axis and
reset the other axis to 0.
Replace the "lock brush size to zoom" paint option with a "lock
brush to view" option, which links the entire brush transform to
the view transform, so that the brush remains invariant in display
space under scaling, rotation, and reflection.
Add support for reflecting brushes as part of their transformation.
The reflection is performed as the last step of the transformation,
across the vertical axis.
The option to reflect the brush is not exposed in the UI, or
through the PDB, but is intended to be used for linking the brush
transformation to the view transformation, in the next commit.
Add an offset_angle parameter to gimp_constrain_line(), which
offsets the radial lines by a given angle.
Add gimpdisplayshell-utils.[ch], with two new functions:
- gimp_display_shell_get_constrained_line_offset_angle():
Returns the offset angle to be passed to
gimp_constrain_line(), in order to constrain line angles in
display space, according to the shell's rotation angle and
flip mode.
- gimp_display_shell_constrain_line(): A convenience function
which calls gimp_constrain_line() with the said offset angle.
Use the new functions in all instances where we constrain line
angles, so that angles are constrained in display space, rather
than image space.
The only exception is GimpEditSelectionTool, which keeps
constraining angles in image space, since it's not entirely obvious
that we want to constrain angles of dragged layers/selections in
display space.
Replace the GIMP_BOUNDARY_HALF_WAY macro by two others : one for perceptual and
one for linear gamma.
Use the GIMP_BOUNDARY_HALF_WAY_LINEAR to compute channels and floating selection
boundaries.
The free select tool now commits on double click inside a closed
polygon, which caused the foreground select tool to switch modes in
the middle of a click, breaking both its own and its parent class'
state.
Fixed by detecting whether the commit was done by double click and
delaying the mode switch until after the parent class button release
code is done.
Unrelated: Don't call both COMMIT and HALT, the generic tool mechanism
does that automatically now, forgot to port this file.
...is a regression in common cases
Commit the free select tool on double click inside the polygon.
Done by implementing GimpCanvasItem::hit() in GimpCanvasPolygon, using
ugly code.
Update the dprod production of generated enum files to include
abbreviated value descriptions, as per the previous commits.
Add a comment for translators above the abbreviated descriptions,
specifying the full description they abbreviate.
When a single blend-tool action adds and removes the same gradient
stop, restore the original gradient, rather than actually adding
and removing the stop, so that the affected midpoint returns to its
original state at the beginning of the action, rather than being
reset (and, consequently, so that the redo stack isn't lost.)
... from the undo stack
When a blend-tool edit action modifies the gradient, do a deep
comparison of the original gradient against the current gradient,
to test if anything changed, instead of just assuming that
something did change.
In GimpCanvasTransformPreview, use the transform matrix to
determine if we're doing a perspective transform, rather than
relying on a separate property, so that we don't use the slow
perspective path unnecessarily.
Consequently, remove the does_perspective member of
GimpTransformTool, since it's no longer used.
Change gimp_tool_set_active_modifier_state() to honor the new
GimpToolControlSetting. Explicitly set the mode to SEPARATE in
all tools that require modifier keys during a stroke.
And here comes the actual fix: change GimpTransformTool and
GimpToolTransformGrid to use SAME mode, and remove their
active_modifer_key() and hover_modifier() impls, so it makes no
difference whether a modifier is pressed before of after mouse button
press/release.
Add new enum GimpToolActiveModifiers { OFF, SAME, SEPARATE } and
new API gimp_tool_control_set,get_active_modifiers(), the default
value is OFF.
OFF: the tool gets no modifier keys at all during a stroke
SAME: all modifiers are always delivered via GimpTool::modifier_key(),
and no magic is applied whatsoever when a mouse button is pressed or
released.
SEPARATE: this is the "classic" way: modifiers while hovering and
while stroking are delivered separately, and hover modifiers don't
affect stroke modifiers.
Add a framework for saving and restoring internal data objects, in
gimp-internal-data.c. Internal data objects are saved in separate
files under a new "internal-data" subdirectory of the user's gimp
directory. The internal data is saved, restored, and cleared
together with the tool options.
Use this to save and restore the custom gradient. In the future,
we might add similar writable internal data objects that we'd want
to save.
gimp_dockable_blink() is used to attract the user's attention to a
specific dockable. Generalize this to arbitrary widgets, by
replacing gimp_dockable_blink[_cancel]() with
gimp_widget_blink[_cancel](), in gimpwidgets-utils.c.
Allow propgui constructors to specify an (optional) callback function
when creating pickers, to be called when a color/coordinate is picked,
similarly to controller callbacks.
Implement picker callback support in GimpFilterTool. When the active
picker has an associated callback function, call it instead of the
class's color_picked() function.
Add lots of "#include <gegl.h>" to .c files that miss it, which is
now necessary, since this commit adds a Babl* parameter in
propgui-types.h.
When one of the line widget's properties changes, only update the
blend tool filter if the property has an effect on the result. In
particular, don't update the filter when only the selection
changes.
Separate the handling of changes to the FG/BG color from the gradient
dirty signal handling, so that the gradient editor doesn't purge the
history in response. Additionally, correctly respond to such changes
whenever the gradient has segments that depend on the FG/BG colors,
even if the dependency is introduced after the gradient is selected.
Move the tool undo functionality of the blend tool to the editor,
and add support for undoing gradient edit operations. Each undo
step that affects the gradient holds, in addition to the line
endpoint poisitions, a copy of the gradient at the beginning of the
operation, as well as necessary information to allow the selection
to "follow" undo. When undoing the operation, the saved gradient
is copied back to the active gradient.
To avoid all kinds of complex scenarios, when the active gradient
changes, or when the gradient is modified externally (e.g., by the
(old) gradient editor), all undo steps that affect the gradient are
deleted from the history, while those that affect only the endpoint
positions are kept.
Allows setting the midpoint's position, blending function, and
coloring type.
The midpoint can be converted to a stop, and centered, through
editor buttons.
Allows setting the stop's position, and its left and right colors
and color types. A chain button can be used to modify the two
colors (and color types) together.
The stop can be deleted through an editor button.
To be used by the blend tool gradient editor to edit the gradient
endpoint/stop/midpoint properties corresponding to the selected
handle.
The GUI is currently empty; the following commits add its contents.
When a midpoint is double-clicked, convert it into a gradient stop
(i.e., split the corresponding segment at the midpoint,) by
responding to the line's handle-clicked signal.
Add a tentative_gradient member to GimpBlendTool, which, when set,
is displayed instead of the current gradient.
Use this to show a version of the gradient with the currently
selected stop deleted, upon receiving a prepare-to-remove-slider
signal, i.e., when the slider is about to be removed.
Add a boolean "modify active gradient" option to the blend tool.
when checked, the active gradient is modified in-place while edited.
When unchecked, the active gradient is copied to the internal
"custom" gradient upon editing, and the custom gradient becomes
subsequently active.
Show a hint when the option is checked, but the active gradient is
non-writable, and can't be edited directly.
This commit adds the new gimpblendtool-editor.[hc] files, which are
where the gradient-editing related functionality of the blend tool
is going to go.
Add a boolean "instant mode" option to the blend tool, togglable
using shift. When checked, commit the gradient immediately when
the mouse is released.
When not in instant mode, don't commit the gradient when clicking
outside the line, since this will become easy to do accidentally
once we add on-canvas gradient editing.
While I am at it, let's spread the improvement to options_box which was
also a weak pointer with g_object_add_weak_pointer(). Let's make it
rather a GWeakRef for the same reason as I did options_gui.
Other than multi-threading (which here is not the problem), using
GWeakRef has the other advantage that it makes the type of pointer
obvious, hence avoiding the kind of errors as fixed in commit 12df796.
One can't just change the pointer value directly, and has to use
g_weak_ref_set(), so such problem won't happen again.
Repalce the two separate size entries, used for the position and
size properties of GimpRectangleOptions, with a single size entry
with two fields, so that they accept ratio expressions. Note that
this doesn't change the UI.
... the matrix is not actually used
Don't abort transform-tool commits when the transformation matrix
is the identity, for transform tools that don't calculate a
transformation matrix to begin with (i.e., the flip tool),
otherwise they do nothing.
...in both the core and libgimp.
Images now know what the default mode for new layers is:
- NORMAL for empty images
- NORMAL for images with any non-legacy layer
- NORMAL_LEGAVY for images with only legacy layers
This changes behavior when layers are created from the UI, but *also*
when created by plug-ins (yes there is a compat issue here):
- Most (all?) single-layer file importers now create NORMAL layers
- Screenshot, Webpage etc also create NORMAL layers
Scripts that create images from scratch (logos etc) should not be
affected because they usually have NORMAL_LEGACY hardcoded.
3rd party plug-ins and scripts will also behave old-style unless they
get ported to gimp_image_get_default_new_layer_mode().
Paint tools in straight line mode (shift click) will now display the
angle in status bar. Angle 0 is considered as the horizontal line from
left to right, and angle is measured counterclockwise from there, which
is the most common convention.
Add "gboolean with_filters" to gimp_drawable_calculate_histogram(),
which is passed as FALSE in almost all places, except the histogram
dockable where we want to see both the drawable's unmodified histogram
*and* the histogram after filters are applied.
and update the grid as soon as a constraint is changed, not only on
the next motion. Change GimpTransformTool to forward the events to the
widget if it exists, but still handle them if it doesn't (yes this
code duplication is ugly, but the widget can hardly handle events if
it doesn't exist...).
More than 2000 lines of code less in app/, instead of
if (instance->member)
{
g_object_unref/g_free/g_whatever (instance->member);
instance->member = NULL;
}
we now simply use
g_clear_object/pointer (&instance->member);
Change the text selection to draw an outline around each selected
glyph. It looks just as ugly as before but at least keeps the text
readable regardless of its color.
if did revert to the previous selection and thus break stuff like
enbaling quick mask or inverting the selection, because I merged the
undo magic it does into gimp_rectangle_select_tool_halt(), whereas
before it was done by the former gimp_rectangle_tool_cancel(), so only
on explicit cancel not HALT from whatever source.
Do the same in the new code and move the undo magic from halt() to
rectangle_response(CANCEL), which is exactly the same distinction as
with the old GimpRectangleTool code.
Don't unconditionally call COMMIT in rectangle_response(), because
that now implicitly HALTs the tool. Instead, check if we got here
because of a click, and call our commit() directly.
GimpOperationTool's aux inputs were not properly ported to the new way
filter tools work (complete destruction and re-creation of the tool
dialog).
Split creating the operation GUI and adding it to the dialog into
separate functions, and call them at the right places.
Call HALT generically in gimp_tool_control() after calling COMMIT, and
remove all hacks in tools that call both COMMIT and HALT or call
halt() from commit().
Some tools interact with their subclasses (e.g. filter tool and
operation tool), and it's essential that COMMIT runs through the
entire class hierarchy before HALT.
Probably breaks something, please test.
Need to keep around the operation's name and its description, so
everything can be re-created when an image is clicked.
Instead, completely shut down GimpOperationTool when GimpGeglTool is
halted, so the next click will bring up a dialog with only the
operation selection combo.
which allow to override stuff from GimpToolInfo for dynamic tools like
GimpFilterTool and friends. When NULL, the getters are falling back to
GimpToolInfo strings.
...and "export_dialog_title"
It's ridiculous to keep this code around for strings that are only
marginally different (and not better) than the strings we can generate
from other strings we have anyway.
to ::can_undo() and ::can_redo(). They still return description
strings and the new naming is slightly off :) but get_undo_desc() will
be needed for something else soon, and half of the time the functions
are indeed used to check whether there are undo/redo staps at all.
Add supprt for placing sliders on a GimpToolLine -- handles that can
be dragged over the line. The sliders are accesible through a new
"sliders" property, and via the gimp_tool_line_{get,set}_sliders()
functions.
Add a slider-line controller, which works like a line controller,
but whose callback also supplies/takes an array of sliders.
Note that the data type for individual sliders is called
GimpControllerSlider (in particular, it's not line specific), so
that we may use it with other controller/tool-widget types in the
future.
Use the new gimp_filter_tool_get_drawable_area() instead of always
using gimp_item_mask_intersect() which is only right when the
operation is applied to the "selection" region. Also call
gimp_operation_tool_sync_op() when the region is changed in the UI.
Pass a "GimpCreateControllerFunc" to all gimppropgui-*.[ch]
constructors which takes a callback (to update the config object when
the on-canvas GUI) and a controller type that determines the
callback's signature, and returns another callback (to update the
on-canvas GUI when the config object changes).
In GimpOperationTool, pass such a GimpCreateControllerFunc that
handles creating and adding on-canvas controller via the new
gimpfiltertool-widgets.[ch]. So far, a simple line like in the
blend tool is supported.
Add a custom GUI for gegl:spiral, and have its origin, radius and
angle controlled by such a line.
which return's the used drawable's offsets and a GeglRectangle
where the filter is applied according to GimpFilterOptions::region
(either the selection or the whole drawable).
and call it from GimpFilterTool's "notify" callback. Remove signal
connections from all subblasses and instead implement ::config_notify().
The config object belongs to GimpFilterTool, and only GimpFilterTool
should know when it's created and can be connected to.
so things from the tool's previous use get destroyed, including their
(maybe dangling) signal connections. Also shut down more stuff in
halt(), including destroying not just hiding the GUI.
because widgets are bound to one GimpDisplayShell. Also, chain up
unconditionally in gimp_color_tool_draw(), we always want to draw the
widget even while picking colors.
The widget is fed events by GimpFilterTool, the actual interaction
with the filters operation and config will be done by subclasses.
The order of precedence when there are multiple possible canvas
interactions is: moving the split preview guide, color picking,
widget.
We can't rely on g_object_unref() in halt() for breaking all property
GBindings between the tool options and GimpToolRectangle, because we
might be in the middle of a signal emission which also refs and keeps
the rectangle alive until the last callback returns. So we had
dangling rectangles interacting with tool options.
Remember all bindings in a list, and break them explicitly when we
shut down the rectangle in halt().
Also, forgot to unset the display's highlight in the rectangle
selection tool.
The tool manager still keeps an active tool which it unrefs on
destruction, triggering a final HALT on the tool, which may want to
lookup tool options to reset something. Happened with the new
widget-ported rectangle select tool.
We were leaking all tool widgets set with gimp_draw_tool_set_widget(),
and those having signal connections to e.g. the display shell were
doing things when they were supposed to be gone. Fixes make check.
- factor out widget creation to new start() function
- and tool shutdown to new halt() function
- connect to "response" and remove key_press()
- remove oper_update(), it was doing the same as the draw tool impl
and a default key_press() handler that emits CONFIRM, CANCEL and RESET
responses. Remove code with the same purpose from all subclasses.
Change tools feed key_press() to the widget and connect to its
"response" instead of implementing key_press() themselves. This will
only be better and less code after the tool side of this is done
generically.
Simply use g_object_bind_property() to connect the grid properties of
GimpTransformOoptions and GimpToolTransformGrid and remove all other
grid property setting code.
This option behaves similarly to the other transform tool, however
it's limited to "adjust" and "clip" only. Now that the flip tool
can reflect across guides, this option is meaningful.