diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c index 168e70703c..f845f758cc 100644 --- a/gtk/gtkpathbar.c +++ b/gtk/gtkpathbar.c @@ -428,12 +428,129 @@ fill_path_bar (GtkPathBar *self, path_chunk = create_path_chunk (self, current_path->str, splitted_path[i], NULL, TRUE); - gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), path_chunk); + gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), path_chunk, FALSE); } g_string_free (current_path, TRUE); } +static void +hide_overflow_handling (GtkPathBar *self) +{ + GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); + GtkWidget *path_chunk; + GtkWidget *overflow_button; + GtkWidget *tail_button; + GtkWidget *path_bar_container; + g_print ("###### hide overflow %d\n", priv->inverted); + + get_path_bar_widgets (GTK_PATH_BAR (self), NULL, &overflow_button, &tail_button, &path_bar_container, TRUE); + + gtk_widget_hide (overflow_button); + gtk_widget_hide (tail_button); + path_chunk = create_path_chunk (self, "/meeh", "The tail", + NULL, TRUE); + gtk_path_bar_container_add (path_bar_container, path_chunk, FALSE); +} + +static void +on_invert_animation_done (GtkPathBarContainer *container, + GtkPathBar *self) +{ + GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); + GtkWidget *path_chunk; + GtkWidget *overflow_button; + GtkWidget *tail_button; + + g_print ("###### animation done %d\n", priv->inverted); + + if (priv->inverted) + { + hide_overflow_handling (self); + } +} + +static void +start_overflow_handling (GtkPathBar *self) +{ + GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); + GtkWidget *path_bar_container; + GtkWidget *overflow_button; + GtkWidget *tail_button; + GList *children; + GList *last; + + get_path_bar_widgets (GTK_PATH_BAR (self), NULL, &overflow_button, &tail_button, &path_bar_container, TRUE); + gtk_widget_show (overflow_button); + gtk_widget_show (tail_button); + children = gtk_path_bar_container_get_children (path_bar_container); + last = g_list_last (children); + if (last) + gtk_path_bar_container_remove (path_bar_container, last->data, FALSE); +} + +static void +on_overflow_clicked (GtkButton *button, + gpointer user_data) +{ + GtkPathBar *self = GTK_PATH_BAR (user_data); + + gtk_path_bar_set_inverted (self, !gtk_path_bar_get_inverted (self)); +} + +static void +update_overflow (GtkPathBar *self) +{ + GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); + GtkWidget *path_bar_container; + GList *children; + GList *shown_children; + GList *child; + GList *last_shown_child; + GList *button_children; + GtkWidget *overflow_button; + + get_path_bar_widgets (GTK_PATH_BAR (self), NULL, &overflow_button, NULL, &path_bar_container, TRUE); + shown_children = gtk_path_bar_container_get_shown_children (path_bar_container); + last_shown_child = g_list_last (shown_children); + children = gtk_path_bar_container_get_children (path_bar_container); + + for (child = children; child != NULL; child = child->next) + { + gboolean visible = last_shown_child->data != child->data; + + button_children = gtk_container_get_children (GTK_CONTAINER (child->data)); + if (GTK_IS_SEPARATOR (button_children->data)) + gtk_widget_set_visible (button_children->data, visible); + else + gtk_widget_set_visible (button_children->next->data, visible); + } + + if ((g_list_length (shown_children) == g_list_length (children) || + (priv->inverted && !gtk_path_bar_container_get_invert_animation (path_bar_container))) && + gtk_widget_get_visible (overflow_button)) + { + g_print ("~~~~~~~~~~~changeeeeed equal lenght\n"); + hide_overflow_handling (self); + } + else if (g_list_length (shown_children) != g_list_length (children) && + !gtk_widget_get_visible (overflow_button) && !priv->inverted) + { + g_print ("~~~~~~~~~~~changeeeeed different length %d %d\n", g_list_length (shown_children), g_list_length (children)); + start_overflow_handling (self); + } + + +} + +static void +on_children_shown_changed (GtkPathBarContainer *container, + GParamSpec *spec, + GtkPathBar *self) +{ + update_overflow (self); +} + static void update_path_bar (GtkPathBar *self, const gchar *old_path) @@ -514,7 +631,7 @@ update_path_bar (GtkPathBar *self, if (i < g_strv_length (splitted_old_path)) continue; - gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (path_bar_container), l->data); + gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (path_bar_container), l->data, TRUE); } } /* Completely different path */ @@ -533,56 +650,7 @@ update_path_bar (GtkPathBar *self, } g_print ("update path finish %p\n",path_bar); - gtk_stack_set_visible_child (GTK_STACK (self), path_bar); -} - -static void -on_invert_animation_done (GtkPathBarContainer *container, - GtkPathBar *self) -{ - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); - GtkWidget *path_chunk; - GtkWidget *overflow_button; - GtkWidget *tail_button; - g_print ("###### animation done\n"); - - get_path_bar_widgets (GTK_PATH_BAR (self), NULL, &overflow_button, &tail_button, NULL, TRUE); - - if (priv->inverted) - { - gtk_widget_hide (overflow_button); - gtk_widget_hide (tail_button); - path_chunk = create_path_chunk (self, "/meeh", "The tail", - NULL, TRUE); - gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (container), path_chunk); - } -} - -static void -on_children_shown_changed (GtkPathBarContainer *container, - GParamSpec *spec, - GtkPathBar *self) -{ - GList *children; - GList *shown_children; - GList *child; - GList *last_shown_child; - GList *button_children; - - shown_children = gtk_path_bar_container_get_shown_children (container); - last_shown_child = g_list_last (shown_children); - children = gtk_path_bar_container_get_children (container); - - for (child = children; child != NULL; child = child->next) - { - gboolean visible = last_shown_child->data != child->data; - - button_children = gtk_container_get_children (GTK_CONTAINER (child->data)); - if (GTK_IS_SEPARATOR (button_children->data)) - gtk_widget_set_visible (button_children->data, visible); - else - gtk_widget_set_visible (button_children->next->data, visible); - } + gtk_stack_set_visible_child (GTK_STACK (self), path_bar); } static void @@ -613,32 +681,6 @@ update_selected_path (GtkPathBar *self) g_list_free (children); } -static void -on_overflow_clicked (GtkButton *button, - gpointer user_data) -{ - GtkPathBar *self = GTK_PATH_BAR (user_data); - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); - GtkWidget *path_bar_container; - GtkWidget *overflow_button; - GtkWidget *tail_button; - GList *children; - GList *last; - - get_path_bar_widgets (GTK_PATH_BAR (self), NULL, &overflow_button, &tail_button, &path_bar_container, TRUE); - if (!priv->inverted) - { - gtk_widget_show (overflow_button); - gtk_widget_show (tail_button); - children = gtk_path_bar_container_get_children (path_bar_container); - last = g_list_last (children); - if (last) - gtk_path_bar_container_remove (path_bar_container, last->data); - } - - gtk_path_bar_set_inverted (self, !gtk_path_bar_get_inverted (self)); -} - static void gtk_path_bar_finalize (GObject *object) { @@ -816,7 +858,7 @@ gtk_path_bar_init (GtkPathBar *self) g_signal_connect (priv->path_bar_container_2, "invert-animation-done", G_CALLBACK (on_invert_animation_done), self); - priv->inverted = FALSE; + gtk_path_bar_set_inverted (self, TRUE); } @@ -1023,7 +1065,17 @@ gtk_path_bar_set_inverted (GtkPathBar *self, if (priv->inverted != inverted) { + GtkWidget *path_chunk; + GtkWidget *overflow_button; + GtkWidget *tail_button; + GtkWidget *path_bar_container; + priv->inverted = inverted != FALSE; + + g_print ("###### set inverted\n"); + + get_path_bar_widgets (GTK_PATH_BAR (self), &path_bar_container, &overflow_button, &tail_button, NULL, TRUE); + gtk_path_bar_container_set_inverted (GTK_PATH_BAR_CONTAINER (priv->path_bar_container_1), inverted); gtk_path_bar_container_set_inverted (GTK_PATH_BAR_CONTAINER (priv->path_bar_container_2), inverted); diff --git a/gtk/gtkpathbarbox.c b/gtk/gtkpathbarbox.c index 1e4bee03b4..dec1950503 100644 --- a/gtk/gtkpathbarbox.c +++ b/gtk/gtkpathbarbox.c @@ -118,8 +118,12 @@ gtk_path_bar_box_size_allocate (GtkWidget *widget, children = gtk_container_get_children (GTK_CONTAINER (self)); sizes = g_newa (GtkRequestedSize, g_list_length (children)); + if (children == NULL) + return; + for (child = children, i = 0; child != NULL; child = g_list_next (child), i++) { + g_print ("minimum size bef %d\n", gtk_widget_get_visible (child->data)); if (!gtk_widget_get_visible (child->data)) continue; @@ -127,6 +131,7 @@ gtk_path_bar_box_size_allocate (GtkWidget *widget, allocation->height, &sizes[i].minimum_size, &sizes[i].natural_size); + g_print ("minimum size %d %d\n", i, sizes[i].minimum_size); sizes[i].data = child->data; available_size -= sizes[i].minimum_size; n_visible_children++; @@ -135,13 +140,16 @@ gtk_path_bar_box_size_allocate (GtkWidget *widget, gtk_distribute_natural_allocation (MAX (0, available_size), n_visible_children, sizes); + g_print ("n visible children %d\n", n_visible_children); for (child = children, i = 0; child != NULL; child = g_list_next (child), i++) { + g_print ("allocate size bef %d\n", gtk_widget_get_visible (child->data)); if (!gtk_widget_get_visible (child->data)) continue; child_available_size.width = sizes[i].minimum_size; child_available_size.height = allocation->height; + g_print ("path bar box size allocate really? %d %d\n", child_available_size.width, child_available_size.height); if (GTK_IS_PATH_BAR_CONTAINER (child->data)) { @@ -153,6 +161,7 @@ gtk_path_bar_box_size_allocate (GtkWidget *widget, &natural_size, &distributed_size); + g_print ("path bar box size allocate %d %d\n", child_available_size.width, distributed_size.width); sizes[i].minimum_size = MIN (child_available_size.width, distributed_size.width); } diff --git a/gtk/gtkpathbarcontainer.c b/gtk/gtkpathbarcontainer.c index ca0ada0d33..e76891eb6b 100644 --- a/gtk/gtkpathbarcontainer.c +++ b/gtk/gtkpathbarcontainer.c @@ -33,8 +33,8 @@ //TODO remove #include "gtkbutton.h" -#define REVEALER_ANIMATION_TIME 250 //ms -#define INVERT_ANIMATION_SPEED 1.2 //px/ms +#define REVEALER_ANIMATION_TIME 750 //ms +#define INVERT_ANIMATION_SPEED 0.2 //px/ms #define INVERT_ANIMATION_MAX_TIME 10000 //ms struct _GtkPathBarContainerPrivate @@ -59,6 +59,8 @@ struct _GtkPathBarContainerPrivate gboolean allocated; guint parent_available_width; + + guint children_shown_idle_id; }; G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBarContainer, gtk_path_bar_container, GTK_TYPE_BIN) @@ -122,7 +124,8 @@ gtk_path_bar_container_get_property (GObject *object, void gtk_path_bar_container_add (GtkPathBarContainer *self, - GtkWidget *widget) + GtkWidget *widget, + gboolean animate) { GtkPathBarContainer *children_box = GTK_PATH_BAR_CONTAINER (self); GtkWidget *revealer; @@ -135,8 +138,16 @@ gtk_path_bar_container_add (GtkPathBarContainer *self, GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); gtk_container_add (GTK_CONTAINER (revealer), widget); gtk_container_add (GTK_CONTAINER (priv->children_box), revealer); - gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), - REVEALER_ANIMATION_TIME); + if (animate) + { + gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), + REVEALER_ANIMATION_TIME); + } + else + { + gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), + 0); + } priv->children = g_list_append (priv->children, widget); gtk_widget_show_all (revealer); @@ -155,7 +166,7 @@ really_remove_child (GtkPathBarContainer *self, GtkWidget *revealer; revealer = gtk_widget_get_parent (child->data); - if (child->data == widget && !gtk_revealer_get_child_revealed (GTK_REVEALER (revealer))) + if (child->data == widget) { gboolean was_visible = gtk_widget_get_visible (widget); @@ -184,7 +195,8 @@ unrevealed_really_remove_child (GObject *widget, void gtk_path_bar_container_remove (GtkPathBarContainer *self, - GtkWidget *widget) + GtkWidget *widget, + gboolean animate) { GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self); GtkWidget *to_remove; @@ -197,6 +209,14 @@ gtk_path_bar_container_remove (GtkPathBarContainer *self, priv->children_to_remove = g_list_append (priv->children_to_remove, to_remove); priv->children = g_list_remove (priv->children, to_remove); + if (!animate) + { + really_remove_child (self, widget); + priv->children_to_show = g_list_remove (priv->children_to_show, to_remove); + priv->children_to_hide = g_list_remove (priv->children_to_hide, to_remove); + + } + gtk_widget_queue_resize (GTK_WIDGET (self)); } @@ -303,6 +323,19 @@ get_children_preferred_size_for_requisition (GtkPathBarContainer *self, g_list_free (children); } +static gboolean +emit_children_shown_idle (gpointer user_data) +{ + GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (user_data); + GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self); + + g_object_notify (G_OBJECT (self), "children-shown"); + + priv->children_shown_idle_id = 0; + + return FALSE; +} + static void update_children_visibility (GtkPathBarContainer *self) { @@ -349,6 +382,7 @@ update_children_visibility (GtkPathBarContainer *self) if (!allocate_more_children || current_children_width > available_size.width) { + g_print ("€€€€ Not allocate more %d \n", available_size.width); allocate_more_children = FALSE; if (gtk_revealer_get_child_revealed (GTK_REVEALER (gtk_widget_get_parent (child_widget)))) children_to_hide = g_list_prepend (children_to_hide, child_widget); @@ -358,6 +392,7 @@ update_children_visibility (GtkPathBarContainer *self) if (!g_list_find (priv->children_to_remove, child_widget)) children_to_show = g_list_prepend (children_to_show, child_widget); + g_print ("children to show %d %d\n", g_list_length (children_to_show), i); } for (child = children_to_show, child_to_compare = priv->children_to_show; @@ -397,8 +432,11 @@ update_children_visibility (GtkPathBarContainer *self) { priv->children_to_show = g_list_reverse (priv->children_to_show); priv->children_to_hide = g_list_reverse (priv->children_to_hide); - } - g_object_notify (G_OBJECT (self), "children-shown"); + g_print ("children to sho????%d", g_list_length (priv->children_to_show)); + }; + + if (!priv->children_shown_idle_id) + priv->children_shown_idle_id = g_idle_add (emit_children_shown_idle, self); } g_list_free (children); @@ -438,8 +476,6 @@ revealer_on_show_completed (GObject *widget, remove_opacity_classes (GTK_WIDGET (widget)); g_signal_handlers_disconnect_by_func (widget, revealer_on_show_completed, user_data); - priv->children_to_show = g_list_remove (priv->children_to_show, - gtk_bin_get_child (GTK_BIN (widget))); } static void @@ -990,6 +1026,14 @@ gtk_path_bar_container_draw (GtkWidget *widget, return GDK_EVENT_PROPAGATE; } +static void +gtk_path_bar_container_finalize (GObject *object) +{ + GtkPathBarContainer *self = GTK_PATH_BAR_CONTAINER (object); + + g_idle_remove_by_data (self); +} + static void real_get_preferred_size_for_requisition (GtkWidget *widget, GtkRequisition *available_size, @@ -1062,6 +1106,7 @@ gtk_path_bar_container_class_init (GtkPathBarContainerClass *class) object_class->set_property = gtk_path_bar_container_set_property; object_class->get_property = gtk_path_bar_container_get_property; + object_class->finalize = gtk_path_bar_container_finalize; widget_class->size_allocate = gtk_path_bar_container_size_allocate; widget_class->get_preferred_width = gtk_path_bar_container_get_preferred_width; @@ -1206,6 +1251,14 @@ gtk_path_bar_container_get_inverted (GtkPathBarContainer *self) return priv->inverted; } +gboolean +gtk_path_bar_container_get_invert_animation (GtkPathBarContainer *self) +{ + GtkPathBarContainerPrivate *priv = gtk_path_bar_container_get_instance_private (self); + + return priv->invert_animation; +} + GList * gtk_path_bar_container_get_overflow_children (GtkPathBarContainer *self) { diff --git a/gtk/gtkpathbarcontainer.h b/gtk/gtkpathbarcontainer.h index e9d0e94210..a8f9547a2a 100644 --- a/gtk/gtkpathbarcontainer.h +++ b/gtk/gtkpathbarcontainer.h @@ -91,11 +91,13 @@ GList *gtk_path_bar_container_get_overflow_children (GtkPathBarCont GDK_AVAILABLE_IN_3_20 void gtk_path_bar_container_add (GtkPathBarContainer *self, - GtkWidget *widget); + GtkWidget *widget, + gboolean animate); GDK_AVAILABLE_IN_3_20 void gtk_path_bar_container_remove (GtkPathBarContainer *self, - GtkWidget *widget); + GtkWidget *widget, + gboolean animate); GDK_AVAILABLE_IN_3_20 void gtk_path_bar_container_remove_all_children (GtkPathBarContainer *self); @@ -118,6 +120,9 @@ void gtk_path_bar_container_adapt_to_size GDK_AVAILABLE_IN_3_20 GList * gtk_path_bar_container_get_shown_children (GtkPathBarContainer *self); +GDK_AVAILABLE_IN_3_20 +gboolean gtk_path_bar_container_get_invert_animation (GtkPathBarContainer *self); + G_END_DECLS #endif /* GTK_PATH_BAR_CONTAINER_H_ */ diff --git a/tests/testpathbarcontainer.c b/tests/testpathbarcontainer.c index 1798d4f232..4d91b684f7 100644 --- a/tests/testpathbarcontainer.c +++ b/tests/testpathbarcontainer.c @@ -33,7 +33,7 @@ on_button_clicked (GtkWidget *button, gpointer user_data) { g_print ("button clicked\n"); - gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (user_data), button); + gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (user_data), button, TRUE); } static void @@ -47,7 +47,7 @@ on_reset_button_clicked (GtkButton *reset_button) { button = gtk_button_new_with_label (get_lorem_ipsum ()); g_signal_connect (button, "clicked", (GCallback) on_button_clicked, path_bar_container); - gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), button); + gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), button, FALSE); } gtk_widget_show_all (path_bar_container); @@ -61,7 +61,7 @@ on_add_button (gint line) button = gtk_button_new_with_label (get_lorem_ipsum ()); gtk_widget_show (button); g_signal_connect (button, "clicked", (GCallback) on_button_clicked, path_bar_container); - gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), button); + gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), button, TRUE); gtk_container_add (GTK_CONTAINER (path_bar_box), gtk_button_new_with_label ("eeeeoo")); } @@ -75,7 +75,7 @@ on_remove_button (gint line) last = g_list_last (children); if (last) gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (path_bar_container), - last->data); + last->data, TRUE); g_list_free (children); }