[gnome-calendar/gbsneto/gtk4: 1/8] WIP: year-view: Port to GTK4




commit de66a99881334845e8ed59fe4749ba601053e257
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Feb 7 19:49:28 2022 -0300

    WIP: year-view: Port to GTK4

 src/gui/views/gcal-year-view.c  | 1996 ++++++---------------------------------
 src/gui/views/gcal-year-view.ui |  188 +---
 src/theme/Adwaita.css           |  120 +--
 3 files changed, 338 insertions(+), 1966 deletions(-)
---
diff --git a/src/gui/views/gcal-year-view.c b/src/gui/views/gcal-year-view.c
index ac32a8f9..b8ebc658 100644
--- a/src/gui/views/gcal-year-view.c
+++ b/src/gui/views/gcal-year-view.c
@@ -22,14 +22,13 @@
 #include "gcal-clock.h"
 #include "gcal-context.h"
 #include "gcal-debug.h"
+#include "gcal-range-tree.h"
 #include "gcal-timeline-subscriber.h"
 #include "gcal-year-view.h"
 #include "gcal-view.h"
 #include "gcal-utils.h"
 
 #include <glib/gi18n.h>
-#include <math.h>
-#include <string.h>
 
 #define NAVIGATOR_MAX_GRID_SIZE 4
 #define VISUAL_CLUES_SIDE 3.0
@@ -37,55 +36,17 @@
 
 typedef struct
 {
-  /* month span from 0 to 11 */
-  gint                start_day, start_month;
-  gint                end_day, end_month;
-  gint                hovered_day, hovered_month;
-  gint                dnd_day, dnd_month;
-} ButtonData;
-
-typedef struct
-{
-  gdouble             box_side;
-  GdkPoint            coordinates [12];
-} GridData;
+  GtkWidget         *week_number[6];
+  GtkWidget         *day[31];
+  GtkWidget         *grid;
+} MonthData;
 
 struct _GcalYearView
 {
   GtkBox              parent;
 
-  /* composite, GtkBuilder's widgets */
-  GtkWidget          *navigator;
-  GtkWidget          *sidebar;
-  GtkWidget          *events_sidebar;
-  GtkWidget          *navigator_stack;
-  GtkWidget          *no_events_title;
-  GtkWidget          *navigator_sidebar;
-  GtkWidget          *scrolled_window;
-  GtkLabel           *temp_label;   /* unowned */
-  GtkImage           *weather_icon; /* unowned */
-
-  GtkWidget          *popover; /* Popover for popover_mode */
-
-  /* manager singleton */
-  GcalContext        *context;
-
-  /* range shown on the sidebar */
-  GDateTime          *start_selected_date;
-  GDateTime          *end_selected_date;
-
-  /* geometry info */
-  GridData           *navigator_grid;
-  guint               number_of_columns;
-  guint               column_width;
-  guint               row_height;
-  guint               header_height;
-  guint               sidebar_width;
-
-  /* state flags */
-  gboolean            popover_mode;
-  gboolean            button_pressed;
-  ButtonData         *selected_data;
+  GtkFlowBox         *flowbox;
+  GtkLabel           *year_label;
 
   /**
    * first day of the week according to user locale, being
@@ -93,1482 +54,408 @@ struct _GcalYearView
    */
   gint                first_weekday;
 
-  /* first and last weeks of the year */
-  guint               first_week_of_year;
-  guint               last_week_of_year;
-
-  /* Storage for the accumulated scrolling */
-  gdouble               scroll_value;
-
-  /* show week numbers from GNOME Shell settings */
   GSettings          *calendar_settings;
-  gboolean            show_week_numbers;
 
-  /* text direction factors */
-  gint                k;
+  MonthData           months[12];
 
-  /* date property */
   GDateTime          *date;
+  GcalContext        *context;
+  gulong              update_indicators_idle_id;
 
-  /*
-   * Array with the events at every month. Events
-   * that span multiple months are added multiple
-   * times to the array.
-   */
-  GPtrArray          *events[12];
+  GcalRangeTree      *events;
 };
 
 enum {
   PROP_0,
   PROP_DATE,
   PROP_CONTEXT,
-  PROP_SHOW_WEEK_NUMBERS,
   LAST_PROP
 };
 
 static void          gcal_view_interface_init                    (GcalViewInterface  *iface);
 
-static void          update_weather                              (GcalYearView       *self);
-
 static void          gcal_timeline_subscriber_interface_init     (GcalTimelineSubscriberInterface *iface);
 
+static gboolean      update_event_indicators_in_idle_cb          (gpointer           data);
 
 G_DEFINE_TYPE_WITH_CODE (GcalYearView, gcal_year_view, GTK_TYPE_BOX,
                          G_IMPLEMENT_INTERFACE (GCAL_TYPE_VIEW, gcal_view_interface_init)
                          G_IMPLEMENT_INTERFACE (GCAL_TYPE_TIMELINE_SUBSCRIBER,
                                                 gcal_timeline_subscriber_interface_init));
 
-static gint
-compare_events (GcalEventWidget *widget1,
-                GcalEventWidget *widget2)
+static GtkWidget*
+create_day_label (guint day)
 {
-  return gcal_event_compare (gcal_event_widget_get_event (widget1), gcal_event_widget_get_event (widget2));
-}
+  g_autofree gchar *day_str = NULL;
+  GtkWidget *overlay;
+  GtkWidget *label;
+  GtkWidget *dot;
 
-static guint
-get_last_week_of_year_dmy (gint       first_weekday,
-                           GDateDay   day,
-                           GDateMonth month,
-                           GDateYear  year)
-{
-  GDate day_of_year;
-  gint day_of_week;
+  day_str = g_strdup_printf ("%u", day);
+  label = gtk_label_new (day_str);
+  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
+  gtk_widget_add_css_class (label, "days");
+  gtk_widget_add_css_class (label, "numeric");
 
-  g_date_set_dmy (&day_of_year, day, month, year);
-  day_of_week = g_date_get_weekday (&day_of_year) % 7;
+  dot = g_object_new (ADW_TYPE_BIN,
+                      "css-name", "dot",
+                      "valign", GTK_ALIGN_END,
+                      "halign", GTK_ALIGN_CENTER,
+                      NULL);
 
-  if (day_of_week >= first_weekday)
-    g_date_add_days (&day_of_year, (6 - day_of_week) + first_weekday);
-  else
-    g_date_add_days (&day_of_year, first_weekday - day_of_week - 1);
+  overlay = gtk_overlay_new ();
+  gtk_overlay_set_child (GTK_OVERLAY (overlay), label);
+  gtk_overlay_add_overlay (GTK_OVERLAY (overlay), dot);
+  g_object_set_data (G_OBJECT (overlay), "dot", dot);
 
-  return g_date_get_iso8601_week_of_year (&day_of_year);
+  return overlay;
 }
 
 static void
-event_activated (GcalEventWidget *widget,
-                 gpointer         user_data)
+set_dot_visible (GtkWidget *day_widget,
+                 gboolean   visible)
 {
-  GcalYearView *view = GCAL_YEAR_VIEW (user_data);
-
-  if (view->popover_mode)
-    gtk_widget_hide (view->popover);
-  g_signal_emit_by_name (view, "event-activated", widget);
+  GtkWidget *dot = g_object_get_data (G_OBJECT (day_widget), "dot");
+  gtk_widget_set_visible (dot, visible);
 }
 
 static void
-weather_changed (GcalWeatherService *weather_service,
-                 GcalYearView       *self)
+init_month_data (GcalYearView *self,
+                 guint         month,
+                 MonthData    *month_data)
 {
-  g_return_if_fail (GCAL_IS_WEATHER_SERVICE (weather_service));
-  g_return_if_fail (GCAL_IS_YEAR_VIEW (self));
+  GtkWidget *month_name;
+  GtkWidget *separator;
+  guint i;
 
-  update_weather (self);
-}
+  month_data->grid = g_object_new (GTK_TYPE_GRID,
+                                   "column-spacing", 6,
+                                   "row-spacing", 6,
+                                   "column-spacing", 6,
+                                   "hexpand", TRUE,
+                                   "vexpand", TRUE,
+                                   NULL);
+  gtk_widget_add_css_class (month_data->grid, "month");
+  gtk_widget_add_css_class (month_data->grid, "card");
+  gtk_widget_add_css_class (month_data->grid, "activatable");
+  gtk_flow_box_append (self->flowbox, month_data->grid);
 
-static void
-order_selected_data (ButtonData *selected_data)
-{
-  gint swap;
-  if (selected_data->end_month < selected_data->start_month)
-    {
-      swap = selected_data->start_month;
-      selected_data->start_month = selected_data->end_month;
-      selected_data->end_month = swap;
+  month_name = gtk_label_new (gcal_get_month_name (month));
+  gtk_widget_set_hexpand (month_name, TRUE);
+  gtk_widget_add_css_class (month_name, "accent");
+  gtk_widget_add_css_class (month_name, "title-4");
+  gtk_grid_attach (GTK_GRID (month_data->grid), month_name, 0, 0, 8, 1);
 
-      swap = selected_data->start_day;
-      selected_data->start_day = selected_data->end_day;
-      selected_data->end_day = swap;
-    }
-  else if (selected_data->start_month == selected_data->end_month && selected_data->end_day < 
selected_data->start_day)
-    {
-      swap = selected_data->start_day;
-      selected_data->start_day = selected_data->end_day;
-      selected_data->end_day = swap;
-    }
-}
+  separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+  gtk_grid_attach (GTK_GRID (month_data->grid), separator, 0, 1, 8, 1);
 
