Menu and submenu by author


#1

I’m following instructions to make menu but i get a bad behavior: Menu copies.
I make 3 menus.

Menu 1

require 'sketchup.rb'
module NN_MyOwnUniqueNamespace
  module Awesome_A

    unless file_loaded?( __FILE__ )
      menu = UI.menu( 'Plugins' )
      submenu = menu.add_submenu("AAA_xxx")
      aaasubmenu = submenu.add_submenu("AAA")
      aaasubmenu.add_item( 'a1' ) { self.hello_world }
      aaasubmenu.add_item( 'a2' ) { self.hello_world }
    end

  file_loaded( __FILE__ )

  end # module Awesome_A
end # module NN_MyOwnUniqueNamespace

Menu 2

require 'sketchup.rb'
module NN_MyOwnUniqueNamespace
  module Awesome_B

    unless file_loaded?( __FILE__ )
      menu = UI.menu( 'Plugins' )
      submenu = menu.add_submenu("AAA_xxx")
      bbbsubmenu = submenu.add_submenu("BBB")
      bbbsubmenu.add_item( 'b1' ) { self.hello_world }
      bbbsubmenu.add_item( 'b2' ) { self.hello_world }
    end

  file_loaded( __FILE__ )

  end # module Awesome_B
end # module NN_MyOwnUniqueNamespace

Menu 3

require 'sketchup.rb'
module NN_MyOwnUniqueNamespace
  module Awesome_C

    unless file_loaded?( __FILE__ )
      menu = UI.menu( 'Plugins' )
      submenu = menu.add_submenu("AAA_xxx")
      cccsubmenu = submenu.add_submenu("CCC")
      cccsubmenu.add_item( 'c1' ) { self.hello_world }
      cccsubmenu.add_item( 'c2' ) { self.hello_world }
    end

  file_loaded( __FILE__ )

  end # module Awesome_C
end # module NN_MyOwnUniqueNamespace

Where is my fault? I don’t know how figure out.

This is a snapshot from menu


#2

The API doesn’t look up existing menus when you call menu.add_menu - it blindly does what it says on the tin - it adds.

That being said, if you stored your menu references in an instance variables you might achieve this.

require 'sketchup.rb'
module NN_MyOwnUniqueNamespace
  def self.get_menu
    # This will create the menu on demand.
    @submenu ||= menu.add_submenu("AAA_xxx")
    @submenu
  end

  module Awesome_A

    unless file_loaded?( __FILE__ )
      menu = UI.menu( 'Plugins' )
      submenu = NN_MyOwnUniqueNamespace.get_menu
      aaasubmenu = submenu.add_submenu("AAA")
      aaasubmenu.add_item( 'a1' ) { self.hello_world }
      aaasubmenu.add_item( 'a2' ) { self.hello_world }
    end

  file_loaded( __FILE__ )

  end # module Awesome_A
end # module NN_MyOwnUniqueNamespace

Then in your other extension:

require 'sketchup.rb'
module NN_MyOwnUniqueNamespace
  def self.get_menu
    # This will create the menu on demand.
    @submenu ||= menu.add_submenu("AAA_xxx")
    @submenu
  end

  module Awesome_B

    unless file_loaded?( __FILE__ )
      menu = UI.menu( 'Plugins' )
      submenu = NN_MyOwnUniqueNamespace.get_menu
      bbbsubmenu = submenu.add_submenu("BBB")
      bbbsubmenu.add_item( 'b1' ) { self.hello_world }
      bbbsubmenu.add_item( 'b2' ) { self.hello_world }
    end

  file_loaded( __FILE__ )

  end # module Awesome_B
end # module NN_MyOwnUniqueNamespace

But note that this only works if they both load at startup. If you have one of them installed, and the user install the other afterwards the menus won’t be created because the menu item has become stale.


#3

And how i do to show submenu instantly after install?

I just did copy and paste your code and got the error at startup.

Error Loading File hello.rb
Error: #<NameError: undefined local variable or method `menu' for NN_MyOwnUniqueNamespace:Module>
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello.rb:5:in `get_menu'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello.rb:13:in `<module:Awesome_A>'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello.rb:9:in `<module:NN_MyOwnUniqueNamespace>'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello.rb:2:in `<top (required)>'
Error Loading File hello2.rb
Error: #<NameError: undefined local variable or method `menu' for NN_MyOwnUniqueNamespace:Module>
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello2.rb:5:in `get_menu'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello2.rb:13:in `<module:Awesome_B>'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello2.rb:9:in `<module:NN_MyOwnUniqueNamespace>'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello2.rb:2:in `<top (required)>'
Error Loading File hello3.rb
Error: #<NameError: undefined local variable or method `menu' for NN_MyOwnUniqueNamespace:Module>
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello3.rb:5:in `get_menu'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello3.rb:13:in `<module:Awesome_C>'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello3.rb:9:in `<module:NN_MyOwnUniqueNamespace>'
C:/ProgramData/SketchUp/SketchUp 2014/SketchUp/Plugins/hello3.rb:2:in `<top (required)>'

#4

I didn’t actually try to code before testing - sorry. I forgot to add menu = UI.menu( 'Plugins' ) in self.get_menu.


#5

Thank you! Works nice!

I noted that is 2 lines with @submenu.
I can delete the second @submenu or it is needed for a good operation of the code?


#6

You mean this?

def self.get_menu
    # This will create the menu on demand.
    @submenu ||= menu.add_submenu("AAA_xxx")
    @submenu
  end

The last @submenu is there to ensure the method return the menu object. Ruby has implicit returns, where the value of the last statement automatically returns.


#7

Yes, It is it.

Thank you very much!

Can you describe how to create a submenu without need reboot the sketchup?


#8

If you’re using that pattern above then you can’t. You need a “fresh” menu object to make the menus appear.