/* Eye Of Gnome - Thumbnail Navigator
 *
 * Copyright (C) 2006 The Free Software Foundation
 *
 * Author: Lucas Rocha <lucasr@gnome.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

#include "eog-thumb-nav.h"
#include "cheese-thumb-view.h"

#include <glib.h>
#include <glib/gi18n.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <string.h>
#include <math.h>

struct _EogThumbNav
{
  GtkBox base_instance;
};

typedef struct
{
  gboolean show_buttons;
  gboolean vertical;
  gboolean scroll_dir;
  gint scroll_pos;
  gint scroll_id;

  GtkWidget *button_up;
  GtkWidget *button_down;
  GtkWidget *button_left;
  GtkWidget *button_right;
  GtkWidget *sw;
  GtkWidget *thumbview;
  GtkWidget *vbox;
  GtkAdjustment *hadj;
  GtkAdjustment *vadj;
  GtkAdjustment *adj;
} EogThumbNavPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (EogThumbNav, eog_thumb_nav, GTK_TYPE_BOX)

#define EOG_THUMB_NAV_SCROLL_INC     20
#define EOG_THUMB_NAV_SCROLL_MOVE    20
#define EOG_THUMB_NAV_SCROLL_TIMEOUT 20

enum
{
  PROP_SHOW_BUTTONS = 1,
  PROP_THUMB_VIEW,
  PROP_MODE
};

static gboolean
eog_thumb_nav_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
{
  EogThumbNav *nav = EOG_THUMB_NAV (user_data);
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);
  gint         inc = EOG_THUMB_NAV_SCROLL_INC * 3;
  gdouble      value, upper, page_size, delta_x, delta_y;
  gboolean smooth;

  priv->adj =priv->vertical ? priv->vadj : priv->hadj;

  switch (event->direction)
  {
    /* Handle smooth scroll events from mouse wheels, bug 672311. */
    case GDK_SCROLL_SMOOTH:
      smooth = gdk_event_get_scroll_deltas ((const GdkEvent *) event,
                                            &delta_x, &delta_y);
      /* Pass through non-mouse wheel events. */
      if (G_UNLIKELY (!smooth) || delta_x != 0.0 || fabs (delta_y) != 1.0)
        return FALSE;

      inc *= (gint) delta_y;
      break;
    case GDK_SCROLL_UP:
    case GDK_SCROLL_LEFT:
      inc *= -1;
      break;

    case GDK_SCROLL_DOWN:
    case GDK_SCROLL_RIGHT:
      break;

    default:
      g_assert_not_reached ();
      return FALSE;
  }

  value = gtk_adjustment_get_value (priv->adj);
  if (inc < 0)
    gtk_adjustment_set_value (priv->adj, MAX (0, value + inc));
  else
  {
    upper     = gtk_adjustment_get_upper (priv->adj);
    page_size = gtk_adjustment_get_page_size (priv->adj);
    gtk_adjustment_set_value (priv->adj, MIN (upper - page_size, value + inc));
  }

  gtk_adjustment_value_changed (priv->adj);

  return TRUE;
}

static void
eog_thumb_nav_vadj_changed (GtkAdjustment *vadj, gpointer user_data)
{
  EogThumbNav        *nav;
  EogThumbNavPrivate *priv;
  gdouble             value, upper, page_size;

  nav  = EOG_THUMB_NAV (user_data);
  priv = eog_thumb_nav_get_instance_private (nav);

  g_object_get (vadj,
                "value", &value,
                "upper", &upper,
                "page_size", &page_size,
                NULL);
  gtk_widget_set_sensitive (priv->button_up, value > 0);

  gtk_widget_set_sensitive (priv->button_down,
                            value < upper - page_size);
}

