* src/widget/Makefile.am, src/maemo/Makefile.am:
authorJose Dapena Paz <jdapena@igalia.com>
Mon, 3 Dec 2007 17:36:28 +0000 (17:36 +0000)
committerJose Dapena Paz <jdapena@igalia.com>
Mon, 3 Dec 2007 17:36:28 +0000 (17:36 +0000)
        * Now modest-scroll-area is in widgets instead of maemo.
* Moved src/maemo/modest-scroll-area.[ch] to
  src/widgets/modest-scroll-area.[ch].

pmo-trunk-r3857

src/maemo/Makefile.am
src/maemo/modest-scroll-area.c [deleted file]
src/maemo/modest-scroll-area.h [deleted file]
src/widgets/Makefile.am
src/widgets/modest-scroll-area.c [new file with mode: 0644]
src/widgets/modest-scroll-area.h [new file with mode: 0644]

index 5993b02..e8b4e2b 100644 (file)
@@ -61,8 +61,6 @@ libmodest_ui_la_SOURCES=              \
        modest-platform.c             \
        modest-signature-editor-dialog.c         \
        modest-signature-editor-dialog.h         \
-       modest-scroll-area.h          \
-       modest-scroll-area.c          \
        modest-msg-view-window.c      \
        modest-msg-edit-window.c      \
        modest-maemo-utils.c          \
