[gnome-calendar/wip/pandusonu/week-view] week-header: implement drag n' drop
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/wip/pandusonu/week-view] week-header: implement drag n' drop
- Date: Tue, 17 Jan 2017 13:25:15 +0000 (UTC)
commit 7a21e1e5ac6e8d1092a05a009b69982f869b2446
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Jan 17 11:23:41 2017 -0200
week-header: implement drag n' drop
src/views/gcal-week-header.c | 152 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 145 insertions(+), 7 deletions(-)
---
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index 75c6956..32d1655 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -71,6 +71,7 @@ struct _GcalWeekHeader
gint selection_start;
gint selection_end;
+ gint dnd_cell;
GtkSizeGroup *sizegroup;
};
@@ -1179,13 +1180,16 @@ gcal_week_header_draw (GtkWidget *widget,
cell_width = (alloc.width - start_x) / 7.0;
- /* Start by redrawing the entire background */
- gtk_render_background (context,
- cr,
- alloc.x,
- alloc.y,
- alloc.width,
- alloc.height);
+ /* Drag and Drop highlight */
+ if (self->dnd_cell != -1)
+ {
+ gtk_render_background (context,
+ cr,
+ start_x + self->dnd_cell * cell_width,
+ start_y,
+ cell_width,
+ alloc.height - start_y + 6);
+ }
/* Draw the selection background */
if (self->selection_start != -1 && self->selection_end != -1)
@@ -1342,6 +1346,129 @@ gcal_week_header_draw (GtkWidget *widget,
return FALSE;
}
+
+static gint
+get_dnd_cell (GtkWidget *widget,
+ gint x,
+ gint y)
+{
+ gdouble column_width;
+
+ column_width = gtk_widget_get_allocated_width (widget) / 7.0;
+
+ return x / column_width;
+}
+
+static gboolean
+gcal_week_header_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ GcalWeekHeader *self;
+
+ self = GCAL_WEEK_HEADER (widget);
+ self->dnd_cell = get_dnd_cell (widget, x, y);
+
+ /* Setup the drag highlight */
+ if (self->dnd_cell != -1)
+ gtk_drag_highlight (widget);
+ else
+ gtk_drag_unhighlight (widget);
+
+ /*
+ * Sets the status of the drag - if it fails, sets the action to 0 and
+ * aborts the drag with FALSE.
+ */
+ gdk_drag_status (context,
+ self->dnd_cell == -1 ? 0 : GDK_ACTION_COPY,
+ time);
+
+ gtk_widget_queue_draw (widget);
+
+ return self->dnd_cell != -1;
+}
+
+static gboolean
+gcal_week_header_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ GcalWeekHeader *self;
+ g_autoptr (GDateTime) week_start;
+ g_autoptr (GDateTime) dnd_date;
+ GtkWidget *event_widget;
+ GcalEvent *event;
+ gboolean ltr;
+ gint drop_cell;
+
+ self = GCAL_WEEK_HEADER (widget);
+ ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
+ drop_cell = get_dnd_cell (widget, x, y);
+ event_widget = gtk_drag_get_source_widget (context);
+
+ week_start = dnd_date = NULL;
+
+ if (!GCAL_IS_EVENT_WIDGET (event_widget))
+ return FALSE;
+
+ /* RTL languages swap the drop cell column */
+ if (!ltr)
+ {
+ drop_cell = 6 - drop_cell;
+ }
+
+ event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (event_widget));
+ week_start = get_start_of_week (self->active_date);
+ dnd_date = g_date_time_add_days (week_start, drop_cell);
+
+ /*
+ * Set the event's start and end dates. Since the event may have a
+ * NULL end date, so we have to check it here
+ */
+ gcal_event_set_all_day (event, TRUE);
+ gcal_event_set_date_start (event, dnd_date);
+
+ if (gcal_event_get_date_end (event))
+ {
+ g_autoptr (GDateTime) new_end;
+
+ new_end = g_date_time_add_days (dnd_date, 1);
+
+ gcal_event_set_date_end (event, new_end);
+ }
+
+ /* Commit the changes */
+ gcal_manager_update_event (self->manager, event);
+
+ /* Cancel the DnD */
+ self->dnd_cell = -1;
+ gtk_drag_unhighlight (widget);
+
+ gtk_drag_finish (context, TRUE, FALSE, time);
+
+ gtk_widget_queue_draw (widget);
+
+ return TRUE;
+}
+
+static void
+gcal_week_header_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time)
+{
+ GcalWeekHeader *self = GCAL_WEEK_HEADER (widget);
+
+ /* Cancel the drag */
+ self->dnd_cell = -1;
+ gtk_drag_unhighlight (widget);
+
+ gtk_widget_queue_draw (widget);
+}
+
static void
gcal_week_header_class_init (GcalWeekHeaderClass *kclass)
{
@@ -1354,6 +1481,9 @@ gcal_week_header_class_init (GcalWeekHeaderClass *kclass)
widget_class->draw = gcal_week_header_draw;
widget_class->size_allocate = gcal_week_header_size_allocate;
+ widget_class->drag_motion = gcal_week_header_drag_motion;
+ widget_class->drag_leave = gcal_week_header_drag_leave;
+ widget_class->drag_drop = gcal_week_header_drag_drop;
g_object_class_install_property (object_class,
PROP_ACTIVE_DATE,
@@ -1398,8 +1528,16 @@ gcal_week_header_init (GcalWeekHeader *self)
self->expanded = FALSE;
self->selection_start = -1;
self->selection_end = -1;
+ self->dnd_cell = -1;
gtk_widget_init_template (GTK_WIDGET (self));
+
+ /* Setup the week header as a drag n' drop destination */
+ gtk_drag_dest_set (GTK_WIDGET (self),
+ 0,
+ NULL,
+ 0,
+ GDK_ACTION_MOVE);
}
/* Public API */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]