views/month: Recycle event widgets using the pool
Create a new GcalEventWidgetPool shared between all month view rows. The event widgets are distributed to rows as needed. When rows are done with the event widget, the give them back to the pool so that other rows can reuse them. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/758>
This commit is contained in:
committed by
Marge Bot
parent
3692747362
commit
bbc041eed9
@@ -53,6 +53,8 @@ struct _GcalMonthViewRow
|
||||
|
||||
GListModel *events;
|
||||
|
||||
GcalEventWidgetPool *event_widget_pool;
|
||||
|
||||
GHashTable *layout_blocks;
|
||||
gboolean layout_blocks_valid;
|
||||
};
|
||||
@@ -684,6 +686,37 @@ extract_current_event_widgets (GcalMonthViewRow *self)
|
||||
return g_steal_pointer (&event_widgets);
|
||||
}
|
||||
|
||||
static void
|
||||
return_remaining_event_widgets_to_pool (GcalMonthViewRow *self,
|
||||
GHashTable *event_widgets)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GPtrArray *widgets;
|
||||
|
||||
g_assert (GCAL_IS_MONTH_VIEW_ROW (self));
|
||||
g_assert (event_widgets != NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, event_widgets);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &widgets))
|
||||
{
|
||||
g_assert (widgets != NULL);
|
||||
|
||||
while (widgets->len > 0)
|
||||
{
|
||||
GtkWidget *widget = g_ptr_array_steal_index_fast (widgets, 0);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (widget, on_event_widget_activated_cb, self);
|
||||
gtk_widget_unparent (widget);
|
||||
|
||||
gcal_event_widget_pool_reclaim (self->event_widget_pool, g_steal_pointer (&widget));
|
||||
}
|
||||
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
|
||||
g_assert (g_hash_table_size (event_widgets) == 0);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
pick_existing_event_widget (GHashTable *event_widgets,
|
||||
GcalEvent *event)
|
||||
@@ -700,6 +733,26 @@ pick_existing_event_widget (GHashTable *event_widgets,
|
||||
return g_ptr_array_steal_index_fast (widgets, 0);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
pick_or_create_event_widget_for_event (GcalMonthViewRow *self,
|
||||
GHashTable *event_widgets,
|
||||
GcalEvent *event)
|
||||
{
|
||||
GtkWidget *event_widget;
|
||||
|
||||
event_widget = pick_existing_event_widget (event_widgets, event);
|
||||
if (!event_widget)
|
||||
{
|
||||
event_widget = gcal_event_widget_pool_take_or_create (self->event_widget_pool, event);
|
||||
|
||||
g_assert (GCAL_IS_EVENT_WIDGET (event_widget));
|
||||
|
||||
setup_child_widget (self, event_widget);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&event_widget);
|
||||
}
|
||||
|
||||
static void
|
||||
recalculate_layout_blocks (GcalMonthViewRow *self)
|
||||
{
|
||||
@@ -745,14 +798,10 @@ recalculate_layout_blocks (GcalMonthViewRow *self)
|
||||
{
|
||||
GtkWidget *event_widget;
|
||||
|
||||
event_widget = pick_existing_event_widget (event_widgets, event);
|
||||
if (!event_widget)
|
||||
{
|
||||
event_widget = gcal_event_widget_new (event);
|
||||
if (!gcal_event_get_all_day (event) && !gcal_event_is_multiday (event))
|
||||
gcal_event_widget_set_timestamp_policy (GCAL_EVENT_WIDGET (event_widget), GCAL_TIMESTAMP_POLICY_START);
|
||||
setup_child_widget (self, event_widget);
|
||||
}
|
||||
event_widget = pick_or_create_event_widget_for_event (self, event_widgets, event);
|
||||
|
||||
if (!gcal_event_get_all_day (event) && !gcal_event_is_multiday (event))
|
||||
gcal_event_widget_set_timestamp_policy (GCAL_EVENT_WIDGET (event_widget), GCAL_TIMESTAMP_POLICY_START);
|
||||
|
||||
block = g_new (GcalEventBlock, 1);
|
||||
block->event_widget = g_steal_pointer (&event_widget);
|
||||
@@ -765,12 +814,10 @@ recalculate_layout_blocks (GcalMonthViewRow *self)
|
||||
{
|
||||
GtkWidget *new_event_widget;
|
||||
|
||||
new_event_widget = pick_existing_event_widget (event_widgets, event);
|
||||
if (!new_event_widget)
|
||||
{
|
||||
new_event_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (block->event_widget));
|
||||
setup_child_widget (self, new_event_widget);
|
||||
}
|
||||
new_event_widget = pick_or_create_event_widget_for_event (self, event_widgets, event);
|
||||
|
||||
if (!gcal_event_get_all_day (event) && !gcal_event_is_multiday (event))
|
||||
gcal_event_widget_set_timestamp_policy (GCAL_EVENT_WIDGET (new_event_widget), GCAL_TIMESTAMP_POLICY_START);
|
||||
|
||||
block = g_new (GcalEventBlock, 1);
|
||||
block->event_widget = g_steal_pointer (&new_event_widget);
|
||||
@@ -814,6 +861,8 @@ recalculate_layout_blocks (GcalMonthViewRow *self)
|
||||
g_hash_table_insert (self->layout_blocks, event, g_steal_pointer (&blocks));
|
||||
}
|
||||
|
||||
return_remaining_event_widgets_to_pool (self, event_widgets);
|
||||
|
||||
self->layout_blocks_valid = TRUE;
|
||||
|
||||
GCAL_EXIT;
|
||||
@@ -1172,6 +1221,7 @@ gcal_month_view_row_finalize (GObject *object)
|
||||
{
|
||||
GcalMonthViewRow *self = (GcalMonthViewRow *)object;
|
||||
|
||||
g_clear_object (&self->event_widget_pool);
|
||||
g_clear_pointer (&self->range, gcal_range_unref);
|
||||
|
||||
G_OBJECT_CLASS (gcal_month_view_row_parent_class)->finalize (object);
|
||||
@@ -1304,9 +1354,16 @@ gcal_month_view_row_init (GcalMonthViewRow *self)
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gcal_month_view_row_new (void)
|
||||
gcal_month_view_row_new (GcalEventWidgetPool *event_widget_pool)
|
||||
{
|
||||
return g_object_new (GCAL_TYPE_MONTH_VIEW_ROW, NULL);
|
||||
g_autoptr (GcalMonthViewRow) self = NULL;
|
||||
|
||||
g_assert (GCAL_IS_EVENT_WIDGET_POOL (event_widget_pool));
|
||||
|
||||
self = g_object_new (GCAL_TYPE_MONTH_VIEW_ROW, NULL);
|
||||
self->event_widget_pool = g_object_ref (event_widget_pool);
|
||||
|
||||
return GTK_WIDGET (g_steal_pointer (&self));
|
||||
}
|
||||
|
||||
GcalRange *
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "gcal-context.h"
|
||||
#include "gcal-event.h"
|
||||
#include "gcal-event-widget-pool.h"
|
||||
#include "gcal-range.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -32,7 +33,7 @@ G_BEGIN_DECLS
|
||||
#define GCAL_TYPE_MONTH_VIEW_ROW (gcal_month_view_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GcalMonthViewRow, gcal_month_view_row, GCAL, MONTH_VIEW_ROW, GtkWidget)
|
||||
|
||||
GtkWidget * gcal_month_view_row_new (void);
|
||||
GtkWidget * gcal_month_view_row_new (GcalEventWidgetPool *event_widget_pool);
|
||||
|
||||
GcalRange * gcal_month_view_row_get_range (GcalMonthViewRow *self);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "gcal-debug.h"
|
||||
#include "gcal-event-widget-pool.h"
|
||||
#include "gcal-month-cell.h"
|
||||
#include "gcal-month-popover.h"
|
||||
#include "gcal-month-view.h"
|
||||
@@ -56,6 +57,8 @@ struct _GcalMonthView
|
||||
|
||||
GPtrArray *week_rows;
|
||||
|
||||
GcalEventWidgetPool *event_widget_pool;
|
||||
|
||||
struct {
|
||||
GtkWidget *popover;
|
||||
GcalMonthViewRow *row;
|
||||
@@ -1737,6 +1740,7 @@ gcal_month_view_finalize (GObject *object)
|
||||
{
|
||||
GcalMonthView *self = (GcalMonthView *)object;
|
||||
|
||||
g_clear_object (&self->event_widget_pool);
|
||||
gcal_clear_date_time (&self->selection.start);
|
||||
gcal_clear_date_time (&self->selection.end);
|
||||
gcal_clear_date_time (&self->date);
|
||||
@@ -1836,6 +1840,8 @@ gcal_month_view_init (GcalMonthView *self)
|
||||
{
|
||||
g_autoptr (GDateTime) now = NULL;
|
||||
|
||||
self->event_widget_pool = gcal_event_widget_pool_new ();
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
update_weekday_labels (self);
|
||||
|
||||
@@ -1847,7 +1853,7 @@ gcal_month_view_init (GcalMonthView *self)
|
||||
self->week_rows = g_ptr_array_new_full (N_TOTAL_ROWS, (GDestroyNotify) gtk_widget_unparent);
|
||||
for (gint i = 0; i < N_TOTAL_ROWS; i++)
|
||||
{
|
||||
GtkWidget *row = gcal_month_view_row_new ();
|
||||
GtkWidget *row = gcal_month_view_row_new (self->event_widget_pool);
|
||||
g_signal_connect (row, "event-activated", G_CALLBACK (on_event_widget_activated_cb), self);
|
||||
g_signal_connect (row, "cell-activated", G_CALLBACK (on_month_row_cell_activated_cb), self);
|
||||
g_signal_connect (row, "show-overflow", G_CALLBACK (on_month_row_show_overflow_cb), self);
|
||||
|
||||
Reference in New Issue
Block a user