Introduce a WidgetState structure and compute it from GcalScheduleValues

You may think, yet more indirection!  But behold:

1. We take events from the widgets ("schedule type (all-day) changed") and turn
   them into actions (gcal_schedule_values_set_all_day()).

2. Those actions (e.g. that function) decide how to change the GcalScheduleValues.

3. We compute the desired state of the wigets, based on the new
   values.

4. We set the state of the widgets based on that.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/550>
This commit is contained in:
Federico Mena Quintero
2025-08-27 19:59:17 -03:00
committed by Georges Basile Stavracas Neto
parent 2c476f6d02
commit 640488883b
+46 -5
View File
@@ -57,6 +57,22 @@ struct _GcalScheduleSection
GcalEventEditorFlags flags;
};
/* Desired state of the widgets, computed from GcalScheduleValues.
*
* There is some subtle logic to decide how to update the widgets based on how
* each of them causes the GcalScheduleValues to be modified. We encapsulate
* the desired state in this struct, so we can have tests for it.
*/
typedef struct
{
gboolean date_widgets_visible;
gboolean date_time_widgets_visible;
} WidgetState;
static void widget_state_free (WidgetState *state);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WidgetState, widget_state_free);
static void gcal_event_editor_section_iface_init (GcalEventEditorSectionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GcalScheduleSection, gcal_schedule_section, GTK_TYPE_BOX,
@@ -107,6 +123,23 @@ gcal_schedule_values_set_all_day (const GcalScheduleValues *values, gboolean all
return copy;
}
static WidgetState *
widget_state_from_values (const GcalScheduleValues *values)
{
WidgetState *state = g_new0 (WidgetState, 1);
state->date_widgets_visible = values->all_day;
state->date_time_widgets_visible = !values->all_day;
return state;
}
static void
widget_state_free (WidgetState *state)
{
g_free (state);
}
/*
* Auxiliary methods
*/
@@ -151,6 +184,15 @@ remove_recurrence_properties (GcalEvent *event)
e_cal_component_commit_sequence (comp);
}
static void
update_widgets (GcalScheduleSection *self,
WidgetState *state)
{
gtk_widget_set_visible (GTK_WIDGET (self->start_date_group), state->date_widgets_visible);
gtk_widget_set_visible (GTK_WIDGET (self->end_date_group), state->date_widgets_visible);
gtk_widget_set_visible (GTK_WIDGET (self->start_date_time_chooser), state->date_time_widgets_visible);
gtk_widget_set_visible (GTK_WIDGET (self->end_date_time_chooser), state->date_time_widgets_visible);
}
/*
* Callbacks
@@ -162,14 +204,13 @@ on_schedule_type_changed_cb (GtkWidget *widget,
GcalScheduleSection *self)
{
gboolean all_day = all_day_selected (self);
gtk_widget_set_visible (GTK_WIDGET (self->start_date_group), all_day);
gtk_widget_set_visible (GTK_WIDGET (self->end_date_group), all_day);
gtk_widget_set_visible (GTK_WIDGET (self->start_date_time_chooser), !all_day);
gtk_widget_set_visible (GTK_WIDGET (self->end_date_time_chooser), !all_day);
GcalScheduleValues *updated = gcal_schedule_values_set_all_day (self->values, all_day);
g_autoptr (WidgetState) state = widget_state_from_values (updated);
block_date_signals (self);
update_widgets (self, state);
if (all_day)
{
g_autoptr (GDateTime) start_local = NULL;