VDSTools 1.6.0 “the model” is out

This release rebuilds how NativeTableView stores its data. The public API stays the same: no signature changed, and no method was added or removed. If your code worked with 1.5.1, it works with 1.6.0. If it doesn’t, that’s a bug, and I’ll fix it first.

One object per row instead of sixteen parallel arrays
Until now, a row’s text, subtitles, tooltips, tags, colours, bold, alignments, icon and image were kept in sixteen separate arrays. Every operation that adds, inserts, removes, clears, moves or sorts rows had to update all sixteen. Forgetting one only showed up at the first sort, and it happened three times in two months, for example subtitles that stayed in place while the text moved. Now each row is one object, so moving a row moves everything it carries. A row only gets its style storage the first time you set a non-default style.

Measured at 100,000 rows × 5 columns, 1.5.1 → 1.6.0:

1.5.1 1.6.0
Fill 424 ms 285 ms
Sort 471 ms 117 ms
100 inserts in the middle 126 ms 9.7 ms
Clear 4.7 ms 10.4 ms
Memory 64.2 MB 40.1 MB

Clearing the table is slower than before, but stays around ten milliseconds.

An old bug fixed in both the table and the outline
A randomised stress test found this one. AddRow and AddNode only update the model, which is why they’re fast in a loop: you call Reload once at the end. If you called an animated InsertRow, RemoveRow or MoveRow (or the …Node equivalents) before that Reload, AppKit was told about rows it didn’t know yet, and it raised an exception.

That exception is an Objective-C exception, and Xojo’s Try doesn’t catch it. AppKit wrote it to the system log and silently dropped the Xojo event that was running. There was no dialog, no crash and no report: the event handler just stopped halfway. Both classes now check whether AppKit’s row count matches the model first. If it doesn’t, they reload instead of animating. This is documented as pitfall 64. Pitfall 65 is a related trap: numberOfChildrenOfItem: asks your own data source, so it can’t tell you whether AppKit is out of date.

New: SortsNaturally
Off by default. When you turn it on, digits are read as numbers, so “Task 2” sorts before “Task 10”, as in the Finder. If the table was already sorted by a header click, it re-sorts right away, and SortChanged is raised first so your own sort still takes over. You can also set it in the Inspector of NativeTableViewControl.

In the demo
The Table page has a new 100,000 rows button. It fills the table, shows how long that took, and lets you sort, scroll and drag on real volume. Sort by “Task”, tick Natural sort underneath, and watch the order fix itself.

The full changelog is in the release notes. Thanks to the buyers who keep sending precise reports. They are what made this release possible.

VDSTools 1.6.1: pictures, swipe actions and star ratings

Three additions requested by one buyer, and nothing existing changes. The only catch: NativeMenu.AddItem("title", Nil) no longer compiles. Write AddItem("title") instead.

  • Pictures sized in points: NativeButton.SetPicture(source, pointSize) now scales the picture down instead of letting it overflow the button. Menu items can show a Picture, or the Finder icon of a file or app (AddItem(title, file)).
  • Swipe actions on table rows, as in Mail: buttons on either edge, each in its own colour. A full swipe performs the first action.
  • Gauges in cells: a Level column can show stars, segments, a bar or relevancy marks, set with a click. The style can be set per column or per cell.
  • Fix: showing a hidden column no longer leaves the table wider than its view.

Pitfall 66: a table that scrolls horizontally loses its swipe. The swipe takes over the scroll gestures, and a full swipe only bounces back. Make the table fit its width. And contrary to what AppKit’s public header suggests, the full swipe does exist: it’s allowsFullSwipe, an undocumented property that is on by default.

The demo shows all of it. Full changelog in the release notes.