[gnome-calendar/search-improvements] year-view: initial GtkWidget::size_allocate impl
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/search-improvements] year-view: initial GtkWidget::size_allocate impl
- Date: Mon, 5 Jan 2015 22:31:41 +0000 (UTC)
commit c1f6f7ac4742102ae75c614f1e056cdec17b0428
Author: Erick PĂ©rez Castellanos <erick red gmail com>
Date: Mon Dec 29 16:35:41 2014 -0500
year-view: initial GtkWidget::size_allocate impl
This impl uses internals structures from GcalSubscriber
src/gcal-year-view.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 273 insertions(+), 5 deletions(-)
---
diff --git a/src/gcal-year-view.c b/src/gcal-year-view.c
index 802b9f7..e2ae043 100644
--- a/src/gcal-year-view.c
+++ b/src/gcal-year-view.c
@@ -28,6 +28,8 @@
typedef struct
{
+ /* overflow buttons */
+ GHashTable *internal_children;
GdkWindow *event_window;
@@ -54,6 +56,14 @@ enum
static void event_opened (GcalEventWidget *event_widget,
gpointer user_data);
+static gboolean get_widget_parts (gint first_cell,
+ gint last_cell,
+ gint natural_height,
+ gdouble vertical_cell_space,
+ gdouble *size_left,
+ GArray *cells,
+ GArray *lengths);
+
static void gcal_view_interface_init (GcalViewIface *iface);
static void gcal_year_view_set_property (GObject *object,
@@ -130,6 +140,53 @@ event_opened (GcalEventWidget *event_widget,
event_widget);
}
+static gboolean
+get_widget_parts (gint first_cell,
+ gint last_cell,
+ gint natural_height,
+ gdouble vertical_cell_space,
+ gdouble *size_left,
+ GArray *cells,
+ GArray *lengths)
+{
+ gint i;
+ gint current_part_length;
+ gdouble y, old_y = - 1.0;
+
+ if (last_cell < first_cell)
+ {
+ gint swap = last_cell;
+ last_cell = first_cell;
+ first_cell = swap;
+ }
+
+ for (i = first_cell; i <= last_cell; i++)
+ {
+ if (size_left[i] < natural_height)
+ {
+ return FALSE;
+ }
+ else
+ {
+ y = vertical_cell_space - size_left[i];
+ if (y != old_y)
+ {
+ current_part_length = 1;
+ g_array_append_val (cells, i);
+ g_array_append_val (lengths, current_part_length);
+ old_y = y;
+ }
+ else
+ {
+ current_part_length++;
+ g_array_index (lengths, gint, lengths->len - 1) = current_part_length;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
static void
gcal_year_view_class_init (GcalYearViewClass *klass)
{
@@ -370,18 +427,229 @@ gcal_year_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GcalYearViewPrivate *priv;
+ GcalSubscriberPrivate *ppriv;
+ gint i, j, sw;
+
+ gint padding_bottom;
+ PangoLayout *layout;
+ PangoFontDescription *font_desc;
+ gint font_height;
+
+ gdouble cell_width, cell_height, vertical_cell_space;
+ gdouble pos_x, pos_y;
+ gdouble size_left [12];
+
+ const gchar *uuid;
+ GtkWidget *child_widget;
+ GtkAllocation child_allocation;
+ gint natural_height;
+
+ GList *widgets, *l, *aux, *l2 = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
priv = gcal_year_view_get_instance_private (GCAL_YEAR_VIEW (widget));
+ ppriv = GCAL_SUBSCRIBER (widget)->priv;
+
+ /* remove every widget' parts, but the master widget */
+ widgets = g_hash_table_get_values (ppriv->children);
+ for (aux = widgets; aux != NULL; aux = g_list_next (aux))
+ {
+ l = g_list_next ((GList*) aux->data);
+ for (; l != NULL; l = g_list_next (l))
+ l2 = g_list_append (l2, l->data);
+ }
+ g_list_free (widgets);
+
+ for (aux = l2; aux != NULL; aux = g_list_next (aux))
+ gtk_widget_destroy ((GtkWidget*) aux->data);
+ g_list_free (l2);
+
+ /* clean overflow information */
+ g_hash_table_remove_all (ppriv->overflow_cells);
gtk_widget_set_allocation (widget, allocation);
if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (priv->event_window, allocation->x, allocation->y, allocation->width,
allocation->height);
+
+ gtk_style_context_get (gtk_widget_get_style_context (widget), gtk_widget_get_state_flags (widget),
+ "font", &font_desc, "padding-bottom", &padding_bottom, NULL);
+
+ layout = gtk_widget_create_pango_layout (widget, _("Other events"));
+ pango_layout_set_font_description (layout, font_desc);
+ pango_layout_get_pixel_size (layout, NULL, &font_height);
+ pango_font_description_free (font_desc);
+ g_object_unref (layout);
+
+ cell_width = allocation->width / 6.0;
+ cell_height = allocation->height / 2.0;
+ vertical_cell_space = cell_height - (padding_bottom + font_height);
+
+ for (i = 0; i < 12; i++)
+ size_left[i] = vertical_cell_space;
+
+ sw = 1 - 2 * priv->k;
+
+ /* allocate multimonth events */
+ for (l = ppriv->multi_cell_children; l != NULL; l = g_list_next (l))
+ {
+ gint first_cell, last_cell, first_row, last_row, start, end;
+ gboolean visible;
+
+ const icaltimetype *date;
+ GArray *cells, *lengths;
+
+ child_widget = (GtkWidget*) l->data;
+ uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child_widget));
+ if (!gtk_widget_is_visible (child_widget) && !g_hash_table_contains (ppriv->hidden_as_overflow, uuid))
+ continue;
+
+ gtk_widget_show (child_widget);
+ gtk_widget_get_preferred_height (child_widget, NULL, &natural_height);
+
+ j = 1;
+ date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (child_widget));
+ if (date->year == priv->date->year)
+ j = date->month;
+ first_cell = 6 * ((j - 1) / 6) + 6 * priv->k + sw * ((j - 1) % 6) - (1 * priv->k);
+
+ j = 12;
+ date = gcal_event_widget_peek_end_date (GCAL_EVENT_WIDGET (child_widget));
+ if (date->year == priv->date->year)
+ j = date->month;
+ last_cell = 6 * ((j - 1) / 6) + 6 * priv->k + sw * ((j - 1) % 6) - (1 * priv->k);
+
+ /* FIXME missing mark widgets with continuos tags */
+
+ first_row = first_cell / 6;
+ last_row = last_cell / 6;
+ visible = TRUE;
+ cells = g_array_sized_new (TRUE, TRUE, sizeof (gint), 16);
+ lengths = g_array_sized_new (TRUE, TRUE, sizeof (gint), 16);
+ for (i = first_row; i <= last_row && visible; i++)
+ {
+ start = i * 6 + priv->k * 5;
+ end = i * 6 + (1 - priv->k) * 5;
+
+ if (i == first_row)
+ {
+ start = first_cell;
+ }
+ if (i == last_row)
+ {
+ end = last_cell;
+ }
+
+ visible = get_widget_parts (start, end, natural_height, vertical_cell_space, size_left, cells,
lengths);
+ }
+
+ if (visible)
+ {
+ for (i = 0; i < cells->len; i++)
+ {
+ gint cell_idx = g_array_index (cells, gint, i);
+ gint row = cell_idx / 6;
+ gint column = cell_idx % 6;
+ pos_x = cell_width * column;
+ pos_y = cell_height * row;
+
+ child_allocation.x = pos_x;
+ child_allocation.y = pos_y + vertical_cell_space - size_left[cell_idx];
+ child_allocation.width = cell_width * g_array_index (lengths, gint, i);
+ child_allocation.height = natural_height;
+
+ if (i != 0)
+ {
+ child_widget = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
+
+ //setup_child (child_widget, widget);
+ gtk_widget_set_parent (child_widget, widget); /* FIXME */
+ gtk_widget_show (child_widget);
+
+ aux = g_hash_table_lookup (ppriv->children, uuid);
+ aux = g_list_append (aux, child_widget);
+ }
+ gtk_widget_size_allocate (child_widget, &child_allocation);
+ g_hash_table_remove (ppriv->hidden_as_overflow, uuid);
+
+ /* update size_left */
+ for (j = 0; j < g_array_index (lengths, gint, i); j++)
+ size_left[cell_idx + j] -= natural_height;
+ }
+ }
+ else
+ {
+ gtk_widget_hide (child_widget);
+ g_hash_table_add (ppriv->hidden_as_overflow, g_strdup (uuid));
+
+ for (i = first_cell; i <= last_cell; i++)
+ {
+ aux = g_hash_table_lookup (ppriv->overflow_cells, GINT_TO_POINTER (i));
+ aux = g_list_append (aux, child_widget);
+
+ if (g_list_length (aux) == 1)
+ g_hash_table_insert (ppriv->overflow_cells, GINT_TO_POINTER (i), aux);
+ else
+ g_hash_table_replace (ppriv->overflow_cells, GINT_TO_POINTER (i), g_list_copy (aux));
+ }
+ }
+
+ g_array_free (cells, TRUE);
+ g_array_free (lengths, TRUE);
+ }
+
+ g_hash_table_iter_init (&iter, ppriv->single_cell_children);
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- gdk_window_move_resize (priv->event_window,
- allocation->x,
- allocation->y,
- allocation->width,
- allocation->height);
+ j = GPOINTER_TO_INT (key);
+ i = 6 * ((j - 1) / 6) + 6 * priv->k + sw * ((j - 1) % 6) - (1 * priv->k);
+
+ l = (GList*) value;
+ for (aux = l; aux != NULL; aux = g_list_next (aux))
+ {
+ child_widget = (GtkWidget*) aux->data;
+
+ uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (child_widget));
+ if (!gtk_widget_is_visible (child_widget) && !g_hash_table_contains (ppriv->hidden_as_overflow,
uuid))
+ continue;
+
+ gtk_widget_show (child_widget);
+ gtk_widget_get_preferred_height (child_widget, NULL, &natural_height);
+
+ if (size_left[i] > natural_height)
+ {
+ pos_x = cell_width * (i % 6);
+ pos_y = cell_height * (i / 6);
+
+ child_allocation.x = pos_x;
+ child_allocation.y = pos_y + vertical_cell_space - size_left[i];
+ child_allocation.width = cell_width;
+ child_allocation.height = natural_height;
+ gtk_widget_show (child_widget);
+ gtk_widget_size_allocate (child_widget, &child_allocation);
+ g_hash_table_remove (ppriv->hidden_as_overflow, uuid);
+
+ size_left[i] -= natural_height;
+ }
+ else
+ {
+ gtk_widget_hide (child_widget);
+ g_hash_table_add (ppriv->hidden_as_overflow, g_strdup (uuid));
+
+ l = g_hash_table_lookup (ppriv->overflow_cells, GINT_TO_POINTER (i));
+ l = g_list_append (l, child_widget);
+
+ if (g_list_length (l) == 1)
+ g_hash_table_insert (ppriv->overflow_cells, GINT_TO_POINTER (i), l);
+ else
+ g_hash_table_replace (ppriv->overflow_cells, GINT_TO_POINTER (i), g_list_copy (l));
+ }
+ }
}
+
+ /* FIXME: remove on Gtk+ 3.15.4 release */
+ if (g_hash_table_size (ppriv->overflow_cells) != 0)
+ gtk_widget_queue_draw_area (widget, allocation->x, allocation->y, allocation->width, allocation->height);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]