week-header: reimplement header expansion and collapsing
This commit is contained in:
+117
-53
@@ -53,6 +53,7 @@ struct _GcalWeekHeader
|
|||||||
* and the events will be placed
|
* and the events will be placed
|
||||||
*/
|
*/
|
||||||
GList *events[7];
|
GList *events[7];
|
||||||
|
GtkWidget *overflow_label[7];
|
||||||
|
|
||||||
gint first_weekday;
|
gint first_weekday;
|
||||||
|
|
||||||
@@ -209,6 +210,68 @@ add_event_to_weekday (GcalWeekHeader *self,
|
|||||||
return g_list_index (l, event);
|
return g_list_index (l, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_event_visible (GcalWeekHeader *self,
|
||||||
|
gint weekday,
|
||||||
|
gint position)
|
||||||
|
{
|
||||||
|
gboolean show_label;
|
||||||
|
|
||||||
|
if (self->expanded)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
show_label = g_list_length (self->events[weekday]) > 3;
|
||||||
|
|
||||||
|
return show_label ? position < 2 : position < 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_overflow_labels (GcalWeekHeader *self)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
GtkWidget *label;
|
||||||
|
gboolean show_label;
|
||||||
|
gint n_events;
|
||||||
|
|
||||||
|
n_events = g_list_length (self->events[i]);
|
||||||
|
show_label = n_events > 3;
|
||||||
|
label = self->overflow_label[i];
|
||||||
|
|
||||||
|
if (show_label)
|
||||||
|
{
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
text = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "Other event", "Other %d events", n_events - 2), n_events - 2);
|
||||||
|
|
||||||
|
/* TODO: use a button and show an overflow popover */
|
||||||
|
if (!label)
|
||||||
|
{
|
||||||
|
label = gtk_label_new ("");
|
||||||
|
gtk_grid_attach (GTK_GRID (self->grid),
|
||||||
|
label,
|
||||||
|
i,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1);
|
||||||
|
|
||||||
|
self->overflow_label[i] = label;
|
||||||
|
|
||||||
|
gtk_widget_show (label);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_label_set_label (GTK_LABEL (label), text);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_clear_pointer (&self->overflow_label[i], gtk_widget_destroy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
merge_events (GcalWeekHeader *self,
|
merge_events (GcalWeekHeader *self,
|
||||||
GtkWidget *event,
|
GtkWidget *event,
|
||||||
@@ -301,6 +364,8 @@ check_mergeable_events (GcalWeekHeader *self)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
merge_events (self, current_widget, to_be_removed);
|
merge_events (self, current_widget, to_be_removed);
|
||||||
|
|
||||||
|
gtk_widget_set_visible (current_widget, is_event_visible (self, weekday + i, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
@@ -435,6 +500,8 @@ move_events_at_column (GcalWeekHeader *self,
|
|||||||
l->data,
|
l->data,
|
||||||
"top_attach", top_attach,
|
"top_attach", top_attach,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
gtk_widget_set_visible (l->data, is_event_visible (self, left_attach, top_attach - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_pointer (&children, g_list_free);
|
g_clear_pointer (&children, g_list_free);
|
||||||
@@ -467,7 +534,7 @@ add_event_to_grid (GcalWeekHeader *self,
|
|||||||
1,
|
1,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
gtk_widget_show (widget);
|
gtk_widget_set_visible (widget, is_event_visible (self, start, position));
|
||||||
|
|
||||||
/* Single-day events are the simplest case, and the code above is enough to deal with them */
|
/* Single-day events are the simplest case, and the code above is enough to deal with them */
|
||||||
if (!gcal_event_is_multiday (event))
|
if (!gcal_event_is_multiday (event))
|
||||||
@@ -527,6 +594,8 @@ add_event_to_grid (GcalWeekHeader *self,
|
|||||||
/* From now on, let's modify this widget */
|
/* From now on, let's modify this widget */
|
||||||
widget = cloned_widget;
|
widget = cloned_widget;
|
||||||
|
|
||||||
|
gtk_widget_set_visible (widget, is_event_visible (self, i, new_position));
|
||||||
|
|
||||||
g_clear_pointer (&cloned_widget_start_dt, g_date_time_unref);
|
g_clear_pointer (&cloned_widget_start_dt, g_date_time_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,7 +724,9 @@ update_title (GcalWeekHeader *self)
|
|||||||
static void
|
static void
|
||||||
header_collapse (GcalWeekHeader *self)
|
header_collapse (GcalWeekHeader *self)
|
||||||
{
|
{
|
||||||
gint hidden_events[7], row, i;
|
GList *children, *l;
|
||||||
|
|
||||||
|
children = gtk_container_get_children (GTK_CONTAINER (self->grid));
|
||||||
|
|
||||||
self->expanded = FALSE;
|
self->expanded = FALSE;
|
||||||
|
|
||||||
@@ -665,68 +736,31 @@ header_collapse (GcalWeekHeader *self)
|
|||||||
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (self->scrolledwindow), -1);
|
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (self->scrolledwindow), -1);
|
||||||
gtk_image_set_from_icon_name (GTK_IMAGE (self->expand_button_image), "go-down-symbolic", 4);
|
gtk_image_set_from_icon_name (GTK_IMAGE (self->expand_button_image), "go-down-symbolic", 4);
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
for (l = children; l != NULL; l = l->next)
|
||||||
hidden_events[i] = 0;
|
|
||||||
|
|
||||||
/* Gets count of number of extra events in each column */
|
|
||||||
for (row = 4; ; row++)
|
|
||||||
{
|
{
|
||||||
gboolean empty;
|
gint top_attach, left_attach;
|
||||||
|
|
||||||
empty = TRUE;
|
gtk_container_child_get (GTK_CONTAINER (self->grid),
|
||||||
|
l->data,
|
||||||
|
"top-attach", &top_attach,
|
||||||
|
"left_attach", &left_attach,
|
||||||
|
NULL);
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
gtk_widget_set_visible (l->data, is_event_visible (self, left_attach, top_attach - 1));
|
||||||
{
|
|
||||||
if (gtk_grid_get_child_at (GTK_GRID (self->grid), i, row))
|
|
||||||
{
|
|
||||||
hidden_events[i]++;
|
|
||||||
empty = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removes the excess events and adds them to the object list of events */
|
update_overflow_labels (self);
|
||||||
for ( ; row >= 4; row--)
|
|
||||||
{
|
|
||||||
for (i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
if (gtk_grid_get_child_at (GTK_GRID (self->grid), i, row))
|
|
||||||
{
|
|
||||||
GcalEventWidget *widget;
|
|
||||||
|
|
||||||
widget = GCAL_EVENT_WIDGET (gtk_grid_get_child_at (GTK_GRID (self->grid), i, row));
|
g_clear_pointer (&children, g_list_free);
|
||||||
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (widget));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds labels in the last row */
|
|
||||||
for (i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
if (hidden_events[i])
|
|
||||||
{
|
|
||||||
GtkWidget *widget;
|
|
||||||
gchar *other_events_label;
|
|
||||||
|
|
||||||
other_events_label = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "Other event", "Other %d events", hidden_events[i]),
|
|
||||||
hidden_events[i]);
|
|
||||||
widget = gtk_label_new (other_events_label);
|
|
||||||
|
|
||||||
gtk_widget_set_visible (widget, TRUE);
|
|
||||||
gtk_grid_attach (GTK_GRID (self->grid), widget, i, 4, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
header_expand (GcalWeekHeader *self)
|
header_expand (GcalWeekHeader *self)
|
||||||
{
|
{
|
||||||
GtkWidget *week_view;
|
GtkWidget *week_view;
|
||||||
|
GList *children, *l;
|
||||||
|
|
||||||
|
children = gtk_container_get_children (GTK_CONTAINER (self->grid));
|
||||||
week_view = gtk_widget_get_ancestor (GTK_WIDGET (self), GCAL_TYPE_WEEK_VIEW);
|
week_view = gtk_widget_get_ancestor (GTK_WIDGET (self), GCAL_TYPE_WEEK_VIEW);
|
||||||
|
|
||||||
self->expanded = TRUE;
|
self->expanded = TRUE;
|
||||||
@@ -734,11 +768,35 @@ header_expand (GcalWeekHeader *self)
|
|||||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->scrolledwindow),
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->scrolledwindow),
|
||||||
GTK_POLICY_NEVER,
|
GTK_POLICY_NEVER,
|
||||||
GTK_POLICY_AUTOMATIC);
|
GTK_POLICY_AUTOMATIC);
|
||||||
|
|
||||||
|
/* TODO: animate this transition */
|
||||||
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (self->scrolledwindow),
|
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (self->scrolledwindow),
|
||||||
gtk_widget_get_allocated_height (week_view)/2);
|
3 * gtk_widget_get_allocated_height (week_view) / 2);
|
||||||
|
|
||||||
gtk_image_set_from_icon_name (GTK_IMAGE (self->expand_button_image), "go-up-symbolic", 4);
|
gtk_image_set_from_icon_name (GTK_IMAGE (self->expand_button_image), "go-up-symbolic", 4);
|
||||||
|
|
||||||
gtk_grid_remove_row (GTK_GRID (self->grid), 4);
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
/* Remove any remaining labels */
|
||||||
|
if (GTK_IS_LABEL (l->data))
|
||||||
|
{
|
||||||
|
gint left_attach;
|
||||||
|
|
||||||
|
gtk_container_child_get (GTK_CONTAINER (self->grid),
|
||||||
|
l->data,
|
||||||
|
"left_attach", &left_attach,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
self->overflow_label[left_attach] = NULL;
|
||||||
|
gtk_widget_destroy (l->data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_show (l->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&children, g_list_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1052,6 +1110,9 @@ gcal_week_header_add_event (GcalWeekHeader *self,
|
|||||||
/* Check if we eventually can merge events */
|
/* Check if we eventually can merge events */
|
||||||
check_mergeable_events (self);
|
check_mergeable_events (self);
|
||||||
|
|
||||||
|
/* And also update the overflow labels */
|
||||||
|
update_overflow_labels (self);
|
||||||
|
|
||||||
g_clear_pointer (&week_end, g_date_time_unref);
|
g_clear_pointer (&week_end, g_date_time_unref);
|
||||||
g_clear_pointer (&week_start, g_date_time_unref);
|
g_clear_pointer (&week_start, g_date_time_unref);
|
||||||
}
|
}
|
||||||
@@ -1111,6 +1172,9 @@ gcal_week_header_remove_event (GcalWeekHeader *self,
|
|||||||
/* Check if we eventually can merge events */
|
/* Check if we eventually can merge events */
|
||||||
check_mergeable_events (self);
|
check_mergeable_events (self);
|
||||||
|
|
||||||
|
/* And also update the overflow labels */
|
||||||
|
update_overflow_labels (self);
|
||||||
|
|
||||||
g_clear_pointer (&children, g_list_free);
|
g_clear_pointer (&children, g_list_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user