2009-02-27 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-bread-crumb-trail.c
index 49b1155..5ed23e0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007 Nokia Corporation, all rights reserved.
  *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
  * Author: Xan Lopez <xan.lopez@nokia.com>
  *
  * This library is free software; you can redistribute it and/or
  * implemented if needed. See #HildonBreadCrumb for more details.
  */
 
+#undef HILDON_DISABLE_DEPRECATED
+
 #include <gdk/gdkkeysyms.h>
+
 #include "hildon-marshalers.h"
 #include "hildon-bread-crumb-trail.h"
 #include "hildon-bread-crumb-widget.h"
@@ -265,6 +268,10 @@ hildon_bread_crumb_trail_size_allocate (GtkWidget *widget,
   GList *p, *first_show, *first_hide;
   gint back_button_size;
   HildonBreadCrumbTrailPrivate *priv = HILDON_BREAD_CRUMB_TRAIL (widget)->priv;
+  gboolean rtl;
+
+  /* Get the rtl status */
+  rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
 
   widget->allocation = *allocation;
 
@@ -272,14 +279,24 @@ hildon_bread_crumb_trail_size_allocate (GtkWidget *widget,
   allocation_width = allocation->width - 2 * border_width;
 
   /* Allocate the back button */
-  child_allocation.x = allocation->x + border_width;
+  if (rtl)
+    child_allocation.x = allocation->width - border_width;
+  else
+    child_allocation.x = allocation->x + border_width;
+
   child_allocation.y = allocation->y + border_width;
   gtk_widget_get_child_requisition (priv->back_button, &child_requisition);
   /* We want the back button to be a square */
   back_button_size = MAX (child_requisition.width, child_requisition.height);
   child_allocation.width = child_allocation.height = back_button_size;
+
+  if (rtl)
+    child_allocation.x -= back_button_size;
+
   gtk_widget_size_allocate (priv->back_button, &child_allocation);
-  child_allocation.x += back_button_size;
+
+  if (!rtl)
+    child_allocation.x += back_button_size;
 
   /* If there are no buttons there's nothing else to do */
   if (priv->item_list == NULL)
@@ -323,8 +340,14 @@ hildon_bread_crumb_trail_size_allocate (GtkWidget *widget,
             {
               first_hide = p->next;
               gtk_widget_set_child_visible (child, TRUE);
+
+              if (rtl)
+                child_allocation.x -= child_allocation.width;
+
               gtk_widget_size_allocate (child, &child_allocation);
-              child_allocation.x += child_allocation.width;
+
+              if (!rtl)
+                child_allocation.x += child_allocation.width;
             }
           else
             {
@@ -360,15 +383,19 @@ hildon_bread_crumb_trail_size_allocate (GtkWidget *widget,
 
       child_allocation.width = natural_width;
       gtk_widget_set_child_visible (child, TRUE);
+
+      if (rtl)
+        child_allocation.x -= child_allocation.width;
+
       gtk_widget_size_allocate (child, &child_allocation);
-      child_allocation.x += child_allocation.width;
+
+      if (!rtl)
+        child_allocation.x += child_allocation.width;
     }
 
   for (p = first_hide; p; p = p->next)
     {
       item = HILDON_BREAD_CRUMB (p->data);
-      child = GTK_WIDGET (item);
-
       gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
     }
 }
@@ -470,7 +497,7 @@ static void
 hildon_bread_crumb_trail_remove (GtkContainer *container,
                                  GtkWidget *widget)
 {
-  GList *p;
+  GList *p, *next;
   HildonBreadCrumbTrailPrivate *priv;
   gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
 
@@ -480,14 +507,15 @@ hildon_bread_crumb_trail_remove (GtkContainer *container,
 
   while (p)
     {
+      next = p->next;
+
       if (widget == GTK_WIDGET (p->data))
         {
           g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (crumb_activated_cb),
                                                 HILDON_BREAD_CRUMB_TRAIL (container));
           gtk_widget_unparent (widget);
 
-          priv->item_list = g_list_remove_link (priv->item_list, p);
-          g_list_free (p);
+          priv->item_list = g_list_delete_link (priv->item_list, p);
 
           hildon_bread_crumb_trail_update_back_button_sensitivity (HILDON_BREAD_CRUMB_TRAIL (container));
 
@@ -497,7 +525,7 @@ hildon_bread_crumb_trail_remove (GtkContainer *container,
             }
         }
 
-      p = p->next;
+      p = next;
     }
 }
 
@@ -656,11 +684,15 @@ hildon_bread_crumb_trail_push_text (HildonBreadCrumbTrail *bct,
   g_return_if_fail (text != NULL);
 
   widget = _hildon_bread_crumb_widget_new_with_text (text);
+  if (bct->priv->item_list == NULL)
+    {
+      g_object_set (G_OBJECT (widget), "show-separator", FALSE, NULL);
+    }
   attach_bread_crumb (bct, widget, id, destroy);
 }
 
 /**
- * hildon_bread_crumb_trail_push_text:
+ * hildon_bread_crumb_trail_push_icon:
  * @bct: pointer to #HildonBreadCrumbTrail
  * @text: content of the new bread crumb
  * @icon: a widget to set as the icon in the bread crumb
@@ -687,6 +719,10 @@ hildon_bread_crumb_trail_push_icon (HildonBreadCrumbTrail *bct,
   g_return_if_fail (GTK_IS_WIDGET (icon));
 
   widget = _hildon_bread_crumb_widget_new_with_icon (icon, text);
+  if (bct->priv->item_list == NULL)
+    {
+      g_object_set (G_OBJECT (widget), "show-separator", FALSE, NULL);
+    }
   attach_bread_crumb (bct, widget, id, destroy);
 }
 
@@ -743,4 +779,13 @@ hildon_bread_crumb_trail_clear (HildonBreadCrumbTrail *bct)
     {
       hildon_bread_crumb_trail_pop (bct);
     }
+
+  /*
+    Sensitivity hack from hell. We need to do this while
+     http://bugzilla.gnome.org/show_bug.cgi?id=56070 is not
+     fixed to allow repeated clicking on the back button if
+     someone clears and rebuilds the trail when it's clicked
+  */
+  gtk_widget_hide (priv->back_button);
+  gtk_widget_show (priv->back_button);
 }