public override void EnablePlugin() { base.EnablePlugin(); if (Instance != null) { throw new InvalidOperationException(); } Instance = this; var editorInterface = GetEditorInterface(); var editorBaseControl = editorInterface.GetBaseControl(); editorSettings = editorInterface.GetEditorSettings(); errorDialog = new AcceptDialog(); editorBaseControl.AddChild(errorDialog); MonoBottomPanel = new MonoBottomPanel(); bottomPanelBtn = AddControlToBottomPanel(MonoBottomPanel, "Mono".TTR()); AddChild(new HotReloadAssemblyWatcher { Name = "HotReloadAssemblyWatcher" }); menuPopup = new PopupMenu(); menuPopup.Hide(); menuPopup.SetAsToplevel(true); AddToolSubmenuItem("Mono", menuPopup); // TODO: Remove or edit this info dialog once Mono support is no longer in alpha { menuPopup.AddItem("About C# support".TTR(), (int)MenuOptions.AboutCSharp); aboutDialog = new AcceptDialog(); editorBaseControl.AddChild(aboutDialog); aboutDialog.WindowTitle = "Important: C# support is not feature-complete"; // We don't use DialogText as the default AcceptDialog Label doesn't play well with the TextureRect and CheckBox // we'll add. Instead we add containers and a new autowrapped Label inside. // Main VBoxContainer (icon + label on top, checkbox at bottom) var aboutVBox = new VBoxContainer(); aboutDialog.AddChild(aboutVBox); // HBoxContainer for icon + label var aboutHBox = new HBoxContainer(); aboutVBox.AddChild(aboutHBox); var aboutIcon = new TextureRect(); aboutIcon.Texture = aboutIcon.GetIcon("NodeWarning", "EditorIcons"); aboutHBox.AddChild(aboutIcon); var aboutLabel = new Label(); aboutHBox.AddChild(aboutLabel); aboutLabel.RectMinSize = new Vector2(600, 150) * EditorScale; aboutLabel.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill; aboutLabel.Autowrap = true; aboutLabel.Text = "C# support in Godot Engine is in late alpha stage and, while already usable, " + "it is not meant for use in production.\n\n" + "Projects can be exported to Linux, macOS and Windows, but not yet to mobile or web platforms. " + "Bugs and usability issues will be addressed gradually over future releases, " + "potentially including compatibility breaking changes as new features are implemented for a better overall C# experience.\n\n" + "If you experience issues with this Mono build, please report them on Godot's issue tracker with details about your system, MSBuild version, IDE, etc.:\n\n" + " https://github.com/godotengine/godot/issues\n\n" + "Your critical feedback at this stage will play a great role in shaping the C# support in future releases, so thank you!"; EditorDef("mono/editor/show_info_on_start", true); // CheckBox in main container aboutDialogCheckBox = new CheckBox { Text = "Show this warning when starting the editor" }; aboutDialogCheckBox.Connect("toggled", this, nameof(_ToggleAboutDialogOnStart)); aboutVBox.AddChild(aboutDialogCheckBox); } if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath)) { // Make sure the existing project has Api assembly references configured correctly CSharpProject.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); } else { bottomPanelBtn.Hide(); menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln); } menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed)); var buildButton = new ToolButton { Text = "Build", HintTooltip = "Build solution", FocusMode = Control.FocusModeEnum.None }; buildButton.Connect("pressed", this, nameof(_BuildSolutionPressed)); AddControlToContainer(CustomControlContainer.Toolbar, buildButton); // External editor settings EditorDef("mono/editor/external_editor", ExternalEditor.None); string settingsHintStr = "Disabled"; if (OS.IsWindows()) { settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" + $",Visual Studio Code:{(int) ExternalEditor.VsCode}"; } else if (OS.IsOSX()) { settingsHintStr += $",Visual Studio:{(int) ExternalEditor.VisualStudioForMac}" + $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" + $",Visual Studio Code:{(int) ExternalEditor.VsCode}"; } else if (OS.IsUnix()) { settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" + $",Visual Studio Code:{(int) ExternalEditor.VsCode}"; } editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary { ["type"] = Variant.Type.Int, ["name"] = "mono/editor/external_editor", ["hint"] = PropertyHint.Enum, ["hint_string"] = settingsHintStr }); // Export plugin var exportPlugin = new GodotSharpExport(); AddExportPlugin(exportPlugin); exportPluginWeak = WeakRef(exportPlugin); GodotSharpBuilds.Initialize(); }
public Error OpenInExternalEditor(Script script, int line, int col) { var editor = (ExternalEditor)editorSettings.GetSetting("mono/editor/external_editor"); switch (editor) { case ExternalEditor.VsCode: { if (_vsCodePath.Empty() || !File.Exists(_vsCodePath)) { // Try to search it again if it wasn't found last time or if it was removed from its location _vsCodePath = VsCodeNames.SelectFirstNotNull(OS.PathWhich, orElse: string.Empty); } var args = new List <string>(); bool osxAppBundleInstalled = false; if (OS.IsOSX()) { // The package path is '/Applications/Visual Studio Code.app' const string vscodeBundleId = "com.microsoft.VSCode"; osxAppBundleInstalled = Internal.IsOsxAppBundleInstalled(vscodeBundleId); if (osxAppBundleInstalled) { args.Add("-b"); args.Add(vscodeBundleId); // The reusing of existing windows made by the 'open' command might not choose a wubdiw that is // editing our folder. It's better to ask for a new window and let VSCode do the window management. args.Add("-n"); // The open process must wait until the application finishes (which is instant in VSCode's case) args.Add("--wait-apps"); args.Add("--args"); } } var resourcePath = ProjectSettings.GlobalizePath("res://"); args.Add(resourcePath); string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath); if (line >= 0) { args.Add("-g"); args.Add($"{scriptPath}:{line + 1}:{col}"); } else { args.Add(scriptPath); } string command; if (OS.IsOSX()) { if (!osxAppBundleInstalled && _vsCodePath.Empty()) { GD.PushError("Cannot find code editor: VSCode"); return(Error.FileNotFound); } command = osxAppBundleInstalled ? "/usr/bin/open" : _vsCodePath; } else { if (_vsCodePath.Empty()) { GD.PushError("Cannot find code editor: VSCode"); return(Error.FileNotFound); } command = _vsCodePath; } try { OS.RunProcess(command, args); } catch (Exception e) { GD.PushError($"Error when trying to run code editor: VSCode. Exception message: '{e.Message}'"); } break; } case ExternalEditor.VisualStudioForMac: goto case ExternalEditor.MonoDevelop; case ExternalEditor.MonoDevelop: { MonoDevelopInstance GetMonoDevelopInstance(string solutionPath) { if (OS.IsOSX() && editor == ExternalEditor.VisualStudioForMac) { if (visualStudioForMacInstance == null) { visualStudioForMacInstance = new MonoDevelopInstance(solutionPath, MonoDevelopInstance.EditorId.VisualStudioForMac); } return(visualStudioForMacInstance); } if (monoDevelopInstance == null) { monoDevelopInstance = new MonoDevelopInstance(solutionPath, MonoDevelopInstance.EditorId.MonoDevelop); } return(monoDevelopInstance); } string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath); if (line >= 0) { scriptPath += $";{line + 1};{col}"; } GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath).Execute(scriptPath); break; } case ExternalEditor.None: return(Error.Unavailable); default: throw new ArgumentOutOfRangeException(); } return(Error.Ok); }