diff --git a/src/maemo/modest-scroll-area.c b/src/maemo/modest-scroll-area.c
deleted file mode 100644 (file)
index 90bfb20..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/* Copyright (c) 2007, Nokia Corporation
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * * Neither the name of the Nokia Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * SECTION:modest-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 "modest-scroll-area.h"
-#include <gtk/gtkscrolledwindow.h>
-#include <gtk/gtkfixed.h>
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtkwidget.h>
-#include <string.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;
-
-} ModestScrollArea;
-
-
-static void modest_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
-                                                   ModestScrollArea *sc);
-static void modest_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
-                                                   ModestScrollArea *sc);
-static void modest_scroll_area_size_allocate (GtkWidget *widget,
-                                             GtkAllocation *allocation,
-                                             ModestScrollArea *sc);
-static void modest_scroll_area_child_requisition (GtkWidget *widget,
-                                                 GtkRequisition *req,
-                                                 ModestScrollArea *sc);
-static void modest_scroll_area_fixed_allocate (GtkWidget *widget,
-                                              GtkAllocation *allocation,
-                                              ModestScrollArea *sc);
-
-static int calculate_size (GtkWidget *widget);
-
-/**
- * modest_scroll_area_new:
- * @sw: #GtkWidget - #GtkScrolledWindow
- * @child: #GtkWidget - child to be place inside 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)
- * and eg. couple buttons.  Normaly @GtkScrolledWindow can not handle
- * the situation so that the @GtkTreeView built-in support
- * would work.  The scroll area is connecting this built-in system to
- * the scrolled window and also noticing the buttons.  To use, one should
- * create a box to which pack the buttons and the scroll area.
- * The scroll area then contains the problematic widget eg. the @GtkTreeView.
- * Then the box should be placed in the @GtkScrolledWindow.
- * The function is currently assuming that the newly created scroll area
- * hierarchy is not modified in anyway.  Or if it is, it may lead to
- * unwanted problems.  Also assumed, that the @child will be packed
- * to the @sw.
- *
- * Returns: a @GtkFixed
- */
-GtkWidget *
-modest_scroll_area_new (GtkWidget *sw, GtkWidget *child)
-{
-       GtkWidget *swi;
-       GtkWidget *fixed;
-       ModestScrollArea *sc;
-
-       g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (sw)
-                             && GTK_IS_WIDGET (child), NULL);
-
-       swi = gtk_scrolled_window_new (NULL, NULL);
-       fixed = gtk_fixed_new ();
-       sc = g_malloc (sizeof (ModestScrollArea));
-       memset (sc, 0, sizeof (ModestScrollArea));
-
-       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swi),
-                                       GTK_POLICY_NEVER, GTK_POLICY_NEVER);
-
-       gtk_container_add (GTK_CONTAINER (swi), child);
-       gtk_fixed_put (GTK_FIXED (fixed), swi, 0, 0);
-
-       sc->fixed = fixed;
-       sc->swouter = sw;
-       sc->swinner = swi;
-       sc->child = child;
-       sc->outadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw));
-       sc->inadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (swi));
-
-       g_signal_connect_after (G_OBJECT (child), "size-request",
-                               G_CALLBACK (modest_scroll_area_child_requisition), sc);
-
-       g_signal_connect_after (G_OBJECT (sc->outadj), "value_changed",
-                               G_CALLBACK (modest_scroll_area_outer_value_changed), sc);
-       g_signal_connect_after (G_OBJECT (sc->inadj), "value_changed",
-                               G_CALLBACK (modest_scroll_area_inner_value_changed), sc);
-
-       g_signal_connect_after (G_OBJECT (sw), "size-allocate",
-                               G_CALLBACK (modest_scroll_area_size_allocate), sc);
-       g_signal_connect (G_OBJECT (sc->fixed), "size-allocate",
-                         G_CALLBACK (modest_scroll_area_fixed_allocate), sc);
-       g_signal_connect_swapped (G_OBJECT (sw), "destroy",
-                                 G_CALLBACK (g_free), sc);
-
-       gtk_widget_show_all (sw);
-
-       gtk_widget_set_redraw_on_allocate (GTK_WIDGET(sc->fixed), FALSE);
-       gtk_widget_set_redraw_on_allocate (GTK_WIDGET(sw), FALSE);
-       gtk_widget_set_redraw_on_allocate (GTK_WIDGET(child), FALSE);
-       return fixed;
-}
-
-static void 
-modest_scroll_area_fixed_allocate (GtkWidget *widget,
-                                  GtkAllocation *allocation,
-                                  ModestScrollArea *sc)
-{
-       gtk_widget_set_size_request (sc->swinner, -1,
-                                    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 *tmp = NULL;
-               GList *children = gtk_container_get_children (GTK_CONTAINER (widget));
-               for (tmp = children; tmp != NULL; tmp = g_list_next (tmp)) {
-                       GtkWidget *wid = GTK_WIDGET (tmp->data);
-                       gint sz = calculate_size (wid);
-                       if ((GTK_WIDGET_VISIBLE (wid))) {
-                               size += sz;
-                       }
-               }
-               g_list_free (children);
-       } else { 
-               size = widget->allocation.height;
-       }
-       
-       return size;
-}
-
-static void 
-modest_scroll_area_child_requisition (GtkWidget *widget,
-                                     GtkRequisition *req,
-                                     ModestScrollArea *sc)
-{
-       /* Limit height to fixed height */
-       gint new_req = MAX (req->height, sc->fixed->allocation.height);
-       gint adjust_factor = calculate_size (sc->swouter) * 0.7;
-  
-       adjust_factor = MAX (0, adjust_factor - sc->outadj->value);
-       new_req = MIN (sc->outadj->page_size - adjust_factor, new_req);
-       
-       /* FIXME: hack, to provent gtk criticals */
-       if (new_req < -1)
-               new_req = -1;
-               
-       gtk_widget_set_size_request (sc->fixed, -1, req->height);
-       /* Request inner scrolled window at most page size */
-       gtk_widget_set_size_request (sc->swinner, -1, new_req);
-}
-
-static void 
-modest_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
-                                       ModestScrollArea *sc)
-{
-       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))
-       {
-               gdouble new_pos = 0;
-
-               new_pos = MAX (sc->outadj->value - sc->fixed->allocation.y, 0);
-               new_pos = MIN (new_pos, req.height - sc->inadj->page_size);
-               new_pos = MAX (new_pos, 0);
-
-               gtk_fixed_move (GTK_FIXED (sc->fixed), sc->swinner, 0, new_pos);
-               gtk_adjustment_set_value (sc->inadj, new_pos);
-       }
-}
-
-static void 
-modest_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
-                                                   ModestScrollArea *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);
-}
-
-__inline__ static gint 
-calculate_width (ModestScrollArea *sc)
-{
-       GtkScrolledWindow *scwin = GTK_SCROLLED_WINDOW (sc->swouter);
-       return (scwin->hscrollbar_visible * scwin->hscrollbar->allocation.width);
-}
-
-static void 
-modest_scroll_area_size_allocate (GtkWidget *widget,
-                                 GtkAllocation *allocation,
-                                 ModestScrollArea *sc)
-{
-       g_return_if_fail (widget);
-       g_return_if_fail (allocation);
-       g_return_if_fail (sc);
-
-       gtk_widget_set_size_request (sc->fixed, calculate_width (sc), 
-                                    sc->fixed->allocation.height);
-       gtk_widget_set_size_request (sc->child, 
-                                    sc->fixed->allocation.width, -1);
-}
diff --git a/src/maemo/modest-scroll-area.h b/src/maemo/modest-scroll-area.h
deleted file mode 100644 (file)
index 8fb044a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2007, Nokia Corporation
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * * Neither the name of the Nokia Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * The reason why this is not made as a widget:
- *  We can not create a widget which could return the correct child.
- *  (ie. by gtk_bin_get_child)
- */
-
-#ifndef __MODEST_SCROLL_AREA_H__
-#define __MODEST_SCROLL_AREA_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-    GtkWidget * modest_scroll_area_new(GtkWidget * sw, GtkWidget * child);
-
-G_END_DECLS
-#endif /* __MODEST_SCROLL_AREA_H__ */
index f332e03..3975a21 100644 (file)
@@ -69,6 +69,8 @@ libmodest_widgets_la_SOURCES=          \
        modest-recpt-view.h            \
        modest-retrieve-combo-box.h    \
        modest-retrieve-combo-box.c    \
