making_main_screen_plugins.rst 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. .. _doc_making_main_screen_plugins:
  2. Making main screen plugins
  3. ==========================
  4. What this tutorial covers
  5. -------------------------
  6. Main screen plugins allow you to create
  7. new UIs in the central part of the editor, which appear next to the
  8. "2D", "3D", "Script", and "AssetLib" buttons. Such editor plugins are
  9. referred as "Main screen plugins".
  10. This tutorial leads you through the creation of a basic main screen plugin.
  11. For the sake of simplicity, our main screen plugin will contain a single
  12. button that prints text to the console.
  13. Initializing the plugin
  14. -----------------------
  15. First create a new plugin from the Plugins menu. For this tutorial, we'll put
  16. it in a folder called ``main_screen``, but you can use any name you'd like.
  17. The plugin script will come with ``_enter_tree()`` and ``_exit_tree()``
  18. methods, but for a main screen plugin we need to add a few extra methods.
  19. Add five extra methods such that the script looks like this:
  20. .. tabs::
  21. .. code-tab:: gdscript GDScript
  22. @tool
  23. extends EditorPlugin
  24. func _enter_tree():
  25. pass
  26. func _exit_tree():
  27. pass
  28. func _has_main_screen():
  29. return true
  30. func _make_visible(visible):
  31. pass
  32. func _get_plugin_name():
  33. return "Main Screen Plugin"
  34. func _get_plugin_icon():
  35. return get_editor_interface().get_base_control().get_theme_icon("Node", "EditorIcons")
  36. .. code-tab:: csharp
  37. #if TOOLS
  38. using Godot;
  39. using System;
  40. [Tool]
  41. public partial class MainScreenPlugin : EditorPlugin
  42. {
  43. public override void _EnterTree()
  44. {
  45. }
  46. public override void _ExitTree()
  47. {
  48. }
  49. public override bool _HasMainScreen()
  50. {
  51. return true;
  52. }
  53. public override void _MakeVisible(bool visible)
  54. {
  55. }
  56. public override string _GetPluginName()
  57. {
  58. return "Main Screen Plugin";
  59. }
  60. public override Texture2D _GetPluginIcon()
  61. {
  62. return GetEditorInterface().GetBaseControl().GetThemeIcon("Node", "EditorIcons");
  63. }
  64. }
  65. #endif
  66. The important part in this script is the ``_has_main_screen()`` function,
  67. which is overloaded so it returns ``true``. This function is automatically
  68. called by the editor on plugin activation, to tell it that this plugin
  69. adds a new center view to the editor. For now, we'll leave this script
  70. as-is and we'll come back to it later.
  71. Main screen scene
  72. -----------------
  73. Create a new scene with a root node derived from ``Control`` (for this
  74. example plugin, we'll make the root node a ``CenterContainer``).
  75. Select this root node, and in the viewport, click the ``Layout`` menu
  76. and select ``Full Rect``. You also need to enable the ``Expand``
  77. vertical size flag in the inspector.
  78. The panel now uses all the space available in the main viewport.
  79. Next, let's add a button to our example main screen plugin.
  80. Add a ``Button`` node, and set the text to "Print Hello" or similar.
  81. Add a script to the button like this:
  82. .. tabs::
  83. .. code-tab:: gdscript GDScript
  84. @tool
  85. extends Button
  86. func _on_PrintHello_pressed():
  87. print("Hello from the main screen plugin!")
  88. .. code-tab:: csharp
  89. using Godot;
  90. using System;
  91. [Tool]
  92. public partial class PrintHello : Button
  93. {
  94. public void OnPrintHelloPressed()
  95. {
  96. GD.Print("Hello from the main screen plugin!");
  97. }
  98. }
  99. Then connect the "pressed" signal to itself. If you need help with signals,
  100. see the :ref:`doc_signals` article.
  101. We are done with the main screen panel. Save the scene as ``main_panel.tscn``.
  102. Update the plugin script
  103. ------------------------
  104. We need to update the ``main_screen_plugin.gd`` script so the plugin
  105. instances our main panel scene and places it where it needs to be.
  106. Here is the full plugin script:
  107. .. tabs::
  108. .. code-tab:: gdscript GDScript
  109. @tool
  110. extends EditorPlugin
  111. const MainPanel = preload("res://addons/main_screen/main_panel.tscn")
  112. var main_panel_instance
  113. func _enter_tree():
  114. main_panel_instance = MainPanel.instantiate()
  115. # Add the main panel to the editor's main viewport.
  116. get_editor_interface().get_editor_main_screen().add_child(main_panel_instance)
  117. # Hide the main panel. Very much required.
  118. _make_visible(false)
  119. func _exit_tree():
  120. if main_panel_instance:
  121. main_panel_instance.queue_free()
  122. func _has_main_screen():
  123. return true
  124. func _make_visible(visible):
  125. if main_panel_instance:
  126. main_panel_instance.visible = visible
  127. func _get_plugin_name():
  128. return "Main Screen Plugin"
  129. func _get_plugin_icon():
  130. # Must return some kind of Texture for the icon.
  131. return get_editor_interface().get_base_control().get_theme_icon("Node", "EditorIcons")
  132. .. code-tab:: csharp
  133. #if TOOLS
  134. using Godot;
  135. using System;
  136. [Tool]
  137. public partial class MainScreenPlugin : EditorPlugin
  138. {
  139. PackedScene MainPanel = ResourceLoader.Load<PackedScene>("res://addons/main_screen/main_panel.tscn");
  140. Control MainPanelInstance;
  141. public override void _EnterTree()
  142. {
  143. MainPanelInstance = (Control)MainPanel.Instantiate();
  144. // Add the main panel to the editor's main viewport.
  145. GetEditorInterface().GetEditorMainScreen().AddChild(MainPanelInstance);
  146. // Hide the main panel. Very much required.
  147. _MakeVisible(false);
  148. }
  149. public override void _ExitTree()
  150. {
  151. if (MainPanelInstance != null)
  152. {
  153. MainPanelInstance.QueueFree();
  154. }
  155. }
  156. public override bool _HasMainScreen()
  157. {
  158. return true;
  159. }
  160. public override void _MakeVisible(bool visible)
  161. {
  162. if (MainPanelInstance != null)
  163. {
  164. MainPanelInstance.Visible = visible;
  165. }
  166. }
  167. public override string _GetPluginName()
  168. {
  169. return "Main Screen Plugin";
  170. }
  171. public override Texture2D _GetPluginIcon()
  172. {
  173. // Must return some kind of Texture for the icon.
  174. return GetEditorInterface().GetBaseControl().GetThemeIcon("Node", "EditorIcons");
  175. }
  176. }
  177. #endif
  178. A couple of specific lines were added. ``MainPanel`` is a constant that holds
  179. a reference to the scene, and we instance it into `main_panel_instance`.
  180. The ``_enter_tree()`` function is called before ``_ready()``. This is where
  181. we instance the main panel scene, and add them as children of specific parts
  182. of the editor. We use ``get_editor_interface().get_editor_main_screen()`` to
  183. obtain the main editor screen and add our main panel instance as a child to it.
  184. We call the ``_make_visible(false)`` function to hide the main panel so
  185. it doesn't compete for space when first activating the plugin.
  186. The ``_exit_tree()`` function is called when the plugin is deactivated.
  187. If the main screen still exists, we call ``queue_free()`` to free the
  188. instance and remove it from memory.
  189. The ``_make_visible()`` function is overridden to hide or show the main
  190. panel as needed. This function is automatically called by the editor when the
  191. user clicks on the main viewport buttons at the top of the editor.
  192. The ``_get_plugin_name()`` and ``_get_plugin_icon()`` functions control
  193. the displayed name and icon for the plugin's main viewport button.
  194. Another function you can add is the ``handles()`` function, which
  195. allows you to handle a node type, automatically focusing the main
  196. screen when the type is selected. This is similar to how clicking
  197. on a 3D node will automatically switch to the 3D viewport.
  198. Try the plugin
  199. --------------
  200. Activate the plugin in the Project Settings. You'll observe a new button next
  201. to 2D, 3D, Script above the main viewport. Clicking it will take you to your
  202. new main screen plugin, and the button in the middle will print text.
  203. If you would like to try a finished version of this plugin,
  204. check out the plugin demos here:
  205. https://github.com/godotengine/godot-demo-projects/tree/master/plugins
  206. If you would like to see a more complete example of what main screen plugins
  207. are capable of, check out the 2.5D demo projects here:
  208. https://github.com/godotengine/godot-demo-projects/tree/master/misc/2.5d