-static void
-update_selected_dates_from_button_data (GcalYearView *year_view)
-{
-  if (year_view->selected_data->start_day != 0)
+  for (i = 0; i < 6; i++)
     {
-      ButtonData selected_data = *(year_view->selected_data);
-
-      order_selected_data (&selected_data);
-
-      gcal_clear_date_time (&year_view->start_selected_date);
-      year_view->start_selected_date = g_date_time_new_local (g_date_time_get_year (year_view->date),
-                                                              selected_data.start_month + 1,
-                                                              selected_data.start_day,
-                                                              0, 0, 0);
-
-      gcal_clear_date_time (&year_view->end_selected_date);
-      year_view->end_selected_date = g_date_time_new_local (g_date_time_get_year (year_view->date),
-                                                            selected_data.end_month + 1,
-                                                            selected_data.end_day,
-                                                            23, 59, 59);
-    }
-  else
-    {
-      g_autoptr (GDateTime) start_date = NULL;
-
-      if (year_view->date)
-        start_date = g_date_time_ref (year_view->date);
-      else
-        start_date = g_date_time_new_now_local ();
-
-      gcal_clear_date_time (&year_view->start_selected_date);
-      year_view->start_selected_date = g_date_time_new (gcal_context_get_timezone (year_view->context),
-                                                        g_date_time_get_year (start_date),
-                                                        g_date_time_get_month (start_date),
-                                                        g_date_time_get_day_of_month (start_date),
-                                                        0, 0, 0);
-
-      gcal_clear_date_time (&year_view->end_selected_date);
-      year_view->end_selected_date = g_date_time_add_days (year_view->start_selected_date, 1);
-
-      year_view->selected_data->start_day = g_date_time_get_day_of_month (year_view->start_selected_date);
-      year_view->selected_data->start_month = g_date_time_get_month (year_view->start_selected_date) - 1;
-      year_view->selected_data->end_day = g_date_time_get_day_of_month (year_view->end_selected_date);
-      year_view->selected_data->end_month = g_date_time_get_month (year_view->end_selected_date)-1;
+      month_data->week_number[i] = gtk_label_new (NULL);
+      gtk_widget_set_halign (month_data->week_number[i], GTK_ALIGN_CENTER);
+      gtk_widget_set_valign (month_data->week_number[i], GTK_ALIGN_CENTER);
+      gtk_widget_add_css_class (month_data->week_number[i], "week-number");
+      gtk_grid_attach (GTK_GRID (month_data->grid), month_data->week_number[i], 0, i + 2, 1, 1);
     }
 
-  if (g_date_time_get_year (year_view->end_selected_date) != g_date_time_get_year 
(year_view->start_selected_date))
+  for (i = 0; i < 31; i++)
     {
-      g_autoptr (GDateTime) end_of_year = NULL;
-
-      end_of_year = g_date_time_new (gcal_context_get_timezone (year_view->context),
-                                     g_date_time_get_year (year_view->start_selected_date),
-                                     G_DATE_DECEMBER,
-                                     31,
-                                     0, 0, 0);
-      gcal_set_date_time (&year_view->end_selected_date, end_of_year);
-    }
-}
-
-static void
-update_no_events_page (GcalYearView *year_view)
-{
-  g_autoptr (GDateTime) now = NULL;
-  g_autofree gchar *title = NULL;
-  gboolean has_range;
+      month_data->day[i] = create_day_label (i + 1);
 
-  now = g_date_time_new_now_local ();
-  has_range = gcal_date_time_compare_date (year_view->start_selected_date, year_view->end_selected_date);
-
-  if (gcal_date_time_compare_date (now, year_view->start_selected_date) == 0)
-    {
-      title = g_strdup_printf ("%s%s", _("Today"), has_range ? "…" : "");
-    }
-  else
-    {
-      if (has_range)
-        {
-          /* Translators: This is a date format in the sidebar of the year
-           * view when the selection starts at the specified day and the
-           * end is unspecified.  */
-          title = g_date_time_format (year_view->start_selected_date, _("%B %d…"));
-        }
-      else
-        {
-          /* Translators: This is a date format in the sidebar of the year
-           * view when there is only one specified day selected.  */
-          title = g_date_time_format (year_view->start_selected_date, _("%B %d"));
-        }
+      gtk_grid_attach (GTK_GRID (month_data->grid),
+                       month_data->day[i],
+                       1 + i % 7,
+                       2 + i / 7,
+                       1,
+                       1);
     }
-
-  gtk_label_set_text (GTK_LABEL (year_view->no_events_title), title);
-  update_weather (year_view);
 }
 
 static void
-add_event_to_day_array (GcalYearView  *year_view,
-                        GcalEvent     *event,
-                        GList        **days_widgets_array,
-                        gint           days_span)
+update_weekday_widgets (GcalYearView *self)
 {
-  g_autoptr (GDateTime) second_date = NULL;
-  g_autoptr (GDateTime) date = NULL;
-  GcalCalendar *calendar;
-  GtkWidget *child_widget;
-  GDateTime *dt_start, *dt_end;
-  gboolean is_readonly;
-  gint i;
+  gboolean show_weekdate;
+  guint month;
 
-  calendar = gcal_event_get_calendar (event);
-  is_readonly = gcal_calendar_is_read_only (calendar);
-
-  child_widget = gcal_event_widget_new (year_view->context, event);
-  gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (child_widget), is_readonly);
-
-  dt_start = gcal_event_get_date_start (event);
-  dt_end = gcal_event_get_date_end (event);
+  GCAL_ENTRY;
 
-  /* normalize date on each new event */
-  date = g_date_time_ref (year_view->start_selected_date);
-  second_date = g_date_time_add_days (date, 1);
+  show_weekdate = g_settings_get_boolean (self->calendar_settings, "show-weekdate");
 
-  /* marking and cloning */
-  for (i = 0; i < days_span; i++)
+  for (month = 0; month < 12; month++)
     {
-      GtkWidget *cloned_child;
-      GDateTime *aux;
-      gint start_comparison;
+      g_autoptr (GDateTime) week_date = NULL;
+      GDate date;
+      gint days_delay;
+      gint week;
 
-      cloned_child = child_widget;
-      start_comparison = gcal_date_time_compare_date (dt_start, date);
+      g_date_set_dmy (&date, 1, month + 1, g_date_time_get_year (self->date));
+      days_delay = 7 - (7 - ((g_date_get_weekday (&date) % 7) - (self->first_weekday % 7)));
 
-      if (start_comparison > 0)
-        {
-          /*
-           * The start date of the event is ahead of the current
-           * date being comparent, so we don't add it now.
-           */
-          cloned_child = NULL;
-        }
-      else if (start_comparison == 0)
-        {
-          /*
-           * This is the first day the event happens, so we just use
-           * the previously created event widget.
-           */
-          cloned_child = child_widget;
-        }
-      else
-        {
-          /*
-           * We're in the middle of the event and the dates are between
-           * the event start date > current date > event end date, so
-           * we keep cloning the event widget until we reach the end of
-           * the event.
-           */
-          cloned_child = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
-        }
+      /* Week numbers */
+      week_date = g_date_time_new_local (g_date_time_get_year (self->date),
+                                         month + 1,
+                                         1, 0, 0, 0);
 
-      if (cloned_child != NULL)
+      for (week = 0; week < 6; week++)
         {
-          gint end_comparison;
+          g_autoptr (GDateTime) next_week_date = NULL;
+          GtkWidget *label;
+          gboolean valid_date;
 
-          /*
-           * Setup the event widget's custom dates, so the slanted edges are
-           * applied properly
-           */
-          if (gcal_event_is_multiday (event))
-            {
-              gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (cloned_child), date);
-              gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (cloned_child), second_date);
-            }
-
-          days_widgets_array[i] = g_list_insert_sorted (days_widgets_array[i],
-                                                        cloned_child,
-                                                        (GCompareFunc) compare_events);
-
-          end_comparison = gcal_date_time_compare_date (second_date, dt_end);
-
-          /*
-           * If the end date surpassed the event's end date, we reached the
-           * end of the event's time span and shall stop adding the event to
-           * the list.
-           */
-          if (end_comparison >= 0)
-            break;
-        }
-
-      /* Move the compared dates to the next day */
-      aux = date;
-      date = g_date_time_add_days (date, 1);
-      g_clear_pointer (&aux, g_date_time_unref);
-
-      aux = second_date;
-      second_date = g_date_time_add_days (second_date, 1);
-      g_clear_pointer (&aux, g_date_time_unref);
-    }
-}
-
-static GPtrArray*
-get_events_for_range (GcalYearView *self,
-                      GDateTime    *start,
-                      GDateTime    *end)
-{
-  g_autoptr (GPtrArray) events = NULL;
-  guint i;
-
-  events = g_ptr_array_sized_new (50);
-
-  for (i = g_date_time_get_month (start) - 1; i <= g_date_time_get_month (end) - 1; i++)
-    {
-      GPtrArray *month_events = self->events[i];
-      guint j;
+          valid_date = g_date_valid_dmy (MAX (week * 7 + 1 - days_delay, 1),
+                                         month + 1,
+                                         g_date_time_get_year (self->date));
 
-      for (j = 0; j < month_events->len; j++)
-        {
-          GDateTime *event_start;
-          GDateTime *event_end;
-          GcalEvent *event;
-
-          event = g_ptr_array_index (month_events, j);
-          event_start = gcal_event_get_date_start (event);
-          event_end = gcal_event_get_date_end (event);
+          label = self->months[month].week_number[week];
+          gtk_widget_set_visible (label, valid_date && show_weekdate);
 
-          if (gcal_date_time_compare_date (event_end, start) < 0 ||
-              gcal_date_time_compare_date (event_start, end) > 0)
+          if (valid_date)
             {
-              continue;
-            }
-
-          g_ptr_array_add (events, event);
-        }
-    }
-
-  return g_steal_pointer (&events);
-}
-
-static void
-update_sidebar (GcalYearView *year_view)
-{
-  g_autoptr (GPtrArray) events = NULL;
-  GtkWidget *child_widget;
-  GList **days_widgets_array;
-  gint i, days_span;
-
-  update_selected_dates_from_button_data (year_view);
-
-  gtk_container_foreach (GTK_CONTAINER (year_view->events_sidebar), (GtkCallback) gtk_widget_destroy, NULL);
-
-  days_span = g_date_time_get_day_of_year (year_view->end_selected_date) - g_date_time_get_day_of_year 
(year_view->start_selected_date) + 1;
-  days_widgets_array = g_new0 (GList*, days_span);
-
-  events = get_events_for_range (year_view,
-                                 year_view->start_selected_date,
-                                 year_view->end_selected_date);
+              g_autofree gchar *week_number = NULL;
 
+              week_number = g_strdup_printf ("%d", g_date_time_get_week_of_year (week_date));
+              gtk_label_set_label (GTK_LABEL (label), week_number);
+            }
 
-  if (events->len == 0)
-    {
-      days_span = 0;
-      update_no_events_page (year_view);
-      gtk_stack_set_visible_child_name (GTK_STACK (year_view->navigator_stack), "no-events");
-    }
-  else
-    {
-      gtk_stack_set_visible_child_name (GTK_STACK (year_view->navigator_stack), "events-list");
-    }
-
-  for (i = 0; i < events->len; i++)
-    {
-      add_event_to_day_array (year_view,
-                              g_ptr_array_index (events, i),
-                              days_widgets_array,
-                              days_span);
-    }
-
-  gtk_widget_queue_draw (year_view->navigator);
-
-  for (i = 0; i < days_span; i++)
-    {
-      GList *current_day = days_widgets_array[i];
-      GList *l;
-
-      for (l = current_day; l != NULL; l = g_list_next (l))
-        {
-          child_widget = l->data;
-          gtk_widget_show (child_widget);
-          g_signal_connect_object (child_widget, "activate", G_CALLBACK (event_activated), year_view, 0);
-          g_object_set_data (G_OBJECT (child_widget), "shift", GINT_TO_POINTER (i));
-          gtk_container_add (GTK_CONTAINER (year_view->events_sidebar), child_widget);
+          next_week_date = g_date_time_add_days (week_date, 7);
+          gcal_set_date_time (&week_date, next_week_date);
         }
-
-      g_list_free (current_day);
     }
 
-  g_free (days_widgets_array);
+  GCAL_EXIT;
 }
 
 static void
-reset_sidebar (GcalYearView *year_view)
+update_year_label (GcalYearView *self)
 {
-  memset (year_view->selected_data, 0, sizeof (ButtonData));
-  gtk_widget_queue_draw (GTK_WIDGET (year_view));
+  g_autofree gchar *year = NULL;
 
-  update_sidebar (year_view);
+  year = g_date_time_format (self->date, "%Y");
+  gtk_label_set_label (self->year_label, year);
 }
 
 static void
