modo's Preferences Window is a combination of two viewports:
- The "Preferences" viewport, a tree which shows the different preference categories
- A Form View, which contains the individual preference controls themselves.
Since the preferences are really just commands in a Form View filtered by the current Preference Category selection, you can fairly easily add any commands you want to the preferences, either for one-off additions to existing forms or by defining completely new categories and their associated forms. This article focuses on the latter.
Creating New Preferences
The contents of both of these views are driven entirely through configs. We'll use the OBJ sample plug-in as an example to show how preferences are added to modo's interface.
There are four config components that need to be set up to add something to the preferences:
- Preference Category, to create a new branch in the tree.
- Preference Category Message Table, to define a username for the new category.
- Preference Form, which is added to the main preference form's category and contains the preferences you want to display in the Form View.
- Form Filter, which ensures that your form is only visible when your category is selected.
To define a new preference category, you add a new PreferenceCategories atom to your config with a PrefCat hash. This is the OBJ loader's preference category.
<hash type="PrefCat" key="fileio/wavefrontio"></hash>
This particular category's full path is fileio/wavefrontio. Forward slashes indicate sub-categories, allowing for nesting and organization within the preference tree.
Each component of the path needs a username. This is done with message tables. The table's key is always preferences.categories followed by the language code. The individual T entries represent the component within the category path, each of which must be individually assigned a message entry.
<hash type="Table" key="preferences.categories.en_US">
<hash type="T" key="fileio">File I/O</hash>
<hash type="T" key="fileio/wavefrontio">Wavefront I/O</hash>
Since "fileio" is already defined in the standard resources we really don't have to redefine it here; it is only included to illustrate that you should be sure to supply messages for each component of your preference category path if you know it's not already defined.
To add controls to your newly-created category, you simply need to associate a form with it. This is the OBJ loader's preferences form.
<hash type="Sheet" key="940394857822:sheet">
<atom type="Label">Wavefront Object Export</atom>
<list type="Control" val="cmd user.value sceneio.obj.export.groups ?">
<atom type="Label">Save Meshes as Groups</atom>
<atom type="Tooltip">Save meshes as groups</atom>
<list type="Control" val="cmd user.value sceneio.obj.export.material.format ?">
<atom type="Label">Save Material File</atom>
<atom type="Tooltip">Save the material file (.mtl)</atom>
<hash type="InCategory" key="prefs:general#head">
<hash type="InCategory" key="prefs:general#head">
- Filter is a filter that we set up previously that displays this form when a specific selection has occurred, which in this case is that the wavefrontio preference category is selected.
- InCategory adds the form to the generic preferences form using the [[Form Categories and Groups#Form Categories|form category mechanism][, which in turn is what is actually displayed in the Preference Window's Form View. Which forms are actually shown are determined by the form's filters; if not filter was set, the form would always be visible. The ordinal should be unique.
- Group specifies the [[Form Editor group used to organize the form, and is primarily used to keep the Form Editor neat.
You can also add your form to another already in the preferences using the category mechanism, rather than adding your own category. Since that form will already be filtered, you may not need a filter of your own.
The filter makes sure that our form is visible only when the associated preference category is selected. Your filter will simply be a copy of the following, replacing the prefs/fileio/wavefrontio strings with your own filter category's strings.
<atom type="Filters"> <hash type="Preset" key="prefs/fileio/wavefrontio:filterPreset"> <atom type="Name">Wavefront I/O</atom> <atom type="Category">20385740002:filterCat</atom> <atom type="Enable">1</atom> <list type="Node">1 .group 0 ""</list> <list type="Node">1 prefType fileio/wavefrontio</list> <list type="Node">-1 .endgroup </list> </hash> </atom>
Most of this is fairly esoteric; the filter system is an older, limited mechanism that is not well documented and is only used in special circumstances. It's primary use is to limit which forms are visible in Preferences, Item Properties, Tool Properties and similar Form Views.
- Preset is your preset's hash. This can be anything you want, as long as it is unique and matches that of the Filter atom in your form.
- Name is the name of the preset. Although this isn't generally shown, it's good to have.
- Category is used to group forms in the legacy Filter Editor. The hash 0385740002:filterCat represents the Preferences group, so you can just use that.
- Enable is set to 1 if the filter is enabled, which it should be.
- Node entries are used to build a hierarchy of filter criteria. The important part here is to change the "fileio/wavefrontio" bit to match the Preference Category you created earlier, which will cause the prefType filter to test true when that Preference Category is selected. Everything else should remain the same.