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.
This commit is contained in:
parent
1a4861ec4f
commit
4b4a1be420
@ -908,15 +908,12 @@ static void
|
|||||||
nbtk_box_layout_paint (ClutterActor *actor)
|
nbtk_box_layout_paint (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
NbtkBoxLayoutPrivate *priv = NBTK_BOX_LAYOUT (actor)->priv;
|
NbtkBoxLayoutPrivate *priv = NBTK_BOX_LAYOUT (actor)->priv;
|
||||||
|
ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
|
||||||
GList *l;
|
GList *l;
|
||||||
gdouble x, y;
|
gdouble x, y;
|
||||||
ClutterActorBox child_b;
|
ClutterActorBox child_box;
|
||||||
ClutterActorBox box_b;
|
ClutterActorBox allocation_box;
|
||||||
|
ClutterActorBox content_box;
|
||||||
CLUTTER_ACTOR_CLASS (nbtk_box_layout_parent_class)->paint (actor);
|
|
||||||
|
|
||||||
if (priv->children == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->hadjustment)
|
if (priv->hadjustment)
|
||||||
x = nbtk_adjustment_get_value (priv->hadjustment);
|
x = nbtk_adjustment_get_value (priv->hadjustment);
|
||||||
@ -928,11 +925,40 @@ nbtk_box_layout_paint (ClutterActor *actor)
|
|||||||
else
|
else
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (actor, &box_b);
|
/* If we are translated, then we need to translate back before chaining
|
||||||
box_b.x2 = (box_b.x2 - box_b.x1) + x;
|
* up or the background and borders will be drawn in the wrong place */
|
||||||
box_b.x1 = x;
|
if (x != 0 || y != 0)
|
||||||
box_b.y2 = (box_b.y2 - box_b.y1) + y;
|
{
|
||||||
box_b.y1 = y;
|
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))
|
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))
|
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (child, &child_b);
|
clutter_actor_get_allocation_box (child, &child_box);
|
||||||
|
|
||||||
if ((child_b.x1 < box_b.x2) &&
|
if ((child_box.x1 < content_box.x2) &&
|
||||||
(child_b.x2 > box_b.x1) &&
|
(child_box.x2 > content_box.x1) &&
|
||||||
(child_b.y1 < box_b.y2) &&
|
(child_box.y1 < content_box.y2) &&
|
||||||
(child_b.y2 > box_b.y1))
|
(child_box.y2 > content_box.y1))
|
||||||
{
|
{
|
||||||
clutter_actor_paint (child);
|
clutter_actor_paint (child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->hadjustment || priv->vadjustment)
|
||||||
|
cogl_clip_pop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -958,15 +987,12 @@ nbtk_box_layout_pick (ClutterActor *actor,
|
|||||||
const ClutterColor *color)
|
const ClutterColor *color)
|
||||||
{
|
{
|
||||||
NbtkBoxLayoutPrivate *priv = NBTK_BOX_LAYOUT (actor)->priv;
|
NbtkBoxLayoutPrivate *priv = NBTK_BOX_LAYOUT (actor)->priv;
|
||||||
|
ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
|
||||||
GList *l;
|
GList *l;
|
||||||
gdouble x, y;
|
gdouble x, y;
|
||||||
ClutterActorBox child_b;
|
ClutterActorBox child_box;
|
||||||
ClutterActorBox box_b;
|
ClutterActorBox allocation_box;
|
||||||
|
ClutterActorBox content_box;
|
||||||
CLUTTER_ACTOR_CLASS (nbtk_box_layout_parent_class)->pick (actor, color);
|
|
||||||
|
|
||||||
if (priv->children == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->hadjustment)
|
if (priv->hadjustment)
|
||||||
x = nbtk_adjustment_get_value (priv->hadjustment);
|
x = nbtk_adjustment_get_value (priv->hadjustment);
|
||||||
@ -978,11 +1004,35 @@ nbtk_box_layout_pick (ClutterActor *actor,
|
|||||||
else
|
else
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (actor, &box_b);
|
if (x != 0 || y != 0)
|
||||||
box_b.x2 = (box_b.x2 - box_b.x1) + x;
|
{
|
||||||
box_b.x1 = x;
|
cogl_push_matrix ();
|
||||||
box_b.y2 = (box_b.y2 - box_b.y1) + y;
|
cogl_translate ((int)x, (int)y, 0);
|
||||||
box_b.y1 = y;
|
}
|
||||||
|
|
||||||
|
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))
|
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))
|
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (child, &child_b);
|
clutter_actor_get_allocation_box (child, &child_box);
|
||||||
|
|
||||||
if ((child_b.x1 < box_b.x2)
|
if ((child_box.x1 < content_box.x2) &&
|
||||||
&& (child_b.x2 > box_b.x1)
|
(child_box.x2 > content_box.x1) &&
|
||||||
&& (child_b.y1 < box_b.y2)
|
(child_box.y1 < content_box.y2) &&
|
||||||
&& (child_b.y2 > box_b.y1))
|
(child_box.y2 > content_box.y1))
|
||||||
{
|
{
|
||||||
clutter_actor_paint (child);
|
clutter_actor_paint (child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->hadjustment || priv->vadjustment)
|
||||||
|
cogl_clip_pop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -575,8 +575,7 @@ nbtk_scroll_view_init (NbtkScrollView *self)
|
|||||||
|
|
||||||
/* mouse scroll is enabled by default, so we also need to be reactive */
|
/* mouse scroll is enabled by default, so we also need to be reactive */
|
||||||
priv->mouse_scroll = TRUE;
|
priv->mouse_scroll = TRUE;
|
||||||
g_object_set (G_OBJECT (self), "reactive", TRUE, "clip-to-allocation", TRUE,
|
g_object_set (G_OBJECT (self), "reactive", TRUE, NULL);
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -8,11 +8,17 @@ const UI = imports.testcommon.ui;
|
|||||||
UI.init();
|
UI.init();
|
||||||
let stage = Clutter.Stage.get_default();
|
let stage = Clutter.Stage.get_default();
|
||||||
|
|
||||||
let v = new Nbtk.ScrollView({});
|
let vbox = new Nbtk.BoxLayout({ vertical: true,
|
||||||
stage.add_actor(v);
|
|
||||||
let b = new Nbtk.BoxLayout({ vertical: true,
|
|
||||||
width: stage.width,
|
width: stage.width,
|
||||||
height: stage.height });
|
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,
|
||||||
|
style: "border: 2px solid #880000; border-radius: 10px; padding: 0px 5px;" });
|
||||||
v.add_actor(b);
|
v.add_actor(b);
|
||||||
|
|
||||||
let cc_a = "a".charCodeAt(0);
|
let cc_a = "a".charCodeAt(0);
|
||||||
@ -20,9 +26,16 @@ let s = "";
|
|||||||
for (let i = 0; i < 26 * 3; i++) {
|
for (let i = 0; i < 26 * 3; i++) {
|
||||||
s += String.fromCharCode(cc_a + i % 26);
|
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);
|
b.add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
stage.show();
|
stage.show();
|
||||||
Clutter.main();
|
Clutter.main();
|
||||||
|
stage.destroy();
|
||||||
|
Loading…
Reference in New Issue
Block a user