From e526540552364a16ca9f8f8aa35a5aef224e763e Mon Sep 17 00:00:00 2001 From: Gabriele Barbero Date: Fri, 6 Jun 2025 21:06:41 +0200 Subject: [PATCH] tools: fix on-canvas text editor position on screen after being moved After the on-canvas text editor has been moved, it should remain fixed on the screen when zooming or panning the canvas. This commit preserves the current behavior when the editor is in its original position, and fixes its position on-screen after it has been moved. --- app/tools/gimptexttool-editor.c | 23 +++++++++++++++++++---- app/widgets/gimpoverlaybox.c | 2 +- app/widgets/gimpoverlaychild.c | 27 +++++++++++++++++++-------- app/widgets/gimpoverlaychild.h | 3 +++ 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c index dc5716b2f1..7d9e7f08a0 100644 --- a/app/tools/gimptexttool-editor.c +++ b/app/tools/gimptexttool-editor.c @@ -43,6 +43,7 @@ #include "widgets/gimpdialogfactory.h" #include "widgets/gimpdockcontainer.h" #include "widgets/gimpoverlaybox.h" +#include "widgets/gimpoverlaychild.h" #include "widgets/gimpoverlayframe.h" #include "widgets/gimptextbuffer.h" #include "widgets/gimptexteditor.h" @@ -1930,8 +1931,11 @@ gimp_text_tool_style_overlay_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { - GimpTextTool *text_tool = GIMP_TEXT_TOOL (user_data); - GtkWidget *event_widget = gtk_get_event_widget ((GdkEvent*) event); + GimpTextTool *text_tool = GIMP_TEXT_TOOL (user_data); + GtkWidget *event_widget = gtk_get_event_widget ((GdkEvent*) event); + GimpTool *tool = GIMP_TOOL (text_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpOverlayChild *child_overlay = NULL; if (event_widget != GTK_WIDGET (text_tool->style_overlay) && gtk_widget_is_ancestor (event_widget, GTK_WIDGET (text_tool->style_editor))) @@ -1955,6 +1959,10 @@ gimp_text_tool_style_overlay_button_press (GtkWidget *widget, text_tool->drag_offset_x = event->x; text_tool->drag_offset_y = event->y; + child_overlay = gimp_overlay_child_find (GIMP_OVERLAY_BOX (shell->canvas), + text_tool->style_overlay); + gimp_overlay_child_set_relative_to_shell (child_overlay, FALSE); + return TRUE; } @@ -1963,8 +1971,11 @@ gimp_text_tool_style_overlay_button_release (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { - GimpTextTool *text_tool = GIMP_TEXT_TOOL (user_data); - GtkWidget *event_widget = gtk_get_event_widget ((GdkEvent*) event); + GimpTextTool *text_tool = GIMP_TEXT_TOOL (user_data); + GtkWidget *event_widget = gtk_get_event_widget ((GdkEvent*) event); + GimpTool *tool = GIMP_TOOL (text_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpOverlayChild *child_overlay = NULL; if (event_widget != GTK_WIDGET (text_tool->style_overlay) && gtk_widget_is_ancestor (event_widget, GTK_WIDGET (text_tool->style_editor))) @@ -1974,6 +1985,10 @@ gimp_text_tool_style_overlay_button_release (GtkWidget *widget, text_tool->overlay_dragging = FALSE; + child_overlay = gimp_overlay_child_find (GIMP_OVERLAY_BOX (shell->canvas), + text_tool->style_overlay); + gimp_overlay_child_set_relative_to_shell (child_overlay, TRUE); + if (gtk_widget_get_window (GTK_WIDGET (text_tool->style_overlay))) gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (text_tool->style_overlay)), NULL); diff --git a/app/widgets/gimpoverlaybox.c b/app/widgets/gimpoverlaybox.c index ef879e54ed..c66ff0905a 100644 --- a/app/widgets/gimpoverlaybox.c +++ b/app/widgets/gimpoverlaybox.c @@ -430,7 +430,7 @@ gimp_overlay_box_set_child_position (GimpOverlayBox *box, { GimpOverlayChild *child = gimp_overlay_child_find (box, widget); - if (child) + if (child && ! child->relative_to_shell) { if (! child->has_position || child->x != x || diff --git a/app/widgets/gimpoverlaychild.c b/app/widgets/gimpoverlaychild.c index 7bed66af2b..a739d8a3ae 100644 --- a/app/widgets/gimpoverlaychild.c +++ b/app/widgets/gimpoverlaychild.c @@ -70,14 +70,15 @@ gimp_overlay_child_new (GimpOverlayBox *box, child = g_slice_new0 (GimpOverlayChild); - child->widget = widget; - child->xalign = CLAMP (xalign, 0.0, 1.0); - child->yalign = CLAMP (yalign, 0.0, 1.0); - child->x = 0.0; - child->y = 0.0; - child->has_position = FALSE; - child->angle = angle; - child->opacity = CLAMP (opacity, 0.0, 1.0); + child->widget = widget; + child->xalign = CLAMP (xalign, 0.0, 1.0); + child->yalign = CLAMP (yalign, 0.0, 1.0); + child->x = 0.0; + child->y = 0.0; + child->relative_to_shell = FALSE; + child->has_position = FALSE; + child->angle = angle; + child->opacity = CLAMP (opacity, 0.0, 1.0); cairo_matrix_init_identity (&child->matrix); @@ -509,6 +510,16 @@ gimp_overlay_child_pick (GimpOverlayBox *box, return FALSE; } +void +gimp_overlay_child_set_relative_to_shell (GimpOverlayChild *child, + gboolean relative_to_shell) +{ + g_return_if_fail (child != NULL); + + child->relative_to_shell = relative_to_shell; +} + + /* private functions */ diff --git a/app/widgets/gimpoverlaychild.h b/app/widgets/gimpoverlaychild.h index 3e752a7dbf..b877da243c 100644 --- a/app/widgets/gimpoverlaychild.h +++ b/app/widgets/gimpoverlaychild.h @@ -29,6 +29,7 @@ struct _GimpOverlayChild GtkWidget *widget; GdkWindow *window; + gboolean relative_to_shell; gboolean has_position; gdouble xalign; gdouble yalign; @@ -82,6 +83,8 @@ gboolean gimp_overlay_child_pick (GimpOverlayBox *bo GimpOverlayChild *child, gdouble box_x, gdouble box_y); +void gimp_overlay_child_set_relative_to_shell (GimpOverlayChild *child, + gboolean relative_to_shell); #endif /* __GIMP_OVERLAY_CHILD_H__ */