-update_sidebar_headers (GtkListBoxRow *row,
-                        GtkListBoxRow *before,
-                        gpointer user_data)
+update_event_indicators (GcalYearView *self)
 {
-  GcalYearView *year_view;
-  GtkWidget *row_child, *before_child = NULL, *row_header = NULL;
-  GcalEvent *row_event, *before_event;
-  GDateTime *row_date, *before_date = NULL;
-  gint row_shift, before_shift =-1;
+  guint month;
 
-  year_view = GCAL_YEAR_VIEW (user_data);
-  row_child = gtk_bin_get_child (GTK_BIN (row));
-
-  if (!row_child)
-    return;
-
-  row_event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (row_child));
-  row_date = gcal_event_get_date_start (row_event);
-  row_date = g_date_time_to_local (row_date);
-  row_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row_child), "shift"));
-
-  if (before)
-    {
-      before_child = gtk_bin_get_child (GTK_BIN (before));
-      before_event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (before_child));
-      before_date = gcal_event_get_date_start (before_event);
-      before_date = g_date_time_to_local (before_date);
-      before_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (before_child), "shift"));
-    }
-
-  if (before_shift == -1 || before_shift != row_shift)
-    {
-      g_autoptr (GDateTime) row_day = NULL;
-      g_autoptr (GDateTime) now = NULL;
-      GtkWidget *label;
-      gchar *label_str;
-
-      row_header = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-      now = g_date_time_new_now_local ();
-      row_day = g_date_time_add_days (year_view->start_selected_date, row_shift);
-
-      if (gcal_date_time_compare_date (row_day, now) == 0)
-        label_str = g_strdup (_("Today"));
-      else
-        /* Translators: This is a date format in the sidebar of the year view. */
-        label_str = g_date_time_format (row_day, _("%B %d"));
-
-      label = gtk_label_new (label_str);
-      gtk_style_context_add_class (gtk_widget_get_style_context (label), "sidebar-header");
-      g_object_set (label, "margin", 6, "halign", GTK_ALIGN_START, NULL);
-      g_free (label_str);
-
-      gtk_container_add (GTK_CONTAINER (row_header), label);
-    }
-
-  if (row_header != NULL)
-    gtk_widget_show_all (row_header);
-  gtk_list_box_row_set_header (row, row_header);
-
-  g_clear_pointer (&before_date, g_date_time_unref);
-  g_clear_pointer (&row_date, g_date_time_unref);
-}
-
-static void
-calculate_coord_for_date (GcalYearView *year_view,
-                          gint          day,
-                          gint          month,
-                          gboolean      is_title,
-                          GdkRectangle *rect)
-{
-  gint cell_x, cell_y, clicked_cell, sw;
+  GCAL_ENTRY;
 
-  if (is_title ||
-      year_view->selected_data->start_day != year_view->selected_data->end_day ||
-      year_view->selected_data->start_month != year_view->selected_data->end_month)
+  for (month = 0; month < 12; month++)
     {
-      rect->x = year_view->navigator_grid->coordinates[month].x;
-      rect->y = year_view->navigator_grid->coordinates[month].y;
-      rect->width = year_view->column_width;
-      rect->height =  year_view->row_height;
-
-      return;
-    }
-
-  /* else */
-  sw = 1 - 2 * year_view->k;
-  clicked_cell = day + ((time_day_of_week (1, month, g_date_time_get_year (year_view->date)) - 
year_view->first_weekday + 7) % 7) - 1;
+      guint day;
 
-  cell_x = (clicked_cell % 7 + year_view->k + year_view->show_week_numbers) * 
year_view->navigator_grid->box_side * sw;
-  cell_x += (year_view->k * year_view->navigator_grid->box_side * (7 + year_view->show_week_numbers));
-  cell_y = ((clicked_cell / 7 + 1) * year_view->navigator_grid->box_side);
-
-  rect->x = cell_x + year_view->navigator_grid->coordinates[month].x;
-  rect->y = cell_y + year_view->navigator_grid->coordinates[month].y;
-  rect->width = rect->height =  year_view->navigator_grid->box_side;
-}
-
-static gint
-sidebar_sort_func (GtkListBoxRow *row1,
-                   GtkListBoxRow *row2,
-                   gpointer       user_data)
-{
-  GtkWidget *row1_child, *row2_child;
-  gint result, row1_shift, row2_shift;
-
-  row1_child = gtk_bin_get_child (GTK_BIN (row1));
-  row2_child = gtk_bin_get_child (GTK_BIN (row2));
-  row1_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row1_child), "shift"));
-  row2_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row2_child), "shift"));
-
-  result = row1_shift - row2_shift;
-  if (result == 0)
-    return compare_events (GCAL_EVENT_WIDGET (row1_child), GCAL_EVENT_WIDGET (row2_child));
-
-  return result;
-}
-
-
-static gboolean
-calculate_day_month_for_coord (GcalYearView *year_view,
-                               gdouble       x,
-                               gdouble       y,
-                               gint         *out_day,
-                               gint         *out_month,
-                               gboolean     *is_title)
-{
-  GdkPoint *coordinates;
-  gint row, column, i, sw, clicked_cell, day, month, columns_or_rows;
-  gint number_of_rows;
-  gdouble box_side;
-
-  row = -1;
-  column = -1;
-  box_side = year_view->navigator_grid->box_side;
-  number_of_rows = ceil (12.0 / year_view->number_of_columns);
-  sw = 1 - 2 * year_view->k;
-  coordinates = year_view->navigator_grid->coordinates;
-
-  *is_title = FALSE;
-  columns_or_rows = year_view->number_of_columns > number_of_rows ? year_view->number_of_columns : 
number_of_rows;
-
-  for (i = 0; i < columns_or_rows && ((row == -1) || (column == -1)); i++)
-    {
-      if (row == -1 &&
-          y > coordinates[i * year_view->number_of_columns].y &&
-          y < coordinates[i * year_view->number_of_columns].y + year_view->row_height)
-        {
-          if (y < coordinates[i * year_view->number_of_columns].y + box_side)
-            *is_title = TRUE;
-          row = i;
-        }
-      if (column == -1 &&
-          x > coordinates[i].x + box_side * year_view->show_week_numbers * (1 - year_view->k) &&
-          x < coordinates[i].x + year_view->column_width - box_side * year_view->show_week_numbers * 
year_view->k)
+      for (day = 0; day < 31; day++)
         {
-          column = i;
-        }
-    }
-
-  if (row == -1 || column == -1)
-    return FALSE;
-
-  month = row * year_view->number_of_columns + column;
-
-  if (month < 0 || month > 11)
-    return FALSE;
-
-  *out_month = month;
-
-  if (*is_title)
-    return TRUE;
-
-  row = (y - (year_view->navigator_grid->coordinates[month].y + box_side)) / box_side;
-  column = (x - (year_view->navigator_grid->coordinates[month].x + box_side * year_view->show_week_numbers * 
(1 - year_view->k))) / box_side;
-  clicked_cell = row * 7 + column;
-  day = 7 * ((clicked_cell + 7 * year_view->k) / 7) + sw * (clicked_cell % 7) + (1 - year_view->k);
-  day -= ((time_day_of_week (1, month, g_date_time_get_year (year_view->date)) - year_view->first_weekday + 
7) % 7);
-
-  if (day < 1 || day > time_days_in_month (g_date_time_get_year (year_view->date), month))
-    return FALSE;
-
-  *out_day = day;
-  return TRUE;
-}
-static guint
-count_events_at_day (GcalYearView *self,
-                     GDateTime    *today)
-{
-  g_autoptr (GDateTime) today_end = NULL;
-  GPtrArray *events;
-  guint i, n_events;
-
-  events = self->events[g_date_time_get_month (today) - 1];
-  n_events = 0;
-  today_end = g_date_time_add_days (today, 1);
-
-  for (i = 0; i < events->len; i++)
-    {
-      g_autoptr (GDateTime) event_start = NULL;
-      g_autoptr (GDateTime) event_end = NULL;
-      GcalEvent *event;
+          g_autoptr (GcalRange) range = NULL;
+          g_autoptr (GDateTime) date = NULL;
 
-      event = g_ptr_array_index (events, i);
-
-      event_start = g_date_time_ref (gcal_event_get_date_start (event));
-
-      if (gcal_event_get_all_day (event))
-          event_end = g_date_time_add_days (gcal_event_get_date_end (event), -1);
-      else
-          event_end = g_date_time_ref (gcal_event_get_date_end (event));
+          if (!g_date_valid_dmy (day + 1, month + 1, g_date_time_get_year (self->date)))
+            continue;
 
+          date = g_date_time_new_local (g_date_time_get_year (self->date),
+                                        month + 1,
+                                        day + 1,
+                                        0, 0, 0);
+          range = gcal_range_new_take (g_date_time_ref (date),
+                                       g_date_time_add_days (date, 1),
+                                       GCAL_RANGE_DEFAULT);
 
-      if (gcal_date_time_compare_date (event_start, today_end) >= 0 ||
-          gcal_date_time_compare_date (event_end, today) < 0)
-        {
-          continue;
+          set_dot_visible (self->months[month].day[day],
+                           gcal_range_tree_count_entries_at_range (self->events, range) > 0);
         }
-
-      n_events++;
     }
 
-  return n_events;
+  GCAL_EXIT;
 }
 
 static void
