BuildWindow.cs 11 KB

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