Create submenu in Plugins menu

Hi,
I would like to create submenus in plugins menu.
In fact, I have several .rb file I would like to create a submenu in the menu to call these pluging file .rb

example:
I a.rb b.rb and c.rb
I would like to have in the plugins menu:
Plugins => “My Scripts” => “A”, “B”, “C”
And when I click on A, B or C the corresponding script starts.

I saw that some proposed script do this but I don’t understand how their authors have done.

Can you help me?
Thank you in advance

 submenu = plugins_menu.add_submenu("myTest")
submenu.add_item("a"){ UI.messagebox "I'm a" }
submenu.add_item("b"){ UI.messagebox "I'm b" }```

instead of a message box you can use ```load "path/to/a.rb"```
or similar
have a look at the API docs at Menu...
john

Thank you for your answer,
your script creates submenu, but my .rb doesn’t executes when I click on “a”

If my .rb files in the same folder, the script is :
plugins_menu = UI.menu(“Plugins”)
submenu = plugins_menu.add_submenu(“myTest”)
submenu.add_item(“a”){ scripta.rb }
submenu.add_item(“b”){ scriptb.rb }
?

Thank you in advance

Hi @asjulien

Between the { } you should have some ruby code rather than the script name. Here’s a small example.

File 1:


# plugin1.rb
module Asjulien
    def self.one
       puts "I am One."
    end
end

FIle 2

# plugin2.rb
 module Asjulien
  def self.two
    puts "I am Two."
  end
end

Menu File

# asjulien-menus.rb
require 'plugin1.rb'
require 'plugin2.rb'
module Asjulien
  my_menu = UI.menu('Plugins').add_submenu('Asjulien Tools')
  my_menu.add_item("Tool 1") { Asjulien.one() }
  my_menu.add_item("Tool 2") { Asjulien.two() }
end
1 Like

Jim’s is better, but to explain why your test failed…

you have submenu.add_item(“a”){ scripta.rb }
this fails as SU has no idea what to do with it or where it lives…
if you use load it tells SU to load the file in the “full path to this file”
so you would need submenu.add_item("a"){ load "full path to/scripta.rb" } with the full path…

my example was simply adding to the API example to show you the basic principle…

john

1 Like

or:

home = ENV['HOME']||ENV['USERPROFILE']
temppath = File.join(home,"scripts")

submenu.add_item("a"){
  if Kernel.test(?d,temppath)
    Dir.chdir(temppath) {
      load "scripta.rb" 
    }
  else
    UI.messagebox("Error! Directory path does not exist:\n"<<('"'+temppath+'"')
  end
}
1 Like

Hi,

I would like to have independently installed extensions add items to the same submenu.

Is there a way tho check if the submenu is already there?
Couldn’t find any documentation…

Cheers,
A

This is not yet possible, but long overdue. Sorry…

The menu references get quickly garbage collected after the script that creates them runs.
We have tried assigning them to persistent references on the Ruby side, but they become invalid on the C-side.

1 Like

I see! Thanks for the reply!

Good topic! It enabled me to finally clean up my extensions menu. I used Jim’s code and even without the ‘require…’ it worked fine for me. So the code in the menu file is just:

module Asjulien
  my_menu = UI.menu('Extensions').add_submenu('Asjulien Tools')
  my_menu.add_item("Tool 1") { Asjulien.one() }
  my_menu.add_item("Tool 2") { Asjulien.two() }
end

@villares

Checkout a more recent thread on this subject.

1 Like

I understand that you mean submenu be duplicated when you add a new tool to your previous submenu list.
I’m not sure but I think the reason is that we add submenu in different modules
I try adding repeatedly in the same module in your main module for all tools and it works
Example:
I have 2 tools in seperate ruby files
In tool A rb file you have:

module MyToolBox
   module ToolA
      #Do something
      submenu = MyMenu.get_menu()
       submenu.add_item(“a”){ scripta.rb }
   end #module ToolA
   module MyMenu
      def self.get_menu()
         plugins_menu = UI.menu(“Plugins”)
         submenu = plugins_menu.add_submenu(“myList”)
      end #def get_menu
   end #module MyMenu
end #module MyToolBox

In tool B rb file you have:

module MyToolBox
   module ToolB
      #Do something
      submenu = MyMenu.get_menu()
      submenu.add_item(“b”){ scriptb.rb }
   end #module ToolB
   module MyMenu
      def self.get_menu()
         plugins_menu = UI.menu(“Plugins”)
         submenu = plugins_menu.add_submenu(“myList”)
      end #def get_menu
   end # module MyMenu
end #module MyToolBox

This will not currently work well unless these multiple files are loaded by a single call to Sketchup::require (ie, they are part of the same extension.)

There is an open request for the API …