static void
eog_thumb_nav_hadj_changed (GtkAdjustment *hadj, gpointer user_data)
{
  EogThumbNav        *nav;
  EogThumbNavPrivate *priv;
  gboolean            ltr;
  gdouble             value, upper, page_size;

  nav  = EOG_THUMB_NAV (user_data);
  priv = eog_thumb_nav_get_instance_private (nav);
  ltr  = gtk_widget_get_direction (priv->sw) == GTK_TEXT_DIR_LTR;

  g_object_get (hadj,
                "value", &value,
                "upper", &upper,
                "page_size", &page_size,
                NULL);

  gtk_widget_set_sensitive (ltr ? priv->button_right : priv->button_left,
                            value < upper - page_size);
}

static void
eog_thumb_nav_vadj_value_changed (GtkAdjustment *vadj, gpointer user_data)
{
  EogThumbNav        *nav;
  EogThumbNavPrivate *priv;
  gdouble             value, upper, page_size;

  nav  = EOG_THUMB_NAV (user_data);
  priv = eog_thumb_nav_get_instance_private (nav);

  g_object_get (vadj,
                "value", &value,
                "upper", &upper,
                "page_size", &page_size,
                NULL);

  gtk_widget_set_sensitive (priv->button_up, value > 0);

  gtk_widget_set_sensitive (priv->button_down,
                            value < upper - page_size);
}

static void
eog_thumb_nav_hadj_value_changed (GtkAdjustment *hadj, gpointer user_data)
{
  EogThumbNav        *nav;
  EogThumbNavPrivate *priv;
  gboolean            ltr;
  gdouble             value, upper, page_size;

  nav  = EOG_THUMB_NAV (user_data);
  priv = eog_thumb_nav_get_instance_private (nav);
  ltr  = gtk_widget_get_direction (priv->sw) == GTK_TEXT_DIR_LTR;

  g_object_get (hadj,
                "value", &value,
                "upper", &upper,
                "page_size", &page_size,
                NULL);

  gtk_widget_set_sensitive (ltr ? priv->button_left : priv->button_right, value > 0);

  gtk_widget_set_sensitive (ltr ? priv->button_right : priv->button_left,
                            value < upper - page_size);
}

static gboolean
eog_thumb_nav_scroll_step (gpointer user_data)
{
  EogThumbNav *nav = EOG_THUMB_NAV (user_data);
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);
  gint         delta;
  gdouble      value, upper, page_size;

  if (priv->scroll_pos < 10)
    delta = EOG_THUMB_NAV_SCROLL_INC;
  else if (priv->scroll_pos < 20)
    delta = EOG_THUMB_NAV_SCROLL_INC * 2;
  else if (priv->scroll_pos < 30)
    delta = EOG_THUMB_NAV_SCROLL_INC * 2 + 5;
  else
    delta = EOG_THUMB_NAV_SCROLL_INC * 2 + 12;

  if (!priv->scroll_dir)
    delta *= -1;

  g_object_get (priv->adj,
                "value", &value,
                "upper", &upper,
                "page_size", &page_size,
                NULL);

  if ((gint) (value + (gdouble) delta) >= 0 &&
      (gint) (value + (gdouble) delta) <= upper - page_size)
  {
    gtk_adjustment_set_value (priv->adj, value + (gdouble) delta);
    priv->scroll_pos++;
    gtk_adjustment_value_changed (priv->adj);
  }
  else
  {
    if (delta > 0)
      gtk_adjustment_set_value (priv->adj, upper - page_size);
    else
      gtk_adjustment_set_value (priv->adj, 0);

    priv->scroll_pos = 0;

    gtk_adjustment_value_changed (priv->adj);

    return G_SOURCE_REMOVE;
  }

  return G_SOURCE_CONTINUE;
}