-draw_month_grid (GcalYearView *year_view,
-                 GtkWidget    *widget,
-                 cairo_t      *cr,
-                 gint          month_nr,
-                 gint         *weeks_counter)
+update_month_grid (GcalYearView *self)
 {
-  GtkStyleContext *context;
-  GtkStateFlags state_flags;
-
-  PangoLayout *layout, *slayout;
-  PangoFontDescription *font_desc, *sfont_desc;
-
-  g_autoptr (GDateTime) day = NULL;
   g_autoptr (GDateTime) now = NULL;
+  gboolean show_weekdate;
+  guint month;
 
-  GdkRGBA color;
-  gint layout_width, layout_height, i, j, sw;
-  gint column, row;
-  gboolean column_is_workday;
-  gdouble x, y, box_side, box_padding_top, box_padding_start;
-  gint days_delay, days, shown_rows;
-  gchar *str, *nr_day, *nr_week;
-  gboolean selected_day;
+  GCAL_ENTRY;
 
   now = g_date_time_new_now_local ();
+  show_weekdate = g_settings_get_boolean (self->calendar_settings, "show-weekdate");
 
-  cairo_save (cr);
-  context = gtk_widget_get_style_context (widget);
-  state_flags = gtk_style_context_get_state (context);
-  sw = 1 - 2 * year_view->k;
-  box_side = year_view->navigator_grid->box_side;
-  x = year_view->navigator_grid->coordinates[month_nr].x;
-  y = year_view->navigator_grid->coordinates[month_nr].y;
-
-  /* Get the font description */
-  gtk_style_context_save (context);
-  gtk_style_context_set_state (context, state_flags | GTK_STATE_FLAG_SELECTED);
-  gtk_style_context_get (context, state_flags | GTK_STATE_FLAG_SELECTED, "font", &sfont_desc, NULL);
-  gtk_style_context_restore (context);
-
-  slayout = gtk_widget_create_pango_layout (widget, NULL);
-  pango_layout_set_font_description (slayout, sfont_desc);
-
-  /* header */
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "header");
-
-  str = g_strdup (gcal_get_month_name (month_nr));
-  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
-
-  layout = gtk_widget_create_pango_layout (widget, str);
-  pango_layout_set_font_description (layout, font_desc);
-  pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
-  gtk_render_layout (context, cr, x + (year_view->column_width - layout_width) / 2.0, y + (box_side - 
layout_height) / 2.0,
-                     layout);
-
-  gtk_render_background (context, cr,
-                         x + (year_view->column_width - layout_width) / 2.0, y + (box_side - layout_height) 
/ 2.0,
-                         layout_width, layout_width);
-
-  pango_font_description_free (font_desc);
-  g_free (str);
-  gtk_style_context_restore (context);
-
-  /* separator line */
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "lines");
-
-  gtk_style_context_get_color (context, state_flags, &color);
-  cairo_set_line_width (cr, 0.2);
-  gdk_cairo_set_source_rgba (cr, &color);
-
-  cairo_move_to (cr, x + box_side * year_view->show_week_numbers * (1 - year_view->k), y + box_side + 0.4);
-  cairo_rel_line_to (cr, 7.0 * box_side, 0);
-  cairo_stroke (cr);
-
-  gtk_style_context_restore (context);
-
-  /* days */
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "days");
-
-  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
-  pango_layout_set_font_description (layout, font_desc);
-
-  days_delay = (time_day_of_week (1, month_nr, g_date_time_get_year (year_view->date)) - 
year_view->first_weekday + 7) % 7;
-  days = days_delay + g_date_get_days_in_month (month_nr + 1, g_date_time_get_year (year_view->date));
-  shown_rows = ceil (days / 7.0);
-
-  day = g_date_time_new (gcal_context_get_timezone (year_view->context),
-                         g_date_time_get_year (year_view->date),
-                         month_nr + 1,
-                         1, 0, 0, 0);
-
-  for (i = 0; i < 7 * shown_rows; i++)
+  for (month = 0; month < 12; month++)
     {
-      g_autoptr (GDateTime) next_day = NULL;
-
-      column = (i % 7) + (year_view->k || year_view->show_week_numbers);
-      column_is_workday = is_workday ((7 * year_view->k + sw * (column - (year_view->show_week_numbers * 
!year_view->k) + (sw * year_view->first_weekday))) % 7);
-      row = i / 7;
-
-      j = 7 * ((i + 7 * year_view->k) / 7) + sw * (i % 7) + (1 - year_view->k);
-      if (j <= days_delay)
-        continue;
-      else if (j > days)
-        continue;
-      j -= days_delay;
-
-      nr_day = g_strdup_printf ("%d", j);
-      pango_layout_set_text (layout, nr_day, -1);
-      pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
-      box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
-      box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0;
-
-      /* Draw the hover background */
-      if (year_view->selected_data->hovered_day == j &&
-          year_view->selected_data->hovered_month == month_nr)
-        {
-          gint hover_x, hover_y;
-
-          hover_x = box_side * column + x + box_padding_start / 2.0 - year_view->k * box_side - 2.0;
-          hover_y = box_side * (row + 1) + y + box_padding_top - 1.0;
+      g_autoptr (GDateTime) week_date = NULL;
+      GDate date;
+      guint day;
+      gint days_delay;
+      gint column;
+      gint week;
+      gint row;
 
-          gtk_style_context_set_state (context, state_flags | GTK_STATE_FLAG_PRELIGHT);
+      g_date_set_dmy (&date, 1, month + 1, g_date_time_get_year (self->date));
+      days_delay = 7 - (7 - ((g_date_get_weekday (&date) % 7) - (self->first_weekday % 7)));
 
-          gtk_render_background (context,
-                                 cr,
-                                 hover_x,
-                                 hover_y,
-                                 box_side - box_padding_start / 2.0,
-                                 box_side);
+      column = days_delay;
+      row = 2;
 
-          gtk_style_context_set_state (context, state_flags);
-        }
+      /* Week numbers */
+      week_date = g_date_time_new_local (g_date_time_get_year (self->date),
+                                         month + 1,
+                                         1, 0, 0, 0);
 
-      /* Draw the Drag n' Drop indicator */
-      if (year_view->selected_data->dnd_day == j &&
-          year_view->selected_data->dnd_month == month_nr)
+      for (week = 0; week < 6; week++)
         {
-          gint dnd_x, dnd_y;
-
-          dnd_x = box_side * column + x + box_padding_start / 2.0 - year_view->k * box_side - 2.0;
-          dnd_y = box_side * (row + 1) + y + box_padding_top - 1.0;
+          g_autoptr (GDateTime) next_week_date = NULL;
+          GtkWidget *label;
+          gboolean valid_date;
 
-          gtk_style_context_save (context);
-          gtk_style_context_add_class (context, "dnd");
+          valid_date = g_date_valid_dmy (MAX (week * 7 + 1 - days_delay, 1),
+                                         month + 1,
+                                         g_date_time_get_year (self->date));
 
-          gtk_render_background (context,
-                                 cr,
-                                 dnd_x,
-                                 dnd_y,
-                                 box_side - box_padding_start / 2.0,
-                                 box_side);
+          label = self->months[month].week_number[week];
+          gtk_widget_set_visible (label, valid_date && show_weekdate);
 
-          gtk_style_context_restore (context);
-        }
-
-      selected_day = FALSE;
-      if (year_view->selected_data->start_day != 0)
-        {
-          ButtonData selected_data = *(year_view->selected_data);
-          order_selected_data (&selected_data);
-          if (month_nr > selected_data.start_month && month_nr < selected_data.end_month)
+          if (valid_date)
             {
-              selected_day = TRUE;
-            }
-          else if (month_nr == selected_data.start_month && month_nr == selected_data.end_month)
-            {
-              selected_day = j >= selected_data.start_day && j <= selected_data.end_day;
-            }
-          else if (month_nr == selected_data.start_month && j >= selected_data.start_day)
-            {
-              selected_day = TRUE;
-            }
-          else if (month_nr == selected_data.end_month && j <= selected_data.end_day)
-            {
-              selected_day = TRUE;
-            }
-        }
-
-      if (g_date_time_get_year (year_view->date) == g_date_time_get_year (now) &&
-          month_nr + 1 == g_date_time_get_month (now) &&
-          j == g_date_time_get_day_of_month (now))
-        {
-          PangoLayout *clayout;
-          PangoFontDescription *cfont_desc;
-
-          gtk_style_context_save (context);
-          gtk_style_context_add_class (context, "current");
-
-          clayout = gtk_widget_create_pango_layout (widget, nr_day);
-          gtk_style_context_get (context, state_flags, "font", &cfont_desc, NULL);
-          pango_layout_set_font_description (clayout, cfont_desc);
-          pango_layout_get_pixel_size (clayout, &layout_width, &layout_height);
-          box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
-          box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0;
-
-          /* FIXME: hardcoded padding of the number background */
-          gtk_render_background (context, cr,
-                                 box_side * column + x + sw * box_padding_start - year_view->k * 
layout_width - 2.0,
-                                 box_side * (row + 1) + y + box_padding_top - 1.0,
-                                 layout_width + 4.0, layout_height + 2.0);
-          gtk_render_layout (context, cr,
-                             box_side * column + x + sw * box_padding_start - year_view->k * layout_width,
-                             box_side * (row + 1) + y + box_padding_top,
-                             clayout);
-
-          gtk_style_context_restore (context);
-          pango_font_description_free (cfont_desc);
-          g_object_unref (clayout);
-        }
-      else if (selected_day)
-        {
-          gtk_style_context_set_state (context, state_flags | GTK_STATE_FLAG_SELECTED);
-
-          pango_layout_set_text (slayout, nr_day, -1);
-          pango_layout_get_pixel_size (slayout, &layout_width, &layout_height);
-          box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
-          box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0;
-
-          gtk_render_layout (context, cr,
-                             box_side * column + x + sw * box_padding_start - year_view->k * layout_width,
-                             box_side * (row + 1) + y + box_padding_top,
-                             slayout);
-
-          gtk_style_context_set_state (context, state_flags);
-        }
-      else if (!column_is_workday)
-        {
-          gtk_style_context_save (context);
-          gtk_style_context_add_class (context, "non-workday");
-          gtk_render_layout (context, cr,
-                             box_side * column + x + sw * box_padding_start - year_view->k * layout_width,
-                             box_side * (row + 1) + y + box_padding_top,
-                             layout);
-          gtk_style_context_restore (context);
-        }
-      else
-        {
-          gtk_render_layout (context, cr,
-                             box_side * column + x + sw * box_padding_start - year_view->k * layout_width,
-                             box_side * (row + 1) + y + box_padding_top,
-                             layout);
-        }
-
-      if (count_events_at_day (year_view, day) > 0)
-        {
-          gtk_style_context_save (context);
-          gtk_style_context_add_class (context, "with-events");
-
-          if (selected_day)
-            gtk_style_context_add_class (context, "with-events-selected");
-          else if (!column_is_workday)
-            gtk_style_context_add_class (context, "with-events-non-workday");
-
-          box_padding_start = MAX (0, (box_side - VISUAL_CLUES_SIDE) / 2);
-          gtk_render_background (context, cr,
-                                 box_side * column + x + sw * box_padding_start - year_view->k * 
VISUAL_CLUES_SIDE,
-                                 box_side * (row + 1) + y + box_padding_top + layout_height + 2.0,
-                                 VISUAL_CLUES_SIDE, VISUAL_CLUES_SIDE);
-          gtk_style_context_restore (context);
-        }
+              g_autofree gchar *week_number = NULL;
 
-      /* Update the current day, so we can count the events at this day */
-      next_day = g_date_time_add_days (day, 1);
-      gcal_set_date_time (&day, next_day);
-
-      g_free (nr_day);
-    }
-  pango_font_description_free (font_desc);
-  gtk_style_context_restore (context);
-
-  /* week numbers */
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "week-numbers");
-
-  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
-  pango_layout_set_font_description (layout, font_desc);
+              week_number = g_strdup_printf ("%d", g_date_time_get_week_of_year (week_date));
+              gtk_label_set_label (GTK_LABEL (label), week_number);
+            }
 
-  for (i = 0; i < shown_rows; i++)
-    {
-      /* special condition for first and last weeks of the year */
-      if (month_nr == 0 && year_view->first_week_of_year > 1 && i == 1)
-        *weeks_counter = 1;
-      else if (month_nr == 11 && (i + 1) == shown_rows)
-        *weeks_counter = year_view->last_week_of_year;
-      /* other weeks */
-      else if (i == 0)
-        {
-          if (days_delay == 0 && month_nr != 0)
-            *weeks_counter = *weeks_counter + 1;
+          next_week_date = g_date_time_add_days (week_date, 7);
+          gcal_set_date_time (&week_date, next_week_date);
         }
-      else
-        *weeks_counter = *weeks_counter + 1;
 
-      if (year_view->show_week_numbers)
+      /* Month days */
+      for (day = 0; day < 31; day++)
         {
-          nr_week = g_strdup_printf ("%d", *weeks_counter);
-
-          pango_layout_set_text (layout, nr_week, -1);
-          pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
-          box_padding_top = (box_side - layout_height) / 2.0 > 0 ? (box_side - layout_height) / 2.0 : 0;
-          box_padding_start = (box_side - layout_width) / 2.0 > 0 ? (box_side - layout_width) / 2.0 : 0;
-
-          gtk_render_background (context, cr,
-                                 x + sw * box_padding_top + year_view->k * (8 * box_side - layout_height) - 
WEEK_NUMBER_MARGIN,
-                                 box_side * (i + 1) + y + box_padding_top - WEEK_NUMBER_MARGIN,
-                                 layout_height + WEEK_NUMBER_MARGIN * 2, layout_height + WEEK_NUMBER_MARGIN 
* 2);
-
-          gtk_render_layout (context, cr,
-                             x + sw * box_padding_start + year_view->k * (8 * box_side - layout_width),
-                             box_side * (i + 1) + y + box_padding_top,
-                             layout);
-
-          g_free (nr_week);
-        }
-    }
-  gtk_style_context_restore (context);
-
-  pango_font_description_free (sfont_desc);
-  g_object_unref (slayout);
-
-  pango_font_description_free (font_desc);
-  g_object_unref (layout);
-  cairo_restore (cr);
-}
-
-static gboolean
-draw_navigator (GcalYearView *year_view,
-                cairo_t      *cr,
-                GtkWidget    *widget)
-{
-  GtkStyleContext *context;
-  GtkStateFlags state_flags;
-  GtkBorder padding;
-
-  gint header_height, layout_width, layout_height;
-  gint real_padding_left, real_padding_top, i, sw, weeks_counter, number_of_rows;
-  gdouble width, height;
-
-  gchar *header_str;
-
-  PangoLayout *header_layout;
-  PangoFontDescription *font_desc;
-
-  context = gtk_widget_get_style_context (widget);
-  state_flags = gtk_style_context_get_state (context);
-  sw = 1 - 2 * year_view->k;
-  width = gtk_widget_get_allocated_width (widget);
-  number_of_rows = ceil (12.0 / year_view->number_of_columns);
-
-  /* read header from CSS code related to the view */
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "primary-label");
-
-  header_str = g_strdup_printf ("%d", g_date_time_get_year (year_view->date));
-  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
-  gtk_style_context_get_padding (context, state_flags, &padding);
-
-  gtk_style_context_restore (context);
-
-  header_layout = gtk_widget_create_pango_layout (widget, header_str);
-  pango_layout_set_font_description (header_layout, font_desc);
-  pango_layout_get_pixel_size (header_layout, &layout_width, &layout_height);
-  /* XXX: here the color of the text isn't read from year-view but from navigator widget,
-   * which has the same color on the CSS file */
-  gtk_render_layout (context, cr,
-                     year_view->k * (width - layout_width) + sw * padding.left,
-                     padding.top,
-                     header_layout);
-
-  pango_font_description_free (font_desc);
-  g_object_unref (header_layout);
-  g_free (header_str);
-
-  header_height = padding.top * 2 + layout_height;
-  height = gtk_widget_get_allocated_height (widget) - header_height;
-
-  real_padding_left = (width - year_view->column_width * year_view->number_of_columns) / 
(year_view->number_of_columns + 1);
-  real_padding_top = (height - year_view->row_height * number_of_rows) / number_of_rows;
+          g_autoptr (GDateTime) day_datetime = NULL;
+          GtkLayoutManager *layout_manager;
+          GtkLayoutChild *layout_child;
+          GtkWidget *label;
+          gboolean valid_date;
+          gint weekday;
 
