Skip to main content
Participating Frequently
February 8, 2016
Answered

Scrollable panel gets truncated

  • February 8, 2016
  • 3 replies
  • 1634 views

I am trying to add a scrollbar to one of my panels (something I have tried for many years unsuccessfully).

I stumbled across Peter Kahrel's ScriptUI documentation and he has the following working code

var w = new Window('dialog');

w.maximumSize.height = 300;

var panel = w.add ('panel {alignChildren: "left"}');

var scrollGroup = panel.add ('group {orientation: "column"}');

for (var i = 0; i <= 35; i++) {

scrollGroup.add ('statictext', undefined, 'Label ' + i);

}

var scrollBar = panel.add ('scrollbar {stepdelta: 20}');

// Move the whole scroll group up or down

scrollBar.onChanging = function () {

scrollGroup.location.y = -1 * this.value;

}

w.onShow = function() {

// Set various sizes and locations when the window is drawn

panel.size.height = w.size.height-20;

scrollBar.size.height = w.size.height-40;

scrollBar.size.width = 20;

scrollBar.location = [panel.size.width-30, 8];

scrollBar.maxvalue = scrollGroup.size.height - panel.size.height + 15;

};

w.show();

my problem is, if I add more rows by changing line 05 to this

     for (var i = 0; i <= 300; i++) {

when I scroll the panel it gets to around 35 elements and then there is just blank area in the panel beyond that row.

Anybody good with this stuff, it is something I have needed to do for a long time but adobe's documentation really sucks.

This topic has been closed for replies.
Correct answer UQg

This seems to work.
It's a bit faster than doing the loop directly in Peter's code (basically it changes the step to something bigger),

but i don't know what it would give with items more complicated than a statictext.

And it is assuming same height for all items...

var w = new Window('dialog');

w.maximumSize.height = 300;

var panel = w.add ('panel {alignChildren: "left"}');

var scrollGroup = panel.add('group {orientation: "column", alignChildren: "left", spacing: 5}');

var numItems = 500;

var itemHeight, scrollGroupActualHeight;

for (var i = 0; i < numItems; i++) {

    scrollGroup.add('statictext', undefined, 'Label ' + i);

    };

var scrollBar = panel.add('scrollbar {stepdelta: 1}');

scrollBar.onChanging = function () {

    var children = scrollGroup.children;

    var n;

    for (n=0; n<numItems; n++){

        children.location.y = (n-this.value)*itemHeight;

        };

    };

//============================================

w.onShow = function() {

    // Set various sizes and locations when the window is drawn

    panel.size.height = w.size.height-20;

    scrollBar.size.height = w.size.height-40;

    scrollBar.size.width = 20;

    scrollBar.location = [panel.size.width-30, 8];

  

    itemHeight = scrollGroup.children[0].size[1]+scrollGroup.spacing;

    scrollGroupActualHeight = panel.size[1] - panel.margins[1] - panel.margins[3];        // scrollGroup.size[1] is at the max value

  

    scrollBar.maxvalue = Math.ceil(numItems-(scrollGroupActualHeight/itemHeight));

    };

w.show();

3 replies

Participating Frequently
February 9, 2016

Awesome, thanks UGq! (I never would have figured that out on my own...well maybe but it would have taken months)

UQg
UQgCorrect answer
Legend
February 8, 2016

This seems to work.
It's a bit faster than doing the loop directly in Peter's code (basically it changes the step to something bigger),

but i don't know what it would give with items more complicated than a statictext.

And it is assuming same height for all items...

var w = new Window('dialog');

w.maximumSize.height = 300;

var panel = w.add ('panel {alignChildren: "left"}');

var scrollGroup = panel.add('group {orientation: "column", alignChildren: "left", spacing: 5}');

var numItems = 500;

var itemHeight, scrollGroupActualHeight;

for (var i = 0; i < numItems; i++) {

    scrollGroup.add('statictext', undefined, 'Label ' + i);

    };

var scrollBar = panel.add('scrollbar {stepdelta: 1}');

scrollBar.onChanging = function () {

    var children = scrollGroup.children;

    var n;

    for (n=0; n<numItems; n++){

        children.location.y = (n-this.value)*itemHeight;

        };

    };

//============================================

w.onShow = function() {

    // Set various sizes and locations when the window is drawn

    panel.size.height = w.size.height-20;

    scrollBar.size.height = w.size.height-40;

    scrollBar.size.width = 20;

    scrollBar.location = [panel.size.width-30, 8];

  

    itemHeight = scrollGroup.children[0].size[1]+scrollGroup.spacing;

    scrollGroupActualHeight = panel.size[1] - panel.margins[1] - panel.margins[3];        // scrollGroup.size[1] is at the max value

  

    scrollBar.maxvalue = Math.ceil(numItems-(scrollGroupActualHeight/itemHeight));

    };

w.show();

Participating Frequently
March 7, 2016

So I finally got around to playing with this code.  I tried adding more content per row; when I scroll the bar, only the first 2 rows scroll.

I am probably doing somethinbg stupid, if anybody could figure out what boneheaded thing I did would be awesome.

var w = new Window('dialog');  

w.maximumSize.height = 300;  

var panel = w.add ('panel {alignChildren: "left"}');  

var scrollGroup = panel.add('group {orientation: "column", alignChildren: "left", spacing: 5}'); 

var numItems = 50; 

var itemHeight, scrollGroupActualHeight; 

var maxCol  = 3;

var row;

for (var i = 0; i < numItems; i++) { 

    var col = (i%maxCol);

    if(!col){

        row =  scrollGroup.add('group', undefined);  

          row.orientation = 'row';

              row.alignChildren= ['left', 'top'];

    }

    var r = row.add('group', undefined);  

    r.orientation = 'column';

    r.add('statictext', undefined, i);

    r.add('statictext', undefined, 'rerun');

}

var scrollBar = panel.add('scrollbar {stepdelta: 1}');  

scrollBar.onChanging = function () { 

    var children = scrollGroup.children; 

    var n; 

    for (n=0; n<(numItems % maxCol); n++){ 

        children.location.y = (n-this.value)*itemHeight; 

    }; 

}; 

//============================================ 

w.onShow = function() {  

// Set various sizes and locations when the window is drawn  

panel.size.height = w.size.height-20;  

scrollBar.size.height = w.size.height-40;  

scrollBar.size.width = 20; 

scrollBar.location = [panel.size.width-30, 8]; 

itemHeight = scrollGroup.children[0].size[1]+scrollGroup.spacing; 

scrollGroupActualHeight = panel.size[1] - panel.margins[1] - panel.margins[3];        // scrollGroup.size[1] is at the max value 

scrollBar.maxvalue = Math.ceil(numItems-(scrollGroupActualHeight/itemHeight)); 

};  

w.show(); 

UQg
Legend
March 7, 2016

It's the numItems % maxCol in the loop upper bound. It should be scrollGroup.children.length (if i'm not mistaken, that would be Math.ceil(numItems/maxCol))

Xavier.

UQg
Legend
February 8, 2016

Groups have a maximum size, so that children that fall out of the group bounds are never seen, even if you move the group.

It should work if you move the children individually in a loop (I made a quick try with 350 static texts, it works but... it's slow. Might be improved).