Confused about the cleanup function

After years using Tinderbox in Outline and Chart views (I am also intrigued by Hyperbolic) I’ve finally started gingerly using Map view. And I’m puzzled about what happens when I use “Cleanup.”

My notes (for reasons not worth getting into here) are in a single column within a container. Ie I put each new note UNDER its predecessor. After a while the column of notes looks a bit ragged and I choose Cleanup. My uneven column is replaced by a neat, straight one – but the note order is reversed! My original column, ordered from the top as note 1, note 2, note 3, has become a column in which the order from top to bottom is now 3, 2, 1.

What is disconcerting here is not the behavior but the fact that I don’t understand why it happened and that it makes no sense to me. Why would “Cleanup” change the order in which notes I arranged the notes?

Can anyone enlighten me about this? I have tried the experiment in both a containing note and in an adornment and the result is the same.

David

The only way I can replicate the problem as described is if notes 1, 2 and 3 are created in the order 3, 2, 1.

Before giving the cause it is worth understanding that Map view has an (unseen) order which is used to figure the view’s z-axis. This is the front-to-back ordering used to describe which item is on top when the two overlap. As it happens, $OutlineOrder—a number reflecting an items place on the fully expanded outline (which exists even if you never use outline view)—is used to determine z-order.

So, as you may guess, that is the order used by cleanup. But, why? This is where out human assumptions. My guess is you had items 1,2,3 in rough vertical layout and ‘just’ wanted to grid-align them for a less visually untidy layout. So, we select 3 items and order a column cleanup. But here we make an unstated assumption. We ‘know’ (can see) an existing order that is already a rough column and thus it seems logical this is the resulting answer. But, what we actually tell Tinderbox is “take this list of items and make them into vertical column”.

Now the app has no sense of where the items are. Consider this scenario (noting the creation order is 4, 6 [sic], 5, 7):

4/5/6 are selected. We might assume the logical result is a column 5/6/4. But what about this:

It is no use saying “but I wouldn’t use that layout for a column”. Tinderbox, which has to do the re-alignment, doesn’t have the luxury of such an assumption. so, it takes the list of notes, sorts them on the $OutlineOrder and starting from the position of the first note, it draws the column downwards. This is what we see:

Note 4, the first created (and thus first in $OutlineOrder) becomes the head of the new column, and then they order 5, 6 as per their outline order. Notice one odd effect. Note 5 and Note 7 overlap and normally the newer note is to the front where two overlap. Switch to another tab and back, and sure enough the expected overlap is restored:

There’s nothing untoward in this. I suspect that for efficiency Tinderbox only redraws the part of the map needed to remove the old selection and draw the new one. The overlap positions of all the un-involved are ignored and until a full refresh any overlaps sit behind the new column.

So, that’s the why/what/how of the outcome. I’ll start a new post to discuss the issues arising.

Could Tinderbox guess that we wanted to re-draw from the top-left selected item? In theory, yes. Could it re-order based on the vertical top-bottom ordering of the selection? In theory, yes. Could other items be moved so overlaps don’t occur? In theory, yes. And so on…

But, These optimisations all mean extra code (dev cost) and potentially extra render time as all the overlaps have to be figured. But there will always be edge cases that are hard to ‘see’ via code alone. If you feel you absolutely need some all of these extra optimisation, by all means email a feature suggestion. If you do so, I suggest you explain how all the edge cases are resolved or that will likely be the question you get in reply. Coding that accurately reflects our visual intuition is, as yet, hard.

So, what can you do? In terms of ordering, read up here on how outline order and map view z-order interact. You can change outline order by switching to outline view and drag-re-ordering the items. Or in map view use the View → Arrange menu to move the note up/down (the z-order); these same controls are on the context menu for the selected map item. changing the outline order.

In terms of setting the start of a column (or row, etc.), make sure the desired note is the lowest in $OutlineOrder value of your selection.

Unfortunately, there is no easy method to simply toggle an overlap of $OutlineOrder values in a map. The the selected notes use a common prototype you might consider (temporarily) using a Display/However expression, a caption or even a flag.