-  if (real_padding_top < 0)
-    real_padding_top = 0;
+          label = self->months[month].day[day];
+          valid_date = g_date_valid_dmy (day + 1, month + 1, g_date_time_get_year (self->date));
 
-  weeks_counter = year_view->first_week_of_year;
-  for (i = 0; i < 12; i++)
-    {
-      gint row = i / year_view->number_of_columns;
-      gint column = year_view->k * (year_view->number_of_columns - 1) + sw * (i % 
year_view->number_of_columns);
-
-      year_view->navigator_grid->coordinates[i].x = (column + 1) * real_padding_left + column * 
year_view->column_width;
-      year_view->navigator_grid->coordinates[i].y = row * real_padding_top + row * year_view->row_height + 
header_height;
-      draw_month_grid (year_view, widget, cr, i, &weeks_counter);
-    }
-
-  return FALSE;
-}
-
-static gboolean
-navigator_button_press_cb (GcalYearView   *year_view,
-                           GdkEventButton *event,
-                           GtkWidget      *widget)
-{
-  gint day, month;
-  gboolean is_title = FALSE;
-
-  if (!calculate_day_month_for_coord (year_view, event->x, event->y, &day, &month, &is_title))
-    return GDK_EVENT_PROPAGATE;
-
-  if (is_title)
-    day = 1;
-
-  year_view->button_pressed = TRUE;
-  year_view->selected_data->start_day = day;
-  year_view->selected_data->start_month = month;
+          gtk_widget_set_visible (label, valid_date);
 
-  return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean
-navigator_button_release_cb (GcalYearView   *year_view,
-                             GdkEventButton *event,
-                             GtkWidget      *widget)
-{
-  g_autoptr (GDateTime) new_date = NULL;
-  gboolean is_title = FALSE;
-  gint day, month;
-
-  if (!year_view->button_pressed)
-    return FALSE;
-
-  if (!calculate_day_month_for_coord (year_view, event->x, event->y, &day, &month, &is_title))
-    goto fail;
-
-  if (is_title)
-    day = g_date_get_days_in_month (month + 1, g_date_time_get_year (year_view->date));
-
-  year_view->button_pressed = FALSE;
-  year_view->selected_data->end_day = day;
-  year_view->selected_data->end_month = month;
-
-  /* update date and notify */
-  new_date = g_date_time_new_local (g_date_time_get_year (year_view->date),
-                                    month + 1,
-                                    day,
-                                    0, 0, 0);
-  gcal_set_date_time (&year_view->date, new_date);
-  g_object_notify (G_OBJECT (year_view), "active-date");
-
-  gtk_widget_queue_draw (widget);
-
-  if (year_view->popover_mode)
-    {
-      GdkRectangle rect;
-      GtkWidget *box;
+          if (!valid_date)
+            continue;
 
-      /* sizing */
-      box = gtk_bin_get_child (GTK_BIN (year_view->popover));
-      gtk_widget_set_size_request (box, 200, year_view->navigator_grid->box_side * 2 * 7);
+          day_datetime = g_date_time_new_local (g_date_time_get_year (self->date),
+                                                month + 1,
+                                                day + 1,
+                                                0, 0, 0);
 
-      calculate_coord_for_date (year_view, day, month, is_title, &rect);
-      gtk_popover_set_pointing_to (GTK_POPOVER (year_view->popover), &rect);
+          g_date_set_dmy (&date, day + 1, month + 1, g_date_time_get_year (self->date));
+          weekday = g_date_get_weekday (&date) % 7;
 
-      /* FIXME: do no show over selected days */
-      gtk_popover_set_position (GTK_POPOVER (year_view->popover), GTK_POS_RIGHT);
-      gtk_widget_show (year_view->popover);
-    }
+          if (!is_workday (weekday))
+            gtk_widget_add_css_class (label, "non-workday");
+          else
+            gtk_widget_remove_css_class (label, "non-workday");
 
-  update_sidebar (year_view);
-  return TRUE;
+          if (g_date_time_get_month (now) == month + 1 &&
+              g_date_time_get_day_of_month (now) == day + 1 &&
+              g_date_time_get_year (now) == g_date_time_get_year (self->date))
+            gtk_widget_add_css_class (label, "current");
+          else
+            gtk_widget_remove_css_class (label, "current");
 
-fail:
-  year_view->button_pressed = FALSE;
-  reset_sidebar (year_view);
-  return TRUE;
-}
+          layout_manager = gtk_widget_get_layout_manager (GTK_WIDGET (self->months[month].grid));
+          layout_child = gtk_layout_manager_get_layout_child (layout_manager, label);
 
-static gboolean
-navigator_motion_notify_cb (GcalYearView   *year_view,
-                            GdkEventMotion *event,
-                            GtkWidget      *widget)
-{
-  gint day = 0, month = 0;
-  gboolean is_title = FALSE;
-
-  /* Cancel the hover when selecting a date range */
-  year_view->selected_data->hovered_day = -1;
-  year_view->selected_data->hovered_month = -1;
+          gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (layout_child), column + 1);
+          gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (layout_child), row);
 
-  if (calculate_day_month_for_coord (year_view, event->x, event->y, &day, &month, &is_title))
-    {
-      if (year_view->button_pressed)
-        {
-          if (is_title)
-            day = g_date_get_days_in_month (month + 1, g_date_time_get_year (year_view->date));
-
-          year_view->selected_data->end_day = day;
-          year_view->selected_data->end_month = month;
-          gtk_widget_queue_draw (widget);
-
-          return GDK_EVENT_STOP;
-        }
-      else
-        {
-          /* We only deal with the hover effect when the button is not pressed */
-          year_view->selected_data->hovered_day = day;
-          year_view->selected_data->hovered_month = month;
-          gtk_widget_queue_draw (widget);
-
-          return GDK_EVENT_PROPAGATE;
+          column++;
+          if (column >= 7)
+            row++;
+          column %= 7;
         }
     }
 
-  gtk_widget_queue_draw (widget);
-
-  return GDK_EVENT_STOP;
+  GCAL_EXIT;
 }
 
 static void
-navigator_edge_overshot_cb (GcalYearView    *self,
-                            GtkPositionType  position_type)
+queue_update_event_indicators (GcalYearView *self)
 {
-  g_autoptr (GDateTime) new_date = NULL;
-  GtkAdjustment *adjustment;
-
-  /* Ignore horizontal scrolling (and the year view never scrolls horizontally anyway) */
-  if (position_type == GTK_POS_LEFT || position_type == GTK_POS_RIGHT)
+  if (self->update_indicators_idle_id > 0)
     return;
 
-  adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self->scrolled_window));
-
-  new_date = g_date_time_add_years (self->date, position_type == GTK_POS_BOTTOM ? 1 : -1);
-  gcal_set_date_time (&self->date, new_date);
+  self->update_indicators_idle_id = g_idle_add_full (G_PRIORITY_LOW,
+                                                     update_event_indicators_in_idle_cb,
+                                                     self,
+                                                     NULL);
+}
 
-  gtk_adjustment_set_value (adjustment, 0.0);
-  gtk_widget_queue_draw (self->navigator);
 
-  g_object_notify (G_OBJECT (self), "active-date");
-}
+/*
+ * Callbacks
+ */
 
 static gboolean
-navigator_scroll_event_cb (GcalYearView   *self,
-                           GdkEventScroll *scroll_event)
+update_event_indicators_in_idle_cb (gpointer data)
 {
-  GtkWidget *vscrollbar;
+  GcalYearView *self = GCAL_YEAR_VIEW (data);
 
-  vscrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (self->scrolled_window));
+  update_event_indicators (self);
 
-  /*
-   * If the vertical scrollbar is visible, delegate the year changing check
-   * to GtkScrolledWindow:edge-overshot callback.
-   */
-  if (gtk_widget_get_child_visible (vscrollbar))
-    return GDK_EVENT_PROPAGATE;
-
-  /*
-   * If we accumulated enough scrolling, change the month. Otherwise, we'd scroll
-   * waaay too fast.
-   */
-  if (should_change_date_for_scroll (&self->scroll_value, scroll_event))
-    {
-      g_autoptr (GDateTime) new_date = NULL;
-
-      new_date = g_date_time_add_years (self->date, self->scroll_value > 0 ? 1 : -1);
-      gcal_set_date_time (&self->date, new_date);
-      self->scroll_value = 0;
-
-      gtk_widget_queue_draw (self->navigator);
-
-      g_object_notify (G_OBJECT (self), "active-date");
-    }
-
-  return GDK_EVENT_STOP;
+  self->update_indicators_idle_id = 0;
+  return G_SOURCE_REMOVE;
 }
 
 static void
-add_event_clicked_cb (GcalYearView *year_view,
-                      GtkButton    *button)
+on_clock_day_changed_cb (GcalClock    *clock,
+                         GcalYearView *self)
 {
-  g_autoptr (GDateTime) start_date = NULL;
-  g_autoptr (GDateTime) end_date = NULL;
-
-  if (year_view->start_selected_date)
-    {
-      start_date = g_date_time_new_now_local ();
-    }
-  else
-    {
-      start_date = g_date_time_ref (year_view->start_selected_date);
-      end_date = g_date_time_add_days (year_view->end_selected_date, 1);
-    }
-
-  if (year_view->popover_mode)
-    gtk_widget_hide (year_view->popover);
-
-  g_signal_emit_by_name (GCAL_VIEW (year_view), "create-event-detailed", start_date, end_date);
-}
+  GCAL_ENTRY;
 
-static void
-popover_closed_cb (GcalYearView *year_view,
-                   GtkPopover   *popover)
-{
-  reset_sidebar (year_view);
-}
+  update_month_grid (self);
 
-static void
-calculate_grid_sizes (GcalYearView *self)
-{
-  /* 1 column for week number and 7 for days */
-  if (self->show_week_numbers)
-    self->column_width = self->navigator_grid->box_side * 8;
-  else
-    self->column_width = self->navigator_grid->box_side * 7;
-
-  /* 1 line for month header and 6 lines for weeks */
-  self->row_height = self->navigator_grid->box_side * 7;
+  GCAL_EXIT;
 }
 
 static void