static void
eog_thumb_nav_button_clicked (GtkButton *button, EogThumbNav *nav)
{
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  priv->scroll_pos = 0;

  if ((GTK_WIDGET (button) == priv->button_right) ||
      (GTK_WIDGET (button) == priv->button_left))
  {
    priv->scroll_dir = gtk_widget_get_direction (GTK_WIDGET (button)) == GTK_TEXT_DIR_LTR ?
                       GTK_WIDGET (button) == priv->button_right :
                       GTK_WIDGET (button) == priv->button_left;
  }
  else
  {
    priv->scroll_dir = (GTK_WIDGET (button) == priv->button_down);
  }

  priv->adj = ((GTK_WIDGET (button) == priv->button_right) ||
               (GTK_WIDGET (button) == priv->button_left)) ? priv->hadj : priv->vadj;

  eog_thumb_nav_scroll_step (nav);
}

static void
eog_thumb_nav_start_scroll (GtkButton *button, EogThumbNav *nav)
{
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  if ((GTK_WIDGET (button) == priv->button_right) ||
      (GTK_WIDGET (button) == priv->button_left))
  {
    priv->scroll_dir = gtk_widget_get_direction (GTK_WIDGET (button)) == GTK_TEXT_DIR_LTR ?
                       GTK_WIDGET (button) == priv->button_right :
                       GTK_WIDGET (button) == priv->button_left;
  }
  else
  {
    priv->scroll_dir = (GTK_WIDGET (button) == priv->button_down);
  }

  priv->adj = ((GTK_WIDGET (button) == priv->button_right) ||
               (GTK_WIDGET (button) == priv->button_left)) ? priv->hadj : priv->vadj;

  priv->scroll_id = g_timeout_add (EOG_THUMB_NAV_SCROLL_TIMEOUT,
                                   eog_thumb_nav_scroll_step,
                                   nav);
}

static void
eog_thumb_nav_stop_scroll (GtkButton *button, EogThumbNav *nav)
{
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  if (priv->scroll_id > 0)
  {
    g_source_remove (priv->scroll_id);
    priv->scroll_id  = 0;
    priv->scroll_pos = 0;
  }
}

static void
eog_thumb_nav_get_property (GObject    *object,
                            guint       property_id,
                            GValue     *value,
                            GParamSpec *pspec)
{
  EogThumbNav *nav = EOG_THUMB_NAV (object);
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  switch (property_id)
  {
    case PROP_SHOW_BUTTONS:
      g_value_set_boolean (value,
                           eog_thumb_nav_get_show_buttons (nav));
      break;

    case PROP_THUMB_VIEW:
      g_value_set_object (value, priv->thumbview);
      break;
  }
}

static void
eog_thumb_nav_set_property (GObject      *object,
                            guint         property_id,
                            const GValue *value,
                            GParamSpec   *pspec)
{
  EogThumbNav *nav = EOG_THUMB_NAV (object);
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  switch (property_id)
  {
    case PROP_SHOW_BUTTONS:
      eog_thumb_nav_set_show_buttons (nav,
                                      g_value_get_boolean (value));
      break;

    case PROP_THUMB_VIEW:
      priv->thumbview =
        GTK_WIDGET (g_value_get_object (value));
      break;
  }
}

static GObject *
eog_thumb_nav_constructor (GType                  type,
                           guint                  n_construct_properties,
                           GObjectConstructParam *construct_params)
{
  GObject            *object;
  EogThumbNavPrivate *priv;

  object = G_OBJECT_CLASS (eog_thumb_nav_parent_class)->constructor
             (type, n_construct_properties, construct_params);

  priv = eog_thumb_nav_get_instance_private (EOG_THUMB_NAV (object));

  if (priv->thumbview != NULL)
  {
    gtk_container_add (GTK_CONTAINER (priv->sw), priv->thumbview);
    gtk_widget_show_all (priv->sw);
  }

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_NEVER);

  return object;
}

