event-widget: fix dragging events
This commit is contained in:
+29
-38
@@ -2,50 +2,41 @@
|
|||||||
<interface>
|
<interface>
|
||||||
<template class="GcalEventWidget" parent="GtkBin">
|
<template class="GcalEventWidget" parent="GtkBin">
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkEventBox" id="event_box">
|
<object class="GtkGrid" id="main_grid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="above_child">True</property>
|
<property name="column_spacing">4</property>
|
||||||
<signal name="enter-notify-event" handler="enter_notify_event_cb" object="GcalEventWidget" swapped="no" />
|
<property name="margin-top">1</property>
|
||||||
<signal name="leave-notify-event" handler="leave_notify_event_cb" object="GcalEventWidget" swapped="no" />
|
<property name="margin-bottom">1</property>
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">4</property>
|
||||||
|
<property name="hexpand">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkGrid" id="main_grid">
|
<object class="GtkLabel" id="hour_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="column_spacing">4</property>
|
<property name="xalign">0.0</property>
|
||||||
<property name="margin-top">1</property>
|
<attributes>
|
||||||
<property name="margin-bottom">1</property>
|
<attribute name="weight" value="semibold"/>
|
||||||
<property name="margin-start">6</property>
|
</attributes>
|
||||||
<property name="margin-end">4</property>
|
|
||||||
<property name="hexpand">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="hour_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="xalign">0.0</property>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="weight" value="semibold"/>
|
|
||||||
</attributes>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="summary_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="ellipsize">end</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="summary_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="ellipsize">end</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|||||||
+123
-90
@@ -38,7 +38,6 @@ struct _GcalEventWidget
|
|||||||
GDateTime *dt_end;
|
GDateTime *dt_end;
|
||||||
|
|
||||||
/* widgets */
|
/* widgets */
|
||||||
GtkWidget *event_box;
|
|
||||||
GtkWidget *hour_label;
|
GtkWidget *hour_label;
|
||||||
GtkWidget *main_grid;
|
GtkWidget *main_grid;
|
||||||
GtkWidget *summary_label;
|
GtkWidget *summary_label;
|
||||||
@@ -50,6 +49,8 @@ struct _GcalEventWidget
|
|||||||
|
|
||||||
GcalEvent *event;
|
GcalEvent *event;
|
||||||
|
|
||||||
|
GdkWindow *event_window;
|
||||||
|
|
||||||
GtkOrientation orientation;
|
GtkOrientation orientation;
|
||||||
|
|
||||||
gboolean button_pressed;
|
gboolean button_pressed;
|
||||||
@@ -89,41 +90,27 @@ G_DEFINE_TYPE_WITH_CODE (GcalEventWidget, gcal_event_widget, GTK_TYPE_BIN,
|
|||||||
* Auxiliary methods
|
* Auxiliary methods
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_cursor (GtkWidget *widget,
|
set_drag_source_enabled (GcalEventWidget *self,
|
||||||
CursorType type)
|
gboolean enabled)
|
||||||
{
|
{
|
||||||
GdkDisplay *display;
|
GtkWidget *widget = GTK_WIDGET (self);
|
||||||
GdkCursor *cursor;
|
|
||||||
|
|
||||||
if (!gtk_widget_get_realized (widget))
|
if (enabled)
|
||||||
return;
|
|
||||||
|
|
||||||
display = gtk_widget_get_display (widget);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case CURSOR_NONE:
|
/* Setup the event widget as a drag source */
|
||||||
cursor = NULL;
|
gtk_drag_source_set (widget,
|
||||||
break;
|
GDK_BUTTON1_MASK,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
GDK_ACTION_MOVE);
|
||||||
|
|
||||||
case CURSOR_GRAB:
|
gtk_drag_source_add_text_targets (widget);
|
||||||
cursor = gdk_cursor_new_from_name (display, "grab");
|
}
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
case CURSOR_GRABBING:
|
gtk_drag_source_unset (GTK_WIDGET (widget));
|
||||||
cursor = gdk_cursor_new_from_name (display, "grabbing");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
cursor = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
|
|
||||||
gdk_display_flush (display);
|
|
||||||
|
|
||||||
g_clear_object (&cursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -465,30 +452,6 @@ gcal_event_widget_set_event_internal (GcalEventWidget *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callbacks
|
|
||||||
*/
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
enter_notify_event_cb (GtkWidget *event_box,
|
|
||||||
GdkEvent *event,
|
|
||||||
GtkWidget *widget)
|
|
||||||
{
|
|
||||||
set_cursor (widget, CURSOR_GRAB);
|
|
||||||
return GDK_EVENT_PROPAGATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
leave_notify_event_cb (GtkWidget *event_box,
|
|
||||||
GdkEvent *event,
|
|
||||||
GtkWidget *widget)
|
|
||||||
{
|
|
||||||
set_cursor (widget, CURSOR_NONE);
|
|
||||||
return GDK_EVENT_PROPAGATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GtkWidget overrides
|
* GtkWidget overrides
|
||||||
*/
|
*/
|
||||||
@@ -533,8 +496,6 @@ gcal_event_widget_button_release_event (GtkWidget *widget,
|
|||||||
|
|
||||||
if (self->button_pressed)
|
if (self->button_pressed)
|
||||||
{
|
{
|
||||||
set_cursor (widget, CURSOR_NONE);
|
|
||||||
|
|
||||||
self->button_pressed = FALSE;
|
self->button_pressed = FALSE;
|
||||||
g_signal_emit (widget, signals[ACTIVATE], 0);
|
g_signal_emit (widget, signals[ACTIVATE], 0);
|
||||||
|
|
||||||
@@ -552,6 +513,15 @@ gcal_event_widget_size_allocate (GtkWidget *widget,
|
|||||||
|
|
||||||
self = GCAL_EVENT_WIDGET (widget);
|
self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
|
||||||
|
if (gtk_widget_get_realized (widget))
|
||||||
|
{
|
||||||
|
gdk_window_move_resize (self->event_window,
|
||||||
|
allocation->x,
|
||||||
|
allocation->y,
|
||||||
|
allocation->width,
|
||||||
|
allocation->height);
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to put the summary label below if the orientation is vertical */
|
/* Try to put the summary label below if the orientation is vertical */
|
||||||
if (self->orientation == GTK_ORIENTATION_VERTICAL && !gcal_event_get_all_day (self->event))
|
if (self->orientation == GTK_ORIENTATION_VERTICAL && !gcal_event_get_all_day (self->event))
|
||||||
{
|
{
|
||||||
@@ -566,7 +536,7 @@ gcal_event_widget_size_allocate (GtkWidget *widget,
|
|||||||
"width", 2,
|
"width", 2,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
gtk_widget_get_preferred_height (self->event_box, &minimum_grid_height, NULL);
|
gtk_widget_get_preferred_height (self->main_grid, &minimum_grid_height, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is no vertical space to put the summary label below the hour label.
|
* There is no vertical space to put the summary label below the hour label.
|
||||||
@@ -624,11 +594,68 @@ gcal_event_widget_drag_begin (GtkWidget *widget,
|
|||||||
surface = get_dnd_icon (widget);
|
surface = get_dnd_icon (widget);
|
||||||
|
|
||||||
gtk_drag_set_icon_surface (context, surface);
|
gtk_drag_set_icon_surface (context, surface);
|
||||||
set_cursor (widget, CURSOR_GRABBING);
|
|
||||||
|
|
||||||
g_clear_pointer (&surface, cairo_surface_destroy);
|
g_clear_pointer (&surface, cairo_surface_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_event_widget_map (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GcalEventWidget *self;
|
||||||
|
|
||||||
|
self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->map (widget);
|
||||||
|
|
||||||
|
if (self->event_window != NULL)
|
||||||
|
gdk_window_show (self->event_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_event_widget_realize (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GcalEventWidget *self;
|
||||||
|
GdkWindowAttr attributes;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
GdkWindow *parent_window;
|
||||||
|
GdkCursor *pointer_cursor;
|
||||||
|
gint attributes_mask;
|
||||||
|
|
||||||
|
self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
gtk_widget_set_realized (widget, TRUE);
|
||||||
|
|
||||||
|
parent_window = gtk_widget_get_parent_window (widget);
|
||||||
|
gtk_widget_set_window (widget, parent_window);
|
||||||
|
g_object_ref (parent_window);
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
|
||||||
|
attributes.window_type = GDK_WINDOW_CHILD;
|
||||||
|
attributes.wclass = GDK_INPUT_ONLY;
|
||||||
|
attributes.x = allocation.x;
|
||||||
|
attributes.y = allocation.y;
|
||||||
|
attributes.width = allocation.width;
|
||||||
|
attributes.height = allocation.height;
|
||||||
|
attributes.event_mask = gtk_widget_get_events (widget);
|
||||||
|
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
||||||
|
GDK_BUTTON_RELEASE_MASK |
|
||||||
|
GDK_BUTTON1_MOTION_MASK |
|
||||||
|
GDK_POINTER_MOTION_HINT_MASK |
|
||||||
|
GDK_POINTER_MOTION_MASK |
|
||||||
|
GDK_ENTER_NOTIFY_MASK |
|
||||||
|
GDK_LEAVE_NOTIFY_MASK |
|
||||||
|
GDK_SMOOTH_SCROLL_MASK |
|
||||||
|
GDK_SCROLL_MASK);
|
||||||
|
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
||||||
|
|
||||||
|
self->event_window = gdk_window_new (parent_window, &attributes, attributes_mask);
|
||||||
|
gtk_widget_register_window (widget, self->event_window);
|
||||||
|
gdk_window_show (self->event_window);
|
||||||
|
|
||||||
|
pointer_cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_HAND1);
|
||||||
|
gdk_window_set_cursor (self->event_window, pointer_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gcal_event_widget_scroll_event (GtkWidget *widget,
|
gcal_event_widget_scroll_event (GtkWidget *widget,
|
||||||
GdkEventScroll *scroll_event)
|
GdkEventScroll *scroll_event)
|
||||||
@@ -636,6 +663,35 @@ gcal_event_widget_scroll_event (GtkWidget *widget,
|
|||||||
return GDK_EVENT_PROPAGATE;
|
return GDK_EVENT_PROPAGATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_event_widget_unmap (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GcalEventWidget *self;
|
||||||
|
|
||||||
|
self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->unmap (widget);
|
||||||
|
|
||||||
|
if (self->event_window)
|
||||||
|
gdk_window_hide (self->event_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_event_widget_unrealize (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GcalEventWidget *self;
|
||||||
|
|
||||||
|
self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
|
||||||
|
if (self->event_window)
|
||||||
|
{
|
||||||
|
gtk_widget_unregister_window (widget, self->event_window);
|
||||||
|
gdk_window_destroy (self->event_window);
|
||||||
|
self->event_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->unrealize (widget);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GObject overrides
|
* GObject overrides
|
||||||
@@ -740,8 +796,12 @@ gcal_event_widget_class_init (GcalEventWidgetClass *klass)
|
|||||||
widget_class->button_release_event = gcal_event_widget_button_release_event;
|
widget_class->button_release_event = gcal_event_widget_button_release_event;
|
||||||
widget_class->drag_begin = gcal_event_widget_drag_begin;
|
widget_class->drag_begin = gcal_event_widget_drag_begin;
|
||||||
widget_class->draw = gcal_event_widget_draw;
|
widget_class->draw = gcal_event_widget_draw;
|
||||||
|
widget_class->map = gcal_event_widget_map;
|
||||||
|
widget_class->realize = gcal_event_widget_realize;
|
||||||
widget_class->size_allocate = gcal_event_widget_size_allocate;
|
widget_class->size_allocate = gcal_event_widget_size_allocate;
|
||||||
widget_class->scroll_event = gcal_event_widget_scroll_event;
|
widget_class->scroll_event = gcal_event_widget_scroll_event;
|
||||||
|
widget_class->unmap = gcal_event_widget_unmap;
|
||||||
|
widget_class->unrealize = gcal_event_widget_unrealize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GcalEventWidget::date-end:
|
* GcalEventWidget::date-end:
|
||||||
@@ -806,14 +866,10 @@ gcal_event_widget_class_init (GcalEventWidgetClass *klass)
|
|||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/event-widget.ui");
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/event-widget.ui");
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, event_box);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, hour_label);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, hour_label);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, main_grid);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, main_grid);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, summary_label);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, summary_label);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, enter_notify_event_cb);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, leave_notify_event_cb);
|
|
||||||
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "event");
|
gtk_widget_class_set_css_name (widget_class, "event");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -825,18 +881,13 @@ gcal_event_widget_init (GcalEventWidget *self)
|
|||||||
widget = GTK_WIDGET (self);
|
widget = GTK_WIDGET (self);
|
||||||
self->clock_format_24h = is_clock_format_24h ();
|
self->clock_format_24h = is_clock_format_24h ();
|
||||||
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (self));
|
gtk_widget_init_template (widget);
|
||||||
|
|
||||||
gtk_widget_set_can_focus (widget, TRUE);
|
gtk_widget_set_can_focus (widget, TRUE);
|
||||||
|
gtk_widget_set_has_window (widget, FALSE);
|
||||||
|
|
||||||
/* Setup the event widget as a drag source */
|
/* Setup the event widget as a drag source */
|
||||||
gtk_drag_source_set (widget,
|
set_drag_source_enabled (self, TRUE);
|
||||||
GDK_BUTTON1_MASK,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
GDK_ACTION_MOVE);
|
|
||||||
|
|
||||||
gtk_drag_source_add_text_targets (widget);
|
|
||||||
|
|
||||||
/* Starts with horizontal */
|
/* Starts with horizontal */
|
||||||
self->orientation = GTK_ORIENTATION_HORIZONTAL;
|
self->orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||||
@@ -857,29 +908,11 @@ gcal_event_widget_set_read_only (GcalEventWidget *event,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
|
g_return_if_fail (GCAL_IS_EVENT_WIDGET (event));
|
||||||
|
|
||||||
if (!read_only)
|
set_drag_source_enabled (event, !read_only);
|
||||||
{
|
|
||||||
GtkWidget *widget = GTK_WIDGET (event);
|
|
||||||
|
|
||||||
/* Setup the event widget as a drag source */
|
|
||||||
gtk_drag_source_set (widget,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
GDK_ACTION_MOVE);
|
|
||||||
|
|
||||||
gtk_drag_source_add_text_targets (widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
event->read_only = read_only;
|
event->read_only = read_only;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
gcal_event_widget_get_read_only (GcalEventWidget *event)
|
|
||||||
{
|
|
||||||
return event->read_only;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gcal_event_widget_get_date_end:
|
* gcal_event_widget_get_date_end:
|
||||||
* @self: a #GcalEventWidget
|
* @self: a #GcalEventWidget
|
||||||
@@ -1000,7 +1033,7 @@ gcal_event_widget_clone (GcalEventWidget *widget)
|
|||||||
GtkWidget *new_widget;
|
GtkWidget *new_widget;
|
||||||
|
|
||||||
new_widget = gcal_event_widget_new (widget->event);
|
new_widget = gcal_event_widget_new (widget->event);
|
||||||
gcal_event_widget_set_read_only(GCAL_EVENT_WIDGET (new_widget), gcal_event_widget_get_read_only (widget));
|
gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (new_widget), widget->read_only);
|
||||||
|
|
||||||
return new_widget;
|
return new_widget;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ void gcal_event_widget_set_date_end (GcalEventWidge
|
|||||||
void gcal_event_widget_set_read_only (GcalEventWidget *event,
|
void gcal_event_widget_set_read_only (GcalEventWidget *event,
|
||||||
gboolean read_only);
|
gboolean read_only);
|
||||||
|
|
||||||
gboolean gcal_event_widget_get_read_only (GcalEventWidget *event);
|
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
|
|
||||||
GtkWidget* gcal_event_widget_clone (GcalEventWidget *widget);
|
GtkWidget* gcal_event_widget_clone (GcalEventWidget *widget);
|
||||||
|
|||||||
Reference in New Issue
Block a user