BuildWindow.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using BansheeEngine;
  5. namespace BansheeEditor
  6. {
  7. /// <summary>
  8. /// Provides options for customizing and activating the build process which will output an executable of the game for a
  9. /// specific platform, as well as any required resources.
  10. /// </summary>
  11. [DefaultSize(500, 300)]
  12. internal sealed class BuildWindow : EditorWindow
  13. {
  14. private static readonly Color PLATFORM_BG_COLOR = new Color(33.0f / 255.0f, 33.0f / 255.0f, 33.0f / 255.0f);
  15. private PlatformType selectedPlatform;
  16. private GUIScrollArea optionsScrollArea;
  17. private ulong buildScheduledFrame = ulong.MaxValue;
  18. private GUIToggle[] platformButtons;
  19. /// <summary>
  20. /// Opens the build window if its not open already.
  21. /// </summary>
  22. [MenuItem("Tools/Build", ButtonModifier.CtrlAlt, ButtonCode.B, 9249)]
  23. private static void OpenBuildWindow()
  24. {
  25. OpenWindow<BuildWindow>();
  26. }
  27. /// <inheritdoc/>
  28. protected override LocString GetDisplayName()
  29. {
  30. return new LocEdString("Build");
  31. }
  32. private void OnInitialize()
  33. {
  34. GUILayoutX splitLayout = GUI.AddLayoutX();
  35. GUIPanel platformPanel = splitLayout.AddPanel();
  36. GUIPanel platformForeground = platformPanel.AddPanel();
  37. GUILayoutY platformLayout = platformForeground.AddLayoutY();
  38. GUIPanel platformBackground = platformPanel.AddPanel(1);
  39. GUITexture background = new GUITexture(Builtin.WhiteTexture);
  40. background.SetTint(PLATFORM_BG_COLOR);
  41. splitLayout.AddSpace(5);
  42. GUILayoutY optionsLayout = splitLayout.AddLayoutY();
  43. GUILabel platformsLabel = new GUILabel(new LocEdString("Platforms"), EditorStyles.LabelCentered);
  44. platformLayout.AddSpace(5);
  45. platformLayout.AddElement(platformsLabel);
  46. platformLayout.AddSpace(5);
  47. GUIToggleGroup platformToggleGroup = new GUIToggleGroup();
  48. PlatformType[] availablePlatforms = BuildManager.AvailablePlatforms;
  49. platformButtons = new GUIToggle[availablePlatforms.Length];
  50. for (int i = 0; i < availablePlatforms.Length; i++)
  51. {
  52. PlatformType currentPlatform = availablePlatforms[i];
  53. bool isActive = currentPlatform == BuildManager.ActivePlatform;
  54. string platformName = Enum.GetName(typeof(PlatformType), currentPlatform);
  55. if (isActive)
  56. platformName += " (Active)";
  57. GUIToggle platformToggle = new GUIToggle(new LocEdString(platformName), platformToggleGroup, EditorStyles.Button);
  58. platformToggle.OnToggled += x => OnSelectedPlatformChanged(currentPlatform, x);
  59. platformLayout.AddElement(platformToggle);
  60. platformButtons[i] = platformToggle;
  61. if (isActive)
  62. {
  63. platformToggle.Value = true;
  64. selectedPlatform = currentPlatform;
  65. }
  66. }
  67. platformLayout.AddFlexibleSpace();
  68. GUIButton changePlatformBtn = new GUIButton(new LocEdString("Set active"));
  69. platformLayout.AddElement(changePlatformBtn);
  70. changePlatformBtn.OnClick += ChangeActivePlatform;
  71. platformBackground.AddElement(background);
  72. optionsScrollArea = new GUIScrollArea();
  73. optionsLayout.AddElement(optionsScrollArea);
  74. GUIButton buildButton = new GUIButton(new LocEdString("Build"));
  75. optionsLayout.AddFlexibleSpace();
  76. optionsLayout.AddElement(buildButton);
  77. buildButton.OnClick += TryStartBuild;
  78. BuildPlatformOptionsGUI();
  79. }
  80. private void OnEditorUpdate()
  81. {
  82. if (buildScheduledFrame == Time.FrameIdx)
  83. {
  84. BuildManager.Build();
  85. ProgressBar.Hide();
  86. EditorApplication.OpenExternally(BuildManager.OutputFolder);
  87. DialogBox.Open(new LocEdString("Build complete"), new LocEdString("Build complete"), DialogBox.Type.OK);
  88. }
  89. }
  90. /// <summary>
  91. /// Changes the currently selected platform. Be aware that while platform is selected and you may build for it,
  92. /// it will not be made the active platform.
  93. /// </summary>
  94. /// <param name="type">Platform that was selected or deselected.</param>
  95. /// <param name="selected">True if the platform was selected, false otherwise.</param>
  96. private void OnSelectedPlatformChanged(PlatformType type, bool selected)
  97. {
  98. if (selected)
  99. {
  100. selectedPlatform = type;
  101. BuildPlatformOptionsGUI();
  102. }
  103. }
  104. /// <summary>
  105. /// Changes the currently active build platform.
  106. /// </summary>
  107. private void ChangeActivePlatform()
  108. {
  109. BuildManager.ActivePlatform = selectedPlatform;
  110. PlatformType[] availablePlatforms = BuildManager.AvailablePlatforms;
  111. for (int i = 0; i < availablePlatforms.Length; i++)
  112. {
  113. PlatformType currentPlatform = availablePlatforms[i];
  114. bool isActive = currentPlatform == BuildManager.ActivePlatform;
  115. string platformName = Enum.GetName(typeof (PlatformType), currentPlatform);
  116. if (isActive)
  117. platformName += " (Active)";
  118. platformButtons[i].SetContent(new LocEdString(platformName));
  119. }
  120. }
  121. /// <summary>
  122. /// (Re)creates GUI with platform-specific options.
  123. /// </summary>
  124. private void BuildPlatformOptionsGUI()
  125. {
  126. optionsScrollArea.Layout.Clear();
  127. GUILayout layout = optionsScrollArea.Layout;
  128. PlatformInfo platformInfo = BuildManager.GetPlatformInfo(selectedPlatform);
  129. GUILabel options = new GUILabel(new LocEdString("Platform options"), EditorStyles.LabelCentered);
  130. GUIResourceField sceneField = new GUIResourceField(typeof(Prefab), new LocEdString("Startup scene"));
  131. GUIToggleField debugToggle = new GUIToggleField(new LocEdString("Debug"));
  132. GUIToggleField fullscreenField = new GUIToggleField(new LocEdString("Fullscreen"));
  133. GUIIntField widthField = new GUIIntField(new LocEdString("Window width"));
  134. GUIIntField heightField = new GUIIntField(new LocEdString("Window height"));
  135. GUITextField definesField = new GUITextField(new LocEdString("Defines"));
  136. layout.AddSpace(5);
  137. layout.AddElement(options);
  138. layout.AddSpace(5);
  139. layout.AddElement(sceneField);
  140. layout.AddElement(debugToggle);
  141. layout.AddElement(fullscreenField);
  142. layout.AddElement(widthField);
  143. layout.AddElement(heightField);
  144. layout.AddSpace(5);
  145. layout.AddElement(definesField);
  146. layout.AddSpace(5);
  147. sceneField.ValueRef = platformInfo.MainScene;
  148. debugToggle.Value = platformInfo.Debug;
  149. definesField.Value = platformInfo.Defines;
  150. fullscreenField.Value = platformInfo.Fullscreen;
  151. widthField.Value = platformInfo.WindowedWidth;
  152. heightField.Value = platformInfo.WindowedHeight;
  153. if (platformInfo.Fullscreen)
  154. {
  155. widthField.Active = false;
  156. heightField.Active = false;
  157. }
  158. sceneField.OnChanged += x => platformInfo.MainScene = x;
  159. debugToggle.OnChanged += x => platformInfo.Debug = x;
  160. definesField.OnChanged += x => platformInfo.Defines = x;
  161. fullscreenField.OnChanged += x =>
  162. {
  163. widthField.Active = !x;
  164. heightField.Active = !x;
  165. platformInfo.Fullscreen = x;
  166. };
  167. widthField.OnChanged += x => platformInfo.WindowedWidth = x;
  168. heightField.OnChanged += x => platformInfo.WindowedHeight = x;
  169. switch (platformInfo.Type)
  170. {
  171. case PlatformType.Windows:
  172. {
  173. WinPlatformInfo winPlatformInfo = (WinPlatformInfo) platformInfo;
  174. GUITextField titleField = new GUITextField(new LocEdString("Title"));
  175. layout.AddElement(titleField);
  176. layout.AddSpace(5);
  177. GUITextureField iconField = new GUITextureField(new LocEdString("Icon"));
  178. layout.AddElement(iconField);
  179. titleField.Value = winPlatformInfo.TitleText;
  180. iconField.ValueRef = winPlatformInfo.Icon;
  181. titleField.OnChanged += x => winPlatformInfo.TitleText = x;
  182. iconField.OnChanged += x => winPlatformInfo.Icon = x;
  183. }
  184. break;
  185. }
  186. }
  187. /// <summary>
  188. /// Starts the build process for the currently selected platform.
  189. /// </summary>
  190. private void Build()
  191. {
  192. ProgressBar.Show(new LocEdString("Building..."), 0.0f);
  193. EditorApplication.SaveProject();
  194. // HACK - Delay build one frame so that progress bar has a chance to show. Use coroutines here once implemented.
  195. buildScheduledFrame = Time.FrameIdx + 1;
  196. }
  197. /// <summary>
  198. /// Attempts to save the current scene, and keeps retrying if failed or until user cancels.
  199. /// </summary>
  200. private void TrySaveScene()
  201. {
  202. EditorApplication.SaveScene(Build, TrySaveScene);
  203. }
  204. /// <summary>
  205. /// Attempts to start the build process if user confirms.
  206. /// </summary>
  207. private void TryStartBuild()
  208. {
  209. Action<DialogBox.ResultType> dialogCallback =
  210. (result) =>
  211. {
  212. if (result == DialogBox.ResultType.Yes)
  213. TrySaveScene();
  214. else if (result == DialogBox.ResultType.No)
  215. Build();
  216. };
  217. if (EditorApplication.IsSceneModified())
  218. {
  219. DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
  220. DialogBox.Type.YesNoCancel, dialogCallback);
  221. }
  222. else
  223. {
  224. Build();
  225. }
  226. }
  227. }
  228. }