Fl_Scroll x/yposition and scroll_to confusion

17 views
Skip to first unread message

Mo_Al_

unread,
Jan 26, 2023, 3:51:23 AM1/26/23
to fltk.coredev
Hello

It seems Fl_Scroll takes into account the position of the topmost leftmost widget among its children, where the docs state:
```
Fl_Scroll scroll (10,10,200,200);
Fl_Box b1 ( 10, 10,50,50,"b1"); // relative (x,y) = (0,0)
Fl_Box b2 ( 60, 60,50,50,"b2"); // relative (x,y) = (50,50)
Fl_Box b3 ( 60,110,50,50,"b3"); // relative (x,y) = (50,100)
```

a modified example from the docs:
```
#include <FL/Fl.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>

void btn_cb(Fl_Widget *w, void *data) {
auto s = (Fl_Scroll*)data;
s->scroll_to(0, 0);
}

int main() {
Fl_Window win(400, 300);
Fl_Scroll s(0, 0, 400, 300);
Fl_Button b1(10, 10, 30, 30, "B1");
Fl_Button b2(60, 60, 30, 30, "B2");
Fl_Button b3(60, 110, 30, 30, "B3");
s.end();
win.end();
win.show();
b3.callback(btn_cb, &s);
return Fl::run();
}
```

This makes the relative position of b1 (following the docs) be (10, 10), but using s.scroll_to(0, 0), actually appears to scroll to 10, 10, making the the first button appear at position 0, 0 of the window. To get the initial appearance, one would need to s.scroll_to(-10, -10).
I could be misunderstanding the docs, or is the position of the topleft-most widget the reference for the Fl_Scroll?


Mo_Al_

unread,
Jan 26, 2023, 3:58:38 AM1/26/23
to fltk.coredev
Sorry for posting this here, I meant to post it in fltk-general

Albrecht Schlosser

unread,
Jan 27, 2023, 4:03:04 PM1/27/23
to fltkc...@googlegroups.com
On 1/26/23 09:51 Mo_Al_ wrote:
> It seems Fl_Scroll takes into account the position of the topmost
> leftmost widget among its children, where the docs state:
> ```
> Fl_Scroll scroll (10,10,200,200);
> Fl_Box b1 ( 10, 10,50,50,"b1"); // relative (x,y) = (0,0)
> Fl_Box b2 ( 60, 60,50,50,"b2"); // relative (x,y) = (50,50)
> Fl_Box b3 ( 60,110,50,50,"b3"); // relative (x,y) = (50,100)
> ```

It's a fact that the scrollbars of Fl_Scroll consider the bounding box
of all children for their positioning. I admit that this can be confusing.

> a modified example from the docs:
> ```
> ...
> void btn_cb(Fl_Widget *w, void *data) {
> auto s = (Fl_Scroll*)data;
> s->scroll_to(0, 0);
> }
>
> int main() {
> ...
> return Fl::run();
> }
> ```
>
> This makes the relative position of b1 (following the docs) be (10,
> 10), but using s.scroll_to(0, 0), actually appears to scroll to 10,
> 10, making the the first button appear at position 0, 0 of the window.
> To get the initial appearance, one would need to s.scroll_to(-10, -10).

I never thought of using s->scroll_to(0, 0); like in your example to
position the scrollbars as you did.

The docs state: "The Fl_Scroll widget calculates the bounding box of all
its children by using their widget positions and sizes (x, y, w, h).
Outside labels are not considered. If you need outside labels of any
widgets or free space outside of this bounding box you can add a tiny
invisible Fl_Box at the relevant corner(s) of the Fl_Scroll widget,..."

See https://www.fltk.org/doc-1.4/classFl__Scroll.html

> I could be misunderstanding the docs, or is the position of the
> topleft-most widget the reference for the Fl_Scroll?

More or less, yes. The bounding box of all children determines the width
and height of the contents, and that's what the scrollbars control. The
description cited above gives a hint that you can position an invisible
box at the top left (or any other corner) if you want to extend the
contents of the widget to include spacing around the widgets.

I'm not sure if we can clarify this even more in the docs without
confusing people even more. But maybe we could?

Mo_Al_

unread,
Jan 27, 2023, 4:30:31 PM1/27/23
to fltk.coredev
Thanks Albrecht

I think the confusion arises mostly from the example of the docs having the Fl_Scroll and the topmost leftmost widget having the same x, y coordinates.
Maybe changing the example to:

Fl_Scroll scroll (0, 0,200,200);
Fl_Box b1 ( 10, 10,50,50,"b1"); // relative (x,y) = (0,0)
Fl_Box b2 ( 60, 60,50,50,"b2"); // relative (x,y) = (50,50)
Fl_Box b3 ( 60,110,50,50,"b3"); // relative (x,y) = (50,100)

This would probably make it more apparent that to scroll to the origin of the Fl_Scroll, you would need to pass (-10, -10).
Reply all
Reply to author
Forward
0 new messages