static void
eog_thumb_nav_class_init (EogThumbNavClass *class)
{
  GObjectClass *g_object_class = (GObjectClass *) class;

  g_object_class->constructor  = eog_thumb_nav_constructor;
  g_object_class->get_property = eog_thumb_nav_get_property;
  g_object_class->set_property = eog_thumb_nav_set_property;

  g_object_class_install_property (g_object_class,
                                   PROP_SHOW_BUTTONS,
                                   g_param_spec_boolean ("show-buttons",
                                                         "Show Buttons",
                                                         "Whether to show navigation buttons or not",
                                                         TRUE,
                                                         G_PARAM_READWRITE |
                                                         G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (g_object_class,
                                   PROP_THUMB_VIEW,
                                   g_param_spec_object ("thumbview",
                                                        "Thumbnail View",
                                                        "The internal thumbnail viewer widget",
                                                        CHEESE_TYPE_THUMB_VIEW,
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_STATIC_STRINGS));
}

static void
eog_thumb_nav_init (EogThumbNav *nav)
{
  EogThumbNavPrivate *priv;
  GtkWidget          *arrow;

  priv = eog_thumb_nav_get_instance_private (nav);

  priv->show_buttons = TRUE;
  priv->vertical     = FALSE;

  priv->button_left = gtk_button_new ();
  gtk_button_set_relief (GTK_BUTTON (priv->button_left), GTK_RELIEF_NONE);

  arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_ETCHED_IN);
  gtk_container_add (GTK_CONTAINER (priv->button_left), arrow);

  gtk_widget_set_size_request (GTK_WIDGET (priv->button_left), 25, 0);

  g_signal_connect (priv->button_left,
                    "clicked",
                    G_CALLBACK (eog_thumb_nav_button_clicked),
                    nav);

  g_signal_connect (priv->button_left,
                    "pressed",
                    G_CALLBACK (eog_thumb_nav_start_scroll),
                    nav);

  g_signal_connect (priv->button_left,
                    "released",
                    G_CALLBACK (eog_thumb_nav_stop_scroll),
                    nav);

  priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

  priv->sw = gtk_scrolled_window_new (NULL, NULL);

  gtk_widget_set_name (gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (priv->sw)),
                       "hscrollbar");
  gtk_widget_set_name (gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (priv->sw)),
                       "vscrollbar");

  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->sw),
                                       GTK_SHADOW_IN);



  g_signal_connect (priv->sw,
                    "scroll-event",
                    G_CALLBACK (eog_thumb_nav_scroll_event),
                    nav);

  priv->hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->sw));

  g_signal_connect (priv->hadj,
                    "changed",
                    G_CALLBACK (eog_thumb_nav_hadj_changed),
                    nav);

  g_signal_connect (priv->hadj,
                    "value-changed",
                    G_CALLBACK (eog_thumb_nav_hadj_value_changed),
                    nav);

  priv->vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->sw));

  g_signal_connect (priv->vadj,
                    "changed",
                    G_CALLBACK (eog_thumb_nav_vadj_changed),
                    nav);

  g_signal_connect (priv->vadj,
                    "value-changed",
                    G_CALLBACK (eog_thumb_nav_vadj_value_changed),
                    nav);

  priv->button_right = gtk_button_new ();
  gtk_button_set_relief (GTK_BUTTON (priv->button_right), GTK_RELIEF_NONE);

  arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
  gtk_container_add (GTK_CONTAINER (priv->button_right), arrow);

  gtk_widget_set_size_request (GTK_WIDGET (priv->button_right), 25, 0);

  g_signal_connect (priv->button_right,
                    "clicked",
                    G_CALLBACK (eog_thumb_nav_button_clicked),
                    nav);

  g_signal_connect (priv->button_right,
                    "pressed",
                    G_CALLBACK (eog_thumb_nav_start_scroll),
                    nav);

  g_signal_connect (priv->button_right,
                    "released",
                    G_CALLBACK (eog_thumb_nav_stop_scroll),
                    nav);

  priv->button_down = gtk_button_new ();
  gtk_button_set_relief (GTK_BUTTON (priv->button_down), GTK_RELIEF_NONE);

  arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
  gtk_container_add (GTK_CONTAINER (priv->button_down), arrow);

  gtk_widget_set_size_request (GTK_WIDGET (priv->button_down), 0, 25);

  g_signal_connect (priv->button_down,
                    "clicked",
                    G_CALLBACK (eog_thumb_nav_button_clicked),
                    nav);

  g_signal_connect (priv->button_down,
                    "pressed",
                    G_CALLBACK (eog_thumb_nav_start_scroll),
                    nav);

  g_signal_connect (priv->button_down,
                    "released",
                    G_CALLBACK (eog_thumb_nav_stop_scroll),
                    nav);

  priv->button_up = gtk_button_new ();
  gtk_button_set_relief (GTK_BUTTON (priv->button_up), GTK_RELIEF_NONE);

  arrow = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_NONE);
  gtk_container_add (GTK_CONTAINER (priv->button_up), arrow);

  gtk_widget_set_size_request (GTK_WIDGET (priv->button_up), 0, 25);

  g_signal_connect (priv->button_up,
                    "clicked",
                    G_CALLBACK (eog_thumb_nav_button_clicked),
                    nav);

  g_signal_connect (priv->button_up,
                    "pressed",
                    G_CALLBACK (eog_thumb_nav_start_scroll),
                    nav);

  g_signal_connect (priv->button_up,
                    "released",
                    G_CALLBACK (eog_thumb_nav_stop_scroll),
                    nav);


  g_object_ref (priv->button_up);
  g_object_ref (priv->button_down);
  gtk_box_pack_start (GTK_BOX (nav), priv->button_left, FALSE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (nav), priv->vbox, TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (nav), priv->button_right, FALSE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (priv->vbox), priv->sw, TRUE, TRUE, 0);

  gtk_adjustment_value_changed (priv->hadj);
}

