diff options
-rw-r--r-- | widgets/table/e-tree.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c index ab1d214175..f18ba8c199 100644 --- a/widgets/table/e-tree.c +++ b/widgets/table/e-tree.c @@ -91,6 +91,7 @@ struct ETreePriv { int reflow_idle_id; int scroll_idle_id; + int hover_idle_id; int table_model_change_id; int table_row_change_id; @@ -132,6 +133,9 @@ struct ETreePriv { int last_drop_time; GdkDragContext *last_drop_context; + int hover_x; + int hover_y; + int drag_row; ETreePath drag_path; int drag_col; @@ -193,6 +197,8 @@ static gint et_focus (GtkContainer *container, GtkDirectionType direction); static void scroll_off (ETree *et); static void scroll_on (ETree *et, gboolean down); +static void hover_off (ETree *et); +static void hover_on (ETree *et, int x, int y); static void et_disconnect_from_etta (ETree *et) @@ -230,6 +236,7 @@ et_destroy (GtkObject *object) et->priv->reflow_idle_id = 0; scroll_off (et); + hover_off (et); et_disconnect_from_etta (et); @@ -283,6 +290,7 @@ e_tree_init (GtkObject *object) e_tree->priv->sorter = NULL; e_tree->priv->reflow_idle_id = 0; e_tree->priv->scroll_idle_id = 0; + e_tree->priv->hover_idle_id = 0; e_tree->priv->alternating_row_colors = 1; e_tree->priv->horizontal_draw_grid = 1; @@ -299,6 +307,14 @@ e_tree_init (GtkObject *object) e_tree->priv->drop_col = -1; e_tree->priv->drop_highlight = NULL; + e_tree->priv->last_drop_x = 0; + e_tree->priv->last_drop_y = 0; + e_tree->priv->last_drop_time = 0; + e_tree->priv->last_drop_context = NULL; + + e_tree->priv->hover_x = 0; + e_tree->priv->hover_y = 0; + e_tree->priv->drag_row = -1; e_tree->priv->drag_path = NULL; e_tree->priv->drag_col = -1; @@ -2068,6 +2084,51 @@ scroll_off (ETree *et) et->priv->scroll_idle_id = 0; } } + +static gboolean +hover_timeout (gpointer data) +{ + ETree *et = data; + GtkWidget *widget = data; + int x = et->priv->hover_x; + int y = et->priv->hover_y; + int row, col; + ETreePath path; + + x -= widget->allocation.x; + y -= widget->allocation.y; + e_tree_get_cell_at (et, + x, + y, + &row, + &col); + + path = e_tree_table_adapter_node_at_row(et->priv->etta, row); + if (path && e_tree_model_node_is_expandable (E_TREE_MODEL (et->priv->sorted), path)) { + e_tree_table_adapter_node_set_expanded (et->priv->etta, path, TRUE); + } + + return TRUE; +} + +static void +hover_on (ETree *et, int x, int y) +{ + et->priv->hover_x = x; + et->priv->hover_y = y; + if (et->priv->hover_idle_id != 0) + g_source_remove (et->priv->hover_idle_id); + et->priv->hover_idle_id = g_timeout_add (500, hover_timeout, et); +} + +static void +hover_off (ETree *et) +{ + if (et->priv->hover_idle_id) { + g_source_remove (et->priv->hover_idle_id); + et->priv->hover_idle_id = 0; + } +} static void et_drag_leave(GtkWidget *widget, @@ -2086,6 +2147,7 @@ et_drag_leave(GtkWidget *widget, et->priv->drop_col = -1; scroll_off (et); + hover_off (et); } static gboolean @@ -2103,6 +2165,15 @@ et_drag_motion(GtkWidget *widget, et->priv->last_drop_time = time; et->priv->last_drop_context = context; + if (et->priv->hover_idle_id != 0) { + if (abs (et->priv->hover_x - x) > 3 || + abs (et->priv->hover_y - y) > 3) { + hover_on (et, x, y); + } + } else { + hover_on (et, x, y); + } + ret_val = do_drag_motion (et, context, x, |