Form Categories and Groups
Introduced in modo 401, categories and groups provide an easy way to add a form to any other form, and to organize forms in the Form Editor.
Form Categories are an extremely powerful mechanism. It allows you to insert a new form at the beginning or end of any other form simply by having the kit installed, or by just dropping your script's config into the user configs or scripts directory. They need never touch the Form Editor themselves; the controls will simply appear in the correct place when they run modo. This radically simplifies distributing scripts to users.
The Origin of Categories
Categories got their name from the idea of grouping common forms together. For example, Tool Properties might be a category, Item Properties another category, and Preferences yet another category. The goal was to allow new forms to be easily added to an existing form, without being constrained by limits of the normal parent/child relationship that requires the parent form to maintain a list of its children. Categories were quickly expanded beyond a few special cases to include all forms.
Categories invert the normal parent/child relationship used in the forms hierarchy. Normally, a form maintains a list of all of its children. While this makes sense when building a self-contained form, it makes it difficult to add features to an existing form without changing that form as well. This is further complicated when multiple scripts would like to be added to the same existing form. Furthermore, since the config system has exactly two layers -- the user config, and all imported configs, with the import order of imported configs being undefined and arbitrary -- simply replacing the existing form with the new form doesn't really work. When upgrading to a new version of the application, a manually-edited form will supersede the new form included with the application, unintentionally hiding new functionality from the user.
Head and Tail Categories
Starting with modo 401, each form has two implicit categories, a head category and a tail category. Instead of requiring the parent to keep track of all of its children as in a normal parenting hierarchy, the category system makes the "children" responsible for stating which categories they belong to. Any form added to another form's head category will appear before all other controls in that form, while one added to the tail category will be inserted after all other controls in the form.
Since every form has its own head and tail categories, you can effectively insert a new form at the beginning or end of any other form simply by adding it to the appropriate category. The categorization is completely self contained within your new form.
A single form can be in as many categories as you like. This effectively allows it to replace instancing of forms in most cases (form instances were removed in modo 401 due to their complexity and limited usefulness). It is very common for forms to have no parents, and thus they are often collected into groups to keep the Form Editor clean.
Sorting within Categories
Forms can also be sorted within categories through the use of ordinals. You only need to worry about the ordinal format if you plan on hand editing your configs, or want a very specific position relative to the other forms in the category. An ordinal is simply a series of numbers between 1 and 255 separated by periods. 0 is not legal, and should not be used, as it is used internally to mark the end of the ordinal. Lower numbers appear earlier in the category. If two numbers conflict, the period-separated number is used. You can have as many period-separated numbers as you like, thus ensuring that two ordinals will be unlikely to ever conflict.
This simple ordinal inserts the form in the middle of the category.
This always sorts as the first entry in the middle of the category. What that means is that if another form has an ordinal of 128 in that category, then the second number after the period will be used to decide which one is shown first. If all of the components of the ordinal are the same, the sort order is undefined.
You can have as many ordinal components as you like. Just remember that the numbers must range from 1-255, and that 0 is invalid.
Manually specifying an ordinal is most useful when you are providing multiple forms and want to ensure that one comes before the other. It is often not possible to specifically sort your form relative to other third party forms as you don't have any way of knowing the ordinals of the other forms.
Categories in the Form Editor
To access the categories of a form, simply unfold the +/- disclosure widget to left of the form's name in the Form Editor. The Head Category and Tail Category will be the first two entries.
To add a form to a category, simply drag and drop it into that category. You can also use drag and drop to re-order categories (and thus implicitly change their ordinals), and remove them from the category via a context menu. Once a form is in a category, it will automatically appear in the correct place in its parent form.
If you save a form to disk from the Form Editor, or export its config fragment, all of the categories it contains will be included with it. This means that once you have finished with your script or plug-in's interface, you can distribute it or add it to your kit simply by choosing it and selecting the Save Form button. Your users can just drop your kit, or your script and its config, into the user scripts and/or configs directories, run modo and immediately start using your scripts with no other setup required.
There are a few forms that commonly have other forms added to their categories:
- modo Modes Addendum' (hash: 26077270201:sheet), also known as modo Modes Tail and originally as simply modo Modes. modo Modes is the name of the toolbar along the top of many of the standard modo main window layouts. Kits needed a way to add themselves to those layouts, so they tried adding themselves directly to the modo Modes tail category. They also needed to add themselves to the Animate Modes form's category for the Animate layout. Since it was very likely that even more "modes" forms would be added int he future, the 26077270201:sheet hash was re-assigned to modo Modes Addundum, which was then added to the end of all of the other "modes" forms. Now a kit can add itself to the tail of 26077270201:sheet and it will correctly appear in all of the main window toolbars.
- Item Properties (hash: itemprops:general). This form contains all of the item properties forms as entries into its categories. Each such form is displayed as a vertical tab. Forms usually have filters applied so that they only appear when a specific item type is selected.
- Item Properties: Textures (hash: itemprops:textures). Similar to the Item Properties, but is limited to textures items. It is itself included in the tail category of the Item Properties form, so any forms added here will show up there as well.
- Menu Bar (hash: menubar). This is the main menu bar at the top of the window/screen. New menus can be added by inserting forms into its categories.
Prior to modo 401, forms would often be grouped together by parenting them to other forms purely to keep the Form Editor clean. While this worked in a limited sense, it wasn't very elegant. modo 401 introduces groups.
As with categories, the form itself defines the groups that it belongs to. A form can be in only one group, or in no group at all. Groups are especially useful when dealing with forms in categories, as they often do not have a parent and would otherwise clutter up the root of the Form Editor.
New groups can easily be created from within the Form Editor. A group is not defined solely by its name, but rather by its complete path. For this reason, groups cannot be moved or renamed from the Form Editor, as this would affect all other forms in those groups and cause them to be moved into the user config (since all config changes are written only to the user config; see the Config Files article for more information). Adding a form to a group is a simple matter of drag and drop. Forms inside a group are always sorted alphabetically.
User Readable Group Names and Message Tables
If you are editing a config by hand and want to create groups there, the format is basegroup/subgroup, where forward slashes are used to define the group hierarchy. The names can be user-readable, but it is often desirable to specify them as internal strings and use message tables instead. This example config snippet shows how such a message table might be constructed for a group hierarchy named myGroup, and its child myGroup/mySubGroup. Note that myGroup has its own separate message table entry. The key must always start with attrgroup:, with message index 1 being used as the group's name. Also remember that keys and group names are case sensitive.
<?xml version="1.0"?> <configuration> <atom type="Messages"> <hash type="Table" key="attrgroup:myGroup.en_US"> <hash type="T" key="1">My Group</hash> </hash> <hash type="Table" key="attrgroup:myGroup/mySubGroup.en_US"> <hash type="T" key="1">My Sub-Group</hash> </hash> </atom> </configuration>