-calculate_sizes (GcalYearView *self)
-{
-  GtkStyleContext *context;
-  PangoLayout *layout;
-  PangoFontDescription *font;
-
-  gint padding_left, padding_right, padding_top, padding_bottom;
-  gint width, height, box_width, box_height, natural;
-  gchar *test_str;
-
-  /* get header info from CSS */
-  context = gtk_widget_get_style_context (GTK_WIDGET (self));
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "primary-label");
-  gtk_style_context_get (context, gtk_style_context_get_state (context),
-                         "padding-top", &padding_top,
-                         "padding-bottom", &padding_bottom,
-                         "font", &font, NULL);
-  gtk_style_context_restore (context);
-
-  /* measure header height */
-  test_str = g_strdup_printf ("8888");
-  layout = gtk_widget_create_pango_layout (self->navigator, test_str);
-  pango_layout_set_font_description (layout, font);
-  pango_layout_get_pixel_size (layout, &width, &height);
-
-  pango_font_description_free (font);
-  g_object_unref (layout);
-  g_free (test_str);
-
-  self->header_height = padding_top + height + padding_bottom;
-
-  /* get day info from CSS */
-  context = gtk_widget_get_style_context (GTK_WIDGET (self->navigator));
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "days");
-  gtk_style_context_get (context, gtk_style_context_get_state (context),
-                         "padding-left", &padding_left,
-                         "padding-right", &padding_right,
-                         "padding-top", &padding_top,
-                         "padding-bottom", &padding_bottom,
-                         "font", &font, NULL);
-  gtk_style_context_restore (context);
-
-  /* measure box size */
-  test_str = g_strdup_printf ("88");
-  layout = gtk_widget_create_pango_layout (self->navigator, test_str);
-  pango_layout_set_font_description (layout, font);
-  pango_layout_get_pixel_size (layout, &width, &height);
-
-  pango_font_description_free (font);
-  g_object_unref (layout);
-  g_free (test_str);
-
-  box_width = padding_left + width + padding_right;
-  box_height = padding_top + height + padding_bottom;
-
-  self->navigator_grid->box_side = (box_width > box_height) ? box_width : box_height;
-
-  /* get sidebar width */
-  gtk_widget_get_preferred_width (self->sidebar, &width, &natural);
-  self->sidebar_width = width;
-
-  calculate_grid_sizes (self);
-}
-
-/*
- * Drag and Drop functions
- */
-static gboolean
-navigator_drag_motion_cb (GcalYearView   *self,
-                          GdkDragContext *context,
-                          gint            x,
-                          gint            y,
-                          guint           time,
-                          GtkWidget      *navigator)
+on_flowbox_child_activated_cb (GtkFlowBox      *flowbox,
+                               GtkFlowBoxChild *child,
+                               GcalYearView    *self)
 {
-  gint day, month;
-  gboolean is_title, retval;
-
-  retval = FALSE;
-
-  self->selected_data->dnd_day = -1;
-  self->selected_data->dnd_month = -1;
+  g_autoptr (GDateTime) date = NULL;
+  gint child_index;
 
-  if (calculate_day_month_for_coord (self, x, y, &day, &month, &is_title))
-    {
-      /* For now, don't allow dropping events on the month title */
-      if (!is_title)
-        {
-          self->selected_data->dnd_day = day;
-          self->selected_data->dnd_month = month;
+  GCAL_ENTRY;
 
-          gdk_drag_status (context, GDK_ACTION_MOVE, time);
+  child_index = gtk_flow_box_child_get_index (child);
+  date = g_date_time_new_local (g_date_time_get_year (self->date),
+                                child_index + 1,
+                                1, 0, 0, 0);
 
-          retval = TRUE;
-        }
-    }
-  else
-    {
-      gdk_drag_status (context, 0, time);
-    }
+  gcal_set_date_time (&self->date, date);
+  g_object_notify (G_OBJECT (self), "active-date");
 
-  gtk_widget_queue_draw (self->navigator);
+  gtk_widget_activate_action (GTK_WIDGET (self), "win.change-view", "i", 1);
 
-  return retval;
+  GCAL_EXIT;
 }
 
-static gboolean
-navigator_drag_drop_cb (GcalYearView   *self,
-                        GdkDragContext *context,
-                        gint            x,
-                        gint            y,
-                        guint           time,
-                        GtkWidget      *navigator)
+static void
+on_show_weekdate_changed_cb (GSettings    *settings,
+                             gchar        *key,
+                             GcalYearView *self)
 {
-  gint day, month;
-  gboolean is_title;
-
-  if (calculate_day_month_for_coord (self, x, y, &day, &month, &is_title))
-    {
-      if (!GCAL_IS_EVENT_WIDGET (gtk_drag_get_source_widget (context)))
-        return FALSE;
-
-      if (!is_title)
-        {
-          g_autoptr (GcalEvent) changed_event = NULL;
-          GcalRecurrenceModType mod;
-          GcalEventWidget *event_widget;
-          GcalCalendar *calendar;
-          GcalEvent *event;
-          GDateTime *start_dt, *end_dt;
-          GDateTime *drop_date;
-
-          event_widget = GCAL_EVENT_WIDGET (gtk_drag_get_source_widget (context));
-          event = gcal_event_widget_get_event (event_widget);
-          changed_event = gcal_event_new_from_event (event);
-          calendar = gcal_event_get_calendar (changed_event);
-          mod = GCAL_RECURRENCE_MOD_THIS_ONLY;
-
-          if (gcal_event_has_recurrence (changed_event) &&
-              !ask_recurrence_modification_type (GTK_WIDGET (self), &mod, calendar))
-            {
-              goto out;
-            }
-
-          start_dt = gcal_event_get_date_start (changed_event);
-          end_dt = gcal_event_get_date_end (changed_event);
-
-          drop_date = g_date_time_add_full (start_dt,
-                                            g_date_time_get_year (self->date) - g_date_time_get_year 
(start_dt),
-                                            (month + 1) - g_date_time_get_month (start_dt),
-                                            day - g_date_time_get_day_of_month (start_dt),
-                                            0, 0, 0);
-
-          if (!g_date_time_equal (start_dt, drop_date))
-            {
-              GTimeSpan diff = g_date_time_difference (drop_date, start_dt);
-              GDateTime *new_start;
-
-              new_start = g_date_time_add (start_dt, diff);
-              gcal_event_set_date_start (changed_event, new_start);
-
-              /* The event may have a NULL end date, so we have to check it here */
-              if (end_dt)
-                {
-                  GDateTime *new_end;
-
-                  new_end = g_date_time_add (end_dt, diff);
-                  gcal_event_set_date_end (changed_event, new_end);
-
-                  g_clear_pointer (&new_end, g_date_time_unref);
-                }
-
-              gcal_manager_update_event (gcal_context_get_manager (self->context),
-                                         changed_event,
-                                         mod);
-
-              g_clear_pointer (&new_start, g_date_time_unref);
-            }
-
-          g_clear_pointer (&drop_date, g_date_time_unref);
-        }
-    }
-
-out:
-  /* Cancel the DnD after the event is dropped */
-  self->selected_data->dnd_day = -1;
-  self->selected_data->dnd_month = -1;
-
-  gtk_drag_finish (context, TRUE, FALSE, time);
+  GCAL_ENTRY;
 
-  gtk_widget_queue_draw (navigator);
+  update_weekday_widgets (self);
 
-  return TRUE;
+  GCAL_EXIT;
 }
 
-static void
-navigator_drag_leave_cb (GcalYearView   *self,
-                         GdkDragContext *context,
-                         guint           time,
-                         GtkWidget      *navigator)
-{
-  /* Cancel the DnD after the event is dropped */
-  self->selected_data->dnd_day = -1;
-  self->selected_data->dnd_month = -1;
-
-  gtk_widget_queue_draw (navigator);
-}
 
 /*
  * GcalTimelineSubscriber implementation
@@ -1593,38 +480,15 @@ gcal_year_view_add_event (GcalTimelineSubscriber *subscriber,
                           GcalEvent              *event)
 {
   GcalYearView *self;
-  GDateTime *event_start;
-  GDateTime *event_end;
-  guint start_month;
-  guint end_month;
-  guint i;
 
   GCAL_ENTRY;
 
   self = GCAL_YEAR_VIEW (subscriber);
 
   g_debug ("Caching event '%s' in Year view", gcal_event_get_uid (event));
+  gcal_range_tree_add_range (self->events, gcal_event_get_range (event), g_object_ref (event));
 
-  event_start = gcal_event_get_date_start (event);
-  event_end = gcal_event_get_date_end (event);
-
-  /* Calculate the start & end months */
-  start_month = g_date_time_get_month (event_start) - 1;
-  end_month = g_date_time_get_month (event_end) - 1;
-
-  if (g_date_time_get_year (event_start) < g_date_time_get_year (self->date))
-    start_month = 0;
-
-  if (g_date_time_get_year (event_end) > g_date_time_get_year (self->date))
-    end_month = 11;
-
-  /* Add the event to the cache */
-  for (i = start_month; i <= end_month; i++)
-    g_ptr_array_add (self->events[i], g_object_ref (event));
-
-  update_sidebar (self);
-
-  gtk_widget_queue_draw (GTK_WIDGET (self->navigator));
+  queue_update_event_indicators (self);
 
   GCAL_EXIT;
 }
@@ -1633,68 +497,16 @@ static void
 gcal_year_view_remove_event (GcalTimelineSubscriber *subscriber,
                              GcalEvent              *event)
 {
-  g_autoptr (GList) children = NULL;
   GcalYearView *self;
-  GList *l;
-  const gchar *event_id;
-  guint n_children;
-  guint i;
 
   GCAL_ENTRY;
 
   self = GCAL_YEAR_VIEW (subscriber);
-  event_id = gcal_event_get_uid (event);
-
-  n_children = 0;
-  children = gtk_container_get_children (GTK_CONTAINER (self->events_sidebar));
-
-  for (l = children; l != NULL; l = g_list_next (l))
-    {
-      GcalEventWidget *child_widget;
-      GcalEvent *list_event;
-
-      child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      list_event = gcal_event_widget_get_event (child_widget);
-
-      if (g_strcmp0 (event_id, gcal_event_get_uid (list_event)) == 0)
-        gtk_widget_destroy (GTK_WIDGET (l->data));
-      else
-        n_children++;
-    }
-
-  /*
-   * No children left visible, all the events were removed and now we have to show the
-   * 'No Events' placeholder.
-   */
-  if (n_children == 0)
-    {
-      update_no_events_page (self);
-      gtk_stack_set_visible_child_name (GTK_STACK (self->navigator_stack), "no-events");
-    }
-
-  /* Also remove from the cached list of events */
-  for (i = 0; i < 12; i++)
-    {
-      GPtrArray *events;
-      guint j;
 
-      events = self->events[i];
+  g_debug ("Removing event '%s' from Year view's cache", gcal_event_get_uid (event));
+  gcal_range_tree_remove_range (self->events, gcal_event_get_range (event), event);
 
-      for (j = 0; j < events->len; j++)
-        {
-          GcalEvent *cached_event;
-
-          cached_event = g_ptr_array_index (events, j);
-
-          if (!g_str_equal (gcal_event_get_uid (cached_event), event_id))
-            continue;
-
-          g_debug ("Removing event '%s' from Year view's cache", event_id);
-          g_ptr_array_remove (events, event);
-        }
-    }
-
-  gtk_widget_queue_draw (GTK_WIDGET (self->navigator));
+  queue_update_event_indicators (self);
 
   GCAL_EXIT;
 }
@@ -1708,7 +520,6 @@ gcal_year_view_update_event (GcalTimelineSubscriber *subscriber,
   gcal_year_view_remove_event (subscriber, event);
   gcal_year_view_add_event (subscriber, event);
 
-
   GCAL_EXIT;
 }
 
@@ -1722,7 +533,10 @@ gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
 }
 
 
