BuildWindow.cs 11 KB

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