event-widget: use a stack to handle orientation
Instead of setting the position of the labels in a grid, use two different grids and switch between them using a stack.
This commit is contained in:
+69
-58
@@ -2,85 +2,96 @@
|
|||||||
<interface>
|
<interface>
|
||||||
<template class="GcalEventWidget" parent="GtkBin">
|
<template class="GcalEventWidget" parent="GtkBin">
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkGrid" id="main_grid">
|
<object class="GtkStack" id="stack">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="column_spacing">4</property>
|
<property name="hexpand">False</property>
|
||||||
<property name="margin-top">1</property>
|
<property name="margin-top">1</property>
|
||||||
<property name="margin-bottom">1</property>
|
<property name="margin-bottom">1</property>
|
||||||
<property name="margin-start">6</property>
|
<property name="margin-start">6</property>
|
||||||
<property name="margin-end">4</property>
|
<property name="margin-end">4</property>
|
||||||
<property name="hexpand">False</property>
|
<property name="homogeneous">false</property>
|
||||||
|
|
||||||
|
<!-- Horizontal page -->
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="hour_label">
|
<object class="GtkGrid" id="horizontal_grid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="xalign">0.0</property>
|
<property name="column_spacing">4</property>
|
||||||
<attributes>
|
<child>
|
||||||
<attribute name="weight" value="semibold"/>
|
<object class="GtkLabel" id="summary_label">
|
||||||
</attributes>
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
<property name="ellipsize">end</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="hour_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="name">horizontal</property>
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
|
<!-- Vertical page -->
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="summary_label">
|
<object class="GtkGrid" id="vertical_grid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="hexpand">True</property>
|
<child>
|
||||||
<property name="xalign">0</property>
|
<object class="GtkLabel">
|
||||||
<property name="ellipsize">end</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" bind-source="hour_label" bind-property="label" bind-flags="default" />
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" bind-source="summary_label" bind-property="label" bind-flags="default" />
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
<property name="ellipsize">end</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="name">vertical</property>
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- HACK!!!
|
|
||||||
We need this ghost GtkGrid because we can't change the position of the
|
|
||||||
labels in size-allocate. This grid will simulate the main grid with the
|
|
||||||
labels vertically positioned, so we don't need to chage the main grid's
|
|
||||||
label position in size-allocate -->
|
|
||||||
<object class="GtkGrid" id="ghost_grid">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="column_spacing">4</property>
|
|
||||||
<property name="margin-top">1</property>
|
|
||||||
<property name="margin-bottom">1</property>
|
|
||||||
<property name="margin-start">6</property>
|
|
||||||
<property name="margin-end">4</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" bind-source="hour_label" bind-property="label" bind-flags="default" />
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="xalign">0.0</property>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="weight" value="semibold"/>
|
|
||||||
</attributes>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" bind-source="summary_label" bind-property="label" bind-flags="default" />
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="ellipsize">end</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|||||||
+71
-59
@@ -38,10 +38,11 @@ struct _GcalEventWidget
|
|||||||
GDateTime *dt_end;
|
GDateTime *dt_end;
|
||||||
|
|
||||||
/* widgets */
|
/* widgets */
|
||||||
GtkWidget *ghost_grid;
|
GtkWidget *horizontal_grid;
|
||||||
GtkWidget *hour_label;
|
GtkWidget *hour_label;
|
||||||
GtkWidget *main_grid;
|
GtkWidget *stack;
|
||||||
GtkWidget *summary_label;
|
GtkWidget *summary_label;
|
||||||
|
GtkWidget *vertical_grid;
|
||||||
|
|
||||||
/* internal data */
|
/* internal data */
|
||||||
gboolean clock_format_24h : 1;
|
gboolean clock_format_24h : 1;
|
||||||
@@ -54,7 +55,10 @@ struct _GcalEventWidget
|
|||||||
|
|
||||||
GtkOrientation orientation;
|
GtkOrientation orientation;
|
||||||
|
|
||||||
guint toggle_description_id;
|
guint vertical_label_source_id;
|
||||||
|
gboolean vertical_value_to_set;
|
||||||
|
gboolean vertical_labels;
|
||||||
|
|
||||||
gboolean button_pressed;
|
gboolean button_pressed;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,8 +78,6 @@ enum
|
|||||||
NUM_SIGNALS
|
NUM_SIGNALS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CURSOR_NONE,
|
CURSOR_NONE,
|
||||||
@@ -93,37 +95,53 @@ G_DEFINE_TYPE_WITH_CODE (GcalEventWidget, gcal_event_widget, GTK_TYPE_BIN,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
toggle_description_position_cb (GcalEventWidget *self)
|
can_hold_vertical_labels_with_height (GcalEventWidget *self,
|
||||||
|
gint height)
|
||||||
{
|
{
|
||||||
gint current_top;
|
gint total_height;
|
||||||
|
|
||||||
gtk_container_child_get (GTK_CONTAINER (self->main_grid),
|
gtk_widget_get_preferred_height (self->vertical_grid, &total_height, NULL);
|
||||||
self->summary_label,
|
|
||||||
"top-attach", ¤t_top,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gtk_label_set_line_wrap (GTK_LABEL (self->summary_label),
|
return height >= total_height;
|
||||||
!gtk_label_get_line_wrap (GTK_LABEL (self->summary_label)));
|
}
|
||||||
|
|
||||||
gtk_container_child_set (GTK_CONTAINER (self->main_grid),
|
static void
|
||||||
self->summary_label,
|
set_vertical_labels (GcalEventWidget *self,
|
||||||
"left-attach", current_top == 1 ? 1 : 0,
|
gboolean vertical)
|
||||||
"top-attach", current_top == 1 ? 0 : 1,
|
{
|
||||||
"width", current_top == 1 ? 1 : 2,
|
if (self->vertical_labels == vertical)
|
||||||
NULL);
|
return;
|
||||||
|
|
||||||
self->toggle_description_id = 0;
|
gtk_stack_set_visible_child (GTK_STACK (self->stack), vertical ? self->vertical_grid : self->horizontal_grid);
|
||||||
|
self->vertical_labels = vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
set_vertical_labels_in_idle_cb (gpointer data)
|
||||||
|
{
|
||||||
|
GcalEventWidget *self = (GcalEventWidget*) data;
|
||||||
|
|
||||||
|
set_vertical_labels (self, self->vertical_value_to_set);
|
||||||
|
|
||||||
|
self->vertical_label_source_id = 0;
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
queue_toggle_description_position (GcalEventWidget *self)
|
queue_set_vertical_labels (GcalEventWidget *self,
|
||||||
|
gboolean vertical)
|
||||||
{
|
{
|
||||||
if (self->toggle_description_id > 0)
|
if (self->vertical_label_source_id > 0)
|
||||||
g_source_remove (self->toggle_description_id);
|
{
|
||||||
|
g_source_remove (self->vertical_label_source_id);
|
||||||
|
self->vertical_label_source_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
self->toggle_description_id = g_idle_add ((GSourceFunc) toggle_description_position_cb, self);
|
if (self->vertical_labels == vertical)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->vertical_value_to_set = vertical;
|
||||||
|
self->vertical_label_source_id = g_idle_add (set_vertical_labels_in_idle_cb, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -153,7 +171,8 @@ static void
|
|||||||
gcal_event_widget_update_style (GcalEventWidget *self)
|
gcal_event_widget_update_style (GcalEventWidget *self)
|
||||||
{
|
{
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
gboolean slanted_start, slanted_end;
|
gboolean slanted_start;
|
||||||
|
gboolean slanted_end;
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
||||||
slanted_start = FALSE;
|
slanted_start = FALSE;
|
||||||
@@ -183,8 +202,8 @@ gcal_event_widget_update_style (GcalEventWidget *self)
|
|||||||
gtk_style_context_add_class (context, "slanted-end");
|
gtk_style_context_add_class (context, "slanted-end");
|
||||||
|
|
||||||
/* TODO: adjust margins based on the CSS gradients sizes, not hardcoded */
|
/* TODO: adjust margins based on the CSS gradients sizes, not hardcoded */
|
||||||
gtk_widget_set_margin_start (self->main_grid, slanted_start ? 20 : 4);
|
gtk_widget_set_margin_start (self->stack, slanted_start ? 20 : 4);
|
||||||
gtk_widget_set_margin_end (self->main_grid, slanted_end ? 20 : 4);
|
gtk_widget_set_margin_end (self->stack, slanted_end ? 20 : 4);
|
||||||
|
|
||||||
/* Add style classes for orientation selectors */
|
/* Add style classes for orientation selectors */
|
||||||
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
@@ -212,7 +231,7 @@ gcal_event_widget_update_style (GcalEventWidget *self)
|
|||||||
|
|
||||||
/* XXX: hardcoding these values isn't really great... */
|
/* XXX: hardcoding these values isn't really great... */
|
||||||
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
gtk_widget_set_margin_start (self->main_grid, 8);
|
gtk_widget_set_margin_start (self->stack, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,9 +565,12 @@ gcal_event_widget_size_allocate (GtkWidget *widget,
|
|||||||
GtkAllocation *allocation)
|
GtkAllocation *allocation)
|
||||||
{
|
{
|
||||||
GcalEventWidget *self;
|
GcalEventWidget *self;
|
||||||
|
GtkAllocation old_allocation;
|
||||||
|
|
||||||
self = GCAL_EVENT_WIDGET (widget);
|
self = GCAL_EVENT_WIDGET (widget);
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &old_allocation);
|
||||||
|
|
||||||
if (gtk_widget_get_realized (widget))
|
if (gtk_widget_get_realized (widget))
|
||||||
{
|
{
|
||||||
gdk_window_move_resize (self->event_window,
|
gdk_window_move_resize (self->event_window,
|
||||||
@@ -558,31 +580,20 @@ gcal_event_widget_size_allocate (GtkWidget *widget,
|
|||||||
allocation->height);
|
allocation->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to put the summary label below if the orientation is vertical */
|
|
||||||
if (self->orientation == GTK_ORIENTATION_VERTICAL && !gcal_event_get_all_day (self->event))
|
|
||||||
{
|
|
||||||
gint minimum_grid_height;
|
|
||||||
gint current_top;
|
|
||||||
|
|
||||||
gtk_widget_get_preferred_height (self->ghost_grid, &minimum_grid_height, NULL);
|
|
||||||
|
|
||||||
gtk_container_child_get (GTK_CONTAINER (self->main_grid),
|
|
||||||
self->summary_label,
|
|
||||||
"top-attach", ¤t_top,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since we can't change the position of the events inside size-allocate,
|
|
||||||
* queue it for future iterations of the mainloop.
|
|
||||||
*/
|
|
||||||
if ((allocation->height < minimum_grid_height && current_top == 1) ||
|
|
||||||
(allocation->height >= minimum_grid_height && current_top == 0))
|
|
||||||
{
|
|
||||||
queue_toggle_description_position (self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->size_allocate (widget, allocation);
|
GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->size_allocate (widget, allocation);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only after the child widgets (main grid, labels, etc) are allocated with the parent
|
||||||
|
* class' allocation function, we can check if the current height is enough to hold the
|
||||||
|
* vertical labels.
|
||||||
|
*/
|
||||||
|
if (old_allocation.width != allocation->width || old_allocation.height != allocation->height)
|
||||||
|
{
|
||||||
|
if (self->orientation == GTK_ORIENTATION_HORIZONTAL || gcal_event_get_all_day (self->event))
|
||||||
|
return;
|
||||||
|
|
||||||
|
queue_set_vertical_labels (self, can_hold_vertical_labels_with_height (self, allocation->height));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t*
|
static cairo_surface_t*
|
||||||
@@ -761,8 +772,8 @@ gcal_event_widget_set_property (GObject *object,
|
|||||||
|
|
||||||
case PROP_ORIENTATION:
|
case PROP_ORIENTATION:
|
||||||
self->orientation = g_value_get_enum (value);
|
self->orientation = g_value_get_enum (value);
|
||||||
|
gtk_widget_set_visible (self->vertical_grid, self->orientation == GTK_ORIENTATION_VERTICAL);
|
||||||
gcal_event_widget_update_style (self);
|
gcal_event_widget_update_style (self);
|
||||||
gtk_widget_queue_allocate (GTK_WIDGET (object));
|
|
||||||
g_object_notify (object, "orientation");
|
g_object_notify (object, "orientation");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -817,11 +828,11 @@ gcal_event_widget_finalize (GObject *object)
|
|||||||
g_clear_pointer (&self->css_class, g_free);
|
g_clear_pointer (&self->css_class, g_free);
|
||||||
g_clear_object (&self->event);
|
g_clear_object (&self->event);
|
||||||
|
|
||||||
/* withdraw mainloop sources */
|
/* remove timeouts */
|
||||||
if (self->toggle_description_id > 0)
|
if (self->vertical_label_source_id > 0)
|
||||||
{
|
{
|
||||||
g_source_remove (self->toggle_description_id);
|
g_source_remove (self->vertical_label_source_id);
|
||||||
self->toggle_description_id = 0;
|
self->vertical_label_source_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
|
||||||
@@ -913,10 +924,11 @@ gcal_event_widget_class_init (GcalEventWidgetClass *klass)
|
|||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/event-widget.ui");
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/event-widget.ui");
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, ghost_grid);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, horizontal_grid);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, hour_label);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, hour_label);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, main_grid);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, stack);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, summary_label);
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, summary_label);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, vertical_grid);
|
||||||
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "event");
|
gtk_widget_class_set_css_name (widget_class, "event");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user