[recipes/drag-reorder] Initial dnd reordering support
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes/drag-reorder] Initial dnd reordering support
- Date: Sat, 22 Apr 2017 01:27:47 +0000 (UTC)
commit e75163a758e1c19b5fd64fb2f1701673f99444a6
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Apr 21 21:01:47 2017 -0400
Initial dnd reordering support
Instead of the up/down arrows, show a drag handle, and
support drag-and-drop reordering. As a little benefit,
we can now support reordering between different lists.
src/gr-ingredients-viewer-row.c | 85 ++++++++++++++++++++++++++++++++++++++
src/gr-ingredients-viewer-row.ui | 50 ++--------------------
src/recipes-dark.css | 5 ++
src/recipes-light.css | 5 ++
4 files changed, 100 insertions(+), 45 deletions(-)
---
diff --git a/src/gr-ingredients-viewer-row.c b/src/gr-ingredients-viewer-row.c
index c8dd6a2..57b2078 100644
--- a/src/gr-ingredients-viewer-row.c
+++ b/src/gr-ingredients-viewer-row.c
@@ -34,6 +34,7 @@ struct _GrIngredientsViewerRow
GtkWidget *unit_label;
GtkWidget *ingredient_label;
GtkWidget *buttons_stack;
+ GtkWidget *ebox;
char *amount;
char *unit;
@@ -301,15 +302,99 @@ gr_ingredients_viewer_row_class_init (GrIngredientsViewerRowClass *klass)
gtk_widget_class_bind_template_child (widget_class, GrIngredientsViewerRow, unit_label);
gtk_widget_class_bind_template_child (widget_class, GrIngredientsViewerRow, ingredient_label);
gtk_widget_class_bind_template_child (widget_class, GrIngredientsViewerRow, buttons_stack);
+ gtk_widget_class_bind_template_child (widget_class, GrIngredientsViewerRow, ebox);
gtk_widget_class_bind_template_callback (widget_class, emit_delete);
gtk_widget_class_bind_template_callback (widget_class, emit_move_up);
gtk_widget_class_bind_template_callback (widget_class, emit_move_down);
}
+static GtkTargetEntry entries[] = {
+ { "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 }
+};
+
+static void
+drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data)
+{
+ GtkAllocation alloc;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ GtkWidget *row;
+ int x, y;
+
+ row = gtk_widget_get_ancestor (widget, GTK_TYPE_LIST_BOX_ROW);
+
+ gtk_widget_get_allocation (row, &alloc);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
+ cr = cairo_create (surface);
+
+ gtk_style_context_add_class (gtk_widget_get_style_context (row), "during-dnd");
+ gtk_widget_draw (row, cr);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (row), "during-dnd");
+
+ gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
+ g_print ("offset %d %d\n", x, y);
+ cairo_surface_set_device_offset (surface, -x, -y);
+ gtk_drag_set_icon_surface (context, surface);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+}
+
+void
+drag_data_get (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
+{
+ gtk_selection_data_set (selection_data,
+ gdk_atom_intern_static_string ("GTK_LIST_BOX_ROW"),
+ 32,
+ (const guchar *)&widget,
+ sizeof (gpointer));
+}
+
+static void
+drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint32 time,
+ gpointer data)
+{
+ GtkWidget *target;
+ GtkWidget *row;
+ GtkWidget *source;
+ int pos;
+
+ target = gtk_widget_get_ancestor (widget, GTK_TYPE_LIST_BOX_ROW);
+
+ pos = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (target));
+ row = (gpointer)* (gpointer*)gtk_selection_data_get_data (selection_data);
+ source = gtk_widget_get_ancestor (row, GTK_TYPE_LIST_BOX_ROW);
+
+ g_object_ref (source);
+ gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (source)), source);
+ gtk_list_box_insert (GTK_LIST_BOX (gtk_widget_get_parent (target)), source, pos);
+ g_object_unref (source);
+}
+
static void
gr_ingredients_viewer_row_init (GrIngredientsViewerRow *self)
{
gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
gtk_widget_init_template (GTK_WIDGET (self));
+
+ gtk_drag_source_set (self->ebox, GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);
+ g_signal_connect (self->ebox, "drag-begin", G_CALLBACK (drag_begin), NULL);
+ g_signal_connect (self->ebox, "drag-data-get", G_CALLBACK (drag_data_get), NULL);
+
+ gtk_drag_dest_set (GTK_WIDGET (self), GTK_DEST_DEFAULT_ALL, entries, 1, GDK_ACTION_MOVE);
+ g_signal_connect (self, "drag-data-received", G_CALLBACK (drag_data_received), NULL);
}
diff --git a/src/gr-ingredients-viewer-row.ui b/src/gr-ingredients-viewer-row.ui
index 0608480..da276b8 100644
--- a/src/gr-ingredients-viewer-row.ui
+++ b/src/gr-ingredients-viewer-row.ui
@@ -49,42 +49,7 @@
<object class="GtkButton">
<property name="visible">1</property>
<property name="relief">none</property>
- <signal name="clicked" handler="emit_move_up" swapped="yes"/>
- <style>
- <class name="image-button"/>
- <class name="circular"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="visible">1</property>
- <property name="icon-name">go-up-symbolic</property>
- <property name="icon-size">1</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="visible">1</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="emit_move_down" swapped="yes"/>
- <style>
- <class name="image-button"/>
- <class name="circular"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="visible">1</property>
- <property name="icon-name">go-down-symbolic</property>
- <property name="icon-size">1</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="visible">1</property>
- <property name="relief">none</property>
+ <signal name="clicked" handler="emit_delete" swapped="yes"/>
<style>
<class name="image-button"/>
<class name="circular"/>
@@ -92,26 +57,21 @@
<child>
<object class="GtkImage">
<property name="visible">1</property>
- <property name="icon-name">document-edit-symbolic</property>
+ <property name="icon-name">user-trash-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
</child>
<child>
- <object class="GtkButton">
+ <object class="GtkEventBox" id="ebox">
<property name="visible">1</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="emit_delete" swapped="yes"/>
- <style>
- <class name="image-button"/>
- <class name="circular"/>
- </style>
<child>
<object class="GtkImage">
<property name="visible">1</property>
- <property name="icon-name">user-trash-symbolic</property>
+ <property name="icon-name">open-menu-symbolic</property>
<property name="icon-size">1</property>
+ <property name="margin">4</property>
</object>
</child>
</object>
diff --git a/src/recipes-dark.css b/src/recipes-dark.css
index 7ee631e..f308e10 100644
--- a/src/recipes-dark.css
+++ b/src/recipes-dark.css
@@ -25,3 +25,8 @@
background: #868d94;
}
+.during-dnd {
+ background: #232729;
+ border: 1px solid alpha(white, 0.3);
+ outline-width: 0;
+}
diff --git a/src/recipes-light.css b/src/recipes-light.css
index 7b287f8..bad8565 100644
--- a/src/recipes-light.css
+++ b/src/recipes-light.css
@@ -23,3 +23,8 @@
background: #cbd6e1;
}
+.during-dnd {
+ background: white;
+ border: 1px solid alpha(black, 0.3);
+ outline-width: 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]