[gtk+/wip/im-osk-position: 6/6] scrolledwindow: Handle ::request/unset-clear-area calls from children



commit bee92a0fc7f7744d9c8c7bc17de6f7a6ff3f542f
Author: Carlos Garnacho <carlos lanedo com>
Date:   Wed Jun 27 15:52:28 2012 +0200

    scrolledwindow: Handle ::request/unset-clear-area calls from children
    
    If the focus area is covered by the area to be cleared, update the
    vertical adjustment to keep the focus area visible.

 gtk/gtkscrolledwindow.c |   76 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 75 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 71a68c2..bacc78f 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -175,6 +175,7 @@ struct _GtkScrolledWindowPrivate
 
   gdouble                unclamped_hadj_value;
   gdouble                unclamped_vadj_value;
+  gdouble                clear_area_dy;
 };
 
 typedef struct
@@ -282,6 +283,13 @@ static gboolean _gtk_scrolled_window_set_adjustment_value      (GtkScrolledWindo
                                                                 gdouble            value,
                                                                 gboolean           allow_overshooting,
                                                                 gboolean           snap_to_border);
+static gboolean gtk_scrolled_window_request_clear_area (GtkWidget             *widget,
+                                                        cairo_rectangle_int_t *clear_area,
+                                                        cairo_rectangle_int_t *cursor_area,
+                                                        gpointer               user_data);
+static gboolean gtk_scrolled_window_unset_clear_area   (GtkWidget             *widget,
+                                                        gboolean               snap_back,
+                                                        gpointer               user_data);
 
 static guint signals[LAST_SIGNAL] = {0};
 
@@ -593,9 +601,17 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
   gtk_scrolled_window_update_real_placement (scrolled_window);
   priv->min_content_width = -1;
   priv->min_content_height = -1;
+  priv->clear_area_dy = 0;
 
   gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
   gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);
+
+  g_signal_connect (scrolled_window, "request-clear-area",
+                    G_CALLBACK (gtk_scrolled_window_request_clear_area),
+                    NULL);
+  g_signal_connect (scrolled_window, "unset-clear-area",
+                    G_CALLBACK (gtk_scrolled_window_unset_clear_area),
+                    NULL);
 }
 
 /**
@@ -2379,7 +2395,11 @@ _gtk_scrolled_window_set_adjustment_value (GtkScrolledWindow *scrolled_window,
   if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)))
     prev_value = &priv->unclamped_hadj_value;
   else if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)))
-    prev_value = &priv->unclamped_vadj_value;
+    {
+      if (!snap_to_border)
+        upper += priv->clear_area_dy;
+      prev_value = &priv->unclamped_vadj_value;
+    }
   else
     return FALSE;
 
@@ -3476,6 +3496,60 @@ gtk_scrolled_window_grab_notify (GtkWidget *widget,
     }
 }
 
+static gboolean
+gtk_scrolled_window_request_clear_area (GtkWidget             *widget,
+					cairo_rectangle_int_t *cursor_area,
+					cairo_rectangle_int_t *clear_area,
+					gpointer               user_data)
+{
+  GtkScrolledWindowPrivate *priv;
+  GtkAdjustment *adjustment;
+  gdouble value;
+
+  priv = GTK_SCROLLED_WINDOW (widget)->priv;
+  adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
+  value = priv->unclamped_vadj_value;
+
+  priv->clear_area_dy = cursor_area->y + cursor_area->height - clear_area->y;
+  value = priv->unclamped_vadj_value + priv->clear_area_dy;
+  _gtk_scrolled_window_set_adjustment_value (GTK_SCROLLED_WINDOW (widget),
+                                             adjustment, value,
+                                             FALSE, FALSE);
+
+  return TRUE;
+}
+
+static gboolean
+gtk_scrolled_window_unset_clear_area (GtkWidget *widget,
+                                      gboolean   snap_back,
+                                      gpointer   user_data)
+{
+  GtkScrolledWindowPrivate *priv;
+
+  priv = GTK_SCROLLED_WINDOW (widget)->priv;
+
+  if (priv->clear_area_dy != 0)
+    {
+      if (snap_back)
+        {
+          GtkAdjustment *adjustment;
+          gdouble value;
+
+          adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
+          value = priv->unclamped_vadj_value - priv->clear_area_dy;
+          _gtk_scrolled_window_set_adjustment_value (GTK_SCROLLED_WINDOW (widget),
+                                                     adjustment, value,
+                                                     FALSE, FALSE);
+        }
+
+      priv->clear_area_dy = 0;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
 /**
  * gtk_scrolled_window_get_min_content_width:
  * @scrolled_window: a #GtkScrolledWindow



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]