Today I finally completed the merged tracks implementation. Since the merged track is hidden, I had to implement hidden tracks too, and it was more complicated than I thought. Simply pretending to the UI that the track was removed means that tracknums coming from the UI are wrong. I could insert a layer to correct incoming updates with tracknums based on the current hidden tracks, but it just seemed too complicated, so I decided to implement track collapse in the c++ layer. I actually implemented it as collapsing to a divider, since I was never happy with there being both hidden and collapsed tracks.
It meant a bit of hackery because c++ has to remember the state of the collapsed track so it can restore it. Keeping state in c++ is a bit sketchy because it's duplicated information and because it's internal operations instead of the normal diff -> update -> sync avenue. For example, what happens if a collapsed track is resized in haskell? When it's expanded, it won't get the new size. Mabybe the tracknum translation would have been cleaner? Oh well, I suppose I can switch back if need be.
Along the way I fixed a few long-standing bugs in how tracks are resized.