/**
 * eog_thumb_nav_new:
 * @thumbview: a #CheeseThumbView to embed in the navigation widget.
 * @mode: The navigation mode.
 * @show_buttons: Whether to show the navigation buttons.
 *
 * Creates a new thumbnail navigation widget.
 *
 * Returns: a new #EogThumbNav object.
 **/
GtkWidget *
eog_thumb_nav_new (GtkWidget *thumbview,
                   gboolean   show_buttons)
{
  EogThumbNav        *nav;

  nav = g_object_new (EOG_TYPE_THUMB_NAV,
                      "show-buttons", show_buttons,
                      "thumbview", thumbview,
                      "homogeneous", FALSE,
                      "spacing", 0,
                      NULL);

  return GTK_WIDGET (nav);
}

/**
 * eog_thumb_nav_get_show_buttons:
 * @nav: an #EogThumbNav.
 *
 * Gets whether the navigation buttons are visible.
 *
 * Returns: %TRUE if the navigation buttons are visible,
 * %FALSE otherwise.
 **/
gboolean
eog_thumb_nav_get_show_buttons (EogThumbNav *nav)
{
  EogThumbNavPrivate *priv;

  g_return_val_if_fail (EOG_IS_THUMB_NAV (nav), FALSE);

  priv = eog_thumb_nav_get_instance_private (nav);

  return priv->show_buttons;
}

/**
 * eog_thumb_nav_set_show_buttons:
 * @nav: an #EogThumbNav.
 * @show_buttons: %TRUE to show the buttons, %FALSE to hide them.
 *
 * Sets whether the navigation buttons to the left and right of the
 * widget should be visible.
 **/
void
eog_thumb_nav_set_show_buttons (EogThumbNav *nav, gboolean show_buttons)
{
  EogThumbNavPrivate *priv;

  g_return_if_fail (EOG_IS_THUMB_NAV (nav));

  priv = eog_thumb_nav_get_instance_private (nav);

  g_return_if_fail (priv->button_left != NULL);
  g_return_if_fail (priv->button_right != NULL);

  priv->show_buttons = show_buttons;

  if (show_buttons)
  {
    gtk_widget_show_all (priv->button_left);
    gtk_widget_show_all (priv->button_right);
  }
  else
  {
    gtk_widget_hide (priv->button_left);
    gtk_widget_hide (priv->button_right);
  }
}

