VDSTools 1.4.0 — row images, drag-and-drop fixes, and dragging rows out of a table
Five versions have gone out since 1.3.0, four of them driven by one buyer’s reports. Here is the whole arc in one post.
1.4.0 — dragging a row out, without reordering the table. AllowsRowDragging is new and independent of AllowsRowReordering. Until now reordering gated everything: with it False, pasteboardWriterForRow: returned Niland the source operation mask was left at zero, so no drag started at all — not to a sidebar, not to another application. The name said “reordering”, the code said “all dragging”. The two now combine freely, and dragging to another application is permitted for the first time, as a copy. Two more additions make the payload yours without a single Declare:
AddHandler myTableControl.Table.WritingRow, AddressOf TableWritingRow
Private Sub TableWritingRow(sender As NativeTableView, row As Integer, pasteboardItem As Ptr)
NativeTableView.AddDragType(pasteboardItem, "public.utf8-plain-text", sender.CellAt(row, 1))
End Sub
What the table writes by itself is the row index under a private type, which means nothing outside it — so without this, a drop on Mail or the Finder receives nothing.
1.3.4 — something follows the cursor outside the table. The drag shadow is a view placed inside the table, so it could show nothing past its own edges. The library now composes a Mail-style stack: up to three offset thumbnails, with AppKit’s own red count badge. One or the other, never both — the card while you are inside the table, the stack as soon as you leave — and the swap happens on the source side, in draggingSession:movedToPoint:, since a view that is no longer the destination has no say over the session’s items. Each thumbnail is a crop of the row at 1:1, not the whole row shrunk: a row is wide and short, and reduced it becomes an unreadable band.
1.3.3 — three drag defects, all reported with measurements. The shadow was only moved from validateDrop, which AppKit calls when the proposed destination changes rather than on every move — five times across a 95-point drag, hence jumps of 11 to 24 points; the table is now instantiated from a subclass overriding draggingUpdated:. The insertion line no longer crosses the shadow: AppKit re-fronts its destination view on every update, so subview order cannot win, and the shadow’s layer carries a high zPosition instead. And the insertion line goes to the nearest row edge, instead of oscillating as “on” was re-proposed as “above”.
1.3.2 — subtitle text was truncated regardless of column width. A cell is built against a 120-point placeholder width and then resized by AppKit; what you put in only stretches if it carries an autoresizing mask. The label, gauge and popup had one; the box stacking title and subtitle did not, so it stayed 116 points wide inside a 400-point column. Nothing to do on the caller’s side any more.
1.3.1 — a crash fix, and it needs a rebuild. Picture.CopyOSHandle(MacNSImage) returns an autoreleased object despite the “Copy” in its name. The library released it, believing it owned it: an over-release that only ever hit builtapplications, never the IDE, and surfaced as EXC_BAD_ACCESS in objc_release under objc_autoreleasePoolPop with no Xojo frame in the stack. If you shipped anything using 1.3.0’s row images, rebuild it against 1.3.1 or later.
1.3.0 — your own image as a row icon, where only an SF Symbol was accepted: SetRowImage, SetNodeImage, NativeSidebar.Add(title, image) and SetImage. As persistent as a symbol — the image lives in the model and is re-read on every cell build, so it survives reload, sort, row moves, section collapse and scrolling. Image and symbol exclude one another. That version also fixed a view leak in both sidebars: up to nine objects per cell build.
102 classes, 805 public methods, 62 documented AppKit traps. The demo shows all of it — toggles on the Table and Outline pages, and AllowsRowDragging in the Placeables window: tick it, leave reordering off, and drop a few rows onto TextEdit.