Basics Customize the main menus

Overview

The menu files are in XML format.

  • Each definition file can add, rearrange, and remove menu items from files loaded earlier in the chain (see Files below).

  • Menus and menu items are identified by their id attribute. It is not an error to create a menu or item without an id attribute, but for various reasons every menu/item should have one.

  • For action and toggle menu items, the id value is also a hotkey symbol, allowing you to assign a hotkey to the item in the hotkey editor.

    Hotkey symbols must start with h., so if an item’s id doesn’t start with h. already, Houdini creates its hotkey symbol by prefixing the id with h..

  • Most of the menu items in the shipped files trigger built-in functionality based on the hotkey. However, action items can also trigger Python scripts. See the <scriptItem> tag below.

Files

The main menus are defined by the following files in $HFS/houdini.

MainMenuCommon

Defines menus common to Houdini Master and Escape.

MainMenuMaster

An overlay that adds Master menu items to the common menus. This is applied when you start a Houdini Master license.

MainMenuEscape

An overlay that adds Escape menu items to the common menus. This is applied when you start a Houdini Escape license.

MainMenuMPlay

Menus for Mplay.

Houdini will load $HH/MainMenuCommon first and then $HH/MainMenuMaster. After that, Houdini will load any other MainMenuCommon or MainMenuMaster in the $HOUDINI_PATH. (The default path is $HOME/houdini9.0/ and the current working directory.) This allows per-user menu customization.

Format

The document element for a menu configuration file is always <mainMenu>. Menu definition and manipulation elements go inside <mainMenu>.

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
...
</mainMenu>

Four tags are allowed inside mainMenu: menuBar, addScriptItem, modifyItem, and removeItem.

<menuBar>

Defines the structure of menus. The MainMenuCommon file that ships with Houdini contains a menuBar element that defines the main menus. You can then use the add, modify, and remove tags to then customize the basic structure in later files.

You can also use this tag to define additional structure to add on to the menus defined in previous files.

This example will add a new top-level menu called “My Scripts” containing three items that run scripts when chosen by the user.

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
  <menuBar>
    <subMenu id="my_submenu">
      <label>My Scripts</label>

      <scriptItem>
        <label>My First Item</label>
        <scriptPath>$HOME/scripts/first_script.py</scriptPath>
      </scriptItem>

      <titleItem>
        <label>My Title</label>
      </titleItem>

      <scriptItem id="h.second_item">
        <label>My Second Item</label>
        <scriptPath>$HOME/scripts/generic_script.py</scriptPath>
        <scriptArgs>-q -n camera</scriptArgs>
      </scriptItem>

      <separatorItem/>

      <scriptItem id="h.third_item">
        <label>My Third Item</label>
        <scriptPath>$HOME/scripts/generic_script.py</scriptPath>
        <scriptArgs>-q -n light</scriptArgs>
      </scriptItem>
    </subMenu>
  </menuBar>
</mainMenu>

<subMenu>

Inside <menuBar>, this attaches a top-level menu. Inside another subMenu, it creates a sub-menu.

<scriptItem>

Inside a <subMenu>, attaches a menu item that triggers a Python script when the user chooses it.

<scriptPath>

Contains a path to the script to run when the user chooses this menu item.

<scriptArgs>

(Optional) An argument string to pass to the script when it’s called. In the script you can retrieve these arguments using the sys.argv list.

<titleItem>

Attaches a read-only title to help categorize the items following it in the menu.

<label>

Inside a subMenu, <scriptItem>, or <titleItem>, defines the text of the menu, menu item, or title.

<separatorItem>

Inside a <subMenu>, attaches a separator line.

Note

It is not currently possible to create scripted checkbox and radio style menu items, dynamically enable and disable user-defined menus/items, or sub-menus with dynamic contents.

The default menus use extra tags not defined above. These tags are closely tied to Houdini’s internal implementation and are not currently useful for user customization.

To attach new items or sub-menus to existing menus, duplicate the existing parent structure and put your new items inside. Houdini will match up the duplicated structure to the defined structure.

For example, The default Edit > Preferences sub-menu is defined like this:

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
    <menuBar>
        ...
        <subMenu id="edit_menu">
            <label>Edit</label>
            ...
            <subMenu id="preferences_submenu">
                <label>Preferences</label>
                ...
            </subMenu>
            ...
        </subMenu>
        ...
    </menuBar>
</mainMenu>

To add a new item to the preferences sub-menu in an overlay file, do this:

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
    <menuBar>
        <subMenu id="edit_menu">
            <subMenu id="preferences_submenu">
                <scriptItem id="h.mypref">
                    <label>My Preference</label>
                    <scriptPath>$HOME/scripts/generic_script.py</scriptPath>
                </scriptItem>
            </subMenu>
        </subMenu>
    </menuBar>
</mainMenu>

(See also the addScriptItem tag below for how to add a single item without duplicating structure.)

To fine-tune the position of your new script item within the menu you are attaching to, you can use the following sub-tags inside <scriptItem>:

<insertBefore />

Insert this item at the beginning of the menu, before existing items.

<insertBefore>id</insertBefore>

Insert this item before the item with id="id".

<insertAfter />

Insert this item at the end of the menu, after existing items.

<insertAfter>id</insertAfter>

Insert this item after the item with id="id".

<insertAtIndex>num</insertAtIndex>

Insert this item at the nthe position in the menu.

So, to insert your new menu item before the 3D Viewports entry in the Preferences sub-menu, do this:

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
    <menuBar>
        <subMenu id="edit_menu">
            <subMenu id="preferences_submenu">
                <scriptItem id="h.mypref">
                    <label>My Preference</label>
                    <scriptPath>$HOME/scripts/generic_script.py</scriptPath>

                    <insertBefore>h.prefs_viewports</insertBefore>
                </scriptItem>
            </subMenu>
        </subMenu>
    </menuBar>
</mainMenu>

<addScriptItem>

This tag inside <mainMenu> lets you add a single script item to an existing parent menu without duplicating the menu structure as shown above.

<mainMenu>
    <addScriptItem id="h.mypref">
        <parent>preferences_submenu</parent>

        <label>My Preference</label>
        <scriptPath>$HOME/scripts/generic_script.py</scriptPath>

        <insertBefore>h.prefs_viewports</insertBefore>
    </addScriptItem>
</mainMenu>

<parent>id</parent>

The id of the menu to attach this item to.

<modifyItem>

This tag inside <mainMenu> lets you relabel, rearrange, or re-parent an existing item.

A <modifyItem> element can contain <label>, <parent>, <insertAfter>, <insertBefore>, and <insertAtIndex> elements.

For example, the following XML code moves the Render > Create Render Node > Other Output Nodes > Dynamics item one level up:

<mainMenu>
    <modifyItem id="h.create_dynamics">
        <label>Moved Dynamics</label>
        <parent>render_create_submenu</parent>
        <insertBefore>render_create_subsubmenu</insertBefore>
    </modifyItem>
</mainMenu>

You can also use the <modifyItem> tag within the <menuBar> definition structure to adjust any items previously defined.

<removeItem>

This tag inside <mainMenu> lets you remove an existing item.

For example, the following XML code moves the Desktop sub-menu to the top level and removes the unnecessary separator.

<mainMenu>
  <menuBar>
    <subMenu id="desktop_submenu">
      <modifyItem><insertBefore>help_menu</insertBefore></modifyItem>
    </subMenu>
  </menuBar>

  <removeItem id="windows_menu_sep_1"/>
</mainMenu>