2006-10-31 Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
[hildon] / hildon-widgets / hildon-scroll-area.c
index eab32e3..37751b5 100644 (file)
@@ -1,14 +1,14 @@
 /*
  * This file is part of hildon-libs
  *
- * Copyright (C) 2005 Nokia Corporation.
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
  *
- * Contact: Luc Pionchon <luc.pionchon@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
  *
  * This library is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  */
 
-/* hildon-scroll-area.c
+/**
+ * SECTION:hildon-scroll-area
+ * @short_description: A helper to create Maemo specific views,
+ * which are using scrollable area
  *
+ * #GtkScrollArea combines a large widget that needs scrolling (like a
+ * text editor or a tree view) and other widgets that wouldn't fit one
+ * the screen normally without scrolling (like entries, toolbars etc.)
+ * into one scrollable area.
  */
 
 #include "hildon-scroll-area.h"
 typedef struct
   {
     GtkWidget *fixed;
+
+    /* Scrolled windows */
     GtkWidget *swouter;
     GtkWidget *swinner;
+
+    /* Widget that's being contained */
     GtkWidget *child;
 
+    /* Vertical adjustment for scrolled windows */
     GtkAdjustment *outadj;
     GtkAdjustment *inadj;
 
@@ -60,14 +72,15 @@ static void hildon_scroll_area_fixed_allocate (GtkWidget *widget,
                                               GtkAllocation *allocation,
                                               HildonScrollArea *sc);
 
+static int calculate_size (GtkWidget *widget);
+
 /**
  * hildon_scroll_area_new:
  * @sw: #GtkWidget - #GtkScrolledWindow
- * @child: #GtkWidget - Child to be place inside the sw
+ * @child: #GtkWidget - child to be place inside the sw
  *
- * This is not a widget. It's a helper function to provide
- * hildon specified scrolling for applications.
- * Puts and connects the @child to the @sw.
+ * This is not a widget. It's a helper function to create
+ * hildon-specific scrolling methods.
  * A common situation where the scroll area should be used
  * might be following.  A view containing @GtkTreeView based widget,
  * (or any similar widget which has built-in @GtkScrolledWindow support)
@@ -139,14 +152,45 @@ static void hildon_scroll_area_fixed_allocate (GtkWidget *widget,
                               MIN (sc->outadj->page_size, allocation->height));
 }
 
+
+static int calculate_size (GtkWidget *widget)
+{
+  int size = 0;
+
+  if (GTK_IS_TEXT_VIEW (widget))
+    return 0;
+
+  if (GTK_IS_CONTAINER (widget)) {
+    GList *children = gtk_container_get_children (GTK_CONTAINER (widget));
+    while (children != NULL) {
+      GtkWidget *wid = GTK_WIDGET (children->data);
+      gint sz = calculate_size (wid);
+      if ((GTK_WIDGET_VISIBLE (wid))) {
+        size += sz;
+      }
+
+      children = g_list_next (children);
+    }
+  } else { 
+    size = widget->allocation.height;
+  }
+
+  return size;
+}
+
 static void hildon_scroll_area_child_requisition (GtkWidget *widget,
                                                  GtkRequisition *req,
                                                  HildonScrollArea *sc)
 {
+  /* Limit height to fixed height */
   gint new_req = MAX (req->height, sc->fixed->allocation.height);
+  new_req = MIN (sc->outadj->page_size - adjust_factor, new_req);
+  gint adjust_factor = calculate_size (sc->swouter) * 0.7;
+  adjust_factor = MAX (0, adjust_factor - sc->outadj->value);
+
   gtk_widget_set_size_request (sc->fixed, -1, req->height);
-  gtk_widget_set_size_request (sc->swinner, -1,
-                              MIN (sc->outadj->page_size, new_req));
+  /* Request inner scrolled window at most page size */
+  gtk_widget_set_size_request (sc->swinner, -1, new_req);
 }
 
 static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
@@ -155,6 +199,7 @@ static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
   GtkRequisition req;
   gtk_widget_size_request (sc->child, &req);
 
+  /* Update inner adjustment position based on outer one, update fixed position */
   if ((sc->outadj->value + sc->outadj->page_size) > sc->fixed->allocation.y
       && sc->outadj->value < (sc->fixed->allocation.y + req.height))
     {
@@ -172,6 +217,7 @@ static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
 static void hildon_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
                                                    HildonScrollArea *sc)
 {
+  /* Update outer adjustment based on inner adjustment position */
   if (sc->outadj->value != sc->fixed->allocation.y + adjustment->value)
     gtk_adjustment_set_value (sc->outadj,
                              sc->fixed->allocation.y + adjustment->value);