void
eog_thumb_nav_set_policy (EogThumbNav  *nav,
                          GtkPolicyType hscrollbar_policy,
                          GtkPolicyType vscrollbar_policy)
{
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
                                  hscrollbar_policy,
                                  vscrollbar_policy);
}

gboolean
eog_thumb_nav_is_vertical (EogThumbNav *nav)
{
  EogThumbNavPrivate *priv = eog_thumb_nav_get_instance_private (nav);

  return priv->vertical;
}

void
eog_thumb_nav_set_vertical (EogThumbNav *nav, gboolean vertical)
{
  EogThumbNavPrivate *priv;

  g_return_if_fail (EOG_IS_THUMB_NAV (nav));

  priv = eog_thumb_nav_get_instance_private (nav);

  g_return_if_fail (priv->button_left != NULL);
  g_return_if_fail (priv->button_right != NULL);
  g_return_if_fail (priv->vbox != NULL);
  g_return_if_fail (priv->sw != NULL);

  if (vertical == priv->vertical) return;

  /* show/hide doesn't work because of a mandatory show_all in cheese-window */

  if (vertical)
  {
    g_return_if_fail (!gtk_widget_get_parent (priv->button_up));
    g_return_if_fail (!gtk_widget_get_parent (priv->button_down));
    g_return_if_fail (gtk_widget_get_parent (priv->button_left));
    g_return_if_fail (gtk_widget_get_parent (priv->button_right));

    gtk_box_pack_start (GTK_BOX (priv->vbox), priv->button_up, FALSE, FALSE, 0);
    gtk_box_reorder_child (GTK_BOX (priv->vbox), priv->button_up, 0);
    gtk_box_pack_start (GTK_BOX (priv->vbox), priv->button_down, FALSE, FALSE, 0);
    g_object_unref (priv->button_up);
    g_object_unref (priv->button_down);

    g_object_ref (priv->button_left);
    gtk_container_remove (GTK_CONTAINER (nav), priv->button_left);
    g_object_ref (priv->button_right);
    gtk_container_remove (GTK_CONTAINER (nav), priv->button_right);
    gtk_adjustment_value_changed (priv->vadj);

    eog_thumb_nav_set_policy (nav,
                              GTK_POLICY_NEVER,
                              GTK_POLICY_AUTOMATIC);
    priv->vertical = TRUE;
  }
  else
  {
    g_return_if_fail (!gtk_widget_get_parent (priv->button_left));
    g_return_if_fail (!gtk_widget_get_parent (priv->button_right));
    g_return_if_fail (gtk_widget_get_parent (priv->button_up));
    g_return_if_fail (gtk_widget_get_parent (priv->button_down));

    gtk_box_pack_start (GTK_BOX (nav), priv->button_left, FALSE, FALSE, 0);
    gtk_box_reorder_child (GTK_BOX (nav), priv->button_left, 0);
    gtk_box_pack_start (GTK_BOX (nav), priv->button_right, FALSE, FALSE, 0);
    g_object_unref (priv->button_left);
    g_object_unref (priv->button_right);

    g_object_ref (priv->button_up);
    gtk_container_remove (GTK_CONTAINER (priv->vbox), priv->button_up);
    g_object_ref (priv->button_down);
    gtk_container_remove (GTK_CONTAINER (priv->vbox), priv->button_down);
    gtk_adjustment_value_changed (priv->hadj);

    eog_thumb_nav_set_policy (nav,
                              GTK_POLICY_AUTOMATIC,
                              GTK_POLICY_NEVER);
    priv->vertical = FALSE;
  }
  gtk_widget_show_all (GTK_WIDGET (nav));
}
