frang75 / nappgui_src

SDK for building cross-platform desktop apps in ANSI-C
https://www.nappgui.com
MIT License
442 stars 43 forks source link

Possible problem with tableview_select(...)? #114

Closed SamSandq closed 2 months ago

SamSandq commented 2 months ago

I noticed in my table that if I want to select a row with

tableview_select(table, rows, 1);

it sometimes fails. I traced it down to the fact that I have a highly dynamic table using it as a TreeView. When I start of with a shorter table (i.e., many branches closed in the 'treeview'), and open up branches (thus expanding the visible table), I cannot use the tableview_select(...) on lines below the original maximum number of lines.

I was forced to do a tableview_update(...)which cured the problem. However, I think this call should instead be in the tableview.c: tableview_selectfunction, not in my own code. It seems to me that that function does not update its internal use of data->num_rows before attempting the select; and the line

if (n > 0 && rows[0] < data->num_rows)

disallows a new select. I may be wrong, but report the possible issue nonetheless.

frang75 commented 2 months ago

Not really. tableview_update() calls should only be done when the data source represented in the table has been altered. Making indiscriminate calls to tableview_update() can have a performance penalty, since we don't know "how expensive" it can be to access the data source.

The response to ekGUI_EVENT_TBL_NROWS event must to be the exact number of records in dataset. ONLY in case that dataset changes (and the app controler knows that), we do have to call tableview_update() so that the viewer prepares for a number of different records.

Certain internal adaptations must be made within the TableView control so that it can render tree structures correctly and efficiently.

SamSandq commented 2 months ago

You are right that the updates to the table should be minimised; however, every open/close of a branch cause a "change" in the table, so they are potentially numerous.

Internally, I keep two arrays: one is the "real" one, a flat list of all collections in my database. This changes only on collection additions and deletions, which happen very infrequently. Each collection in that has a status: open branch, closed branch, or leaf.

The other one is a "show" array, which is generated anew at every fold; it only contains indices to the real one. The show one only contains the visible lines, with the status indicator (which causes them to be displayed differently).

This may not be the best data structure, but it works.