RPS Navigate - Radial Menu Configuration

D_RPSNavigate_600ppi RPS Navigate - Radial Menu Configuration

In this post we describe the content, structure and syntax of the RPS Navigate command configuration files.

If you wish to return to the RPS Navigate command help document, click the link below

Click Here


Video Demonstration

Below you will find a video demonstration on how to configure the single ring puck control. A dual and triple ring control will also be demonstrated, that will be released shortly.


1. :arrows_counterclockwise: File Format Overview

The .rps settings file uses standard JSON, defining the layout, captions, commands, and structure of the radial interface.

:mag: JSON Syntax Reminders

  • Commas: Always omit the comma after the final item in an object or array.

    :white_check_mark: Correct usage:

    {
      "command": "TrackRegionOutline",
      "caption": "Trk Region"
    }
    

    :x: Incorrect usage:

    {
    "command": "TrackRegionOutline",
    "caption": "Trk Region",
    }
    
  • Quotes: Always use double quotes " for all keys and string values in JSON.

    :white_check_mark: Correct usage:

    {
      "label": "Measure",
      "command": "openMeasureTool"
    }
    

    :x: Incorrect usage:

    {
    'label': 'Measure',
    'command': 'openMeasureTool'
    }
    
  • Brackets: Use the correct bracket types to define structure in JSON.

    • {} for key-value pairs (objects)
      :white_check_mark: Correct usage:

      {
        "caption": "Favorites",
        "items": []
      }
      

      :x: Incorrect usage:

      [
        "caption": "Favorites",
        "items": {}
      ]
      
    • [] for lists of items (arrays)
      :white_check_mark: Correct usage:

      {
        "items": [
          { "command": "measure", "caption": " " },
          { "command": "ExploreObject", "caption": " " }
        ]
      }
      

      :x: Incorrect usage:

      {
        "items": {
          "command": "measure",
          "caption": " "
        }
      }
      

:warning: Common Pitfalls & Tips

  • Improper Escaping: If a string contains double quotes, escape them using a backslash \.

    :white_check_mark: Correct usage:

    {
      "tooltip": "Click to select the \"active\" layer"
    }
    
    
    ❌ Incorrect usage:
    {
      "tooltip": "Click to select the "active" layer"
    }
    

  • Misnested Menus: Don’t reference string values (e.g. “FAVORITE_UTILITY”) as items unless the parser supports menu linking. When nesting, prefer inline menu arrays over dangling string identifiers unless you’ve built support for those hooks.

  • :white_check_mark: Correct usage:

    {
    "items": [
      { "command": "CreatePipe", "caption": "UT Pipe" },
      { "command": "CreateUtilityNode", "caption": "UT Node" }
    ]
    }
    
  • :x: Ambiguous reference:

    {
    "items": [
      "FAVORITE_UTILITY"
    ]
    }
    
  • Typo Traps in Key Names: Mistyped keys like “FAVORTIE_CLEANUP” instead of “FAVORITE_CLEANUP” will silently break expected menu loading.

  • :white_check_mark: Check for typos:

    {
    "FAVORITE_CLEANUP": {
      "caption": "Cleanup",
      "items": [...]
      }
    }
    
  • :x: Common error:

    {
    "FAVORTIE_CLEANUP": {
      ...
      }
    }
    
  • Dangling Commas or Block Mismatches: Use a JSON linter to detect things like open quotes, unclosed braces, or trailing commas—these can easily hide in dense config files.

  • :white_check_mark: Pro tip: Use jsonlint.com or a VS Code plugin to validate as you go.

2. :brick: Base Schema & Object Anatomy

Base Schema

This refers to the core structure or scaffolding of your configuration file—what makes the entire JSON layout valid and functional. In this case, your schema has two main top-level keys:

{ "items": { ... }, "menus": { ... } }
  • items: This acts like an entry point lookup—think of it as defining radial layouts by name. Each key here corresponds to a layout anchor (like RPSSmartElevate) and points to a ring of referenced menu names.
  • menus: This is the actual definition block for those menus—where each named group (like Extended_UTILITY or Cleanup) is fleshed out with a caption and a list of items.

These two pieces together form the base schema of your file. Without one or the other, the menu system wouldn’t know how to draw the UI or what to populate into the radial rings.


Object Anatomy

Now let’s zoom in and define the anatomy of a single menu group object inside menus.

Here’s a standard example:

"Extended_UTILITY": { 
  "caption": "More", 
  "items": [ 
        { "command": "EditUtilityRun", "caption": "EditRun" },
         ... 
  ] 
}

This object contains:

  • Key (Extended_UTILITY): A unique identifier for the group, often used in references from items or other menus.

  • caption: This string appears as the label in the UI’s ring or radial node.

  • items: This is an array that can contain:

    • command objects: with command and caption keys, e.g.:
{ "command": "InsertTrenchTemplate", "caption": "Insert Tmp" }
  • string references: pointing to other menu groups, e.g. "Extended_CLEANUP"—this allows for menu nesting or reuse.

So in essence, each object in menus is a menu group definition composed of:

  1. Metadata (caption), Parameters (params),
  2. An action list (items) which are either executable commands or references to other menus.

