diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs
index 0088cdf86..261090d4a 100644
--- a/Source/Editor/Windows/GameCookerWindow.cs
+++ b/Source/Editor/Windows/GameCookerWindow.cs
@@ -196,6 +196,12 @@ namespace FlaxEditor.Windows
var label = layout.Label(text, TextAlignment.Center);
label.Label.AutoHeight = true;
}
+
+ ///
+ /// Used to add platform specific tools if available.
+ ///
+ /// The layout to start the tools at.
+ public virtual void OnCustomToolsLayout(LayoutElementsContainer layout) { }
public virtual void Build()
{
@@ -237,6 +243,272 @@ namespace FlaxEditor.Windows
class Android : Platform
{
protected override BuildPlatform BuildPlatform => BuildPlatform.AndroidARM64;
+
+ ///
+ public override void OnCustomToolsLayout(LayoutElementsContainer layout)
+ {
+ base.OnCustomToolsLayout(layout);
+
+ // Add emulation options to android tab.
+ layout.Space(5);
+ var emulatorGroup = layout.Group("Tools");
+ var sdkPath = Environment.GetEnvironmentVariable("ANDROID_HOME");
+ if (string.IsNullOrEmpty(sdkPath))
+ sdkPath = Environment.GetEnvironmentVariable("ANDROID_SDK");
+ emulatorGroup.Label($"SDK path: {sdkPath}");
+
+ // AVD and starting emulator
+ var avdGroup = emulatorGroup.Group("AVD Emulator");
+ avdGroup.Label("Note: Create AVDs using Android Studio.");
+ avdGroup.Panel.IsClosed = false;
+ var refreshAVDListButton = avdGroup.Button("Refresh AVD list").Button;
+ var avdListGroup = avdGroup.Group("AVD List");
+ avdListGroup.Panel.IsClosed = false;
+ var noAvdLabel = avdListGroup.Label("No AVDs detected. Click Refresh.", TextAlignment.Center).Label;
+ var avdListTree = new Tree(false)
+ {
+ Parent = avdListGroup.Panel,
+ };
+ refreshAVDListButton.Clicked += () =>
+ {
+ if (avdListTree.Children.Count > 0)
+ avdListTree.DisposeChildren();
+
+ var processStartInfo = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = Path.Combine(sdkPath, "emulator", "emulator.exe"),
+ Arguments = "-list-avds",
+ RedirectStandardOutput = true,
+ CreateNoWindow = true,
+ };
+
+ var process = new System.Diagnostics.Process
+ {
+ StartInfo = processStartInfo
+ };
+ process.Start();
+ var output = new string(process.StandardOutput.ReadToEnd());
+ /*
+ CreateProcessSettings processSettings = new CreateProcessSettings
+ {
+ FileName = Path.Combine(sdkPath, "emulator", "emulator.exe"),
+ Arguments = "-list-avds",
+ HiddenWindow = false,
+ SaveOutput = true,
+ WaitForEnd = true,
+ };
+ //processSettings.ShellExecute = true;
+ FlaxEngine.Platform.CreateProcess(ref processSettings);
+
+ var output = new string(processSettings.Output);*/
+ if (output.Length == 0)
+ {
+ noAvdLabel.Visible = true;
+ FlaxEditor.Editor.LogWarning("No AVDs detected.");
+ return;
+ }
+ noAvdLabel.Visible = false;
+ var splitOutput = output.Split('\n');
+ foreach (var line in splitOutput)
+ {
+ if (string.IsNullOrEmpty(line.Trim()))
+ continue;
+ var item = new TreeNode
+ {
+ Text = line.Trim(),
+ Parent = avdListTree,
+ };
+ }
+ avdListGroup.Panel.IsClosed = false;
+ };
+
+ avdGroup.Label("Emulator AVD Commands:");
+ var commandsTextBox = avdGroup.TextBox().TextBox;
+ commandsTextBox.IsMultiline = false;
+ commandsTextBox.Text = "-no-snapshot-load -no-boot-anim"; // TODO: save user changes
+
+ var startEmulatorButton = avdGroup.Button("Start AVD Emulator").Button;
+ startEmulatorButton.TooltipText = "Starts selected AVD from list.";
+ startEmulatorButton.Clicked += () =>
+ {
+ if (avdListTree.Selection.Count == 0)
+ return;
+
+ CreateProcessSettings processSettings = new CreateProcessSettings
+ {
+ FileName = Path.Combine(sdkPath, "emulator", "emulator.exe"),
+ Arguments = $"-avd {avdListTree.Selection[0].Text} {commandsTextBox.Text}",
+ HiddenWindow = true,
+ SaveOutput = false,
+ WaitForEnd = false,
+ };
+ processSettings.ShellExecute = true;
+ FlaxEngine.Platform.CreateProcess(ref processSettings);
+ };
+
+ emulatorGroup.Space(2);
+
+ // Device
+ var installGroup = emulatorGroup.Group("Install");
+ installGroup.Panel.IsClosed = false;
+ installGroup.Label("Note: Used to install to AVD or physical devices.");
+ var refreshDeviceListButton = installGroup.Button("Refresh device list").Button;
+ var deviceListGroup = installGroup.Group("List of devices");
+ deviceListGroup.Panel.IsClosed = false;
+ var noDevicesLabel = deviceListGroup.Label("No devices found. Click Refresh.", TextAlignment.Center).Label;
+ var deviceListTree = new Tree(false)
+ {
+ Parent = deviceListGroup.Panel,
+ };
+ refreshDeviceListButton.Clicked += () =>
+ {
+ if (deviceListTree.Children.Count > 0)
+ deviceListTree.DisposeChildren();
+
+ var processStartInfo = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
+ Arguments = "devices -l",
+ RedirectStandardOutput = true,
+ CreateNoWindow = true,
+ };
+
+ var process = new System.Diagnostics.Process
+ {
+ StartInfo = processStartInfo
+ };
+ process.Start();
+ var output = new string(process.StandardOutput.ReadToEnd());
+ /*
+ CreateProcessSettings processSettings = new CreateProcessSettings
+ {
+ FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
+ Arguments = "devices -l",
+ HiddenWindow = false,
+ //SaveOutput = true,
+ WaitForEnd = true,
+ };
+ processSettings.SaveOutput = true;
+ processSettings.ShellExecute = false;
+ FlaxEngine.Platform.CreateProcess(ref processSettings);
+
+ var output = new string(processSettings.Output);
+ */
+
+ if (output.Length > 0 && !output.Equals("List of devices attached", StringComparison.Ordinal))
+ {
+ noDevicesLabel.Visible = false;
+ var splitLines = output.Split('\n');
+ foreach (var line in splitLines)
+ {
+ if (line.Trim().Equals("List of devices attached", StringComparison.Ordinal) || string.IsNullOrEmpty(line.Trim()))
+ continue;
+
+ var tab = line.Split("device ");
+ if (tab.Length < 2)
+ continue;
+ var item = new TreeNode
+ {
+ Text = $"{tab[0].Trim()} - {tab[1].Trim()}",
+ Tag = tab[0].Trim(),
+ Parent = deviceListTree,
+ };
+ }
+ }
+ else
+ {
+ noDevicesLabel.Visible = true;
+ }
+
+ deviceListGroup.Panel.IsClosed = false;
+ };
+
+ var autoStart = installGroup.Checkbox("Try to auto start activity on device.");
+ var installButton = installGroup.Button("Install APK to Device").Button;
+ installButton.TooltipText = "Installs APK from the output folder to the selected device.";
+ installButton.Clicked += () =>
+ {
+ if (deviceListTree.Selection.Count == 0)
+ return;
+
+ // Get built APK at output path
+ string output = StringUtils.ConvertRelativePathToAbsolute(Globals.ProjectFolder, StringUtils.NormalizePath(Output));
+ if (!Directory.Exists(output))
+ {
+ FlaxEditor.Editor.LogWarning("Can not copy APK because output folder does not exist.");
+ return;
+ }
+
+ var apkFiles = Directory.GetFiles(output, "*.apk");
+ if (apkFiles.Length == 0)
+ {
+ FlaxEditor.Editor.LogWarning("Can not copy APK because no .apk files were found in output folder.");
+ return;
+ }
+
+ string apkFilesString = string.Empty;
+ for (int i = 0; i < apkFiles.Length; i++)
+ {
+ var file = apkFiles[i];
+ if (i == 0)
+ {
+ apkFilesString = $"\"{file}\"";
+ continue;
+ }
+ apkFilesString += $" \"{file}\"";
+ }
+
+ CreateProcessSettings processSettings = new CreateProcessSettings
+ {
+ FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
+ Arguments = $"-s {deviceListTree.Selection[0].Tag} {(apkFiles.Length > 1 ? "install-multiple" : "install")} {apkFilesString}",
+ LogOutput = true,
+ };
+ FlaxEngine.Platform.CreateProcess(ref processSettings);
+
+ if (autoStart.CheckBox.Checked)
+ {
+ var gameSettings = GameSettings.Load();
+ var productName = gameSettings.ProductName.Replace(" ", "").ToLower();
+ var companyName = gameSettings.CompanyName.Replace(" ", "").ToLower();
+ CreateProcessSettings processSettings1 = new CreateProcessSettings
+ {
+ FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
+ Arguments = $"shell am start -n com.{companyName}.{productName}/com.flaxengine.GameActivity",
+ LogOutput = true,
+ };
+ FlaxEngine.Platform.CreateProcess(ref processSettings1);
+ }
+ };
+
+ var adbLogButton = emulatorGroup.Button("Start adb log collecting").Button;
+ adbLogButton.TooltipText = "In debug and development builds the engine and game logs can be output directly to the adb.";
+ adbLogButton.Clicked += () =>
+ {
+ var processStartInfo = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
+ Arguments = "logcat Flax:I *:S",
+ CreateNoWindow = false,
+ WindowStyle = ProcessWindowStyle.Normal,
+ };
+
+ var process = new System.Diagnostics.Process
+ {
+ StartInfo = processStartInfo
+ };
+ process.Start();
+ /*
+ CreateProcessSettings processSettings = new CreateProcessSettings
+ {
+ FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
+ Arguments = $"logcat Flax:I *:S",
+ WaitForEnd = false,
+ };
+ FlaxEngine.Platform.CreateProcess(ref processSettings);
+ */
+ };
+ }
}
class Switch : Platform
@@ -347,269 +619,7 @@ namespace FlaxEditor.Windows
_buildButton = layout.Button("Build").Button;
_buildButton.Clicked += OnBuildClicked;
-
- // Add emulation options to android tab.
- if (_platform == PlatformType.Android)
- {
- layout.Space(5);
- var emulatorGroup = layout.Group("Tools");
- var sdkPath = Environment.GetEnvironmentVariable("ANDROID_HOME");
- if (string.IsNullOrEmpty(sdkPath))
- sdkPath = Environment.GetEnvironmentVariable("ANDROID_SDK");
- emulatorGroup.Label($"SDK path: {sdkPath}");
-
- // AVD and starting emulator
- var avdGroup = emulatorGroup.Group("AVD Emulator");
- avdGroup.Label("Note: Create AVDs using Android Studio.");
- avdGroup.Panel.IsClosed = false;
- var refreshAVDListButton = avdGroup.Button("Refresh AVD list").Button;
- var avdListGroup = avdGroup.Group("AVD List");
- avdListGroup.Panel.IsClosed = false;
- var noAvdLabel = avdListGroup.Label("No AVDs detected. Click Refresh.", TextAlignment.Center).Label;
- var avdListTree = new Tree(false)
- {
- Parent = avdListGroup.Panel,
- };
- refreshAVDListButton.Clicked += () =>
- {
- if (avdListTree.Children.Count > 0)
- avdListTree.DisposeChildren();
-
- var processStartInfo = new System.Diagnostics.ProcessStartInfo
- {
- FileName = Path.Combine(sdkPath, "emulator", "emulator.exe"),
- Arguments = "-list-avds",
- RedirectStandardOutput = true,
- CreateNoWindow = true,
- };
-
- var process = new System.Diagnostics.Process
- {
- StartInfo = processStartInfo
- };
- process.Start();
- var output = new string(process.StandardOutput.ReadToEnd());
- /*
- CreateProcessSettings processSettings = new CreateProcessSettings
- {
- FileName = Path.Combine(sdkPath, "emulator", "emulator.exe"),
- Arguments = "-list-avds",
- HiddenWindow = false,
- SaveOutput = true,
- WaitForEnd = true,
- };
- //processSettings.ShellExecute = true;
- FlaxEngine.Platform.CreateProcess(ref processSettings);
-
- var output = new string(processSettings.Output);*/
- if (output.Length == 0)
- {
- noAvdLabel.Visible = true;
- FlaxEditor.Editor.LogWarning("No AVDs detected.");
- return;
- }
- noAvdLabel.Visible = false;
- var splitOutput = output.Split('\n');
- foreach (var line in splitOutput)
- {
- if (string.IsNullOrEmpty(line.Trim()))
- continue;
- var item = new TreeNode
- {
- Text = line.Trim(),
- Parent = avdListTree,
- };
- }
- avdListGroup.Panel.IsClosed = false;
- };
-
- avdGroup.Label("Emulator AVD Commands:");
- var commandsTextBox = avdGroup.TextBox().TextBox;
- commandsTextBox.IsMultiline = false;
- commandsTextBox.Text = "-no-snapshot-load -no-boot-anim"; // TODO: save user changes
-
- var startEmulatorButton = avdGroup.Button("Start AVD Emulator").Button;
- startEmulatorButton.TooltipText = "Starts selected AVD from list.";
- startEmulatorButton.Clicked += () =>
- {
- if (avdListTree.Selection.Count == 0)
- return;
-
- CreateProcessSettings processSettings = new CreateProcessSettings
- {
- FileName = Path.Combine(sdkPath, "emulator", "emulator.exe"),
- Arguments = $"-avd {avdListTree.Selection[0].Text} {commandsTextBox.Text}",
- HiddenWindow = true,
- SaveOutput = false,
- WaitForEnd = false,
- };
- processSettings.ShellExecute = true;
- FlaxEngine.Platform.CreateProcess(ref processSettings);
- };
-
- emulatorGroup.Space(2);
-
- // Device
- var installGroup = emulatorGroup.Group("Install");
- installGroup.Panel.IsClosed = false;
- installGroup.Label("Note: Used to install to AVD or physical devices.");
- var refreshDeviceListButton = installGroup.Button("Refresh device list").Button;
- var deviceListGroup = installGroup.Group("List of devices");
- deviceListGroup.Panel.IsClosed = false;
- var noDevicesLabel = deviceListGroup.Label("No devices found. Click Refresh.", TextAlignment.Center).Label;
- var deviceListTree = new Tree(false)
- {
- Parent = deviceListGroup.Panel,
- };
- refreshDeviceListButton.Clicked += () =>
- {
- if (deviceListTree.Children.Count > 0)
- deviceListTree.DisposeChildren();
-
- var processStartInfo = new System.Diagnostics.ProcessStartInfo
- {
- FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
- Arguments = "devices -l",
- RedirectStandardOutput = true,
- CreateNoWindow = true,
- };
-
- var process = new System.Diagnostics.Process
- {
- StartInfo = processStartInfo
- };
- process.Start();
- var output = new string(process.StandardOutput.ReadToEnd());
- /*
- CreateProcessSettings processSettings = new CreateProcessSettings
- {
- FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
- Arguments = "devices -l",
- HiddenWindow = false,
- //SaveOutput = true,
- WaitForEnd = true,
- };
- processSettings.SaveOutput = true;
- processSettings.ShellExecute = false;
- FlaxEngine.Platform.CreateProcess(ref processSettings);
-
- var output = new string(processSettings.Output);
- */
-
- if (output.Length > 0 && !output.Equals("List of devices attached", StringComparison.Ordinal))
- {
- noDevicesLabel.Visible = false;
- var splitLines = output.Split('\n');
- foreach (var line in splitLines)
- {
- if (line.Trim().Equals("List of devices attached", StringComparison.Ordinal) || string.IsNullOrEmpty(line.Trim()))
- continue;
-
- var tab = line.Split("device ");
- if (tab.Length < 2)
- continue;
- var item = new TreeNode
- {
- Text = $"{tab[0].Trim()} - {tab[1].Trim()}",
- Tag = tab[0].Trim(),
- Parent = deviceListTree,
- };
- }
- }
- else
- {
- noDevicesLabel.Visible = true;
- }
-
- deviceListGroup.Panel.IsClosed = false;
- };
-
- var autoStart = installGroup.Checkbox("Try to auto start activity on device.");
- var installButton = installGroup.Button("Install APK to Device").Button;
- installButton.TooltipText = "Installs APK from the output folder to the selected device.";
- installButton.Clicked += () =>
- {
- if (deviceListTree.Selection.Count == 0)
- return;
-
- // Get built APK at output path
- string output = StringUtils.ConvertRelativePathToAbsolute(Globals.ProjectFolder, StringUtils.NormalizePath(proxy.PerPlatformOptions[_platform].Output));
- if (!Directory.Exists(output))
- {
- FlaxEditor.Editor.LogWarning("Can not copy APK because output folder does not exist.");
- return;
- }
-
- var apkFiles = Directory.GetFiles(output, "*.apk");
- if (apkFiles.Length == 0)
- {
- FlaxEditor.Editor.LogWarning("Can not copy APK because no .apk files were found in output folder.");
- return;
- }
-
- string apkFilesString = string.Empty;
- for (int i = 0; i < apkFiles.Length; i++)
- {
- var file = apkFiles[i];
- if (i == 0)
- {
- apkFilesString = $"\"{file}\"";
- continue;
- }
- apkFilesString += $" \"{file}\"";
- }
-
- CreateProcessSettings processSettings = new CreateProcessSettings
- {
- FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
- Arguments = $"-s {deviceListTree.Selection[0].Tag} {(apkFiles.Length > 1 ? "install-multiple" : "install")} {apkFilesString}",
- LogOutput = true,
- };
- FlaxEngine.Platform.CreateProcess(ref processSettings);
-
- if (autoStart.CheckBox.Checked)
- {
- var gameSettings = GameSettings.Load();
- var productName = gameSettings.ProductName.Replace(" ", "").ToLower();
- var companyName = gameSettings.CompanyName.Replace(" ", "").ToLower();
- CreateProcessSettings processSettings1 = new CreateProcessSettings
- {
- FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
- Arguments = $"shell am start -n com.{companyName}.{productName}/com.flaxengine.GameActivity",
- LogOutput = true,
- };
- FlaxEngine.Platform.CreateProcess(ref processSettings1);
- }
- };
-
- var adbLogButton = emulatorGroup.Button("Start adb log collecting").Button;
- adbLogButton.TooltipText = "In debug and development builds the engine and game logs can be output directly to the adb.";
- adbLogButton.Clicked += () =>
- {
- var processStartInfo = new System.Diagnostics.ProcessStartInfo
- {
- FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
- Arguments = "logcat Flax:I *:S",
- CreateNoWindow = false,
- WindowStyle = ProcessWindowStyle.Normal,
- };
-
- var process = new System.Diagnostics.Process
- {
- StartInfo = processStartInfo
- };
- process.Start();
- /*
- CreateProcessSettings processSettings = new CreateProcessSettings
- {
- FileName = Path.Combine(sdkPath, "platform-tools", "adb.exe"),
- Arguments = $"logcat Flax:I *:S",
- WaitForEnd = false,
- };
- FlaxEngine.Platform.CreateProcess(ref processSettings);
- */
- };
- }
+ platformObj.OnCustomToolsLayout(layout);
}
else
{