month-view: updated press/release/motions handlers
Now internal values of button press, motion and releases are kept according the cell numbers alone, as explained in the comments.
This commit is contained in:
+129
-110
@@ -50,7 +50,11 @@ typedef struct
|
|||||||
* 0 for Sunday, 1 for Monday and so on */
|
* 0 for Sunday, 1 for Monday and so on */
|
||||||
gint first_weekday;
|
gint first_weekday;
|
||||||
|
|
||||||
/* button_down/up flag */
|
/**
|
||||||
|
* button_down/up flag
|
||||||
|
* These keeps the cell index, meaning 0 for left top, 1 for the next in the row from left to right, etc.
|
||||||
|
* Note that this does not take into account the disabled row before the first active row.
|
||||||
|
*/
|
||||||
gint clicked_cell;
|
gint clicked_cell;
|
||||||
gint start_mark_cell;
|
gint start_mark_cell;
|
||||||
gint end_mark_cell;
|
gint end_mark_cell;
|
||||||
@@ -70,6 +74,12 @@ enum
|
|||||||
static void event_opened (GcalEventWidget *event_widget,
|
static void event_opened (GcalEventWidget *event_widget,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
static gint get_cell_and_center_from_position (GcalMonthView *view,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *out_x,
|
||||||
|
gdouble *out_y);
|
||||||
|
|
||||||
static void gcal_view_interface_init (GcalViewIface *iface);
|
static void gcal_view_interface_init (GcalViewIface *iface);
|
||||||
|
|
||||||
static void gcal_month_view_set_property (GObject *object,
|
static void gcal_month_view_set_property (GObject *object,
|
||||||
@@ -154,6 +164,50 @@ event_opened (GcalEventWidget *event_widget,
|
|||||||
event_widget);
|
event_widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
get_cell_and_center_from_position (GcalMonthView *view,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *out_x,
|
||||||
|
gdouble *out_y)
|
||||||
|
{
|
||||||
|
GcalMonthViewPrivate *priv;
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
gdouble start_grid_y;
|
||||||
|
|
||||||
|
gint shown_rows;
|
||||||
|
gdouble first_row_gap;
|
||||||
|
|
||||||
|
gdouble cell_width;
|
||||||
|
gdouble cell_height;
|
||||||
|
|
||||||
|
gint cell;
|
||||||
|
|
||||||
|
priv = gcal_month_view_get_instance_private (view);
|
||||||
|
widget = GTK_WIDGET (view);
|
||||||
|
|
||||||
|
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
||||||
|
|
||||||
|
shown_rows = ceil ((priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year)) / 7.0);
|
||||||
|
first_row_gap = (6 - shown_rows) * 0.5; /* invalid area before the actual rows */
|
||||||
|
|
||||||
|
cell_width = gtk_widget_get_allocated_width (widget) / 7.0;
|
||||||
|
cell_height = (gtk_widget_get_allocated_height (widget) - start_grid_y) / 6.0;
|
||||||
|
|
||||||
|
y = y - start_grid_y - first_row_gap * cell_height;
|
||||||
|
|
||||||
|
cell = 7 * (gint)(y / cell_height) + (gint)(x / cell_width);
|
||||||
|
|
||||||
|
if (out_x != NULL)
|
||||||
|
*out_x = cell_width * ((cell % 7) + 0.5);
|
||||||
|
|
||||||
|
if (out_y != NULL)
|
||||||
|
*out_y = cell_height * ((cell / 7) + 0.5 * (3.0 - (shown_rows % 2))) + start_grid_y;
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gcal_month_view_class_init (GcalMonthViewClass *klass)
|
gcal_month_view_class_init (GcalMonthViewClass *klass)
|
||||||
{
|
{
|
||||||
@@ -745,45 +799,37 @@ gcal_month_view_button_press (GtkWidget *widget,
|
|||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
{
|
{
|
||||||
GcalMonthViewPrivate *priv;
|
GcalMonthViewPrivate *priv;
|
||||||
gdouble x, y;
|
|
||||||
gint width, height;
|
|
||||||
gdouble start_grid_y;
|
|
||||||
|
|
||||||
gdouble days;
|
gint days;
|
||||||
gint shown_rows;
|
|
||||||
|
|
||||||
gdouble lines_gap;
|
gint j;
|
||||||
gdouble lines_gap_for_5;
|
gint sw, k;
|
||||||
|
|
||||||
gdouble v_block;
|
|
||||||
|
|
||||||
priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
|
priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
|
||||||
|
|
||||||
x = event->x;
|
|
||||||
y = event->y;
|
|
||||||
|
|
||||||
width = gtk_widget_get_allocated_width (widget);
|
|
||||||
height = gtk_widget_get_allocated_height (widget);
|
|
||||||
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
|
||||||
|
|
||||||
y = y - start_grid_y;
|
|
||||||
|
|
||||||
days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
|
days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
|
||||||
shown_rows = ceil (days / 7.0);
|
|
||||||
|
|
||||||
lines_gap = ((shown_rows + 1) / 2.0) + 0.5 - ceil (shown_rows / 2.0);
|
/* orientation factors */
|
||||||
lines_gap_for_5 = shown_rows == 5 ? lines_gap : 0;
|
if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
|
||||||
|
|
||||||
v_block = (height - start_grid_y) / 6.0;
|
|
||||||
|
|
||||||
priv->clicked_cell = 7 * (floor ((y - (lines_gap_for_5 * v_block)) / v_block)) + floor (x / (width / 7));
|
|
||||||
|
|
||||||
if (priv->clicked_cell < days)
|
|
||||||
{
|
{
|
||||||
priv->start_mark_cell = priv->clicked_cell;
|
sw = 1;
|
||||||
|
k = 0;
|
||||||
|
}
|
||||||
|
else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
|
||||||
|
{
|
||||||
|
sw = -1;
|
||||||
|
k = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_debug ("pressed cell is: %d", priv->start_mark_cell);
|
priv->clicked_cell = get_cell_and_center_from_position (GCAL_MONTH_VIEW (widget), event->x, event->y, NULL, NULL);
|
||||||
|
|
||||||
|
j = 7 * ((priv->clicked_cell + 7 * k) / 7) + sw * (priv->clicked_cell % 7) + (1 - k);
|
||||||
|
|
||||||
|
if (j > priv->days_delay && j <= days)
|
||||||
|
priv->start_mark_cell = priv->clicked_cell;
|
||||||
|
|
||||||
|
g_debug ("clicked is: %d", priv->clicked_cell);
|
||||||
|
g_debug ("pressed is: %d", priv->start_mark_cell);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -803,18 +849,11 @@ gcal_month_view_motion_notify_event (GtkWidget *widget,
|
|||||||
GdkEventMotion *event)
|
GdkEventMotion *event)
|
||||||
{
|
{
|
||||||
GcalMonthViewPrivate *priv;
|
GcalMonthViewPrivate *priv;
|
||||||
gint width, height;
|
|
||||||
gint y;
|
|
||||||
gdouble start_grid_y;
|
|
||||||
|
|
||||||
gdouble days;
|
gint days;
|
||||||
gint shown_rows;
|
|
||||||
|
|
||||||
gdouble lines_gap;
|
|
||||||
gdouble lines_gap_for_5;
|
|
||||||
|
|
||||||
gdouble v_block;
|
|
||||||
|
|
||||||
|
gint j;
|
||||||
|
gint sw, k;
|
||||||
gint new_end_cell;
|
gint new_end_cell;
|
||||||
|
|
||||||
priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
|
priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
|
||||||
@@ -823,35 +862,32 @@ gcal_month_view_motion_notify_event (GtkWidget *widget,
|
|||||||
priv->clicked_cell == -1)
|
priv->clicked_cell == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
width = gtk_widget_get_allocated_width (widget);
|
|
||||||
height = gtk_widget_get_allocated_height (widget);
|
|
||||||
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
|
||||||
|
|
||||||
y = event->y - start_grid_y;
|
|
||||||
if (y < 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
|
days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
|
||||||
shown_rows = ceil (days / 7.0);
|
|
||||||
|
|
||||||
lines_gap = ((shown_rows + 1) / 2.0) + 0.5 - ceil (shown_rows / 2.0);
|
/* orientation factors */
|
||||||
lines_gap_for_5 = shown_rows == 5 ? lines_gap : 0;
|
if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
|
||||||
|
|
||||||
v_block = (height - start_grid_y) / 6.0;
|
|
||||||
|
|
||||||
/* caching value */
|
|
||||||
new_end_cell = 7 * (floor ((y - (lines_gap_for_5 * v_block)) / v_block)) + floor (event->x / (width / 7));
|
|
||||||
if (priv->end_mark_cell != new_end_cell)
|
|
||||||
{
|
{
|
||||||
gtk_widget_queue_draw (widget);
|
sw = 1;
|
||||||
|
k = 0;
|
||||||
|
}
|
||||||
|
else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
|
||||||
|
{
|
||||||
|
sw = -1;
|
||||||
|
k = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->end_mark_cell = new_end_cell;
|
new_end_cell = get_cell_and_center_from_position (GCAL_MONTH_VIEW (widget), event->x, event->y, NULL, NULL);
|
||||||
|
|
||||||
g_debug ("move_notify: %d, %d, %d",
|
j = 7 * ((new_end_cell + 7 * k) / 7) + sw * (new_end_cell % 7) + (1 - k);
|
||||||
priv->start_mark_cell,
|
|
||||||
priv->end_mark_cell,
|
if (j > priv->days_delay && j <= days)
|
||||||
new_end_cell);
|
{
|
||||||
|
if (priv->end_mark_cell != new_end_cell)
|
||||||
|
gtk_widget_queue_draw (widget);
|
||||||
|
|
||||||
|
g_debug ("move_notify: %d, %d, %d", priv->start_mark_cell, priv->end_mark_cell, new_end_cell);
|
||||||
|
priv->end_mark_cell = new_end_cell;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -861,19 +897,14 @@ gcal_month_view_button_release (GtkWidget *widget,
|
|||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
{
|
{
|
||||||
GcalMonthViewPrivate *priv;
|
GcalMonthViewPrivate *priv;
|
||||||
gdouble x, y;
|
|
||||||
gint width, height;
|
gint days;
|
||||||
gdouble start_grid_y;
|
|
||||||
|
gint j;
|
||||||
|
gint sw, k;
|
||||||
gint released;
|
gint released;
|
||||||
|
|
||||||
gdouble days;
|
gdouble x,y;
|
||||||
gint shown_rows;
|
|
||||||
|
|
||||||
gdouble lines_gap;
|
|
||||||
gdouble lines_gap_for_5;
|
|
||||||
gint february_gap;
|
|
||||||
|
|
||||||
gdouble v_block;
|
|
||||||
|
|
||||||
icaltimetype *start_date;
|
icaltimetype *start_date;
|
||||||
icaltimetype *end_date;
|
icaltimetype *end_date;
|
||||||
@@ -883,31 +914,25 @@ gcal_month_view_button_release (GtkWidget *widget,
|
|||||||
if (priv->clicked_cell == -1)
|
if (priv->clicked_cell == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
x = event->x;
|
days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
|
||||||
y = event->y;
|
|
||||||
|
|
||||||
width = gtk_widget_get_allocated_width (widget);
|
/* orientation factors */
|
||||||
height = gtk_widget_get_allocated_height (widget);
|
if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
|
||||||
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
{
|
||||||
|
sw = 1;
|
||||||
|
k = 0;
|
||||||
|
}
|
||||||
|
else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
|
||||||
|
{
|
||||||
|
sw = -1;
|
||||||
|
k = 1;
|
||||||
|
}
|
||||||
|
|
||||||
y = y - start_grid_y;
|
released = get_cell_and_center_from_position (GCAL_MONTH_VIEW (widget), event->x, event->y, &x, &y);
|
||||||
|
|
||||||
days = priv->days_delay + icaltime_days_in_month (priv->date->month,
|
j = 7 * ((released + 7 * k) / 7) + sw * (released % 7) + (1 - k);
|
||||||
priv->date->year);
|
|
||||||
shown_rows = ceil (days / 7.0);
|
|
||||||
|
|
||||||
lines_gap = ((shown_rows + 1) / 2.0) + 0.5 - ceil (shown_rows / 2.0);
|
if (j <= priv->days_delay || j > days)
|
||||||
lines_gap_for_5 = shown_rows == 5 ? lines_gap : 0;
|
|
||||||
february_gap = shown_rows == 4 ? 1 : 0;
|
|
||||||
|
|
||||||
v_block = (height - start_grid_y) / 6.0;
|
|
||||||
|
|
||||||
released = 7 * (floor ((y - (lines_gap_for_5 * v_block)) / v_block)) +
|
|
||||||
floor (event->x / (width / 7));
|
|
||||||
|
|
||||||
/* whether the event is out of the days of the month */
|
|
||||||
if (released < priv->days_delay + 7 * february_gap ||
|
|
||||||
released >= days)
|
|
||||||
{
|
{
|
||||||
priv->clicked_cell = -1;
|
priv->clicked_cell = -1;
|
||||||
priv->start_mark_cell = -1;
|
priv->start_mark_cell = -1;
|
||||||
@@ -922,34 +947,28 @@ gcal_month_view_button_release (GtkWidget *widget,
|
|||||||
|
|
||||||
gtk_widget_queue_draw (widget);
|
gtk_widget_queue_draw (widget);
|
||||||
|
|
||||||
x = (width / 7) * ((priv->end_mark_cell % 7) + 0.5);
|
|
||||||
y = start_grid_y + v_block * (lines_gap_for_5 + (priv->end_mark_cell / 7) + 0.5);
|
|
||||||
|
|
||||||
start_date = gcal_dup_icaltime (priv->date);
|
start_date = gcal_dup_icaltime (priv->date);
|
||||||
start_date->day = priv->start_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
|
start_date->day = 7 * ((priv->start_mark_cell + 7 * k) / 7) + sw * (priv->start_mark_cell % 7) + (1 - k);
|
||||||
|
start_date->day -= priv->days_delay;
|
||||||
start_date->is_date = 1;
|
start_date->is_date = 1;
|
||||||
|
|
||||||
end_date = NULL;
|
end_date = NULL;
|
||||||
if (priv->start_mark_cell != priv->end_mark_cell)
|
if (priv->start_mark_cell != priv->end_mark_cell)
|
||||||
{
|
{
|
||||||
end_date = gcal_dup_icaltime (priv->date);
|
end_date = gcal_dup_icaltime (priv->date);
|
||||||
end_date->day = priv->end_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
|
end_date->day = j - priv->days_delay;
|
||||||
end_date->is_date = 1;
|
end_date->is_date = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->start_mark_cell > priv->end_mark_cell)
|
if (start_date->day > end_date->day)
|
||||||
{
|
{
|
||||||
start_date->day = priv->end_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
|
gint day;
|
||||||
end_date->day = priv->start_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
|
day = start_date->day;
|
||||||
|
start_date->day = end_date->day;
|
||||||
|
end_date->day = day;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_debug ("[view] will emit signal on: %f, %f, with %s",
|
g_signal_emit_by_name (GCAL_VIEW (widget), "create-event", start_date, end_date, x, y);
|
||||||
x, y, icaltime_as_ical_string (*start_date));
|
|
||||||
|
|
||||||
g_signal_emit_by_name (GCAL_VIEW (widget),
|
|
||||||
"create-event",
|
|
||||||
start_date, end_date,
|
|
||||||
x, y);
|
|
||||||
|
|
||||||
g_free (start_date);
|
g_free (start_date);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user