3. :control_knobs: Menu Definitions & Layout

Menu Definitions

These are the building blocks that describe what each menu contains and how it’s labeled. Every definition lives inside the "menus" object in your base schema and has the following structure, lets look at the home menu as an example:

image

This is created from this section in the configuration file:

  "home": {
    "items": [               
         "MODEL",
         "TAKEOFF_1",    
         "Reporting",
         "CAD",
         "PDF",
         "Cleanup",
         "DataPrep"
      ]
      "central": "close"
}      

  • MenuKey: The internal identifier for this menu (e.g., home, Cleanup, PDF).
  • caption: What appears on the UI ring or radial node. ( not utilized in this example as home is referencing other menus)
  • items: An array of actions (commands) or nested menu references.

Each menu is self-contained and reusable across layouts—almost like defining a class or prefab.


Expanded Ring Menus

Within you configuration file you have the ability to define expandable ring menus as seen in the image below:

image

Users have the ability to define up to two rings that extend from the center radial menu. These rings are defined using the term “subItems”. The example below shows how the ring in the image is defined in the configuration file.

 {
  		"command": "rpsCadCleanup",
  		"caption": "Cleanup",
  			"subItems": [
    			{ "command": "rpsCadCleanup", "caption": "CAD Cleanup" },
    			{ "command": "RPSConvertToLinestring", "caption": "Convert LS" },
    			{ "command": "RPSOptimizeLinestrings", "caption": "Optim LS" },
    			{ "command": "RPSExplodeLines", "caption": "Expld Line" },
    			{ "command": "rpsExplodeSolids", "caption": "Expld Solid" },
    			{ "command": "RPSSmartCopy", "caption": "Copy" },
			"EXTENDED_CLEANUP"]},
		{

sub items must be containted within a set of “[ ]” and can only be added to a command reference no a menu reference.

Adding a second ring would look like this:

image

and this ring is defined in our config file with an additional set of subItems

"command": "RPSSmartSelect",
  		"caption": "DataPrep",
  			"subItems": [
    			{ "command": "RPSSmartSelect", "caption": "Select" },
    			{ "command": "RPSSmartPointManager", "caption": "Point" },
    			{ "command": "RPSSmartDraw", "caption": "Draw",
				"subItems": [{ "command": "RPSSmartDraw", "caption": "2D", "params": "U"},
					{ "command": "RPSSmartDraw", "caption": "Sngl Elev", "params": "F"},
					{ "command": "RPSSmartDraw", "caption": "3D", "params": "Z"},
					{ "command": "RPSSmartDraw", "caption": "Auto 3D", "params": "X"},
					{ "command": "RPSSmartDraw", "caption": "Surface", "params": "M"}]},
    			{"command": "RPSSmartEdit", "caption": "Edit",
				"subItems": [{"command": "RPSSmartEdit", "caption":"Break", "params": "B"},
					{"command": "RPSSmartEdit", "caption":"Join", "params": "J"}, 
					{"command": "RPSSmartEdit", "caption":"Trim/Extend", "params": "T"},
					{"command": "RPSSmartEdit", "caption":"Edit", "params": "L"},
					{"command": "RPSSmartEdit", "caption":"Filet/Chamf", "params": "F"},
					{"command": "RPSSmartEdit", "caption":"Insert", "params": "I"},
					{"command": "RPSSmartEdit", "caption":"Remove", "params": "R"},
					{"command": "RPSSmartEdit", "caption":"Flags", "params": "M"}]},
    			{"command": "RPSSmartElevate", "caption": "Elevate",
				"subItems": [{"command": "RPSSmartElevate", "caption": "Spot", "params": "H"},
					{"command": "RPSSmartElevate", "caption": "Simple", "params": "R"},
					{"command": "RPSSmartElevate", "caption": "Edit", "params": "F"},
					{"command": "RPSSmartElevate", "caption": "Intersect", "params": "I"},
					{"command": "RPSSmartElevate", "caption": "Points", "params": "J"},
					{"command": "RPSSmartElevate", "caption": "Model", "params": "M"},
					{"command": "RPSSmartElevate", "caption": "Contour", "params": "C"},
					{"command": "RPSSmartElevate", "caption": "Pads", "params": "B"},
					{"command": "RPSSmartElevate", "caption": "Plane", "params": "P"},
					{"command": "RPSSmartElevate", "caption": "Delta", "params": "O"},
					{"command": "RPSSmartElevate", "caption": "Absolute", "params": "K"}]},
    			{ "command": "RPSMultiOffsetLine", "caption": "Offset" },
			"EXTENDED_DATAPREP"]}

In the above example you can see that smart draw has sub items for the various modes of the command. and those modes are activated by the params variable. these params are unique to RPS commands that have multiple modes. If we were adding commands that didn’t have modes to this menu we would exclude the params from our definition.


:compass: Radial Menu Layout vs. Config Sequencing

:page_facing_up: Overview

In the radial menu configuration, tools are arranged using a 7-position layout, but the RPS design philosophy treats the 7 o’clock position as the ergonomic anchor—the spot where the primary tool goes.