+       modest-scroll-area.h          \
+       modest-scroll-area.c          \
        modest-scroll-text.c           \
        modest-scroll-text.h           \
        modest-serversecurity-combo-box.h modest-serversecurity-combo-box.c \
diff --git a/src/widgets/modest-scroll-area.c b/src/widgets/modest-scroll-area.c
new file mode 100644 (file)
index 0000000..90bfb20
--- /dev/null
@@ -0,0 +1,268 @@
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * SECTION:modest-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 "modest-scroll-area.h"
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkfixed.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
+#include <string.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;
+
+} ModestScrollArea;
+
+
+static void modest_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
+                                                   ModestScrollArea *sc);
+static void modest_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
+                                                   ModestScrollArea *sc);
+static void modest_scroll_area_size_allocate (GtkWidget *widget,
+                                             GtkAllocation *allocation,
+                                             ModestScrollArea *sc);
+static void modest_scroll_area_child_requisition (GtkWidget *widget,
+                                                 GtkRequisition *req,
+                                                 ModestScrollArea *sc);
+static void modest_scroll_area_fixed_allocate (GtkWidget *widget,
+                                              GtkAllocation *allocation,
+                                              ModestScrollArea *sc);
+
+static int calculate_size (GtkWidget *widget);
+
+/**
+ * modest_scroll_area_new:
+ * @sw: #GtkWidget - #GtkScrolledWindow
+ * @child: #GtkWidget - child to be place inside 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)
+ * and eg. couple buttons.  Normaly @GtkScrolledWindow can not handle
+ * the situation so that the @GtkTreeView built-in support
+ * would work.  The scroll area is connecting this built-in system to
+ * the scrolled window and also noticing the buttons.  To use, one should
+ * create a box to which pack the buttons and the scroll area.
+ * The scroll area then contains the problematic widget eg. the @GtkTreeView.
+ * Then the box should be placed in the @GtkScrolledWindow.
+ * The function is currently assuming that the newly created scroll area
+ * hierarchy is not modified in anyway.  Or if it is, it may lead to
+ * unwanted problems.  Also assumed, that the @child will be packed
+ * to the @sw.
+ *
+ * Returns: a @GtkFixed
+ */
+GtkWidget *
+modest_scroll_area_new (GtkWidget *sw, GtkWidget *child)
+{
+       GtkWidget *swi;
+       GtkWidget *fixed;
+       ModestScrollArea *sc;
+
+       g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (sw)
+                             && GTK_IS_WIDGET (child), NULL);
+
+       swi = gtk_scrolled_window_new (NULL, NULL);
+       fixed = gtk_fixed_new ();
+       sc = g_malloc (sizeof (ModestScrollArea));
+       memset (sc, 0, sizeof (ModestScrollArea));
+
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swi),
+                                       GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+
+       gtk_container_add (GTK_CONTAINER (swi), child);
+       gtk_fixed_put (GTK_FIXED (fixed), swi, 0, 0);
+
+       sc->fixed = fixed;
+       sc->swouter = sw;
+       sc->swinner = swi;
+       sc->child = child;
+       sc->outadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw));
+       sc->inadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (swi));
+
+       g_signal_connect_after (G_OBJECT (child), "size-request",
+                               G_CALLBACK (modest_scroll_area_child_requisition), sc);
+
+       g_signal_connect_after (G_OBJECT (sc->outadj), "value_changed",
+                               G_CALLBACK (modest_scroll_area_outer_value_changed), sc);
+       g_signal_connect_after (G_OBJECT (sc->inadj), "value_changed",
+                               G_CALLBACK (modest_scroll_area_inner_value_changed), sc);
+
+       g_signal_connect_after (G_OBJECT (sw), "size-allocate",
+                               G_CALLBACK (modest_scroll_area_size_allocate), sc);
+       g_signal_connect (G_OBJECT (sc->fixed), "size-allocate",
+                         G_CALLBACK (modest_scroll_area_fixed_allocate), sc);
+       g_signal_connect_swapped (G_OBJECT (sw), "destroy",
+                                 G_CALLBACK (g_free), sc);
+
+       gtk_widget_show_all (sw);
+
+       gtk_widget_set_redraw_on_allocate (GTK_WIDGET(sc->fixed), FALSE);
+       gtk_widget_set_redraw_on_allocate (GTK_WIDGET(sw), FALSE);
+       gtk_widget_set_redraw_on_allocate (GTK_WIDGET(child), FALSE);
+       return fixed;
+}
+
+static void 
+modest_scroll_area_fixed_allocate (GtkWidget *widget,
+                                  GtkAllocation *allocation,
+                                  ModestScrollArea *sc)
+{
+       gtk_widget_set_size_request (sc->swinner, -1,
+                                    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 *tmp = NULL;
+               GList *children = gtk_container_get_children (GTK_CONTAINER (widget));
+               for (tmp = children; tmp != NULL; tmp = g_list_next (tmp)) {
+                       GtkWidget *wid = GTK_WIDGET (tmp->data);
+                       gint sz = calculate_size (wid);
+                       if ((GTK_WIDGET_VISIBLE (wid))) {
+                               size += sz;
+                       }
+               }
+               g_list_free (children);
+       } else { 
+               size = widget->allocation.height;
+       }
+       
+       return size;
+}
+
+static void 
+modest_scroll_area_child_requisition (GtkWidget *widget,
+                                     GtkRequisition *req,
+                                     ModestScrollArea *sc)
+{
+       /* Limit height to fixed height */
+       gint new_req = MAX (req->height, sc->fixed->allocation.height);
+       gint adjust_factor = calculate_size (sc->swouter) * 0.7;
+  
+       adjust_factor = MAX (0, adjust_factor - sc->outadj->value);
+       new_req = MIN (sc->outadj->page_size - adjust_factor, new_req);
+       
+       /* FIXME: hack, to provent gtk criticals */
+       if (new_req < -1)
+               new_req = -1;
+               
+       gtk_widget_set_size_request (sc->fixed, -1, req->height);
+       /* Request inner scrolled window at most page size */
+       gtk_widget_set_size_request (sc->swinner, -1, new_req);
+}
+
+static void 
+modest_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
+                                       ModestScrollArea *sc)
+{
+       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))
+       {
+               gdouble new_pos = 0;
+
+               new_pos = MAX (sc->outadj->value - sc->fixed->allocation.y, 0);
+               new_pos = MIN (new_pos, req.height - sc->inadj->page_size);
+               new_pos = MAX (new_pos, 0);
+
+               gtk_fixed_move (GTK_FIXED (sc->fixed), sc->swinner, 0, new_pos);
+               gtk_adjustment_set_value (sc->inadj, new_pos);
+       }
+}
+
+static void 
+modest_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
+                                                   ModestScrollArea *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);
+}
+
+__inline__ static gint 
+calculate_width (ModestScrollArea *sc)
+{
+       GtkScrolledWindow *scwin = GTK_SCROLLED_WINDOW (sc->swouter);
+       return (scwin->hscrollbar_visible * scwin->hscrollbar->allocation.width);
+}
+
+static void 
+modest_scroll_area_size_allocate (GtkWidget *widget,
+                                 GtkAllocation *allocation,
+                                 ModestScrollArea *sc)
+{
+       g_return_if_fail (widget);
+       g_return_if_fail (allocation);
+       g_return_if_fail (sc);
+
+       gtk_widget_set_size_request (sc->fixed, calculate_width (sc), 
+                                    sc->fixed->allocation.height);
+       gtk_widget_set_size_request (sc->child, 
+                                    sc->fixed->allocation.width, -1);
+}
diff --git a/src/widgets/modest-scroll-area.h b/src/widgets/modest-scroll-area.h
new file mode 100644 (file)
index 0000000..8fb044a
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * The reason why this is not made as a widget:
+ *  We can not create a widget which could return the correct child.
+ *  (ie. by gtk_bin_get_child)
+ */
+
+#ifndef __MODEST_SCROLL_AREA_H__
+#define __MODEST_SCROLL_AREA_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+    GtkWidget * modest_scroll_area_new(GtkWidget * sw, GtkWidget * child);
+
+G_END_DECLS
+#endif /* __MODEST_SCROLL_AREA_H__ */