after text box moved using Alt key
In gimp_text_tool_button_release(), handle the "moving" case
separately instead of running into the default else branch that
assumes the user clicked outside and made a new text layer.
On tool change, we used to simply halt tools before switching to the
new one, which meant losing ongoing live-previewed tool changes, like
transforms, warps and color corrections. This change makes them being
applied to the image instead before switching to the new tool:
Add enum value GIMP_TOOL_ACTION_COMMIT that is passed to
GimpTool::control() before tool switching. Handle the new enum value
in all tools, and actually commit the previewed stuff. This changes
the behavior of GimpCageTool, GimpImageMapTool, GimpTransformTool and
GimpWarpTool.
Applying a preset overwrites all the tool option's properties, also
temporarily its name. This name change gets auto-synced with the
option's text proxy object which also inherits from GimpObject and has
a name. Make sure we don't queue that name change for being applied to
the text layer's text object, because that code only handles
properties of GimpText itself.
It seems that when the undo action reverts a text -> mark-up change
(or v.v.) the notifications are inverted, first is emitted the new
value notification and successively the property becoming NULL. The
result is that gimp_text_buffer_set_{text,mark-up} is called last with
NULL, unsetting both text_buffer text and mark-up.
The right way to do it is to always prefer "markup" over "text" if
markup is present, no matter if the notification was for "markup" or
"text".
When setting the unit of a property shared with a gimp_prop_size_entry,
a conversion is applied to the corresponding size property (to preserve
size_entry's ref-value), but the conversion risks to change the size
property already updated.
To update, at the same time, size and unit, it is better to start updating
size_entry's unit in order to trigger the useless conversion on the stale
size.
by using the right function to figure the location of both kinds of
cursors. Also fix crash in my last cursor movement commit: check for
error values returned by pango_layout_move_cursor_visually() and don't
try to move the cursor beyond the buffer boundaries.
- add gimp_draw_tool_push_group()/pop_group() which manage a stack
of groups; all items automatically get added to the stack's top group
- use push_group()/pop_group() all over the place, which saves a lot
of code in most cases
- return GimpCanvasGroup not GimpCanvasItem pointers from
gimp_draw_tool_add_stroke_group() and fill_group()
Unrelated:
- add GipmCanvasGroup parameter to gimp_rectangle_tool_draw()
- put rect select's round corners into the stroke group to
avoid ugly overdrawing (the mis-alignment of arcs becomes
very visible now however, will fix that soon)
My earlier change to using gimp_drawable_push_undo() here was a very
bad idea. Go back to using gimp_image_undo_push_drawable_mod(), but
make use of its new tile-copying feature so the problem that made me
do the earlier change is fixed too. See comments in the changed code.
Need to call gimp_text_tool_ensure_layou() in gimp_text_tool_draw()
explicitely now, because we don't redundantly call the
get_cursor_rect() function any more when there is a selection.
- request "click" releases instead of trying to detect them ourselves,
but keep a minimum reasonable text layer size anyway (reduce it from
20 to 3 pixels though).
- ignore RELEASE_CANCEL when selecting, we can't undo that yet.
- properly handle RELEASE_CANCEL when creating new lext layers (don't
leave a dead overlay style editor around).
so we also correctly handle non-text and non-markup changes (e.g. via
tool options). This is not exactly the right place to call
block_drawing(), but all places which change change the actual content
(and thus un-sync buffer and layout cursor posotions) already block
drawing before the actual buffer change happens.
instead of duplicating GimpTextLayout's positioning logic in two
different incomplete ways. Also gets rid of the unrelated offset
return values of gimp_text_tool_editor_get_cursor_rect().
Earlier I claimed that drawing would work now because we make sure
that buffer and layout are always in sync. This was nonsense. In fact,
we constantly ran into the sutiation where the buffer was modified,
and we were drawing with the previous layout. It's unclear why this
didn't cause drawing artifacts, but it did cause e.g. the cursor
temporarily jumping to the next position while editing in the middle
of text (especially visible at line ends).
Several underlying problems existed: first, we now modify the buffer
from outside the text tool (from GimpTextStyleEditor) where we can't
pause the tool; second, proxy changes are handled asymetrically
(property changes are queued and processed all together in an idle
function) so we can't pause/resume drawing across the entire operation
because it has many beginnings and only one end.
Therefore:
- add gimp_text_tool_block_drawing()/unblock_drawing(), where block()
can be called as many times as needed, and a single unblock()
enables drawing again. block() also clears the layout, because it
served its purpose (it was just used to pause drawing, and we know
the buffer will change, so kill it).
- connect to GtkTextBuffer::begin-user-action and call block() from
the callback, so we undraw stuff and kill the cached layout before
any buffer change happens.
- call unblock() at the end of gimp_text_tool_apply() because then
the text and the buffer are in sync again, the tool is undrawn and
we can safely create the layout again to draw our stuff.
- also call block()/unblock() from some other places, like when a
new text layer is created.
- get rid of *all* calls to draw_tool_pause()/resume() around buffer
modifications, they are not needed any longer.
- add calls to begin/end_user_action() where they were missing.
In gimp_text_tool_connect(), set either text *or* markup on the
buffer, or the latter will always override the former (now that text
and markup are mutually exclusive in GimpText).
- in GimpText, make "text" and "markup" mutually exclusive, so that
whenever one is set to non-NULL, the other is cleared automatically.
- add gimp_text_buffer_has_markup() which returns TRUE if any char
in the buffer is tagged.
- in the text tool, only set "markup" on the text proxy if there is
actually markup in the buffer, and set "text" otherwise.
This way we don't push "text" *and* "markup" undos on each keystroke,
and undo compression works the way it did before.
- Add signal GimpText::changed() and emit it from
GObject::dispatch_properties_changed() after all notifications have
been emitted, so "changed" is emitted only once for any number of
properties set within a g_object_freeze/thaw_notify() pair.
- Connect GimpTextLayer to "changed" instead of "notify" so we aviod
lots of expensive re-rendering when multiple properties are set
at once.
- Connect GimpTextTool to "notify" *and* "changed", and move some
common code to the "changed" callback (e.g. we don't need to
re-frame the item for each set property).
Add gimp_text_buffer_get_iter_at_index() which does the reverse thing
than the already existing function gimp_text_buffer_get_iter_index().
Use the new function when cursor-navigation lines. Add "gboolean
layout_index" to both functions, which if TRUE indicates that the
passed in/out index is an index into the PangoLayout's content rather
than the text buffer's. When dealing with layout indices, take into
account the additional characters we insert into the serialized markup
(and thus the layout) for each character that is tagged with spacing.