While the menu buttons will adapt in size to the amount of buttons you have defined. We found that seven is our preferred layout. As long as your menu has an odd number of buttons you will get a button that sits nicely on 6 o’clock.

As an additional note we recommend not exceeding 8 buttons with captions and 12 without captions.

However, under the hood, the menu system still builds from 12 o’clock, meaning index 0 of each items array renders at the top of the UI. So while the rendering engine counts clockwise from 12, we place our “start” tool where the user expects it visually—at 7.

:mantelpiece_clock: Radial Mapping: Render Order vs. Design Intent

JSON Index Render Position
0 12 o’clock
1 ~1:30
2 ~4:00
3 ~5:30
4 ~7:30
5 ~9:00
6 ~10:30

Layouts

Layouts live in the "items" section and define how the menus are arranged in the UI, usually in a radial or tiered ring structure. Lets look at the Modeling menu as an example:

image

"MODEL": {
            "caption": "Model", ## what we saw on the home menu button
            "items": [
    		{ "command": "CreateSideSlope", "caption": "Sideslope" },
    		{ "command": "Explode", "caption": "Explode" },
		    { "command": "RPSCreateSlopeIndicators", "caption": "Slope Indic" },
    		"EXTENDED_MODEL",
    		{ "command": "RPSSmartModel", "caption": "Smart Model" },
    		{"command": "RPSSmartDraw", "caption": "Draw"},
    		{ "command": "RPSSlopeDesigner", "caption": "Slope Design" }
            ]
        },

CAD Layers Example:

image

  "CAD_LAYERS": {
            "caption": "Layers", ## what we saw on the CAD menu
            "items": [
    		{ "command": "StandardizeLayers", "caption": "Standardize" },
		    { "command": "MapLayers", "caption": "Map Layers" },
    		{ "command": "RPSCopyLayerGroupMembers", "caption": "Copy Group" },
		    { "command": "LayerManager", "caption": "Layer Mgr" },
    		{ "command": "RPSNewLayer", "caption": "New Layer" },
    		{ "command": "RPSRelayer", "caption": "Relayer" },
		    { "command": "RPSlayermanager", "caption": "Layer Mgr" }

            ]
        },

Each layout is essentially a radial entry point—mapping to a scene, context, or workflow. You could have RPSSmartElevate, TAKEOFF_1, MODEL_1, etc., each calling its own set of menus depending on what’s needed for that task.

You can think of it like this:

Concept Description Example
Menu A list of tools with a label Extended_STRATA
items A structure that arranges menus visually MaterialSiteManager in TAKEOFF_1

Menus = what, items = where & when.


4. :repeat: Submenus & Item Referencing

Submenus

Submenus are nested menu groups referenced within other menus. Instead of crowding a single group with every tool, submenus allow you to organize related tools into their own collapsible sets.

Why it matters:
Submenus streamline UI navigation and keep main workflows focused. They also allow for deeper tool access without visual overload.

Example:

"Cleanup": { 
    "caption": "Cleanup", 
    "items": [ 
          "Extended_CLEANUP", 
          { "command": "RPSOptimizeLinestrings",  "caption": "Optimize LS" } 
    ]
 }

In this example, "Extended_CLEANUP" is a submenu. When selected in the UI, it opens a new ring or side panel containing its own items.

Item Referencing

Instead of repeating commands across multiple menus, the system supports referencing any defined menu by name.

Benefits:

  • Promotes consistency across workflows
  • Reduces duplication and human error
  • Makes maintenance easy—update the referenced group once, and it updates everywhere

Example:

"MODEL_1": { 
     "topMenu": [ 
        "Extended_MODEL", 
        "Extended_DATAPREP" 
     ] 
}

Here, both menu keys point to pre-defined groups stored in the main "menus" block. This layout can call those groups in any order, as needed for the workflow.

CONFIG FILE
│
├── items (Layouts)
│   ├── MODEL_1
│   │   ├── refMenu
│   │   │   ├── Extended_MODEL
│   │   │   └── Extended_DATAPREP
│   │   └── toolbox
│   │       └── CAD_ANNOTATION
│   └── TAKEOFF_1
│       └── refMenu
│           ├── Extended_TAKEOFF
│           └── Extended_DATAPREP
│
└── menus (Menu Definitions)
    ├── Extended_DATAPREP
    │   ├── caption: "More"
    │   └── items
    │       ├── { command: "TrackRegionOutline", ... }
    │       └── ...
    ├── Extended_MODEL
    ├── CAD_ANNOTATION
    └── Cleanup
        ├── items
        │   ├── "Extended_CLEANUP"     ← submenu (referenced by name)
        │   └── { command: "RPSOptimizeLinestrings", ... }
        └── caption: "Cleanup"

Video Demonstration

The following video shows how to configure and edit the RPS Navigate radial menu system.


Use Case Videos

The following videos show the use of the RPS Navigate command in a work process context


Feedback and Enhancement Requests

If you would like to provide feedback on the use of the RPS Navigate command or to request enhancements or improvements to the command please click Reply below.