I think what you wanted in the first place is not, in fact Cleanup, but something like View ▸ Arrange ▸ Align Left Edges.

Cleanup methods operate on notes in outline order. So, if you clean up three notes to a row, the leftmost note will be the first in outline order.

One way to see the current item’s $OutlineOrder, without having to add the attribute to the KA table or in a display expression, etc., is to use the QuickStamp Inspector:

N.B. this only works for a single selected item, but selecting items in sequence, will allow you to see their $OutlineOrder

Mark,
Thank you for this lucid explanation. It illuminates the underlying puzzle beautifully and also shows that it might be possible to just switch to Outline view to deal with such problems. (Though that might not work, because it is easier to use adornments than containers when working with a bunch of notes, but the structure conveyed by adornments doesn’t carry over into Outline, so, I dunno. Have to think about that one.)

I think perhaps the take-away here is that Cleanup is s shotgun that I don’t need to use to swat the fly of “these notes could look a little neater.”

Again, thank you!

David

That’s the answer! Thank you!

This is a great idea! Appreciate it!

D

How to handle CleanupAction with/in Agents is clear (right click on an agent > Get Info… > attributes > Agent > CleanupAction )

But how does one achieve that for any other Container (especially the Prototypes-Containers) is not as obvious.

May I ask for instructions.

Actually it is simple , You don’t! Why? $CleanupAction addresses the reverse problem: where the agents—and only and agent ‘updates’ the layout of its child map to reflect the current refresh of alias(es). Sometimes there are a good reasons the user doesn’t want this, thus $CleanupAction.

For normal containers you want menu View ▸ Arrange ▸ Cleanup.

I get it.

But now add another Prototype from File > Bulit-In Prototypes … and you’ll find all existing as well as the newly added Prototype cleaned up to grid … I don’t want this, because there is a logical structure in which (in Map View) I arrange the Prototypes in the Prototypes-Container … and I don’t want to lose this structure every time I add a new Prototype – which results in finding all Prototypes cleaned up to “grid” (there is – as far as I can tell – no “none” option)

Perhaps there might be a way to determine the order with an action code function? If supplied the function would return the order to use; if not, the default built in order would be used Possible?

Aha - it appears the Prototypes container has a special form of sorting applied that is invoked when a new prototype is added via the File menu. Setting the container’s $CleanupAction to none (i.e. "") manually has no effect. This suggests a change in behaviour requires a change to the app itself.

I don’t know it any other app-generated containers share this issue.

Alright, we‘ll habe to ask @eastgate to check whether it‘s bug or feature …

Meanwhile, @mwra: how does one set CleanupAction for a Container to ”none“ or ”“? I saw this only possible for Agents.

I used a QuickStamp, but you could use Get Info or action code via a stamp or rule. But, please note, I did so as a test, and as expected it had no effect on how the container behaves. $CleanupAction is part of the Agent group of System attributes and is intended for agents. So, there’s little point experimenting further.

This is the first time I recall anyone using a user-modified map layout of the Prototypes container. that is likely why this issue hasn’t been noticed.

If I had to hazard a guess it perhaps seemed a good idea in Tinderbox’s earliest days and, as noted, passed without comment since. However, I do find the behaviour odd and the auto-repositioning performs not useful function as far as I can see. Regardless, it is not something the user can fix (as at v9.5.2).

It was meant to be a feature, in order to ensure that newly-added prototypes would be visible somewhere.

In this case, a decent workaround might be: add whatever built-in prototypes you expect to need?

I’ll look into respecting $CleanupAction in these folders.

In this case, a decent workaround might be: add whatever built-in prototypes you expect to need?

by this, @eastgate, you mean from the get go!?

I’ll look into respecting $CleanupAction in these folders,

Highly appreciated!

Adding a built-in prototype is something one typically does early in a project. OK — there are now a dozen built-in prototypes — but I expect one would know for a given project that, yes, we’ll certainly need Person, and that we’re probably not going to need any References.