-/* GcalView implementation */
+/*
+ * GcalView interface
+ */
+
 static GDateTime*
 gcal_year_view_get_date (GcalView *view)
 {
@@ -1737,35 +551,22 @@ gcal_year_view_set_date (GcalView  *view,
 {
   GcalYearView *self;
   gboolean year_changed;
-  gboolean needs_reset;
 
   GCAL_ENTRY;
 
   self = GCAL_YEAR_VIEW (view);
 
-  needs_reset = self->date &&
-                self->start_selected_date &&
-                !g_date_time_equal (self->date, date);
-
   year_changed = !self->date || g_date_time_get_year (self->date) != g_date_time_get_year (date);
 
   gcal_set_date_time (&self->date, date);
 
-  self->first_week_of_year = get_last_week_of_year_dmy (self->first_weekday,
-                                                        1,
-                                                        G_DATE_JANUARY,
-                                                        g_date_time_get_year (self->date));
-  self->last_week_of_year = get_last_week_of_year_dmy (self->first_weekday,
-                                                       31,
-                                                       G_DATE_DECEMBER,
-                                                       g_date_time_get_year (self->date));
-
-  if (needs_reset)
-    reset_sidebar (self);
-
   if (year_changed)
     gcal_timeline_subscriber_range_changed (GCAL_TIMELINE_SUBSCRIBER (view));
 
+  update_weekday_widgets (self);
+  update_month_grid (self);
+  update_year_label (self);
+
   GCAL_EXIT;
 }
 
@@ -1774,17 +575,7 @@ gcal_year_view_get_children_by_uuid (GcalView              *view,
                                      GcalRecurrenceModType  mod,
                                      const gchar           *uuid)
 {
-  GcalYearView *self = GCAL_YEAR_VIEW (view);
-  GList *result, *children;
-
-  result = NULL;
-
-  children = gtk_container_get_children (GTK_CONTAINER (self->sidebar));
-  result = filter_event_list_by_uid_and_modtype (children, mod, uuid);
-
-  g_list_free (children);
-
-  return result;
+  return NULL;
 }
 
 static GDateTime*
@@ -1820,20 +611,11 @@ static void
 gcal_year_view_finalize (GObject *object)
 {
   GcalYearView *year_view = GCAL_YEAR_VIEW (object);
-  guint i;
-
-  g_free (year_view->navigator_grid);
-  g_free (year_view->selected_data);
 
-  g_clear_pointer (&year_view->start_selected_date, g_date_time_unref);
-  g_clear_pointer (&year_view->end_selected_date, g_date_time_unref);
   g_clear_pointer (&year_view->date, g_date_time_unref);
-
+  g_clear_pointer (&year_view->events, gcal_range_tree_unref);
   g_clear_object (&year_view->calendar_settings);
 
-  for (i = 0; i < 12; i++)
-    g_clear_pointer (&year_view->events[i], g_ptr_array_unref);
-
   G_OBJECT_CLASS (gcal_year_view_parent_class)->finalize (object);
 }
 
@@ -1855,10 +637,6 @@ gcal_year_view_get_property (GObject    *object,
       g_value_set_object (value, self->context);
       break;
 
-    case PROP_SHOW_WEEK_NUMBERS:
-      g_value_set_boolean (value, self->show_week_numbers);
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -1884,26 +662,9 @@ gcal_year_view_set_property (GObject      *object,
 
       g_signal_connect_object (gcal_context_get_clock (self->context),
                                "day-changed",
-                               G_CALLBACK (gtk_widget_queue_draw),
+                               G_CALLBACK (on_clock_day_changed_cb),
                                self,
                                G_CONNECT_SWAPPED);
-
-      g_signal_connect_object (gcal_context_get_weather_service (self->context),
-                               "weather-changed",
-                               G_CALLBACK (weather_changed),
-                               self,
-                               0);
-      update_weather (self);
-      break;
-
-    case PROP_SHOW_WEEK_NUMBERS:
-      if (self->show_week_numbers != g_value_get_boolean (value))
-        {
-          self->show_week_numbers = g_value_get_boolean (value);
-          calculate_grid_sizes (self);
-          g_object_notify (object, "show-week-numbers");
-          gtk_widget_queue_allocate (GTK_WIDGET (self));
-        }
       break;
 
     default:
@@ -1911,108 +672,6 @@ gcal_year_view_set_property (GObject      *object,
     }
 }
 
-static void
-gcal_year_view_get_preferred_width (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  GcalYearView *year_view = GCAL_YEAR_VIEW (widget);
-  GtkStyleContext *context;
-  gint padding_left, padding_right, hpadding;
-
-  context = gtk_widget_get_style_context (year_view->navigator);
-
-  gtk_style_context_get (context,
-                         gtk_style_context_get_state (context),
-                         "padding-left", &padding_left,
-                         "padding-right", &padding_right, NULL);
-
-  hpadding = padding_left + padding_right;
-  if (minimum != NULL)
-    *minimum = hpadding + year_view->column_width;
-  if (natural != NULL)
-    *natural = hpadding + year_view->column_width + year_view->sidebar_width;
-}
-
-static void
-gcal_year_view_size_allocate (GtkWidget     *widget,
-                              GtkAllocation *alloc)
-{
-  GcalYearView *year_view = GCAL_YEAR_VIEW (widget);
-  GtkStyleContext *context;
-  gint padding_left, padding_right, padding_top, padding_bottom, hpadding, vpadding;
-  gint number_of_rows;
-
-  context = gtk_widget_get_style_context (widget);
-  gtk_style_context_save (context);
-  gtk_style_context_add_class (context, "year-navigator");
-  gtk_style_context_get (context,
-                         gtk_style_context_get_state (context),
-                         "padding-left", &padding_left,
-                         "padding-right", &padding_right,
-                         "padding-top", &padding_top,
-                         "padding-bottom", &padding_bottom, NULL);
-  gtk_style_context_restore (context);
-
-  hpadding = padding_left + padding_right;
-  vpadding = padding_top + padding_bottom;
-
-  year_view->popover_mode = (alloc->width < (hpadding + year_view->column_width * 2 + 
year_view->sidebar_width));
-
-  year_view->number_of_columns = (alloc->width - hpadding - year_view->sidebar_width * 
!year_view->popover_mode) / year_view->column_width;
-
-  if (year_view->number_of_columns > NAVIGATOR_MAX_GRID_SIZE)
-    year_view->number_of_columns = NAVIGATOR_MAX_GRID_SIZE;
-
-  number_of_rows = ceil (12.0 / year_view->number_of_columns);
-
-  gtk_widget_set_size_request (year_view->navigator,
-                               hpadding + year_view->column_width * year_view->number_of_columns,
-                               vpadding + year_view->row_height * number_of_rows + year_view->header_height);
-
-  if (year_view->popover_mode && !gtk_widget_is_ancestor (year_view->events_sidebar, year_view->popover))
-    {
-      g_object_ref (year_view->sidebar);
-
-      gtk_container_remove (GTK_CONTAINER (widget), year_view->sidebar);
-      gtk_container_add (GTK_CONTAINER (year_view->popover), year_view->sidebar);
-
-      g_object_unref (year_view->sidebar);
-
-      gtk_widget_show_all (year_view->sidebar);
-      popover_closed_cb (GCAL_YEAR_VIEW (widget), GTK_POPOVER (year_view->popover));
-    }
-  else if (!year_view->popover_mode && gtk_widget_is_ancestor (year_view->events_sidebar, 
year_view->popover))
-    {
-      g_object_ref (year_view->sidebar);
-
-      gtk_container_remove (GTK_CONTAINER (year_view->popover), year_view->sidebar);
-      gtk_box_pack_end (GTK_BOX (widget), year_view->sidebar, FALSE, TRUE, 0);
-
-      g_object_unref (year_view->sidebar);
-
-      gtk_widget_show (year_view->sidebar);
-      g_signal_handlers_block_by_func (year_view->popover, popover_closed_cb, widget);
-      gtk_widget_hide (year_view->popover);
-      g_signal_handlers_unblock_by_func (year_view->popover, popover_closed_cb, widget);
-    }
-
-  GTK_WIDGET_CLASS (gcal_year_view_parent_class)->size_allocate (widget, alloc);
-}
-
-static void
-gcal_year_view_direction_changed (GtkWidget        *widget,
-                                  GtkTextDirection  previous_direction)
-{
-  GcalYearView *year_view = GCAL_YEAR_VIEW (widget);
-
-  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
-    year_view->k = 0;
-  else if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-    year_view->k = 1;
-}
-
-
 static void
 gcal_year_view_class_init (GcalYearViewClass *klass)
 {
@@ -2023,45 +682,15 @@ gcal_year_view_class_init (GcalYearViewClass *klass)
   object_class->get_property = gcal_year_view_get_property;
   object_class->set_property = gcal_year_view_set_property;
 
-  widget_class->get_preferred_width = gcal_year_view_get_preferred_width;
-  widget_class->size_allocate = gcal_year_view_size_allocate;
-  widget_class->direction_changed = gcal_year_view_direction_changed;
-
   g_object_class_override_property (object_class, PROP_DATE, "active-date");
   g_object_class_override_property (object_class, PROP_CONTEXT, "context");
 
-  g_object_class_install_property (object_class,
-                                   PROP_SHOW_WEEK_NUMBERS,
-                                   g_param_spec_boolean ("show-week-numbers",
-                                                         "Show Week Numbers",
-                                                         "Show Week Numbers Column",
-                                                         FALSE,
-                                                         G_PARAM_READWRITE));
-
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/calendar/ui/views/gcal-year-view.ui");
 
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, navigator);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, sidebar);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, events_sidebar);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, navigator_stack);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, navigator_sidebar);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, no_events_title);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, popover);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, scrolled_window);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, temp_label);
-  gtk_widget_class_bind_template_child (widget_class, GcalYearView, weather_icon);
-
-  gtk_widget_class_bind_template_callback (widget_class, draw_navigator);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_button_press_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_button_release_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_drag_drop_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_drag_leave_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_drag_motion_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_edge_overshot_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_motion_notify_cb);
-  gtk_widget_class_bind_template_callback (widget_class, navigator_scroll_event_cb);
-  gtk_widget_class_bind_template_callback (widget_class, add_event_clicked_cb);
-  gtk_widget_class_bind_template_callback (widget_class, popover_closed_cb);
+  gtk_widget_class_bind_template_child (widget_class, GcalYearView, flowbox);
+  gtk_widget_class_bind_template_child (widget_class, GcalYearView, year_label);
+
+  gtk_widget_class_bind_template_callback (widget_class, on_flowbox_child_activated_cb);
 
   gtk_widget_class_set_css_name (widget_class, "calendar-view");
 }
@@ -2071,94 +700,15 @@ gcal_year_view_init (GcalYearView *self)
 {
   guint i;
 
-  for (i = 0; i < 12; i++)
-    self->events[i] = g_ptr_array_new_with_free_func (g_object_unref);
-
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_LTR)
-    self->k = 0;
-  else if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
-    self->k = 1;
-
   self->first_weekday = get_first_weekday ();
-
-  self->navigator_grid = g_new0 (GridData, 1);
-  self->selected_data = g_new0 (ButtonData, 1);
+  self->events = gcal_range_tree_new_with_free_func (g_object_unref);
 
   /* bind GNOME Shell' show week numbers property to GNOME Calendar's one */
   self->calendar_settings = g_settings_new ("org.gnome.desktop.calendar");
