[gnome-shell/nbtk-introduction] Fix interaction of borders/background and scrolling



commit 4b4a1be420252139a49f7fa89790b01224c386a1
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Sep 21 19:11:09 2009 -0400

    Fix interaction of borders/background and scrolling
    
    NbtkBoxLayout: Make consistent that the area scrolled and clipped
    to is the content area (excluding borders and padding.) Translate
    back appropriately when chaining up so that the parent background
    is drawn at the right place and picking on the box (if it's reactive)
    picks at the right place on the screen.
    
    clip-to-allocation is removed from NbtkScrollView since it's just
    not right - if the child has any non-moving elements, like headers or
    borders, it will need to set a narrower clip. And even if the entire
    child scrolls, we want to clip to an arrow that excludes the scrollbars.

 src/nbtk/nbtk-box-layout.c     |  121 ++++++++++++++++++++++++++++-----------
 src/nbtk/nbtk-scroll-view.c    |    3 +-
 tests/interactive/scrolling.js |   23 ++++++--
 3 files changed, 106 insertions(+), 41 deletions(-)
---
diff --git a/src/nbtk/nbtk-box-layout.c b/src/nbtk/nbtk-box-layout.c
index 86c7096..c880539 100644
--- a/src/nbtk/nbtk-box-layout.c
+++ b/src/nbtk/nbtk-box-layout.c
@@ -908,15 +908,12 @@ static void
 nbtk_box_layout_paint (ClutterActor *actor)
 {
   NbtkBoxLayoutPrivate *priv = NBTK_BOX_LAYOUT (actor)->priv;
+  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
   GList *l;
   gdouble x, y;
-  ClutterActorBox child_b;
-  ClutterActorBox box_b;
-
-  CLUTTER_ACTOR_CLASS (nbtk_box_layout_parent_class)->paint (actor);
-
-  if (priv->children == NULL)
-    return;
+  ClutterActorBox child_box;
+  ClutterActorBox allocation_box;
+  ClutterActorBox content_box;
 
   if (priv->hadjustment)
     x = nbtk_adjustment_get_value (priv->hadjustment);
@@ -928,11 +925,40 @@ nbtk_box_layout_paint (ClutterActor *actor)
   else
     y = 0;
 
-  clutter_actor_get_allocation_box (actor, &box_b);
-  box_b.x2 = (box_b.x2 - box_b.x1) + x;
-  box_b.x1 = x;
-  box_b.y2 = (box_b.y2 - box_b.y1) + y;
-  box_b.y1 = y;
+  /* If we are translated, then we need to translate back before chaining
+   * up or the background and borders will be drawn in the wrong place */
+  if (x != 0 || y != 0)
+    {
+      cogl_push_matrix ();
+      cogl_translate ((int)x, (int)y, 0);
+    }
+
+  CLUTTER_ACTOR_CLASS (nbtk_box_layout_parent_class)->paint (actor);
+
+  if (x != 0 || y != 0)
+    {
+      cogl_pop_matrix ();
+    }
+
+  if (priv->children == NULL)
+    return;
+
+  clutter_actor_get_allocation_box (actor, &allocation_box);
+  shell_theme_node_get_content_box (theme_node, &allocation_box, &content_box);
+
+  content_box.x1 += x;
+  content_box.y1 += y;
+  content_box.x2 += x;
+  content_box.y2 += y;
+
+  /* The content area forms the viewport into the scrolled contents, while
+   * the borders and background stay in place; after drawing the borders and
+   * background, we clip to the content area */
+  if (priv->hadjustment || priv->vadjustment)
+    cogl_clip_push ((int)content_box.x1,
+                    (int)content_box.y1,
+                    (int)content_box.x2 - (int)content_box.x1,
+                    (int)content_box.y2 - (int)content_box.y1);
 
   for (l = priv->children; l; l = g_list_next (l))
     {
@@ -941,16 +967,19 @@ nbtk_box_layout_paint (ClutterActor *actor)
       if (!CLUTTER_ACTOR_IS_VISIBLE (child))
         continue;
 
-      clutter_actor_get_allocation_box (child, &child_b);
+      clutter_actor_get_allocation_box (child, &child_box);
 
-      if ((child_b.x1 < box_b.x2) &&
-          (child_b.x2 > box_b.x1) &&
-          (child_b.y1 < box_b.y2) &&
-          (child_b.y2 > box_b.y1))
+      if ((child_box.x1 < content_box.x2) &&
+          (child_box.x2 > content_box.x1) &&
+          (child_box.y1 < content_box.y2) &&
+          (child_box.y2 > content_box.y1))
         {
           clutter_actor_paint (child);
         }
     }
+
+  if (priv->hadjustment || priv->vadjustment)
+    cogl_clip_pop ();
 }
 
 static void
@@ -958,15 +987,12 @@ nbtk_box_layout_pick (ClutterActor *actor,
                       const ClutterColor *color)
 {
   NbtkBoxLayoutPrivate *priv = NBTK_BOX_LAYOUT (actor)->priv;
+  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
   GList *l;
   gdouble x, y;
-  ClutterActorBox child_b;
-  ClutterActorBox box_b;
-
-  CLUTTER_ACTOR_CLASS (nbtk_box_layout_parent_class)->pick (actor, color);
-
-  if (priv->children == NULL)
-    return;
+  ClutterActorBox child_box;
+  ClutterActorBox allocation_box;
+  ClutterActorBox content_box;
 
   if (priv->hadjustment)
     x = nbtk_adjustment_get_value (priv->hadjustment);
@@ -978,11 +1004,35 @@ nbtk_box_layout_pick (ClutterActor *actor,
   else
     y = 0;
 
-  clutter_actor_get_allocation_box (actor, &box_b);
-  box_b.x2 = (box_b.x2 - box_b.x1) + x;
-  box_b.x1 = x;
-  box_b.y2 = (box_b.y2 - box_b.y1) + y;
-  box_b.y1 = y;
+  if (x != 0 || y != 0)
+    {
+      cogl_push_matrix ();
+      cogl_translate ((int)x, (int)y, 0);
+    }
+
+  CLUTTER_ACTOR_CLASS (nbtk_box_layout_parent_class)->pick (actor, color);
+
+  if (x != 0 || y != 0)
+    {
+      cogl_pop_matrix ();
+    }
+
+  if (priv->children == NULL)
+    return;
+
+  clutter_actor_get_allocation_box (actor, &allocation_box);
+  shell_theme_node_get_content_box (theme_node, &allocation_box, &content_box);
+
+  content_box.x1 += x;
+  content_box.y1 += y;
+  content_box.x2 += x;
+  content_box.y2 += y;
+
+  if (priv->hadjustment || priv->vadjustment)
+    cogl_clip_push ((int)content_box.x1,
+                    (int)content_box.y1,
+                    (int)content_box.x2 - (int)content_box.x1,
+                    (int)content_box.y2 - (int)content_box.y1);
 
   for (l = priv->children; l; l = g_list_next (l))
     {
@@ -991,16 +1041,19 @@ nbtk_box_layout_pick (ClutterActor *actor,
       if (!CLUTTER_ACTOR_IS_VISIBLE (child))
         continue;
 
-      clutter_actor_get_allocation_box (child, &child_b);
+      clutter_actor_get_allocation_box (child, &child_box);
 
-      if ((child_b.x1 < box_b.x2)
-          && (child_b.x2 > box_b.x1)
-          && (child_b.y1 < box_b.y2)
-          && (child_b.y2 > box_b.y1))
+      if ((child_box.x1 < content_box.x2) &&
+          (child_box.x2 > content_box.x1) &&
+          (child_box.y1 < content_box.y2) &&
+          (child_box.y2 > content_box.y1))
         {
           clutter_actor_paint (child);
         }
     }
+
+  if (priv->hadjustment || priv->vadjustment)
+    cogl_clip_pop ();
 }
 
 static void
diff --git a/src/nbtk/nbtk-scroll-view.c b/src/nbtk/nbtk-scroll-view.c
index f40e7a6..3a5e8ea 100644
--- a/src/nbtk/nbtk-scroll-view.c
+++ b/src/nbtk/nbtk-scroll-view.c
@@ -575,8 +575,7 @@ nbtk_scroll_view_init (NbtkScrollView *self)
 
   /* mouse scroll is enabled by default, so we also need to be reactive */
   priv->mouse_scroll = TRUE;
-  g_object_set (G_OBJECT (self), "reactive", TRUE, "clip-to-allocation", TRUE,
-                NULL);
+  g_object_set (G_OBJECT (self), "reactive", TRUE, NULL);
 }
 
 static void
diff --git a/tests/interactive/scrolling.js b/tests/interactive/scrolling.js
index c1e3d56..366d221 100644
--- a/tests/interactive/scrolling.js
+++ b/tests/interactive/scrolling.js
@@ -8,11 +8,17 @@ const UI = imports.testcommon.ui;
 UI.init();
 let stage = Clutter.Stage.get_default();
 
-let v = new Nbtk.ScrollView({});
-stage.add_actor(v);
+let vbox = new Nbtk.BoxLayout({ vertical: true,
+                                width: stage.width,
+                                height: stage.height,
+                                style: "padding: 10px;" });
+stage.add_actor(vbox);
+
+let v = new Nbtk.ScrollView();
+vbox.add(v, { expand: true });
+
 let b = new Nbtk.BoxLayout({ vertical: true,
-			     width: stage.width,
-			     height: stage.height });
+                             style: "border: 2px solid #880000; border-radius: 10px; padding: 0px 5px;" });
 v.add_actor(b);
 
 let cc_a = "a".charCodeAt(0);
@@ -20,9 +26,16 @@ let s = "";
 for (let i = 0; i < 26 * 3; i++) {
     s += String.fromCharCode(cc_a + i % 26);
 
-    let t = new Nbtk.Label({ "text": s});
+    let t = new Nbtk.Label({ text: s,
+                             reactive: true });
+    let line = i + 1;
+    t.connect('button-press-event',
+              function() {
+                  log("Click on line " + line);
+              });
     b.add(t);
 }
 
 stage.show();
 Clutter.main();
+stage.destroy();



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