From 83497695fdf98ac3fe2a0bc54b463340372616de Mon Sep 17 00:00:00 2001 From: Gabriele Barbero Date: Mon, 9 Jun 2025 01:06:04 +0200 Subject: [PATCH] tools: store the on-canvas text editor position per text layer Once the on-canvas text editor has been moved, its position should be preserved across editing sessions. This commit stores the editor's position per text layer and restores it when the layer is activated again. --- app/text/gimptextlayer.c | 82 +++++++++++++++++++++++++++++++++ app/text/gimptextlayer.h | 10 ++++ app/tools/gimptexttool-editor.c | 35 +++++++++++--- 3 files changed, 121 insertions(+), 6 deletions(-) diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c index 0083a4b782..3c92994c76 100644 --- a/app/text/gimptextlayer.c +++ b/app/text/gimptextlayer.c @@ -68,6 +68,13 @@ enum struct _GimpTextLayerPrivate { GimpTextDirection base_dir; + + /* on-canvas editor position */ + gboolean style_overlay_positioned; + gdouble style_overlay_x; + gdouble style_overlay_y; + gdouble style_overlay_offset_x; + gdouble style_overlay_offset_y; }; static void gimp_text_layer_rasterizable_iface_init @@ -566,6 +573,81 @@ gimp_item_is_text_layer (GimpItem *item) } +void +gimp_text_layer_set_style_overlay_position (GimpTextLayer *layer, + gboolean positioned, + gdouble x, + gdouble y) +{ + GimpTextLayerPrivate *priv; + + g_return_if_fail (GIMP_IS_TEXT_LAYER (layer)); + + priv = layer->private; + + priv->style_overlay_positioned = positioned; + + /* We want to set "style_overlay_x" and "style_overlay_y" only + * when "positioned" is TRUE. Otherwhise, we only want to set + * "style_overlay_positioned" to FALSE */ + if (positioned) + { + priv->style_overlay_x = x; + priv->style_overlay_y = y; + } +} + +gboolean +gimp_text_layer_get_style_overlay_position (GimpTextLayer *layer, + gdouble *x, + gdouble *y) +{ + GimpTextLayerPrivate *priv; + + g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), FALSE); + + priv = layer->private; + + if (! priv->style_overlay_positioned) + return FALSE; + + *x = priv->style_overlay_x; + *y = priv->style_overlay_y; + + return TRUE; +} + +void +gimp_text_layer_set_style_overlay_offset (GimpTextLayer *layer, + gdouble offset_x, + gdouble offset_y) +{ + GimpTextLayerPrivate *priv; + + g_return_if_fail (GIMP_IS_TEXT_LAYER (layer)); + + priv = layer->private; + + priv->style_overlay_offset_x = offset_x; + priv->style_overlay_offset_y = offset_y; +} + +void +gimp_text_layer_get_style_overlay_offset (GimpTextLayer *layer, + gdouble *offset_x, + gdouble *offset_y) +{ + GimpTextLayerPrivate *priv; + + g_return_if_fail (GIMP_IS_TEXT_LAYER (layer)); + + priv = layer->private; + + *offset_x = priv->style_overlay_offset_x; + *offset_y = priv->style_overlay_offset_y; +} + + /* private functions */ static const Babl * diff --git a/app/text/gimptextlayer.h b/app/text/gimptextlayer.h index 88e4301418..a771c78d30 100644 --- a/app/text/gimptextlayer.h +++ b/app/text/gimptextlayer.h @@ -70,3 +70,13 @@ void gimp_text_layer_set (GimpTextLayer *layer, ...) G_GNUC_NULL_TERMINATED; gboolean gimp_item_is_text_layer (GimpItem *item); + +void gimp_text_layer_set_style_overlay_position + (GimpTextLayer *layer, + gboolean positioned, + gdouble x, + gdouble y); +gboolean gimp_text_layer_get_style_overlay_position + (GimpTextLayer *layer, + gdouble *x, + gdouble *y); diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c index c10a307f46..acceac0ec5 100644 --- a/app/tools/gimptexttool-editor.c +++ b/app/tools/gimptexttool-editor.c @@ -38,6 +38,7 @@ #include "menus/menus.h" #include "text/gimptext.h" +#include "text/gimptextlayer.h" #include "text/gimptextlayout.h" #include "widgets/gimpdialogfactory.h" @@ -284,10 +285,23 @@ gimp_text_tool_editor_position (GimpTextTool *text_tool) "y1", &y, NULL); - gimp_display_shell_move_overlay (shell, - text_tool->style_overlay, - x, y, - GIMP_HANDLE_ANCHOR_SOUTH_WEST, 4, 12); + if (text_tool->layer && + gimp_text_layer_get_style_overlay_position (text_tool->layer, &x, &y)) + { + gimp_display_shell_move_overlay (shell, + text_tool->style_overlay, + x, y, -1, + text_tool->drag_offset_x + 25, + text_tool->drag_offset_y + 25); + } + else + { + gimp_display_shell_move_overlay (shell, + text_tool->style_overlay, + x, y, GIMP_HANDLE_ANCHOR_SOUTH_WEST, + 4, 12); + } + if (text_tool->image) { @@ -1974,6 +1988,12 @@ gimp_text_tool_style_overlay_button_press (GtkWidget *widget, return FALSE; } + /* Prevent moving the overlay + * if no text layer has been created + */ + if (! text_tool->layer) + return FALSE; + if (gtk_widget_get_window (GTK_WIDGET (text_tool->style_overlay))) { GdkCursor *cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (text_tool->style_overlay)), @@ -2051,8 +2071,11 @@ gimp_text_tool_style_overlay_button_motion (GtkWidget *widget, gimp_display_shell_move_overlay (shell, text_tool->style_overlay, x, y, -1, - text_tool->drag_offset_x + DEFAULT_DRAG_OFFSET, - text_tool->drag_offset_y + DEFAULT_DRAG_OFFSET); + text_tool->drag_offset_x + 25, + text_tool->drag_offset_y + 25); + + gimp_text_layer_set_style_overlay_position (text_tool->layer, TRUE, + x, y); } return TRUE;