gcal-days-grid: added marks related code

GcalDaysGrid emit signal when marked in order to communicate with
GcalDayView container.
This commit is contained in:
Erick Pérez Castellanos
2014-12-04 17:10:32 -05:00
parent fd464a11a4
commit e9df332422
2 changed files with 258 additions and 4 deletions
+244 -4
View File
@@ -73,8 +73,22 @@ typedef struct
GList *children;
GdkWindow *event_window;
/* button_down/up flags */
gint clicked_cell;
gint start_mark_cell;
gint end_mark_cell;
} GcalDaysGridPrivate;
enum
{
MARKED,
NUM_SIGNALS
};
static guint signals[NUM_SIGNALS] = { 0, };
/* Helpers and private */
static gint compare_child_info (gconstpointer a,
gconstpointer b);
@@ -116,6 +130,9 @@ static gboolean gcal_days_grid_draw (GtkWidget *widg
static gboolean gcal_days_grid_button_press_event (GtkWidget *widget,
GdkEventButton *event);
static gboolean gcal_days_grid_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event);
static gboolean gcal_days_grid_button_release_event (GtkWidget *widget,
GdkEventButton *event);
@@ -172,6 +189,7 @@ gcal_days_grid_class_init (GcalDaysGridClass *klass)
widget_class->size_allocate = gcal_days_grid_size_allocate;
widget_class->draw = gcal_days_grid_draw;
widget_class->button_press_event = gcal_days_grid_button_press_event;
widget_class->motion_notify_event = gcal_days_grid_motion_notify_event;
widget_class->button_release_event = gcal_days_grid_button_release_event;
container_class = GTK_CONTAINER_CLASS (klass);
@@ -201,6 +219,18 @@ gcal_days_grid_class_init (GcalDaysGridClass *klass)
FALSE,
G_PARAM_CONSTRUCT |
G_PARAM_READWRITE));
/* to comunicate to it's parent view the marking */
signals[MARKED] = g_signal_new ("marked",
GCAL_TYPE_DAYS_GRID,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GcalDaysGridClass,
marked),
NULL, NULL, NULL,
G_TYPE_NONE,
2,
G_TYPE_UINT,
G_TYPE_UINT);
}
@@ -217,6 +247,11 @@ gcal_days_grid_init (GcalDaysGrid *self)
priv->req_cell_height = 0;
priv->children = NULL;
priv->clicked_cell = -1;
priv->start_mark_cell = -1;
priv->end_mark_cell = -1;
gtk_style_context_add_class (
gtk_widget_get_style_context (GTK_WIDGET (self)),
"calendar-view");
@@ -577,6 +612,7 @@ gcal_days_grid_draw (GtkWidget *widget,
gint width;
GdkRGBA ligther_color;
GdkRGBA background_selected_color;
GdkRGBA font_color;
PangoLayout *layout;
@@ -604,6 +640,11 @@ gcal_days_grid_draw (GtkWidget *widget,
gtk_widget_get_state_flags (widget) | GTK_STATE_FLAG_INSENSITIVE,
&ligther_color);
gtk_style_context_get_background_color (
gtk_widget_get_style_context (widget),
gtk_widget_get_state_flags (widget) | GTK_STATE_FLAG_SELECTED,
&background_selected_color);
gtk_style_context_get (
gtk_widget_get_style_context (widget),
gtk_widget_get_state_flags (widget),
@@ -641,6 +682,51 @@ gcal_days_grid_draw (GtkWidget *widget,
g_free (hours);
}
/* drawing new-event mark */
if (priv->start_mark_cell != -1 &&
priv->end_mark_cell != -1)
{
gint first_cell;
gint last_cell;
gint columns;
cairo_save (cr);
if (priv->start_mark_cell < priv->end_mark_cell)
{
first_cell = priv->start_mark_cell;
last_cell = priv->end_mark_cell;
}
else
{
first_cell = priv->end_mark_cell;
last_cell = priv->start_mark_cell;
}
cairo_set_source_rgba (cr,
background_selected_color.red,
background_selected_color.green,
background_selected_color.blue,
background_selected_color.alpha);
for (columns = 0; columns < last_cell / 48 - first_cell / 48 + 1; columns++)
{
gint first_point;
gint last_point;
first_point = (columns == 0) ? first_cell : ((first_cell / 48) + columns) * 48;
last_point = (columns == (last_cell / 48 - first_cell / 48)) ? last_cell : ((first_cell / 48) + columns) * 48 + 47;
cairo_rectangle (cr,
priv->scale_width + (width / priv->columns_nr) * (first_point / 48),
(first_point % 48) * (alloc.height / 48),
(width / priv->columns_nr),
(last_point - first_point + 1) * (alloc.height / 48));
cairo_fill (cr);
}
cairo_restore (cr);
}
/* drawing lines */
cairo_set_source_rgb (cr,
ligther_color.red,
@@ -692,16 +778,113 @@ static gboolean
gcal_days_grid_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
g_debug ("Button pressed on days-grid area");
return FALSE;
GcalDaysGridPrivate *priv;
GtkBorder padding;
GtkAllocation alloc;
gint width_block;
gint height_block;
gint left_pad;
priv = gcal_days_grid_get_instance_private (GCAL_DAYS_GRID (widget));
gtk_style_context_get_padding (
gtk_widget_get_style_context (widget),
gtk_widget_get_state_flags (widget),
&padding);
left_pad = padding.left + padding.right + priv->scale_width;
/* XXX: an improvement will be to scroll to that position on click */
if (event->x < left_pad)
return FALSE;
gtk_widget_get_allocation (widget, &alloc);
width_block = (alloc.width - left_pad) / priv->columns_nr;
height_block = (alloc.height - (padding.top + padding.bottom)) / 48;
priv->clicked_cell = 48 * (((gint) event->x - left_pad) / width_block) + event->y / height_block;
priv->start_mark_cell = priv->clicked_cell;
return TRUE;
}
static gboolean
gcal_days_grid_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event)
{
GcalDaysGridPrivate *priv;
GtkBorder padding;
GtkAllocation alloc;
gint width_block;
gint height_block;
gint left_pad;
priv = gcal_days_grid_get_instance_private (GCAL_DAYS_GRID (widget));
if (priv->clicked_cell == -1)
return FALSE;
gtk_style_context_get_padding (
gtk_widget_get_style_context (widget),
gtk_widget_get_state_flags (widget),
&padding);
left_pad = padding.left + padding.right + priv->scale_width;
gtk_widget_get_allocation (widget, &alloc);
width_block = (alloc.width - left_pad) / priv->columns_nr;
height_block = (alloc.height - (padding.top + padding.bottom)) / 48;
priv->end_mark_cell = 48 * (((gint) event->x - left_pad) / width_block) + event->y / height_block;
gtk_widget_queue_draw (widget);
return TRUE;
}
static gboolean
gcal_days_grid_button_release_event (GtkWidget *widget,
GdkEventButton *event)
{
g_debug ("Button released on days-grid area");
return FALSE;
GcalDaysGridPrivate *priv;
GtkBorder padding;
GtkAllocation alloc;
gint width_block;
gint height_block;
gint left_pad;
priv = gcal_days_grid_get_instance_private (GCAL_DAYS_GRID (widget));
if (priv->clicked_cell == -1)
return FALSE;
gtk_style_context_get_padding (
gtk_widget_get_style_context (widget),
gtk_widget_get_state_flags (widget),
&padding);
left_pad = padding.left + padding.right + priv->scale_width;
if (event->x < left_pad)
{
priv->start_mark_cell = -1;
priv->end_mark_cell = -1;
return FALSE;
}
gtk_widget_get_allocation (widget, &alloc);
width_block = (alloc.width - left_pad) / priv->columns_nr;
height_block = (alloc.height - (padding.top + padding.bottom)) / 48;
priv->end_mark_cell = 48 * (((gint) event->x - left_pad) / width_block) + event->y / height_block;
gtk_widget_queue_draw (widget);
g_signal_emit (GCAL_DAYS_GRID (widget),
signals[MARKED], 0,
priv->start_mark_cell, priv->end_mark_cell);
priv->clicked_cell = -1;
return TRUE;
}
/* GtkContainer API */
@@ -939,3 +1122,60 @@ gcal_days_grid_get_by_uuid (GcalDaysGrid *days_grid,
return NULL;
}
void
gcal_days_grid_clear_marks (GcalDaysGrid *days_grid)
{
GcalDaysGridPrivate *priv;
priv = gcal_days_grid_get_instance_private (days_grid);
priv->start_mark_cell = -1;
priv->end_mark_cell = -1;
gtk_widget_queue_draw (GTK_WIDGET (days_grid));
}
void
gcal_days_grid_mark_cell (GcalDaysGrid *days_grid,
guint cell)
{
GcalDaysGridPrivate *priv;
priv = gcal_days_grid_get_instance_private (days_grid);
priv->start_mark_cell = cell;
priv->end_mark_cell = cell;
gtk_widget_queue_draw (GTK_WIDGET (days_grid));
}
void
gcal_days_grid_get_cell_position (GcalDaysGrid *days_grid,
guint cell,
gint *x,
gint *y)
{
GcalDaysGridPrivate *priv;
GtkWidget *widget;
GtkBorder padding;
GtkAllocation alloc;
gint width;
gint height;
gint left_pad;
priv = gcal_days_grid_get_instance_private (days_grid);
widget = GTK_WIDGET (days_grid);
gtk_style_context_get_padding (
gtk_widget_get_style_context (widget),
gtk_widget_get_state_flags (widget),
&padding);
left_pad = padding.left + padding.right + priv->scale_width;
gtk_widget_get_allocation (widget, &alloc);
width = alloc.width - left_pad;
height = alloc.height - (padding.top + padding.bottom);
*x = (gint) left_pad + (width / priv->columns_nr) * (cell / 48 + 0.5);
*y = (gint) (height / 48) * ((cell % 48) + 0.5);
}
+14
View File
@@ -42,6 +42,9 @@ struct _GcalDaysGrid
struct _GcalDaysGridClass
{
GtkContainerClass parent_class;
/* signals */
void (*marked) (guint start_cell, guint end_cell);
};
GType gcal_days_grid_get_type (void);
@@ -59,9 +62,20 @@ void gcal_days_grid_place (GcalDaysGrid *days_gr
guint start_cell,
guint end_cell);
/* GcalView API helpers */
GtkWidget* gcal_days_grid_get_by_uuid (GcalDaysGrid *days_grid,
const gchar *uuid);
void gcal_days_grid_clear_marks (GcalDaysGrid *days_grid);
void gcal_days_grid_mark_cell (GcalDaysGrid *days_grid,
guint cell);
void gcal_days_grid_get_cell_position (GcalDaysGrid *days_grid,
guint cell,
gint *x,
gint *y);
G_END_DECLS
#endif /* __GCAL_DAYS_GRID_H__ */