[gnome-calendar] month-view: use a custom structure to help multiday allocation
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar] month-view: use a custom structure to help multiday allocation
- Date: Sat, 18 Nov 2017 23:58:12 +0000 (UTC)
commit 9fa9de2df78163bcde805707d5cb42319219effb
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sat Nov 18 21:55:30 2017 -0200
month-view: use a custom structure to help multiday allocation
Instead of using 3 different, barely synchronized arrays. This
makes the code easier to read, and is more semantic too.
src/views/gcal-month-view.c | 111 +++++++++++++++++++++++++------------------
1 files changed, 65 insertions(+), 46 deletions(-)
---
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index 7beb0b4..d25e730 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -38,6 +38,15 @@
#define LINE_WIDTH 0.5
+typedef struct
+{
+ GtkWidget *event_widget;
+ gboolean visible;
+ guint8 length;
+ guint8 height;
+ guint8 cell;
+} GcalEventBlock;
+
struct _GcalMonthView
{
GtkContainer parent;
@@ -289,19 +298,18 @@ get_month_cell_at_position (GcalMonthView *self,
return NULL;
}
-static void
+static GPtrArray*
calculate_multiday_event_blocks (GcalMonthView *self,
+ GtkWidget *event_widget,
gint first_cell,
gint last_cell,
- gint natural_height,
gdouble *vertical_cell_space,
gdouble *size_left,
- GArray *cells,
- GArray *lengths,
- GArray *length_visible,
gint *events_at_day,
gint *allocated_events_at_day)
{
+ GcalEventBlock *block;
+ GPtrArray *blocks;
gboolean was_visible;
gdouble old_y;
gdouble y;
@@ -321,27 +329,40 @@ calculate_multiday_event_blocks (GcalMonthView *self,
first_cell = swap;
}
+ blocks = g_ptr_array_new_full (last_cell - first_cell + 1, g_free);
+
GCAL_TRACE_MSG ("Calculating event blocks from cell %d to cell %d", first_cell, last_cell);
for (i = first_cell; i <= last_cell; i++)
{
+ GtkStyleContext *context;
+ GtkBorder margin;
gboolean visible_at_range;
gboolean different_row;
gboolean will_overflow;
gdouble real_height;
gint remaining_events;
+ gint minimum_height;
real_height = size_left[i];
+ /* Calculate the minimum event height */
+ context = gtk_widget_get_style_context (GTK_WIDGET (event_widget));
+
+ gtk_style_context_get_margin (context, gtk_style_context_get_state (context), &margin);
+ gtk_widget_get_preferred_height (GTK_WIDGET (event_widget), &minimum_height, NULL);
+
+ minimum_height += margin.top + margin.bottom;
+
/* Count this event at this cell */
different_row = i / 7 != (i - 1) / 7;
remaining_events = events_at_day[i] - allocated_events_at_day[i];
- will_overflow = remaining_events * natural_height > real_height;
+ will_overflow = remaining_events * minimum_height > real_height;
if (will_overflow)
real_height -= gcal_month_cell_get_overflow_height (GCAL_MONTH_CELL (self->month_cell[i / 7][i %
7]));
- visible_at_range = real_height >= natural_height;
+ visible_at_range = real_height >= minimum_height;
if (visible_at_range)
allocated_events_at_day[i]++;
@@ -359,20 +380,34 @@ calculate_multiday_event_blocks (GcalMonthView *self,
current_part_length = 1;
old_y = y;
- g_array_append_val (cells, i);
- g_array_append_val (lengths, current_part_length);
- g_array_append_val (length_visible, visible_at_range);
+ /* Only create a new event widget after the first one is consumed */
+ if (old_y != -1.0)
+ {
+ event_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (event_widget));
+ gtk_widget_show (event_widget);
+
+ setup_child_widget (self, event_widget);
+ }
+
+ /* Add a new block */
+ block = g_new (GcalEventBlock, 1);
+ block->event_widget = event_widget;
+ block->visible = visible_at_range;
+ block->height = minimum_height;
+ block->length = 1;
+ block->cell = i;
+
+ g_ptr_array_add (blocks, block);
}
else
{
- current_part_length++;
- g_array_index (lengths, gint, lengths->len - 1) = current_part_length;
+ block->length++;
}
was_visible = visible_at_range;
}
- GCAL_EXIT;
+ GCAL_RETURN (blocks);
}
static void
@@ -1562,14 +1597,12 @@ gcal_month_view_size_allocate (GtkWidget *widget,
{
g_autoptr (GDateTime) start_date = NULL;
g_autoptr (GDateTime) end_date = NULL;
- g_autoptr (GArray) visible_at_length = NULL;
- g_autoptr (GArray) lengths = NULL;
- g_autoptr (GArray) blocks = NULL;
+ g_autoptr (GPtrArray) blocks = NULL;
GcalEvent *event;
gboolean all_day;
- gint event_block;
gint first_cell;
gint last_cell;
+ gint block_idx;
child_widget = (GtkWidget*) l->data;
event = gcal_event_widget_get_event (l->data);
@@ -1620,42 +1653,28 @@ gcal_month_view_size_allocate (GtkWidget *widget,
GCAL_TRACE_MSG ("Positioning '%s' (multiday) from %d to %d", gcal_event_get_summary (event),
first_cell, last_cell);
- blocks = g_array_sized_new (TRUE, TRUE, sizeof (gint), 16);
- lengths = g_array_sized_new (TRUE, TRUE, sizeof (gint), 16);
- visible_at_length = g_array_sized_new (TRUE, TRUE, sizeof (gboolean), 16);
-
- /* Position and allocate the child widget */
- minimum_height = get_real_event_widget_height (child_widget);
-
- gtk_style_context_get_margin (child_context,
- gtk_style_context_get_state (child_context),
- &margin);
-
- calculate_multiday_event_blocks (self,
- first_cell, last_cell,
- minimum_height + margin.top + margin.bottom,
- vertical_cell_space,
- size_left,
- blocks,
- lengths,
- visible_at_length,
- events_at_day,
- allocated_events_at_day);
-
- for (event_block = 0; event_block < blocks->len; event_block++)
+ blocks = calculate_multiday_event_blocks (self,
+ child_widget,
+ first_cell, last_cell,
+ vertical_cell_space,
+ size_left,
+ events_at_day,
+ allocated_events_at_day);
+
+ for (block_idx = 0; block_idx < blocks->len; block_idx++)
{
g_autoptr (GDateTime) dt_start = NULL;
g_autoptr (GDateTime) dt_end = NULL;
- gboolean visible;
+ GcalEventBlock *block;
gdouble width;
gint last_block_cell;
gint length;
gint cell;
gint day;
- visible = g_array_index (visible_at_length, gboolean, event_block);
- length = g_array_index (lengths, gint, event_block);
- cell = g_array_index (blocks, gint, event_block);
+ block = g_ptr_array_index (blocks, block_idx);
+ length = block->length;
+ cell = block->cell;
last_block_cell = cell + length - 1;
day = cell - self->days_delay + 1;
@@ -1663,7 +1682,7 @@ gcal_month_view_size_allocate (GtkWidget *widget,
* Setup a new event widget when the cell index changes. This happens when
* the event has a different y position, or when the row changed.
*/
- if (event_block != 0)
+ if (block_idx != 0)
{
child_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
gtk_widget_show (child_widget);
@@ -1677,7 +1696,7 @@ gcal_month_view_size_allocate (GtkWidget *widget,
}
/* No space left, add to the overflow and continue */
- if (!visible)
+ if (!block->visible)
{
gint idx;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]