The concept

This tutoial shows how an agent can be used to tidy away 'people' notes, i.e. those with a 'Person' prototype, that have created on a map into a container elsewhere in the TBX. Becasue it is intended to still use the 'people' on the map, the technique also involves making an alias of each such note (as the originals will no longer be on the map).

The main Outline view window

The main Outline view window

You don't have to lay your document exactly like this but doing so will help make sense of the tutorial.

  1. The map to be worked in is the contents of container 'Map'. A specimen note, 'A note' has been added to make it easier for you to open the map view of the 'Map' container.
  2. The built-in prototype 'Person' has been added. Doing so creates its the default root-level parent container 'Prototypes'.
  3. A container called 'People' has been created. This will hold the newly collected person notes. A specimen person-type note has been added. The container has also been given a 'people' badge to help make it easy to gind in the Outline.
  4. A separator has been added to the main outline beneath which are placed the back-of-house functions. This isn't strictly needed, but can be a helpful way to split content from organisation
  5. An 'Agents' container has been made. Into this has been added an agent called 'aPeopleCarrier' (the 'a' prefix indicating an agent). This is the agent will do the moving of notes.

The People window (Outline view)

The People window (Outline view)

This window will remain open beside the map or behind it (on a small screen). It shows the notes in the document that represent people. In other words the window will give you a visual listing of all your people.

The 'People' container's $OnAdd code

The 'People' container's $OnAdd code

Note: in this and following sections the input box screen-grabs are cropped from the relevant object's Rename dialog.

Code has been set for the OnAdd action so that any note added to the container takes the prototype 'Person'. This isn't strictly necessary for the purposes of this tutorial but does catch the case where you decide to add a new note whilst in the People window. The container has also been given the badge type 'people'.

The main window (Map view)

The main window (Map view)

This is the window in which it is intended to do the main work. As well as a specimen note, an adornment has been added, which will be used to set prototypes. The adornment doesn't need to be big or intrusive, just large enough to drop a note onto it. In use, the adornment will always be empty for reasons that will soon become apparent.

The 'Person setter' adornment's $OnAdd code

The 'Person setter' adornment's $OnAdd code

Again the same action code as above, though this is the object that will be used to do the main work. An adornment's OnAdd action is fired if a noted is created on or moved onto the adornment, just as if a note were being added into a container. To reflect its purpose the adornment has been given a green colour and a 'people' badge.

The 'aPeopleCarrier' $AgentQuery code

The 'aPeopleCarrier' $AgentQuery code

Matches to this query must meet every one of three criteria:

  1. The $Prototype value must be "Person". Of these matches...
  2. The object must not be an alias - i.e. only original notes. Of these matches...
  3. The object must not be a child of the 'People' container.

The last part of the query logic is because you don't want to match Person notes that are already in their final storage place.

The 'aPeopleCarrier' $AgentAction code

The 'aPeopleCarrier' $AgentAction code

The agent creates an alias, within the agent container, of each note matching the agent's query. The agent's action code, applied to each alias in the container, is designed to move the original of that alias into the 'People' container. Moving the alias within the agent doesn't move the original. Moreover the agent just makes a new alias next update cycle; thus a new alis would be added to the People container every agent cylce. Not what you want! Moving the alias' original also means it then fails the last test in the query above so is no longer found and acted on by the agent. In other words, moving the original now places the note outside the scope of the query. The result is that all original notes of prototype 'Person' are detected and moved to the 'People' container once only.

Adding a new person - Step 1 - A new note

Adding a new person - Step 1 - A new note

You are now ready to add a new note to the map that you decide is for a person. Add a note 'John Brown'. Notice the new note is not added directly on the adornment. This is because you need to make an alias before the the new person note disappears from the map.

Adding a new person - Step 2 - Aliasing the new note

Adding a new person - Step 2 - Aliasing the new note

With the new note still selected, press Cmd+L (or menu Edit -> Make Alias). Note the new alias is added 'behind' and slightly offset for the original note.

Adding a new person - Step 3a - Setting the prototype

Adding a new person - Step 3a - Setting the prototype

Now drag the original note onto the adornment. The adornment's $OnAdd now sets the dropped note's prototype. Thus both the dropped note and its alias take on the styling of a Person note. Then, almost instantaneously...

Adding a new person - Step 3b - moving the original

Adding a new person - Step 3b - moving the original

...the original is gone! The agent has found and moved it to the 'People' container.

A new Person in the 'People' container

A new Person in the 'People' container

sure enough, the original note 'John Brown' is now in the 'People' container whilst its alias remains on the map.

Job done!

This technique can be applied to other prototypes, or indeed just groups of notes based on attribute criteria. Don't like having the extra adornment? Just make and save a Stamp using the same code as in the adornment's $OnAdd. Instead of the drag-drop action, after making the alias, select the original and then select and apply your Stamp from the Stamps menu.