There's a specific reason I'm asking how version 3.5 does it. When I first started looking at how to create a File-menu, my search quickly led me to the Godot Docs-page for MenuBar. Then when I went to add one in my project, I realized the page was for 4.2, and MenuBar hadn't been added until 4.0. Wups. BTW, I'm not the only one confused. That stupid (literally) Google AI said this:

But that did actually get me to thinking, how does the Godot Editor do it - after all, it does say it was "built with Godot". 🙂
I presume it involves a MenuButton (which is in 3.5), and various Containers, but I'm not fluent enough yet to replicate it.

20 days later

I think this is what you are looking for:

make sure to also read its documentation

4 days later

Thanks for the reply. However, I'm not just wondering about the popup, but the underlying menu - the one containing the words Scene-Project-Debug-Editor-help. How are those created? It sounds like a MenuBar, but that was only added in Godot 4.0, not 3.5.

    Crawfish the underlying menu - the one containing the words Scene-Project-Debug-Editor-help. How are those created?

    Possibly Tabs or TabContainer, along with MenuButton.

    Crawfish
    It's MenuButton!!
    Press "Items" in your toolbar to add menu entries.
    But I don't know how to make sub menu.


      pegasusearl
      Thanks, that's definitely a step further. Although as you say, I can't find a way to make a sub-menu (like Open Recent ->). I tried making a MenuButton as a child of the top MenuButton (that seemed the obvious answer), but it only appeared as a second button, not as a dropdown option for the first button.

        Crawfish Can Godot 4 do that?
        Well if you need that feature I suspect you need to construct them yourself. Similar to ScrollContainer, MenuButton is just combination of different nodes. If you run the game and go to the "remote" scene tree, you will see there will be Popup and Timer inside MenuButton.

        I would make Button who will popup() the Popup.
        Inside Popup there will be menu items. You can add even more popup inside those popups.

        With this you can add even more than just menu entries and separator, maybe Label or SpinBox.

        I wish I can send video to this forum, but here are screenshot.


        One issue with this is the popup on the submenu seems to be spawned in wrong position. I'm guessing it's because the popup submenu is child of a button so the position is based on it's position in relation to the button while popup's position during runtime will be based on the absolute position.

        To fix this you either have to, put Popup outside (not as a child of entry node), or manually code the Popup position when you call popup().


        Another way is you don't even need to use Popup. You can use PanelContainer or whatever else, I'm guessing you don't need to do wacky positioning with it, but you have to code the visibility yourself. With Popup, it will already worked like what you expect from a popup minus the issue I mentioned above.

          pegasusearl thanks for the information, that does look like it's approaching the functionality of the editor. But with regards to this:

          Well if you need that feature I suspect you need to construct them yourself

          That's why my original question was, "How does the Godot 3.5 editor, do this?" I've read that "The Godot editor itself is made with Godot" - so what does that mean? I'm interpreting it as it uses all the same widgets/components that we have access to in the editor - IOW, that someone on the Godot team put together MenuButtons/PopupMenus, etc, into a FileMenuBar.

          Granted, it's possible it was all done in C++, and they then created a Control called MenuBar, for version 4.0, that was part of the Node system.

            DaveTheCoder

            The Godot Editor is written in C++.

            Sure, but some random person I've never heard before, also said this: Hacker News

            The Godot editor itself is made with Godot, which is cool. Everything you see in the UI there is available for use in your own projects.

            or The Godot editor is a Godot game (V3.5)

            The Godot editor runs on the game engine. It uses the engine's own UI system, it can hot-reload code and scenes when you test your projects, or run game code in the editor. This means you can use the same code and scenes for your games, or build plugins and extend the editor.

            I'm soo confused - make it make sense. 😅

            Okay, seriously, I get that the engine is written in C++, and if you have to write C++ code to use any of the built-in widgets, fine. But it's very unclear from the official docs what exactly is going on. Which is the point of my original question. If it turns out that the Godot Editor uses a mix of C++ calling widgets, to put a FileMenu up, great - I'll just have to figure out a different solution. But if it's doable using only widgets...

              Crawfish I'm soo confused - make it make sense.

              Godot editor is just a front end editor built on the game engine/runtime. The export templates include a prebuilt engine runtime to run your exported game. Normally you use a prebuilt editor and export templates. But you can also use godot on the source level like old school engines that were more like/essentially c/c++ library collections. That is how the editor is built with/on top of the engine as well.

              The Godot editor is a Godot game

              The Godot editor itself is made with Godot

              That's misleading. In a sense it's true, because it uses Godot classes. But the Editor is written in C++, not GDScript or C#, and Godot games are typically not written in C++.

              2 months later

              Well, there may not be a "simple" solution in 3.5, but at least there does turn out to be a solution, that doesn't involve diving into C++ like the Engine does. Several people were right, it involves a MenuButton - and tons of code. I found a good example in this tool:

              Material-Maker

              Note that the current version it's updated to is Godot 4.2 (which has the MenuBar widget - I admit that simplifies things a lot, but for now I didn't want to switch from 3.5). If you wanted the sample code for 3.5, git-checkout the tag 1.3.

              Like I said, it's a lot of code, that looks like this:

              const MENU = [
                  { menu="File/New material", command="new_material", shortcut="Control+N" },
                  { menu="File/New paint project", command="new_paint_project", shortcut="Control+Shift+N", not_in_ports=["HTML5"] },
                  { menu="File/Load", command="load_project", shortcut="Control+O" },
                  { menu="File/Load material from website", command="load_material_from_website" },
                  { menu="File/Load recent", submenu="load_recent", standalone_only=true, not_in_ports=["HTML5"] },
                  { menu="File/-" },
                  { menu="File/Save", command="save_project", shortcut="Control+S" },
                    ...
              
              func create_menu(menu_def : Array, object : Object, menu : PopupMenu, menu_name : String) -> PopupMenu:
                      var menu_item_name = menu_def[i].menu.right(menu_name_length)
                      var is_separator = false
                      if menu_item_name.find("/") != -1:
                          var submenu_name = menu_item_name.split("/")[0]
                          if ! submenus.has(submenu_name):
                              var submenu : PopupMenu
                              if menu.has_node(submenu_name):
                                  submenu = menu.get_node(submenu_name)
                              else:
                                  submenu = PopupMenu.new()
                                  submenu.name = submenu_name
                                  menu.add_child(submenu)
                              create_menu(menu_def, object, submenu, menu_name+submenu_name+"/")
                              menu.add_submenu_item(submenu_name, submenu.get_name())
                              submenus[submenu_name] = submenu
                      elif menu_def[i].has("submenu"):

              But at least it works...