Scrolling to selected value after showvariables

I have a long Text List Object. I am programatically updating the selected row, and then calling “showvariables”.

This has the effect of selecting the correct item. However, the item’s usually a long way down the list, so I’d need to scroll through the whole list to be able to see what’s selected. How can I bring the selected item into view? I’d have thought that “showvariables” would have done this, but it doesn’t (although it does highlight the item).



The method I use first requires that you name the Text List Object (in the example below I have named it simply “theList”). My example is using theSelectedItem as the name of the variable containing the newly selected list item that you would be using with the showvariables (substitute your variable name for this). Once a new item is set and selected we can force the list to scroll to that item with this sample code:

local theListItems,theRow
objectaction "theList","GetList",theListItems
theRow=arraysearch(theListItems, theSelectedItem, 1, cr())
objectaction "theList","scrolltorow",theRow

We are first getting the current contents of the entire list and then searching where the selected item is in the list. Finally we force the list to scroll to that row.

1 Like

Ah, that is brilliant, thank you! Works perfectly… And much simpler than the workaround I’d done (e.g. re-sorting the list by last updated date!)

Gary, does your method put the selected row at the top of the list?
If it does - and the whole rest of this post follows from that - I’m thinking of situations where you might want the row to appear closer to the middle of the object display area. For example, in another world, I had to lookup names. And some “soundx” Find formula could get me close - as long as Chris was spelled with a “C” instead of a “K” :slight_smile: But often I needed to look above or below a “target” to make sure my Hit was correct.

So it was more convenient to bring the Find row into view in the middle of the list rather than at the top.

I’m guessing, in that case, given that you know how many rows the list will display, you can calculate the scrolltorow = therow - (MaxDispayRows-1)/2

That would put your desired row about mid-list in the display, right?

There’s some “homework” to do in determining the item’s location and the number of items above and below it so you don’t try to scroll off the end of the world.

But I think the above idea would work when you feel better knowing what’s above and below your desired row rather than just putting it at the very top of the list.

No, it simply scrolls the list so that the currently selected item in visible. The location could be at the very bottom if the selection is currently below the visible items, or it may be at the very top if it is currently above the current visible items. Lastly, it could be anywhere in the visible list if it currently is visible.

To get the item centered in the Text List Object would take a lot of effort if even possible since you would have to know what current items that are visible in the list as well as handling the situations where it it near the top or near the bottom of the entire list. I would imagine (I haven’t checked) that if you give a row number to scroll to that is off the list that it might just scroll as far a possible or might not scroll at all. Sounds too complicated for the odd situation where it might be handy.

You can add a search box at the top of the Text List. As you type in a search, the rows with matching data show up and others are excluded. You can also programmatically insert the search term.

You can easily add a search box if you use the text list constructor to create the text list.

I really didn’t want to spend any more time with this but it nagged at me enough to give it a go. You would need to know the number of items that can be displayed in the Text list Object at any one time. Below I have set this as 19 for the example code but it could be whatever your particular Text List has visible. This should locate mid-list selected items centered in the display and keep a topmost selected entry lowered as much as possible with bottom selected entries raised as much as possible.

local theListItems,theRow,visItems,totItems,midItem
visItem=19  //this is the max # of visible items displayed on list
objectaction "theList","GetList",theListItems
theRow=arraysearch(theListItems, theSelectedItem, 1, cr())
theRow=?(row >= totItems/2,min(row+midItem,totItems),max(row-midItem,1))
objectaction "theList","scrolltorow",theRow

Back to my project. :hear_no_evil:

Wow. :clap: I was going to say it was not possible.

You could possibly calculate this instead of specifying it as a constant. You can use the “rowrectangle” option to find out the height of a particular row.

local rowRectangle
objectaction "theList","RowRectangle", rowRectangle
let rowHeight = rheight(rowRectangle)
let listHeight = objectinfo("rectangle","theList")
let visItem = int(listHeight/rowHeight)

Note that this assumes that the list doesn’t have a header. If it does have a header, that would have to be subtracted from the listHeight. I don’t know of any way to get the header height programmatically, you would have to put that in as a constant. But at least that would only have to be done once, it wouldn’t change if the height of the object changed.

Note: I have not tested this code.

Wow - that’s excellent - I will give that a try. I had found (as you suggested) that normally the highlighted row was at the very bottom of the box, which was fine for me but felt a bit weird… Getting it in the middle would be even nicer, so I’ll try that.