BuildWindow.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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 bool buildScheduled;
  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, 9296)]
  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 (buildScheduled)
  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. buildScheduled = false;
  87. }
  88. }
  89. /// <summary>
  90. /// Changes the currently selected platform. Be aware that while platform is selected and you may build for it,
  91. /// it will not be made the active platform.
  92. /// </summary>
  93. /// <param name="type">Platform that was selected or deselected.</param>
  94. /// <param name="selected">True if the platform was selected, false otherwise.</param>
  95. private void OnSelectedPlatformChanged(PlatformType type, bool selected)
  96. {
  97. if (selected)
  98. {
  99. selectedPlatform = type;
  100. BuildPlatformOptionsGUI();
  101. }
  102. }
  103. /// <summary>
  104. /// Changes the currently active build platform.
  105. /// </summary>
  106. private void ChangeActivePlatform()
  107. {
  108. BuildManager.ActivePlatform = selectedPlatform;
  109. PlatformType[] availablePlatforms = BuildManager.AvailablePlatforms;
  110. for (int i = 0; i < availablePlatforms.Length; i++)
  111. {
  112. PlatformType currentPlatform = availablePlatforms[i];
  113. bool isActive = currentPlatform == BuildManager.ActivePlatform;
  114. string platformName = Enum.GetName(typeof (PlatformType), currentPlatform);
  115. if (isActive)
  116. platformName += " (Active)";
  117. platformButtons[i].SetContent(new LocEdString(platformName));
  118. }
  119. }
  120. /// <summary>
  121. /// (Re)creates GUI with platform-specific options.
  122. /// </summary>
  123. private void BuildPlatformOptionsGUI()
  124. {
  125. optionsScrollArea.Layout.Clear();
  126. GUILayout layout = optionsScrollArea.Layout;
  127. PlatformInfo platformInfo = BuildManager.GetPlatformInfo(selectedPlatform);
  128. GUILabel options = new GUILabel(new LocEdString("Platform options"), EditorStyles.LabelCentered);
  129. GUIResourceField sceneField = new GUIResourceField(typeof(Prefab), new LocEdString("Startup scene"));
  130. GUIToggleField debugToggle = new GUIToggleField(new LocEdString("Debug"));
  131. GUIToggleField fullscreenField = new GUIToggleField(new LocEdString("Fullscreen"));
  132. GUIIntField widthField = new GUIIntField(new LocEdString("Window width"));
  133. GUIIntField heightField = new GUIIntField(new LocEdString("Window height"));
  134. GUITextField definesField = new GUITextField(new LocEdString("Defines"));
  135. layout.AddSpace(5);
  136. layout.AddElement(options);
  137. layout.AddSpace(5);
  138. layout.AddElement(sceneField);
  139. layout.AddElement(debugToggle);
  140. layout.AddElement(fullscreenField);
  141. layout.AddElement(widthField);
  142. layout.AddElement(heightField);
  143. layout.AddSpace(5);
  144. layout.AddElement(definesField);
  145. layout.AddSpace(5);
  146. sceneField.Value = platformInfo.MainScene;
  147. debugToggle.Value = platformInfo.Debug;
  148. definesField.Value = platformInfo.Defines;
  149. fullscreenField.Value = platformInfo.Fullscreen;
  150. widthField.Value = platformInfo.WindowedWidth;
  151. heightField.Value = platformInfo.WindowedHeight;
  152. if (platformInfo.Fullscreen)
  153. {
  154. widthField.Active = false;
  155. heightField.Active = false;
  156. }
  157. sceneField.OnChanged += x => platformInfo.MainScene = (Prefab)x;
  158. debugToggle.OnChanged += x => platformInfo.Debug = x;
  159. definesField.OnChanged += x => platformInfo.Defines = x;
  160. fullscreenField.OnChanged += x =>
  161. {
  162. widthField.Active = !x;
  163. heightField.Active = !x;
  164. platformInfo.Fullscreen = x;
  165. };
  166. widthField.OnChanged += x => platformInfo.WindowedWidth = x;
  167. heightField.OnChanged += x => platformInfo.WindowedHeight = x;
  168. switch (platformInfo.Type)
  169. {
  170. case PlatformType.Windows:
  171. {
  172. WinPlatformInfo winPlatformInfo = (WinPlatformInfo) platformInfo;
  173. GUITextField titleField = new GUITextField(new LocEdString("Title"));
  174. layout.AddElement(titleField);
  175. layout.AddSpace(5);
  176. GUITextureField iconField = new GUITextureField(new LocEdString("Icon"));
  177. layout.AddElement(iconField);
  178. titleField.Value = winPlatformInfo.TitleText;
  179. iconField.Value = winPlatformInfo.Icon;
  180. titleField.OnChanged += x => winPlatformInfo.TitleText = x;
  181. iconField.OnChanged += x => winPlatformInfo.Icon = x as Texture2D;
  182. }
  183. break;
  184. }
  185. }
  186. /// <summary>
  187. /// Starts the build process for the currently selected platform.
  188. /// </summary>
  189. private void Build()
  190. {
  191. ProgressBar.Show(new LocEdString("Building..."), 0.0f);
  192. EditorApplication.SaveProject();
  193. // HACK - Delay build one frame so that progress bar has a chance to show. Use coroutines here once implemented.
  194. buildScheduled = true;
  195. }
  196. /// <summary>
  197. /// Attempts to save the current scene, and keeps retrying if failed or until user cancels.
  198. /// </summary>
  199. private void TrySaveScene()
  200. {
  201. EditorApplication.SaveScene(Build, TrySaveScene);
  202. }
  203. /// <summary>
  204. /// Attempts to start the build process if user confirms.
  205. /// </summary>
  206. private void TryStartBuild()
  207. {
  208. Action<DialogBox.ResultType> dialogCallback =
  209. (result) =>
  210. {
  211. if (result == DialogBox.ResultType.Yes)
  212. TrySaveScene();
  213. else if (result == DialogBox.ResultType.No)
  214. {
  215. EditorApplication.SaveProject();
  216. EditorApplication.Quit();
  217. }
  218. };
  219. if (EditorApplication.IsSceneModified())
  220. {
  221. DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
  222. DialogBox.Type.YesNoCancel, dialogCallback);
  223. }
  224. else
  225. {
  226. Build();
  227. }
  228. }
  229. }
  230. }