From: Matthias Clasen Date: Fri, 22 May 2020 18:06:00 +0000 (-0400) Subject: gtk-demo: Improve editing in the dnd demo X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~16^2~126^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7fac6b37db2ed16768f63b1b8d0950c24e446fdd;p=gtk4.git gtk-demo: Improve editing in the dnd demo Add a scale for the angle, make the edits apply immediately, and keep the item visible. --- diff --git a/demos/gtk-demo/dnd.c b/demos/gtk-demo/dnd.c index a3f0097648..8f82d0c47b 100644 --- a/demos/gtk-demo/dnd.c +++ b/demos/gtk-demo/dnd.c @@ -17,6 +17,8 @@ struct _CanvasItem { double x, y; double angle; double delta; + + GtkWidget *editor; }; struct _CanvasItemClass { @@ -161,6 +163,7 @@ canvas_item_dispose (GObject *object) CanvasItem *item = CANVAS_ITEM (object); g_clear_pointer (&item->label, gtk_widget_unparent); + g_clear_pointer (&item->editor, gtk_widget_unparent); G_OBJECT_CLASS (canvas_item_parent_class)->dispose (object); } @@ -193,6 +196,79 @@ canvas_item_get_drag_icon (CanvasItem *item) return gtk_widget_paintable_new (item->label); } +static gboolean +canvas_item_is_editing (CanvasItem *item) +{ + return item->editor != NULL; +} + +static void +scale_changed (GtkRange *range, + CanvasItem *item) +{ + item->angle = gtk_range_get_value (range); + apply_transform (item); +} + +static void +text_changed (GtkEditable *editable, + GParamSpec *pspec, + CanvasItem *item) +{ + gtk_label_set_text (GTK_LABEL (item->label), gtk_editable_get_text (editable)); +} + +static void +canvas_item_stop_editing (CanvasItem *item) +{ + GtkWidget *scale; + + if (!item->editor) + return; + + scale = gtk_widget_get_last_child (item->editor); + g_signal_handlers_disconnect_by_func (scale, scale_changed, item); + + gtk_fixed_remove (GTK_FIXED (gtk_widget_get_parent (item->editor)), item->editor); + item->editor = NULL; +} + +static void +canvas_item_start_editing (CanvasItem *item) +{ + GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item)); + GtkWidget *entry; + GtkWidget *scale; + + if (item->editor) + return; + + item->editor = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + + entry = gtk_entry_new (); + + gtk_editable_set_text (GTK_EDITABLE (entry), + gtk_label_get_text (GTK_LABEL (item->label))); + + gtk_editable_set_width_chars (GTK_EDITABLE (entry), 12); + g_signal_connect (entry, "notify::text", G_CALLBACK (text_changed), item); + g_signal_connect_swapped (entry, "activate", G_CALLBACK (canvas_item_stop_editing), item); + + gtk_box_append (GTK_BOX (item->editor), entry); + + scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 360, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_range_set_value (GTK_RANGE (scale), fmod (item->angle, 360)); + + g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed), item); + + gtk_box_append (GTK_BOX (item->editor), scale); + + gtk_fixed_put (GTK_FIXED (canvas), item->editor, item->x, item->y + 50); + gtk_widget_grab_focus (entry); + +} + static GdkContentProvider * prepare (GtkDragSource *source, double x, @@ -293,47 +369,16 @@ new_item_cb (GtkWidget *button, gpointer data) gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER))); } -static void -edit_label_done (GtkWidget *entry, gpointer data) -{ - GtkWidget *canvas = gtk_widget_get_parent (entry); - CanvasItem *item; - int x, y; - - gtk_fixed_get_child_position (GTK_FIXED (canvas), entry, &x, &y); - - item = CANVAS_ITEM (g_object_get_data (G_OBJECT (entry), "item")); - gtk_label_set_text (GTK_LABEL (item->label), gtk_editable_get_text (GTK_EDITABLE (entry))); - gtk_widget_show (GTK_WIDGET (item)); - - gtk_fixed_remove (GTK_FIXED (canvas), entry); -} - static void edit_cb (GtkWidget *button, GtkWidget *child) { - GtkWidget *canvas = gtk_widget_get_parent (child); CanvasItem *item = CANVAS_ITEM (child); - GtkWidget *entry; - double x, y; - - gtk_widget_translate_coordinates (child, canvas, 0, 0, &x, &y); - - entry = gtk_entry_new (); - - g_object_set_data (G_OBJECT (entry), "item", item); - - gtk_editable_set_text (GTK_EDITABLE (entry), - gtk_label_get_text (GTK_LABEL (item->label))); - - gtk_editable_set_width_chars (GTK_EDITABLE (entry), 12); - g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL); - gtk_fixed_put (GTK_FIXED (canvas), entry, x, y); - gtk_widget_grab_focus (entry); - gtk_widget_hide (child); if (button) gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER))); + + if (!canvas_item_is_editing (item)) + canvas_item_start_editing (item); } static void @@ -412,15 +457,20 @@ released_cb (GtkGesture *gesture, { GtkWidget *widget; GtkWidget *child; + CanvasItem *item; widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)); child = gtk_widget_pick (widget, x, y, 0); - child = gtk_widget_get_ancestor (child, canvas_item_get_type ()); + item = (CanvasItem *)gtk_widget_get_ancestor (child, canvas_item_get_type ()); + if (!item) + return; if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY) { - if (child != NULL && child != widget) - edit_cb (NULL, child); + if (canvas_item_is_editing (item)) + canvas_item_stop_editing (item); + else + canvas_item_start_editing (item); } }