-  g_settings_bind (self->calendar_settings, "show-weekdate", self, "show-week-numbers", 
G_SETTINGS_BIND_DEFAULT);
-  g_signal_connect_object (self->calendar_settings, "changed::show-weekdate", G_CALLBACK 
(gtk_widget_queue_draw), self, G_CONNECT_SWAPPED);
-
-  /* layout */
-  self->number_of_columns = 4;
-  calculate_sizes (self);
-
-  gtk_list_box_set_header_func (GTK_LIST_BOX (self->events_sidebar), update_sidebar_headers, self, NULL);
-  gtk_list_box_set_sort_func (GTK_LIST_BOX (self->events_sidebar), sidebar_sort_func, NULL, NULL);
-
-  /* The year navigator is a DnD destination */
-  gtk_drag_dest_set (self->navigator,
-                     0,
-                     NULL,
-                     0,
-                     GDK_ACTION_MOVE);
-}
-
-
-static void
-update_weather (GcalYearView *self)
-{
-  GcalWeatherService *weather_service;
-  gboolean updated = FALSE;
-
-  g_return_if_fail (GCAL_IS_YEAR_VIEW (self));
-
-  weather_service = gcal_context_get_weather_service (self->context);
-
-  if (self->date)
-    {
-      GPtrArray *weather_infos;
-      GDate date;
-      guint i;
-
-      g_date_set_dmy (&date,
-                      g_date_time_get_day_of_month (self->date),
-                      g_date_time_get_month (self->date),
-                      g_date_time_get_year (self->date));
-
-      weather_infos = gcal_weather_service_get_weather_infos (weather_service);
+  g_signal_connect (self->calendar_settings, "changed::show-weekdate", G_CALLBACK 
(on_show_weekdate_changed_cb), self);
 
-      for (i = 0; weather_infos && i < weather_infos->len; i++)
-        {
-          GcalWeatherInfo *info;
-          GDate wdate;
-
-          info = g_ptr_array_index (weather_infos, i);
-
-          gcal_weather_info_get_date (info, &wdate);
-
-          if (g_date_compare (&date, &wdate) == 0)
-            {
-              const gchar *temp_str; /* unowned */
-              const gchar *icon_nm;  /* unowned */
-
-              temp_str = gcal_weather_info_get_temperature (info);
-              icon_nm = gcal_weather_info_get_icon_name (info);
-
-              gtk_label_set_text (self->temp_label, temp_str);
-              gtk_image_set_from_icon_name (self->weather_icon, icon_nm, GTK_ICON_SIZE_SMALL_TOOLBAR);
-              updated = TRUE;
-              break;
-            }
-        }
-    }
-
-  if (!updated)
-    {
-      gtk_label_set_text (self->temp_label, "");
-      gtk_image_clear (self->weather_icon);
-    }
+  for (i = 0; i < 12; i++)
+    init_month_data (self, i, &self->months[i]);
 }
-
diff --git a/src/gui/views/gcal-year-view.ui b/src/gui/views/gcal-year-view.ui
index 6dc8328d..a32d1b2e 100644
--- a/src/gui/views/gcal-year-view.ui
+++ b/src/gui/views/gcal-year-view.ui
@@ -1,172 +1,68 @@
 <?xml version="1.0"?>
 <interface>
-  <!-- interface-requires gtk+ 3.10 -->
   <template class="GcalYearView" parent="GtkBox">
+    <property name="orientation">vertical</property>
     <style>
       <class name="year-view"/>
     </style>
+
     <child>
-      <object class="GtkScrolledWindow" id="scrolled_window">
-        <property name="visible">True</property>
-        <property name="shadow_type">none</property>
-        <property name="vexpand">True</property>
-        <signal name="edge-overshot" handler="navigator_edge_overshot_cb" object="GcalYearView" 
swapped="yes"/>
-        <signal name="scroll-event" handler="navigator_scroll_event_cb" object="GcalYearView" swapped="yes"/>
-        <child>
-          <object class="GtkViewport">
-            <property name="visible">True</property>
-            <property name="shadow_type">none</property>
-            <property name="vexpand">True</property>
-            <child>
-              <object class="GtkDrawingArea" id="navigator">
-                <property name="visible">True</property>
-                <property name="hexpand">True</property>
-                <property 
name="events">GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_STRUCTURE_MASK</property>
-                <signal name="draw" handler="draw_navigator" object="GcalYearView" swapped="yes"/>
-                <signal name="button-press-event" handler="navigator_button_press_cb" object="GcalYearView" 
swapped="yes"/>
-                <signal name="button-release-event" handler="navigator_button_release_cb" 
object="GcalYearView" swapped="yes"/>
-                <signal name="motion-notify-event" handler="navigator_motion_notify_cb" 
object="GcalYearView" swapped="yes"/>
-                <signal name="drag-motion" handler="navigator_drag_motion_cb" object="GcalYearView" 
swapped="yes"/>
-                <signal name="drag-drop" handler="navigator_drag_drop_cb" object="GcalYearView" 
swapped="yes"/>
-                <signal name="drag-leave" handler="navigator_drag_leave_cb" object="GcalYearView" 
swapped="yes"/>
-                <style>
-                  <class name="year-navigator"/>
-                </style>
-              </object>
-            </child>
-          </object>
-        </child>
+      <object class="GtkLabel" id="year_label">
+        <property name="hexpand">true</property>
+        <property name="xalign">1.0</property>
+        <style>
+          <class name="secondary-label" />
+        </style>
       </object>
-      <packing>
-        <property name="position">0</property>
-        <property name="pack_type">start</property>
-      </packing>
     </child>
+
     <child>
-      <object class="GtkBox" id="sidebar">
-        <property name="visible">True</property>
-        <property name="width_request">200</property>
-        <property name="orientation">vertical</property>
+      <object class="GtkSeparator">
+        <property name="orientation">horizontal</property>
+      </object>
+    </child>
+
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <style>
+          <class name="background" />
+        </style>
         <child>
-          <object class="GtkStack" id="navigator_stack">
-            <property name="visible">True</property>
+          <object class="GtkViewport">
+            <property name="scroll-to-focus">True</property>
+
             <child>
-              <object class="GtkScrolledWindow" id="navigator_sidebar">
-                <property name="visible">True</property>
-                <property name="shadow_type">none</property>
-                <property name="vexpand">True</property>
+              <object class="AdwClamp">
+                <property name="margin-top">24</property>
+                <property name="margin-bottom">24</property>
+                <property name="margin-start">24</property>
+                <property name="margin-end">24</property>
+                <property name="maximum-size">1600</property>
+                <property name="tightening-threshold">1200</property>
+
                 <child>
-                  <object class="GtkListBox" id="events_sidebar">
-                    <property name="visible">True</property>
+                  <object class="GtkFlowBox" id="flowbox">
+                    <property name="valign">center</property>
+                    <property name="homogeneous">True</property>
                     <property name="selection-mode">none</property>
+                    <property name="min-children-per-line">1</property>
+                    <property name="max-children-per-line">4</property>
+                    <property name="column-spacing">18</property>
+                    <property name="row-spacing">18</property>
+                    <signal name="child-activated" handler="on_flowbox_child_activated_cb" 
object="GcalYearView" swapped="no" />
                     <style>
-                      <class name="sidebar"/>
+                      <class name="year-navigator"/>
                     </style>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="name">events-list</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <style>
-                  <class name="sidebar"/>
-                </style>
-                <child>
-                  <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="no_events_title">
-                        <property name="visible">True</property>
-                        <property name="halign">start</property>
-                        <property name="label" translatable="yes">Today</property>
-                        <style>
-                          <class name="sidebar-header"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="temp_label">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label">temp</property>
-                        <property name="label">foo</property>
-                        <style>
-                          <class name="temp-label" />
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkImage" id="weather_icon">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="halign">start</property>
-                    <property name="margin_start">6</property>
-                    <property name="label" translatable="yes">No events</property>
-                    <style>
-                      <class name="dim-label"/>
-                      <class name="italic-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-                <property name="name">no-events</property>
-              </packing>
             </child>
+
           </object>
         </child>
-        <child>
-          <object class="GtkButton">
-            <property name="visible">True</property>
-            <property name="valign">end</property>
-            <property name="label" translatable="yes">Add Event…</property>
-            <signal name="clicked" handler="add_event_clicked_cb" object="GcalYearView" swapped="yes"/>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
       </object>
     </child>
   </template>
-  <object class="GtkPopover" id="popover">
-    <property name="relative_to">navigator</property>
-    <style>
-      <class name="events"/>
-    </style>
-    <signal name="closed" handler="popover_closed_cb" object="GcalYearView" swapped="yes"/>
-  </object>
 </interface>
diff --git a/src/theme/Adwaita.css b/src/theme/Adwaita.css
index 31cf12fe..334ce01a 100644
--- a/src/theme/Adwaita.css
+++ b/src/theme/Adwaita.css
@@ -37,128 +37,54 @@ calendar-view:selected {
 }
 
 /* Year View CSS */
-.year-view {
-    padding: 0px;
-}
 
-/* Header the padding if for sizing, on drawing the spacing between cells,
- * and the padding will be automatically calculated
- * Because of year-view widget internals, the color property should be the same
- * of .start-header selector */
-.year-navigator {
-    padding: 12px;
-    color: @theme_selected_bg_color;
-}
-
-.year-navigator.header {
-    color: @theme_selected_bg_color;
-    font-weight: bold;
-}
-
-.year-navigator.lines {
-    color: alpha(@theme_fg_color, 0.4);
+.year-navigator grid.month {
+  padding: 12px;
 }
 
-.year-navigator.days {
+.year-navigator label.days {
     padding: 5px;
     color: @theme_fg_color;
     font-size: 9pt;
+    min-width: 18px;
+    min-height: 18px;
 }
 
-.year-navigator.non-workday {
+.year-navigator label.non-workday {
     color: alpha(@theme_fg_color, 0.5);
 }
 
-.year-navigator.week-numbers {
-    font-size: 70%;
-    font-weight: bold;
-    border-radius: 2px;
+.year-navigator label.week-number {
+    font-size: 0.5rem;
+    border-radius: 50%;
     background-color: alpha(@theme_fg_color, 0.05);
     color: alpha(@theme_fg_color, 0.4);
+    min-width: 18px;
+    min-height: 18px;
 }
 
-/* these two are supposed be changed in sync with .calendar-view */
-.year-navigator.current {
-    background-color: black;
-    border-radius: 2px;
-    color: white;
-    font-weight: bold;
-}
-.year-navigator:selected {
-    color: @theme_selected_bg_color;
+.year-navigator .current label {
+    color: @accent_fg_color;
+    background-color: @accent_bg_color;
+    border-radius: 50%;
     font-weight: bold;
 }
 
-.year-navigator:hover {
-    background-color: alpha(@theme_fg_color, 0.1);
-    border-radius: 2px;
-}
-
-.year-navigator.dnd {
-    border: solid 1px #4e9a06;
-    box-shadow: inset 0 0 0 1px #4e9a06;
-}
-
-.year-navigator.with-events {
+.year-navigator dot {
+    transform: translateX(-1px) translateY(-3px);
     background-color: @theme_fg_color;
     border-radius: 3px;
+    min-width: 3px;
+    min-height: 3px;
 }
 
-.year-navigator.with-events-selected {
-    background-color: @theme_selected_bg_color;
+.year-navigator .current dot {
+    background-color: @accent_fg_color;
 }
 
-.year-navigator.with-events-non-workday {
-    background-color: alpha(@theme_fg_color, 0.5);
-}
 
-.sidebar-header {
-    font-weight: bold;
-    font-size: 11pt;
-}
-
-.italic-label {
-    font-style: italic;
-}
-
-.year-view .sidebar {
-    padding: 4px;
-    border: 1px none @borders;
-}
-
-.year-view .sidebar:backdrop {
-    border-color: @unfocused_borders;
-}
-
-.year-view .sidebar:dir(ltr) {
-    border-left-style: solid;
-}
-.year-view .sidebar:dir(rtl) {
-    border-right-style: solid;
-}
-
-/* no events label */
-.year-view box.sidebar label:nth-child(2) {
-    margin-top: 4px;
-}
-
-.year-view button {
-    border-radius: 0;
-    border-bottom-style: none;
-}
-
-.year-view button:dir(ltr) {
-    border-right-style: none;
-}
-
-.year-view button:dir(rtl) {
-    border-left-style: none;
-}
-
-
-.year-view scrolledwindow {
-    border-top-width: 0;
-    border-bottom-width: 0;
+.year-navigator .non-workday dot {
+    background-color: alpha(@theme_fg_color, 0.5);
 }
 
 popover.events {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]