[libegg/spread-table-dnd: 74/78] Better version of EggSpreadTableDnd with animated drag'n'drop.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libegg/spread-table-dnd: 74/78] Better version of EggSpreadTableDnd with animated drag'n'drop.
- Date: Sun, 10 Apr 2011 07:03:28 +0000 (UTC)
commit d488cc0a396d1dd68e80c488a40b1e3bf3b50950
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Thu Apr 7 23:15:42 2011 +0900
Better version of EggSpreadTableDnd with animated drag'n'drop.
Now drag'n'drop completes properly and the internal drop target state
machine is cleaner, drag-motion callbacks always fetch the drag source
widget and calculate the proper size of the drop widget using height-for-width
apis.
libegg/spreadtable/eggspreadtablednd.c | 471 ++++++++++++++++++++------------
1 files changed, 296 insertions(+), 175 deletions(-)
---
diff --git a/libegg/spreadtable/eggspreadtablednd.c b/libegg/spreadtable/eggspreadtablednd.c
index 4edeffd..72c8a72 100644
--- a/libegg/spreadtable/eggspreadtablednd.c
+++ b/libegg/spreadtable/eggspreadtablednd.c
@@ -96,12 +96,14 @@ static void drag_data_get (GtkWidget *widge
guint info,
guint time,
EggSpreadTableDnd *spread_table);
-static GtkWidget *get_drag_child (EggSpreadTableDnd *spread_table,
- const GtkSelectionData *selection);
+static gboolean drag_failed (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkDragResult result,
+ EggSpreadTableDnd *spread_table);
+
static GtkWidget *get_child_at_position (EggSpreadTableDnd *spread_table,
gint x,
- gint y,
- gint *index);
+ gint y);
static gint get_index_at_position (EggSpreadTableDnd *spread_table,
gint x,
gint y,
@@ -110,32 +112,31 @@ static gint get_index_at_position (EggSpreadTableDnd *sprea
static void cancel_drag (EggSpreadTableDnd *spread_table);
+typedef struct {
+ EggSpreadTableDnd *table;
+ GtkWidget *child;
+} EggSpreadTableDndDragData;
struct _EggSpreadTableDndPrivate {
- GtkWidget *drop_target; /* Remember which child widget is the active placeholder */
- gint drop_index;
- GtkWidget *drag_child; /* The widget that is currently being dragged */
+ /* State of drop target while drag-motion is happening over this spread table */
+ GtkWidget *drop_target; /* Remember which child widget is the active placeholder */
- gint drag_origin; /* The original index of the drag child when the drag began (this is captured
- * in order to restore the original child in the case of a failed drag).
- */
+ /* After successfully calling gtk_drag_get_data(), the drag data ends up in this struct */
+ EggSpreadTableDndDragData drag_data;
- gint drag_child_width; /* The original size of the drag child */
- gint drag_child_height;
+ GtkWidget *drag_child; /* If the drag started on a widget with no window, then the spread table
+ * keeps a hold on which child is being dragged */
- gint disappearing;
+ guint dragging : 1; /* Whether the drag'n'drop operation is currently active over this table */
+ gint disappearing; /* Count of placeholders that are currently disappearing */
- gint pressed_button;
- gint press_start_x;
- gint press_start_y;
+ /* These states are used to trigger a drag operation on a child widget with no window */
+ gint pressed_button;
+ gint press_start_x;
+ gint press_start_y;
};
-typedef struct {
- EggSpreadTableDnd *table;
- GtkWidget *child;
-} EggSpreadTableDndDragData;
-
static GdkAtom dnd_target_atom_child = GDK_NONE;
static const GtkTargetEntry dnd_targets[] = {
{ "application/x-egg-spread-table-dnd-child", GTK_TARGET_SAME_APP, 0 }
@@ -160,13 +161,13 @@ egg_spread_table_dnd_class_init (EggSpreadTableDndClass *class)
widget_class->drag_end = egg_spread_table_dnd_drag_end;
widget_class->drag_data_get = egg_spread_table_dnd_drag_data_get;
widget_class->drag_data_delete = egg_spread_table_dnd_drag_data_delete;
+ widget_class->drag_failed = egg_spread_table_dnd_drag_failed;
/* Drag dest */
widget_class->drag_leave = egg_spread_table_dnd_drag_leave;
widget_class->drag_motion = egg_spread_table_dnd_drag_motion;
widget_class->drag_drop = egg_spread_table_dnd_drag_drop;
widget_class->drag_data_received = egg_spread_table_dnd_drag_data_received;
- widget_class->drag_failed = egg_spread_table_dnd_drag_failed;
container_class->remove = egg_spread_table_dnd_remove;
spread_class->insert_child = egg_spread_table_dnd_insert_child;
@@ -188,7 +189,7 @@ egg_spread_table_dnd_init (EggSpreadTableDnd *spread_table)
/* Setup the spread table as a drag target for our target type */
gtk_drag_dest_set (GTK_WIDGET (spread_table),
- GTK_DEST_DEFAULT_ALL,
+ 0,
dnd_targets, G_N_ELEMENTS (dnd_targets),
GDK_ACTION_MOVE);
@@ -256,7 +257,7 @@ egg_spread_table_dnd_motion (GtkWidget *widget,
spread_table->priv->drag_child =
get_child_at_position (spread_table,
spread_table->priv->press_start_x,
- spread_table->priv->press_start_y, NULL);
+ spread_table->priv->press_start_y);
if (spread_table->priv->drag_child)
{
@@ -281,7 +282,7 @@ egg_spread_table_dnd_button_press (GtkWidget *widget,
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
{
/* Save press to possibly begin a drag */
- if (get_child_at_position (spread_table, event->x, event->y, NULL) &&
+ if (get_child_at_position (spread_table, event->x, event->y) &&
spread_table->priv->pressed_button < 0)
{
spread_table->priv->pressed_button = event->button;
@@ -314,14 +315,14 @@ static void
egg_spread_table_dnd_drag_begin (GtkWidget *widget,
GdkDragContext *context)
{
-
+ g_print ("[source] Spread table drag begin\n");
}
static void
egg_spread_table_dnd_drag_end (GtkWidget *widget,
GdkDragContext *context)
{
-
+ g_print ("[source] Spread table drag end\n");
}
static void
@@ -335,6 +336,8 @@ egg_spread_table_dnd_drag_data_get (GtkWidget *widget,
EggSpreadTableDndDragData drag_data = { spread_table, NULL };
GdkAtom target;
+ g_print ("[source] Spread table drag_data_get\n");
+
target = gtk_selection_data_get_target (selection);
if (spread_table->priv->drag_child &&
@@ -345,7 +348,6 @@ egg_spread_table_dnd_drag_data_get (GtkWidget *widget,
gtk_selection_data_set (selection, target, 8,
(guchar*) &drag_data, sizeof (drag_data));
}
-
}
static void
@@ -353,21 +355,37 @@ egg_spread_table_dnd_drag_data_delete (GtkWidget *widget,
GdkDragContext *context)
{
+ g_print ("[source] Spread table drag_data_delete\n");
+
+}
+
+
+static gboolean
+egg_spread_table_dnd_drag_failed (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkDragResult result)
+{
+ g_print ("[source] Drag failed\n");
+
+ return FALSE;
}
/*****************************************************
* GtkWidgetClass drag dest *
*****************************************************/
-static void
-egg_spread_table_dnd_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint time_)
+static gint
+get_child_line (EggSpreadTableDnd *table,
+ GtkWidget *child)
{
- EggSpreadTableDnd *spread_table = EGG_SPREAD_TABLE_DND (widget);
+ gint size;
- cancel_drag (spread_table);
-}
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (table)) == GTK_ORIENTATION_VERTICAL)
+ size = gtk_widget_get_allocated_width (GTK_WIDGET (table));
+ else
+ size = gtk_widget_get_allocated_height (GTK_WIDGET (table));
+ return egg_spread_table_get_child_line (EGG_SPREAD_TABLE (table), child, size);
+}
static void
adjust_line_segment (EggSpreadTableDnd *spread_table,
@@ -386,36 +404,119 @@ static void
placeholder_animated_out (GtkWidget *placeholder,
EggSpreadTableDnd *spread_table)
{
- gint placeholder_position;
- gint size, line;
-
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (spread_table)) == GTK_ORIENTATION_VERTICAL)
- size = gtk_widget_get_allocated_width (GTK_WIDGET (spread_table));
- else
- size = gtk_widget_get_allocated_height (GTK_WIDGET (spread_table));
-
- line = egg_spread_table_get_child_line (EGG_SPREAD_TABLE (spread_table),
- placeholder, size);
+ gint line;
-
- /* After animating out a placeholder, remove the placeholder
- * and possibly adjust the current drop target index
- */
- gtk_container_child_get (GTK_CONTAINER (spread_table), placeholder,
- "position", &placeholder_position,
- NULL);
-
- if (placeholder_position < spread_table->priv->drop_index)
- spread_table->priv->drop_index--;
+ line = get_child_line (spread_table, placeholder);
/* Adjust line segment here manually since table may be locked */
adjust_line_segment (spread_table, line, -1);
g_print ("finished animating out a placeholder, removing one index from line %d\n", line);
+ if (spread_table->priv->drop_target == placeholder)
+ spread_table->priv->drop_target = NULL;
+
gtk_container_remove (GTK_CONTAINER (spread_table), placeholder);
spread_table->priv->disappearing--;
+
+ if (!spread_table->priv->dragging)
+ {
+ egg_spread_table_unlock (EGG_SPREAD_TABLE (spread_table));
+ g_print ("Unlocking the table\n");
+ }
+}
+
+static void
+egg_spread_table_dnd_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time_)
+{
+ EggSpreadTableDnd *spread_table = EGG_SPREAD_TABLE_DND (widget);
+
+ if (spread_table->priv->drop_target)
+ {
+ egg_placeholder_animate_out (EGG_PLACEHOLDER (spread_table->priv->drop_target),
+ gtk_orientable_get_orientation (GTK_ORIENTABLE (spread_table)));
+
+ g_signal_connect (spread_table->priv->drop_target, "animation-done",
+ G_CALLBACK (placeholder_animated_out), spread_table);
+
+ spread_table->priv->disappearing++;
+ }
+
+ /* XXX Dont nullify drop_target here ! it's needed in drag-drop */
+ spread_table->priv->dragging = FALSE;
+
+ g_print ("[dest] Spread table drag_leave\n");
+}
+
+static void
+get_spread_table_dimentions (EggSpreadTableDnd *spread_table,
+ gint *line_spacing,
+ gint *full_size,
+ gint *line_width)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (spread_table);
+ gint local_full_size, local_spacing;
+ gint lines = egg_spread_table_get_lines (table);
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (GTK_WIDGET (table), &allocation);
+
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (table)) == GTK_ORIENTATION_VERTICAL)
+ {
+ local_full_size = allocation.width;
+ local_spacing = egg_spread_table_get_horizontal_spacing (table);
+ }
+ else
+ {
+ local_full_size = allocation.height;
+ local_spacing = egg_spread_table_get_vertical_spacing (table);
+ }
+
+ if (full_size)
+ *full_size = local_full_size;
+ if (line_spacing)
+ *line_spacing = local_spacing;
+
+ if (line_width)
+ *line_width = (local_full_size - (local_spacing * (lines -1))) / lines;
+}
+
+static void
+get_placeholder_size (EggSpreadTableDnd *spread_table,
+ gint *width,
+ gint *height)
+{
+ GtkOrientation orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (spread_table));
+ gint line_width;
+
+ /* Calculate the size of the required placeholder based on the dimentions of the drag widget */
+ get_spread_table_dimentions (spread_table, NULL, NULL, &line_width);
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ gint min_width;
+
+ gtk_widget_get_preferred_width (spread_table->priv->drag_data.child, &min_width, NULL);
+
+ *width = MIN (line_width, min_width);
+
+ gtk_widget_get_preferred_height_for_width (spread_table->priv->drag_data.child,
+ *width, height, NULL);
+ }
+ else
+ {
+ gint min_height;
+
+ gtk_widget_get_preferred_width (spread_table->priv->drag_data.child, &min_height, NULL);
+
+ *height = MIN (line_width, min_height);
+
+ gtk_widget_get_preferred_width_for_height (spread_table->priv->drag_data.child,
+ *height, width, NULL);
+ }
}
static gboolean
@@ -426,22 +527,35 @@ egg_spread_table_dnd_drag_motion (GtkWidget *widget,
guint time_)
{
EggSpreadTableDnd *spread_table = EGG_SPREAD_TABLE_DND (widget);
- gint index, line;
+ gint index, line, drop_index;
+
+ /* Could be comming from another spread table, lock it now incase
+ * its not already locked. */
+ egg_spread_table_lock (EGG_SPREAD_TABLE (spread_table));
+ spread_table->priv->dragging = TRUE;
+
+ gtk_drag_get_data (widget, context, dnd_target_atom_child, time_);
/* Dont do anything until the currently drop target placeholder finishes animating in */
if ((spread_table->priv->drop_target &&
egg_placeholder_get_animating
(EGG_PLACEHOLDER (spread_table->priv->drop_target)) == EGG_PLACEHOLDER_ANIM_IN) ||
spread_table->priv->disappearing > 0)
- return FALSE;
+ return TRUE;
+
+ if (spread_table->priv->drop_target)
+ gtk_container_child_get (GTK_CONTAINER (spread_table),
+ spread_table->priv->drop_target,
+ "position", &drop_index,
+ NULL);
+ else
+ drop_index = -1;
index = get_index_at_position (spread_table, x, y, &line);
- g_print ("[drag motion] index for position returned is %d for line %d, current drop index is %d\n",
- index, line, spread_table->priv->drop_index);
+ g_print ("Drag motion found new drop index %d, old index %d\n", index, drop_index);
- if (/* !EGG_IS_PLACEHOLDER (child) && */
- index != spread_table->priv->drop_index)
+ if (index != drop_index)
{
if (spread_table->priv->drop_target)
{
@@ -456,18 +570,19 @@ egg_spread_table_dnd_drag_motion (GtkWidget *widget,
}
- /* The drop index is +1 because we add a placeholder here */
- spread_table->priv->drop_index = index;
-
if (index >= 0)
{
+ gint width, height;
+
+ /* Import the drag data, get the drag widget and query it's size for this spread table */
+ get_placeholder_size (spread_table, &width, &height);
+
adjust_line_segment (spread_table, line, 1);
- g_print ("Adding a placeholder, adding one index to line %d\n", line);
+ g_print ("Adding a placeholder at new drop index %d, adding one index to line %d\n",
+ drop_index, line);
- spread_table->priv->drop_target =
- egg_placeholder_new (spread_table->priv->drag_child_width,
- spread_table->priv->drag_child_height);
+ spread_table->priv->drop_target = egg_placeholder_new (width, height);
egg_spread_table_insert_child (EGG_SPREAD_TABLE (spread_table),
spread_table->priv->drop_target, index);
@@ -476,7 +591,7 @@ egg_spread_table_dnd_drag_motion (GtkWidget *widget,
}
}
- return FALSE;
+ return TRUE;
}
static gboolean
@@ -488,68 +603,81 @@ egg_spread_table_dnd_drag_drop (GtkWidget *widget,
{
EggSpreadTableDnd *spread_table = EGG_SPREAD_TABLE_DND (widget);
- cancel_drag (spread_table);
+ gtk_drag_get_data (widget, context, dnd_target_atom_child, time_);
+
+ g_print ("[dest] drag_drop()\n");
+
+ if (spread_table->priv->drop_target &&
+ spread_table->priv->drag_data.child)
+ {
+ gint drop_index;
+
+ /* Carry the widget over */
+ g_object_ref (spread_table->priv->drag_data.child);
+
+ gtk_container_remove (GTK_CONTAINER (spread_table->priv->drag_data.table),
+ spread_table->priv->drag_data.child);
+
+ /* Get the appropriate target index */
+ gtk_container_child_get (GTK_CONTAINER (spread_table),
+ spread_table->priv->drop_target,
+ "position", &drop_index,
+ NULL);
+
+#if 0
+ gtk_container_remove (GTK_CONTAINER (spread_table), spread_table->priv->drop_target);
+ spread_table->priv->drop_target = NULL;
+#endif
+
+ /* Insert drag child at the index */
+ egg_spread_table_insert_child (EGG_SPREAD_TABLE (spread_table),
+ spread_table->priv->drag_data.child,
+ drop_index);
+ g_object_unref (spread_table->priv->drag_data.child);
+
+ /* Ensure visibility */
+ gtk_widget_show (spread_table->priv->drag_data.child);
+
+ /* Unlock the target spread table, any other spread table
+ * should have been unlocked at drag_leave time */
+ egg_spread_table_unlock (EGG_SPREAD_TABLE (spread_table));
+
+ gtk_drag_finish (context, TRUE, TRUE, time_);
+ }
+ else
+ {
+ /* XXX Indicate failed DnD ?? */
+ g_print ("BUG!\n");
+ gtk_drag_finish (context, FALSE, TRUE, time_);
+ }
+
+ //cancel_drag (spread_table);
return FALSE;
}
static void
egg_spread_table_dnd_drag_data_received (GtkWidget *widget,
- GdkDragContext *drag_context,
+ GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
- guint time)
+ guint time_)
{
- EggSpreadTableDnd *spread_table = EGG_SPREAD_TABLE_DND (widget);
- GtkWidget *drag_child;
-
- /* Action time ! now reorder the child to the new position */
- drag_child = get_drag_child (spread_table, data);
+ EggSpreadTableDnd *spread_table = EGG_SPREAD_TABLE_DND (widget);
+ EggSpreadTableDndDragData *drag_data;
- if (drag_child)
- {
- GtkWidget *drop_widget;
- gint index = -1, orig_index;
- GList *children;
- gboolean before;
+ memset (&spread_table->priv->drag_data, 0x0, sizeof (EggSpreadTableDndDragData));
- drop_widget = get_child_at_position (spread_table, x, y, &before);
-
- if (drop_widget)
- {
- children = gtk_container_get_children (GTK_CONTAINER (spread_table));
- index = g_list_index (children, drop_widget);
- orig_index = g_list_index (children, drag_child);
- g_list_free (children);
+ g_return_if_fail (gtk_selection_data_get_format (data) == 8);
+ g_return_if_fail (gtk_selection_data_get_length (data) == sizeof (EggSpreadTableDndDragData));
+ g_return_if_fail (gtk_selection_data_get_target (data) == dnd_target_atom_child);
- if (index >= 0 && orig_index >= 0 && orig_index < index)
- index--;
-
- if (!before)
- index++;
- }
-
- /* It might have been inside another spread table in the same application */
- g_object_ref (drag_child);
- gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (drag_child)), drag_child);
- egg_spread_table_insert_child (EGG_SPREAD_TABLE (spread_table), drag_child, index);
- g_object_unref (drag_child);
-
- }
-
- cancel_drag (spread_table);
+ drag_data = (EggSpreadTableDndDragData*) gtk_selection_data_get_data (data);
+ memcpy (&spread_table->priv->drag_data, drag_data, sizeof (EggSpreadTableDndDragData));
-}
-
-static gboolean
-egg_spread_table_dnd_drag_failed (GtkWidget *widget,
- GdkDragContext *context,
- GtkDragResult result)
-{
-
- return FALSE;
+ gdk_drag_status (context, GDK_ACTION_MOVE, time_);
}
/*****************************************************
@@ -560,10 +688,14 @@ egg_spread_table_dnd_remove (GtkContainer *container,
GtkWidget *child)
{
/* Disconnect dnd */
- g_signal_handlers_disconnect_by_func (child, G_CALLBACK (drag_data_get), container);
- g_signal_handlers_disconnect_by_func (child, G_CALLBACK (drag_begin), container);
- gtk_drag_source_unset (child);
-
+ if (!EGG_IS_PLACEHOLDER (child))
+ {
+ g_signal_handlers_disconnect_by_func (child, G_CALLBACK (drag_data_get), container);
+ g_signal_handlers_disconnect_by_func (child, G_CALLBACK (drag_failed), container);
+ g_signal_handlers_disconnect_by_func (child, G_CALLBACK (drag_begin), container);
+ gtk_drag_source_unset (child);
+ }
+
GTK_CONTAINER_CLASS (egg_spread_table_dnd_parent_class)->remove (container, child);
}
@@ -579,14 +711,19 @@ egg_spread_table_dnd_insert_child (EggSpreadTable *spread_table,
EGG_SPREAD_TABLE_CLASS (egg_spread_table_dnd_parent_class)->insert_child (spread_table, child, index);
/* Connect dnd */
- gtk_drag_source_set (child, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
- dnd_targets, G_N_ELEMENTS (dnd_targets),
- GDK_ACTION_MOVE);
-
- g_signal_connect (child, "drag-data-get",
- G_CALLBACK (drag_data_get), spread_table);
- g_signal_connect (child, "drag-begin",
- G_CALLBACK (drag_begin), spread_table);
+ if (!EGG_IS_PLACEHOLDER (child))
+ {
+ gtk_drag_source_set (child, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
+ dnd_targets, G_N_ELEMENTS (dnd_targets),
+ GDK_ACTION_MOVE);
+
+ g_signal_connect (child, "drag-data-get",
+ G_CALLBACK (drag_data_get), spread_table);
+ g_signal_connect (child, "drag-failed",
+ G_CALLBACK (drag_failed), spread_table);
+ g_signal_connect (child, "drag-begin",
+ G_CALLBACK (drag_begin), spread_table);
+ }
}
/*****************************************************
@@ -599,35 +736,39 @@ drag_begin (GtkWidget *widget,
EggSpreadTableDnd *spread_table)
{
GtkAllocation allocation;
+ gint drop_index;
- /* Hold a ref because we're going to play with the widget out of hierarchy */
- spread_table->priv->drag_child = g_object_ref (widget);
-
+ /* Mark the spread table for an active drag */
egg_spread_table_lock (EGG_SPREAD_TABLE (spread_table));
+ spread_table->priv->dragging = TRUE;
+ /* Hold on to the drag child incase the drag fails */
+ spread_table->priv->drag_child = widget;
/* Save the drag origin in case of failed drags and insert a placeholder as the first
* default drop target */
gtk_container_child_get (GTK_CONTAINER (spread_table),
spread_table->priv->drag_child,
- "position", &spread_table->priv->drag_origin,
+ "position", &drop_index,
NULL);
- spread_table->priv->drop_index = spread_table->priv->drag_origin;
/* Create a placeholder of the correct dimentions and insert it at the drag origin */
gtk_widget_get_allocation (widget, &allocation);
spread_table->priv->drop_target = egg_placeholder_new (allocation.width, allocation.height);
+
egg_spread_table_insert_child (EGG_SPREAD_TABLE (spread_table),
- spread_table->priv->drop_target, spread_table->priv->drop_index);
+ spread_table->priv->drop_target,
+ drop_index);
- spread_table->priv->drag_child_width = allocation.width;
- spread_table->priv->drag_child_height = allocation.height;
+ /* Add one index for the new placeholder */
+ adjust_line_segment (spread_table,
+ get_child_line (spread_table, spread_table->priv->drop_target), 1);
- /* Remove the drag child */
- gtk_container_remove (GTK_CONTAINER (spread_table), spread_table->priv->drag_child);
+ /* Hide the drag child (we cant remove it because it needs a GdkWindow in the mean time) */
+ gtk_widget_hide (spread_table->priv->drag_child);
g_print ("[child %p] Drag began at index %d, added placeholder there with width %d and height %d\n",
- widget, spread_table->priv->drag_origin, allocation.width, allocation.height);
+ widget, drop_index, allocation.width, allocation.height);
}
@@ -653,24 +794,15 @@ drag_data_get (GtkWidget *widget,
}
}
-static GtkWidget *
-get_drag_child (EggSpreadTableDnd *spread_table,
- const GtkSelectionData *selection)
+static gboolean
+drag_failed (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkDragResult result,
+ EggSpreadTableDnd *spread_table)
{
- EggSpreadTableDndDragData *data;
- GdkAtom target;
-
- g_return_val_if_fail (gtk_selection_data_get_format (selection) == 8, NULL);
- g_return_val_if_fail (gtk_selection_data_get_length (selection) == sizeof (EggSpreadTableDndDragData), NULL);
- target = gtk_selection_data_get_target (selection);
- g_return_val_if_fail (target == dnd_target_atom_child, NULL);
-
- data = (EggSpreadTableDndDragData*) gtk_selection_data_get_data (selection);
-
- /* Cancel the drag on the original drag data (incase this is a table-to-table dnd) */
- cancel_drag (data->table);
+ g_print ("[source] Drag failed\n");
- return data->child;
+ return FALSE;
}
static void
@@ -712,22 +844,12 @@ get_index_at_position (EggSpreadTableDnd *spread_table,
lines = egg_spread_table_get_lines (table);
segments = egg_spread_table_get_segments (table);
- gtk_widget_get_allocation (widget, &allocation);
+ get_spread_table_dimentions (spread_table, &spacing, &full_size, &line_width);
if (orientation == GTK_ORIENTATION_VERTICAL)
- {
- full_size = allocation.width;
- spacing = egg_spread_table_get_horizontal_spacing (table);
- position = x;
- }
+ position = x;
else
- {
- full_size = allocation.height;
- spacing = egg_spread_table_get_vertical_spacing (table);
- position = y;
- }
-
- line_width = (full_size - (spacing * (lines -1))) / lines;
+ position = y;
for (i = 0; i < lines; i++)
{
@@ -754,7 +876,8 @@ get_index_at_position (EggSpreadTableDnd *spread_table,
children = gtk_container_get_children (GTK_CONTAINER (spread_table));
for (l = g_list_nth (children, first_child), i = 0;
- l != NULL && index < 0 && i < segments[line]; l = l->next)
+ l != NULL && index < 0 && i < segments[line];
+ l = l->next, i++)
{
child = l->data;
@@ -791,7 +914,6 @@ get_index_at_position (EggSpreadTableDnd *spread_table,
index = first_child + i + placeholder_cnt;
}
}
- i++;
}
if (index < 0)
@@ -799,6 +921,9 @@ get_index_at_position (EggSpreadTableDnd *spread_table,
g_list_free (children);
+ /* g_print ("index for position is %d for line %d[first child %d with %d widgets], current drop index is %d\n", */
+ /* index, line, first_child, segments[line], spread_table->priv->drop_index); */
+
g_free (segments);
if (line_ret)
@@ -810,8 +935,7 @@ get_index_at_position (EggSpreadTableDnd *spread_table,
static GtkWidget *
get_child_at_position (EggSpreadTableDnd *spread_table,
gint x,
- gint y,
- gint *index)
+ gint y)
{
GtkWidget *child, *ret_child = NULL;
GList *children, *l;
@@ -832,9 +956,6 @@ get_child_at_position (EggSpreadTableDnd *spread_table,
y >= allocation.y && y <= allocation.y + allocation.height)
{
ret_child = child;
-
- if (index)
- *index = g_list_index (children, ret_child);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]