diff options
author | Carlos Soriano <csoriano@gnome.org> | 2016-05-06 18:32:33 +0200 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2016-06-01 23:05:23 +0200 |
commit | 5612244ea2ac4099e093529433dd2049c98036a1 (patch) | |
tree | 2d068548e37c9d2d7010a97c407ff6de459ae186 | |
parent | 6c6bc078ee0c0397d5c794f75673a2ab5e58f963 (diff) | |
download | gtk+-5612244ea2ac4099e093529433dd2049c98036a1.tar.gz |
f
-rw-r--r-- | gtk/gtkhidingbox.c | 86 | ||||
-rw-r--r-- | tests/testhidingbox.c | 82 |
2 files changed, 155 insertions, 13 deletions
diff --git a/gtk/gtkhidingbox.c b/gtk/gtkhidingbox.c index 35587533d9..ac45efd4a7 100644 --- a/gtk/gtkhidingbox.c +++ b/gtk/gtkhidingbox.c @@ -29,6 +29,7 @@ #include "gtkintl.h" #include "gtksizerequest.h" #include "gtkbuildable.h" +#include "gtkrevealer.h" #include "glib.h" @@ -46,6 +47,7 @@ struct _GtkHidingBoxPrivate gint inverted :1; GList *widgets_to_hide; GList *widgets_to_show; + GList *widgets_to_remove; GList *widgets_shown; HidingBoxAnimationPhase animation_phase; gint current_width; @@ -53,8 +55,6 @@ struct _GtkHidingBoxPrivate guint needs_update :1; }; -static void update_children_visibility (GtkHidingBox *self); - static void gtk_hiding_box_buildable_add_child (GtkBuildable *buildable, GtkBuilder *builder, @@ -148,13 +148,14 @@ gtk_hiding_box_add (GtkContainer *container, revealer = gtk_revealer_new (); gtk_container_add (GTK_CONTAINER (revealer), widget); + gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), FALSE); priv->children = g_list_append (priv->children, revealer); gtk_widget_set_parent (revealer, GTK_WIDGET (box)); } static void -gtk_hiding_box_remove (GtkContainer *container, - GtkWidget *widget) +really_remove_child (GtkContainer *container, + GtkWidget *widget) { GList *child; GtkHidingBox *box = GTK_HIDING_BOX (container); @@ -176,6 +177,20 @@ gtk_hiding_box_remove (GtkContainer *container, break; } } + +} + +static void +gtk_hiding_box_remove (GtkContainer *container, + GtkWidget *widget) +{ + GList *child; + GtkHidingBox *box = GTK_HIDING_BOX (container); + GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box); + + priv->widgets_to_remove = g_list_append (priv->widgets_to_remove, gtk_widget_get_parent (widget)); + priv->needs_update = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (container)); } static void @@ -230,6 +245,8 @@ update_children_visibility (GtkHidingBox *box, g_list_free (priv->widgets_to_show); priv->widgets_to_show = NULL; + g_list_free (priv->widgets_to_hide); + priv->widgets_to_hide = NULL; *n_visible_children_expanding = 0; *children_size = -priv->spacing; @@ -244,8 +261,7 @@ update_children_visibility (GtkHidingBox *box, child_widget = GTK_WIDGET (child->data); if (!gtk_widget_get_visible (child_widget) || !allocate_more_children) { - if (update) - priv->widgets_to_show = g_list_append (priv->widgets_to_show, child_widget); + priv->widgets_to_hide = g_list_append (priv->widgets_to_hide, child_widget); continue; } @@ -271,12 +287,14 @@ update_children_visibility (GtkHidingBox *box, if (*children_size > allocation->width) { allocate_more_children = FALSE; + priv->widgets_to_hide = g_list_append (priv->widgets_to_hide, child_widget); continue; } if (gtk_widget_get_hexpand (child_widget)) (n_visible_children_expanding)++; (n_visible_children)++; + priv->widgets_to_show = g_list_append (priv->widgets_to_show, child_widget); } for (i = 0; i < n_visible_children; i++) @@ -312,6 +330,13 @@ needs_update (GtkHidingBox *box, gboolean allocate_more_children = TRUE; gint children_size = -priv->spacing; + if (priv->needs_update) + return TRUE; + + if (allocation->width != priv->current_width || + allocation->height != priv->current_height) + return TRUE; + children = g_list_copy (priv->children); sizes_temp = g_newa (GtkRequestedSize, g_list_length (priv->children)); if (priv->inverted) @@ -375,6 +400,29 @@ needs_update (GtkHidingBox *box, } static void +idle_update_revealers (GtkHidingBox *box) +{ + GtkHidingBoxPrivate *priv = gtk_hiding_box_get_instance_private (box); + GList *children; + GList *l; + + for (l = priv->widgets_to_show; l != NULL; l = l->next) + { + gtk_revealer_set_reveal_child (GTK_REVEALER (l->data), TRUE); + } + + for (l = priv->widgets_to_hide; l != NULL; l = l->next) + { + gtk_revealer_set_reveal_child (GTK_REVEALER (l->data), FALSE); + } + + for (l = priv->widgets_to_remove; l != NULL; l = l->next) + { + gtk_revealer_set_reveal_child (GTK_REVEALER (l->data), FALSE); + } +} + +static void gtk_hiding_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { @@ -396,22 +444,28 @@ gtk_hiding_box_size_allocate (GtkWidget *widget, gtk_widget_set_allocation (widget, allocation); sizes = g_newa (GtkRequestedSize, g_list_length (priv->children)); - if (allocation->width != priv->current_width || - allocation->height != current_height) + /* + if (needs_update (box, allocation)) { clear_animation_state (box); - } + g_list_free (priv->widgets_shown); + priv->widgets_shown = NULL; - if (priv->needs_update) - { update_children_visibility (box, allocation, sizes, TRUE, &children_size, &n_visible_children_expanding); + if (priv->animation_phase != ANIMATION_PHASE_NONE) + { + priv->animation_phase = ANIMATION_PHASE_NONE; + } } else + */ { update_children_visibility (box, allocation, sizes, FALSE, &children_size, &n_visible_children_expanding); + + idle_update_revealers (box); } @@ -434,9 +488,14 @@ gtk_hiding_box_size_allocate (GtkWidget *widget, { child_widget = GTK_WIDGET (child->data); - if (!gtk_widget_get_child_visible (child_widget)) - continue; + if (!gtk_revealer_get_reveal_child (GTK_REVEALER (child_widget)) && + !gtk_revealer_get_child_revealed (GTK_REVEALER (child_widget))) + { + gtk_widget_set_child_visible (child_widget, FALSE); + continue; + } + gtk_widget_set_child_visible (child_widget, TRUE); child_allocation.x = x; child_allocation.y = allocation->y; if (gtk_widget_get_hexpand (child_widget)) @@ -543,6 +602,7 @@ gtk_hiding_box_init (GtkHidingBox *box) priv->inverted = FALSE; priv->widgets_to_hide = NULL; priv->widgets_to_show = NULL; + priv->widgets_to_remove = NULL; priv->widgets_shown = NULL; priv->animation_phase = ANIMATION_PHASE_NONE; priv->current_width = 0; diff --git a/tests/testhidingbox.c b/tests/testhidingbox.c new file mode 100644 index 0000000000..7093f5389b --- /dev/null +++ b/tests/testhidingbox.c @@ -0,0 +1,82 @@ +#include "config.h" +#include "glib.h" +#include <gtk/gtk.h> +#include <gtk/gtkhidingboxprivate.h> + +static GtkWidget *hiding_box; + +static void +on_path_selected (GtkPathBar *path_bar, + GParamSpec *pspec, + gpointer *user_data) +{ + g_print ("Path selected: %s\n", gtk_path_bar_get_selected_path (path_bar)); +} + +static void +on_button_clicked (GtkWidget *button, + gpointer user_data) +{ + gtk_container_remove (GTK_CONTAINER (user_data), button); +} + +static void +on_reset_button_clicked (GtkButton *reset_button) +{ + GtkWidget *button; + + gtk_container_foreach (GTK_CONTAINER (hiding_box), gtk_widget_destroy); + + button = gtk_button_new_with_label ("test1"); + g_signal_connect (button, "clicked", on_button_clicked, hiding_box); + gtk_container_add (GTK_CONTAINER (hiding_box), ); + gtk_container_add (GTK_CONTAINER (hiding_box), gtk_button_new_with_label ("test2")); + gtk_container_add (GTK_CONTAINER (hiding_box), gtk_button_new_with_label ("test3")); + gtk_container_add (GTK_CONTAINER (hiding_box), gtk_button_new_with_label ("test4")); +} + +int +main (int argc, char *argv[]) +{ + GtkWidget *window; + GtkWidget *grid; + GtkWidget *reset_button; + GtkWidget *label; + GFile *file = NULL; + GIcon *icon; + + gtk_init (&argc, &argv); + + window = g_object_connect (g_object_new (gtk_window_get_type (), + "type", GTK_WINDOW_TOPLEVEL, + "title", "Test path bar", + "resizable", TRUE, + "default-height", 200, + NULL), + "signal::destroy", gtk_main_quit, NULL, + NULL); + + grid = gtk_grid_new (); + g_type_ensure (GTK_TYPE_HIDING_BOX); + + label = gtk_label_new ("Generic GtkPathBar tests"); + gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1); + + /* ----------------------------------------------------------------------- */ + hiding_box = gtk_hiding_box (); + gtk_grid_attach (GTK_GRID (grid), hiding_box, 0, 1, 1, 1); + + /* Reset button */ + reset_button = gtk_button_new_with_label ("Reset State"); + gtk_widget_set_hexpand (reset_button, TRUE); + g_signal_connect (GTK_BUTTON (reset_button), "clicked", + G_CALLBACK (on_reset_button_clicked), window); + gtk_grid_attach (GTK_GRID (grid), reset_button, 0, 11, 2, 1); + + gtk_container_add (GTK_CONTAINER (window), grid); + gtk_widget_show_all (window); + + gtk_main (); + + return 0; +} |